When writing test programs, the test engineer is often faced with the task of obtaining information about the instruments installed in a chassis. This information may be essential to the ATE program, or to determine how to establish a communication link between the test program and the test resources. The HW instrument driver can be used to query a PCI-type instrument (PCI, cPCI, PXI, PCIe, or PXIe) and return information about those resources. This article focuses on the how to use the HW device driver for querying the PCI system resources.
The HW driver is a Device Driver that is installed with any Geotest product (PXI Instrument, PCI Instruments, ATEasy, DIOEasy, WAVEasy…). There are many procedures within the HW driver that are useful for determining the system configuration. The HW driver is installed in your machine under Program Files\Geotest\HW. This article will focus on just a couple of them, for more information see the HW folder, HW.h for function definition, and the HW.drv ATEasy driver:
Initialize()
The Initialize() procedure Initializes the HW driver and must be called prior to calling any of the other procedures in the HW library.
PciGetSlotNumbers([Val] Word wVendorId, [Val] Word wDeviceId, Var Short panSlotNumbers[], Var Word pwDevicesFound)
The PciGetSlotNumbers() procedure will return an array of slot number(s) for all devices matching the specified Vendor ID and Device ID.
PciGetSlotDevice(Val Long lSlot, Var structHWPCIDEVICE pstPciDev)
The PciGetSlotDevice() procedure returns device information for the instrument installed in the specified slot. The device information is contained in the structure structHWPCIDEVICE.
The structure of the structHWPCIDEVICE data type is shown below:
structHWPCIDEVICE: Struct Public
{
dwVendorId: DWord
dwDeviceId: DWord
dwBus: DWord
stPciSn: structPciSlotNumber !PCI/PXI slot number \
(5 low bit: device #, 3 bits: function #, \
8 bits: Lgacy slot, 16 chassis/slot : 0x203)
stPciCfg: strictPciCommonConfig
aResDesc: structCmPartialResourceDescriptor[8]
aMemDesc: structHwMemoryDesc[8]
szId: Char[256]
}
structPciSlotNumber: Struct Public
{
dwAsUlong: DWord
}
structPciCommonConfig: Struct Public
{
wVendorId: Word
wDeviceId: Word
wCommand: Word
wStatus: Word
ucRevisionId: Byte
ucProgIf: Byte
ucSubClass: Byte
ucBaseClass: Byte
ucCacheLineSize: Byte
ucLatencyTimer: Byte
ucHeaderType: Byte
ucBIST: Byte
stType0: structPciHeaderType0
dwDeviceSpecific: Byte[192]
}
structPciHeaderType0: Struct Public
{
adwBaseAddresses: DWord[6]
dwSubSystem: DWord
dwSubVendorID: DWord
dwROMBaseAddress: DWord
adwReserved2: DWord[2]
ucInterruptLine: Byte
ucInterruptPin: Byte
ucMinimumGrant: Byte
ucMaxinumLatency: Byte
}
structPxiChassisInfo: Struct Public
{
dwSize: Long !Fill with sizeof (PXIChassisInfo)
apcidevBridges: structHWPCIDEVICE[4] ! Bridges in the chassis
wChassisModel: Word !Chassis model # : i.e. 7010
wChassisRevision: Word
dwChassisSerial: DWord
acUserDefinedData: Char[64]
wNumberOfSlots: Word !Total number of slots in the chassis
}
structCmPartialResourceDescriptor: Struct Public
{
ucType: Byte
ucShareDisposition: Byte
wFlags: Word
Address1: DWord
Address2: DWord
Address3: DWord
}
structHwMemoryDesc: Struct Public
{
dwPhAddrLow: DWord
lPhAddrHigh: Long
dwLength: DWord
pvVirtualAddress: DWord
}
With these three procedures, you can perform many useful queries that will return information about the hardware residing on your PCI bus, although we are most interested in just the test instreuments. If, for example, you wanted to know how many GX5290 instruments were installed in a PXI chassis, their slot numbers, and the firmware revision of those instruments, you could use the following code:
wVendorId: Word =0x16E2 ! Geotest Vendor ID
wDeviceId:Word=0x5290 ! GX5290 Device ID
anSlotNumbers: Short[32] ! Array of slot numbers found
wDevicesFound:Word ! Number of slots matching the Vendor and Device ID’s
stPciDev: structHWPCIDEVICE
sDeviceInfo: String
i: Long:
Initialize()
PciGetSlotNumbers(wVendorId, wDeviceId, anSlotNumbers, wDevicesFound)
If wDevicesFound<>0
For i=0 to wDevicesFound-1
PciGetSlotDevice(panSlotNumbers[i], stPciDev)
sDeviceInfo= stPciDev.szId
Print "Slot "+Format(anSlotNumbers[i],"00")+" Firmware: "+Mid(sDeviceInfo, \
Pos("SUBSYS_",sDeviceInfo)+7,4)
Next
EndIf
Once the slot number for an instrument is obtained, it would be a simple matter to initialize the instrument using the slot number(s). In the code below, each GX5290 instrument found in the system scan performed above, is initialized as a DIO Master.
nMasterHandle: Short =0
nBrdNum: Short
wSlot: Word
nDensity:Short
nBanks: Short
anHandle:Short[1]
nStatus:Short
If wDevicesFound<>0
Redim anHandle[wDevicesFound]
For nBrdNum=0 to wDevicesFound-1
wSlot=anSlotNumbers[nBrdNum]
DioSetupInitialization(nMasterHandle, nBrdNum, wSlot, nDensity, \
nBanks, anHandle[nBrdNum], nStatus)
Next
EndIf
For additional information, review the HW programming example installed with ATEasy (HW.PRJ).