Seed Solutions, Inc.
This page is the HTML-based documentation for VNAccess.dll.
A brief mention will be made of each version, with the most recent first.
Version 2.02, dated August 11, 2005. Fixed a bug in the OZ ADC rate control code. Before this bug was fixed, the actual ADC conversion rate was 7 CPS, regardless of the rate setting (7, 25, 50, or 100 CPS).
Version 2.00, dated October 13, 2004. A number of additions and changes. Multiple hardware configurations through flexible parallel port pin assignments is supported. Multiple detectors and fast detectors are supported. A new and more flexible timing model was implemented, and it replaces VNAccessOverlap. This version, or newer, is required if you are using a LTC2440 ADC in the detector.
Version 1.02, dated March 27, 2004. The function VNAccessResetDDS was added, and the control of reset synchronization was better captured in the function calls.
Version 1.01, dated March 25, 2004. The function VNAccessADCResultTouVolts was modified to produce a voltage level which agreed with the N2PK software. VNAccessADCResultToCounts was added.
The first version, 1.00, was dated March 15, 2004.
The contents of VNAccess.zip are described by following this link. This page is part of that zip file.
Click to Download VNAccess.zip
The VNAccess (va-nak-sess) header file (VNAccess.h) has extensive comments, which detail the input parameters and output results of each function call. It also includes some example program sequences that highlight typical calls and their arguments.
The VNAccess use model is based around the idea of a VNA handle, or descriptor. To begin using VNAccess, and a VNA connected to a parallel port on the computer, you must call VNAccessOpen. If there are no errors, a handle, of type VNAHANDLE, will be returned. This handle is then used in nearly all of the calls in VNAccess. When you are done using the VNA, you should call VNAccessClose. After obtaining a valid VNAHANDLE, the VNA should be reset with a call to VNAccessReset. This will put the DDS chips in a known and synchronized state. The VNA should be reset via this call whenever the VNA is turned on. The computer software cannot determine when power is applied to or removed from the VNA. If power is removed from the VNA then reapplied, the DDS chips will lose their synchronization. This means that measurements made after power is restored will most likely be incorrect.
When calls accept or return timing information, the units are usually microseconds, not milliseconds. This is the opposite of many Windows timing functions, where the units are milliseconds. The function description in the header file details the time units.
The version of VNAccess can be obtained by calling VNAccessVersion. What will be returned is an integer value which is the major version number multiplied by 100 added to the minor version number. The version numbers start at 100, which indicates major version 1, minor version 0.
If you have a C or C++ programming environment, you should be able to include VNAccess.h in your source code, and link against VNAccess.lib, using VNAccess.dll when your application program runs. If you want to use VNAccess with Visual Basic, you will need to use VNAccess.h as a guide to write the necessary DECLARE declarations.
VNAccess.dll is thread-safe That is, the same VNAHANDLE can be used by two different threads at the same time. Calls from multiple threads will be serialized within VNAccess.dll.
If the VNA shares a parallel port (perhaps through a printer switch) with a printer, it may be desirable to try to make sure that only one use, printing or VNA access, is going on at the same time. When a printer is in use, it is will be the case that the printer device was opened by name before use, and closed when the printing is complete. A printer name is a string, such as LPT1. Printer devices can only be opened by one application at a time.
VNAccess allows you to specify the name of a printer as an argument to VNAccessOpen. If a name is specified, VNAccessOpen will attempt to open it. If the device can be opened, then that is a sign that it is not in use. VNAccess will hold the printer handle open until VNAccessClose is called. This means that any attempt to open the printer device will fail between the open and close calls. This effectively locks out the printer software, and even other programs using VNAccess.
This feature is optional. If you do not want to use it, simply pass in a NULL for the printer name argument to the VNAccessOpen call.
Do not pass the name of a nonexistent printer device to VNAccessOpen, since the open of it will fail, and that will create the false belief that the printer is in use. Rather, it doesn't exist.
The hardware design of the VNA demands that both DDS chips be set at the same time with a common control sequence. The control lines are shared, only the data lines are distinct. This means that the function calls which set data within the DDS chips have parameters for both chips. You can't set one without setting the other. The parameters are the tuning word, phase shift, and power down state.
The tuning word specifies the frequency. It is related to the DDS output frequency through the master oscillator frequency. See the Data Format Conversions section for information on a function that will convert a frequency to a tuning word. The phase shift is an integer value between 0 and 31. Each step shifts the phase by 11.25 degrees. The power down state is a C language BOOL, which when TRUE (non zero) indicates that the power down state should be entered.
The DDS chips are set with the VNAccessSetDDS function. This function accepts the 6 parameters describing the tuning word, phase, and power down state for each DDS.
In the context of the N2PK VNA, the DDS chips are set twice to drive the pairs of measurements which create what he calls sequential quadrature measurements. These two measurements are made on each side of a phase shift of 90 degrees in the LO DDS generator. The absolute phase shift between the RF and LO signals does not matter, but, it must be repeated for all measurements which will be related by subsequent computation, at some given frequency. This means that the two DDS chips must be synchronized so that each time a pair of quadrature measurements are made, the phase shift between the RF and LO DDS generators will be the same as they were when all similar measurements were made at that frequency. The actual shift does not matter, but it must be the same for all measurements. Of course the LO DDS will shift by 90 degrees between the two measurements. Each of those measurements must have a repeatable phase shift relative to the RF DDS.
The VNAccess call VNAccessResetDDS resets the DDS chips, and puts them into a synchronized state. This should be done before making quadrature measurements. The DDS chips will remain synchronized so long as they are always programmed with the same frequency (through the tuning word). The frequency can certainly change, but both DDS chips are always handed the same tuning word. Since the VNA DDS chips could be used for other applications, such as general purpose signal generators, VNAccess does not demand that the frequencies be the same. VNAccess will, however, track the synchronized state, and the call VNAccessGetDDSSync will return the the current state.
When the VNA is turned on, the DDS chips will not be synchronized. It is not possible for software running on the computer to know if the VNA has gone through a power cycle. This means that synchronization can be lost, by accident, if you cycle power to the VNA while an application program using it is running. It may be wise to add an explicit Reset command to an application program using the VNA so that an accidental power cycle does not require that the program be stopped and started as well. Of course a VNAccessReset call should be made at the start of any program using the VNA.
This mode of operation, where a set of frequency changes and quadrature measurements are made, all based upon a single synchronized reset, appears to be called continuous frequency programming. The alternative mode of operation would perform a synchronization reset for each DDS set. At this point in time, continuous frequency programming appears to offer several advantages, and is preferred. Call VNAccessSetDDSCFP to set the mode (TRUE or FALSE), and VNAccessGetDDSCFP to retrieve the current mode. by default, continuous frequency programming is TRUE, it is the default mode.
At version 2.0 of VNAccess, the function VNAccessDDSFQ_UD appeared. This call strobes the DDS FQ_UD line. It is used to support efficient sequences of DDS changes and ADC readings by pipelining and overlapping DDS and ADC operations.
The ADC result is held in a 32-bit register. It is not necessary to clock out all 32 result bits, although that usually is the request Assuming a full 32-bit result, the lowest 5 bits are the so-called sub LSB bits, although we normally call them the trash data bits. The next 24 bits are the data bits. The top 3 bits in the register hold the end of conversion indicator and a signal bit that combines with the data MSB to indicate out of range input voltages. Please consult the ADC documentation for more information. The out of range condition can be decoded by the VNAccessADCResultTouVolts function described in the Data Format Conversions section.
The ADC in the initial N2PK VNA is relatively slow, taking on the order of 130 mS per conversion. Rather that busy wait that entire interval, taking up all of the CPU performance with this one program in hard run, it is suggested that the first part of the of the 130 mS be passed with a Sleep call, that executes for an interval of around 120 mS. During this time, the computer can run other programs, and otherwise not appear to be bogged down. After the 120 mS passes, the remaining time waiting for the ADC to complete can be accomplished with a busy wait loop, inside the VNAccessGetADCResult function. There are several different mechanisms for sleeping within software running on Windows. Each has their own timing resolution. Even the classic SetTimer call has a resolution near 50 mS. That means that it is possible to sleep around 100 mS before starting to busy wait, which is better than simply busy waiting for the whole interval.
The return value from VNAccessGetADCResult should be carefully checked. A value of VNACCESS_SUCCESS indicates that the call completed successfully. Other values indicate a range of errors or potential errors.
If the return value is VNACCESS_SUCCESS, and if the 32-bit data value is zero, that is a strong indication that the data line from the ADC is grounded, or that the cable to the VNA is unplugged.
If you want to determine if a conversion is currently in progress, you can call VNAccessStatus, and check the return value. If you call VNAccessGetADCResult with a busy wait time of zero, and if the conversion is in progress, the value VNACCESS_CONVERSIONINPROGRESS is returned.
Starting with version 2.0 of VNAccess, two detectors are supported. The calls that work with the ADC, which is the last major stage of a detector all accept an argument which indicates the target detector.
VNAccess includes several data format conversion functions which map between DDS and ADC hardware units on one hand, and more convenient units on the other.
The functions VNAccessFreqToTW and VNAccessTWToFreq convert back and forth between frequency and tuning word (TW) formats. For these two functions, the frequency is specified in units of tenths of Hertz. In other words, a frequency of 1 Hz is specified as an argument of 10, since it's 10 units of 1/10 Hertz. The other argument to these functions is the master oscillator frequency, also specified in 1/10th Hertz units (usually 1483440000).
The resolution of 1/10 Hz was arbitrarily picked because the common master oscillator frequency of 148.344 MHz can be represented in a 32-bit signed number, and it is also close to the actual resolution of the DDS chips at the nominal master oscillator frequency. The DDS chips are capable of slightly higher resolution. If you wish to access that resolution, simply compute your own tuning words and do not use these functions.
The ADC data result is usually considered to be a 24-bit, 2's complement integer. In some cases, it is desirable to view the data as an actual voltage level. This conversion can be performed by the function VNAccessADCResultTouVolts.
The function return value is the ADC result converted to micro volts.
VNAccessADCResultTouVolts should be passed the entire 32-bit ADC conversion result. In addition to performing the conversion to micro volts, the function evaluates the overflow/range information in the result. The result indication is either in range, over range, or under range. Please consult the ADC specification sheet for more details.
If you prefer the raw ADC reading, and overflow checking, you can call VNAccessADCResultToCounts.
Truth be told, setting the DDS chips and reading the ADC in the context of taking VNA measurements requires coordination They are not asynchronous and unrelated operations. Moreover, it is desirable to be able to make measurements as quickly as possible, so that the user has results as quickly as possible.
The VNAccess.h header file includes examples which should be consulted the for the truth. Here's a little prose to help explain what's going on.
The most time-critical resource in the VNA is the ADC (LTC2410), which performs a maximum of approximately 7.4 conversions per second (135 ms/conversion). Readings should not be wasted. The act of reading the last data bit from the ADC automatically starts the next conversion. This ADC behavior creates a sequence of important events. After the previous conversion is complete, the DDS chips can be safely updated, in preparation for the next conversion. The ADC data can also be read at any time after the conversion is complete.
The fast detector employs the LTC2440 ADC. This chip has 10 different conversion rates, using its internal oscillator. It's slowest rate is nearly identical to the single internal rate of the 2410. It's fastest rate is 3520 conversions per second. While that fastest rate reduces the conversion time to a little more than a quarter of a millisecond, the speed comes with a price. The effective number of bits (ENOB) drops with each increase in conversion speed. Faster conversions imply data with lower quality.
As the conversions increase in speed, the dominant factor in the overall rate of the VNA becomes the ADC setup time. After a change to either DDS chip, the new signal must propagate through (transmission) or off of (reflection) the test jig, go through the detector, then through a low pass filter, and finally into the ADC. The effect of the DDS change should arrive at the ADC before the conversion starts, so that the converter is measuring stable data. With the historic low pass filter component values, the typical setup time is 10 ms. When the ADC was always taking 135 ms, the 10 ms setup time was a small contributor to the overall speed of the VNA. With a faster detector, however, the setup time can easily become the dominant component of the total time. The completion of neither period, the setup period, or the conversion period is marked by a computer interrupt. This means that the computer must use a combination of internal timing and hardware polling to move between the phases involved in taking a sample.
The simplest approach to implementing the timing is to busy-wait for the setup time to pass, and then again for the ADC conversion to complete. While this is functionally correct, it is an undesirable implementation, since the application program will appear to be in a hard run mode, and the computer will lose its responsive feel.
A better approach is to make it possible for the VNA application or other applications, to productively use as much of those two periods as possible.
One of the goals of the functions within VNAccess is to expose the soft underbelly of the timing policy to the application, so that it can be as smart and efficient, or as dumb and inefficient as desired.
There is a third component to the VNA timing. It is the overhead needed to communicate with the VNA over the parallel port. That overhead will be a function of the computer speed, and is estimated at between 0.15 and 0.5 ms per ADC conversion. This overhead is buried within the VNAccess functions, and cannot be minimized, given the parallel port interface.
Events and function calls within VNAccess are related to each other through the use of a high speed timer. The resolution of the timer is a function of the operating system, but the resolution is typically less than 1 microsecond. VNAccess uses the high speed timer to establish a microsecond resolution counter. Function calls accept and produce time stamps, which makes it possible to keep a tight leash on the timing. Nothing prohibits the operating system from preempting the program, and doing something else; Windows is not a real-time system. Some events may appear to take much longer than expected, if the program is preempted.
As mentioned earlier, the act of reading the ADC starts the next conversion. This suggests that is a good idea to be prepared for the next conversion while finishing the outstanding reading. If an isolated single reading is the goal of an application, then it will usually be the case that the reading starts a second conversion which will be discarded. It is probably more common that the application intends to make a series of readings, and it is unnecessary, and even undesirable to discard any conversions. The calls in VNAccess have been created to support both single reading activities, and multiple reading sequences.
The sequencing and interaction between the DDS chips, the ADC setup time, the ADC conversion, reading the ADC, and then changing the DDS chips for the next reading suggests a pipelined or overlapped algorithm, which is designed to use all conversions, and make the overall operation as fast as possible, consistent with the timing constraints.
The example code in VNAccess.h contains typical single reading and multiple reading function call sequences. In the example sequences, a sleep call is used to indicate that some number of microseconds will pass before the next interesting event occurs. In application programs, these sleep periods provide a time when other processing takes place. This processing can consume all or part of the sleep period. If the processing extends beyond the sleep period, then the next VNAccess operation will be delayed. But, useful processing will have been accomplished. There is enough dead time within the process of taking a reading that a well-written application should be able to do something useful, and not just sit and spin. This does require careful design, and is not trivial. The alternative, however, is not a pretty sight. While a series of readings are being made, the computer shoots to 100% CPU consumption due to busy-wait loops, and the application is unresponsive, and other programs are slow to respond. When the data set is complete, the program switches to a data-processing mode, where results are displayed, and the user interface is again responsive.
The code examples contain several fine points. They include:
DDS Loading versus FQ_UD Control: The DDS chips change external state when the FQ_UD signal is strobed. Assuming that you know the next set of DDS control values, the DDS chips can be reloaded at any time, even immediately after FQ_UD is strobed. The new data will simply sit in the DDS chips until the next FQ_UD strobe. The loading of the new DDS control values does not slow down the pipeline, since the chips are loaded while something else is going on in parallel.
When to Strobe FQ_UD: A good time to strobe FQ_UD is as soon as a conversion completes, even before the data is read from the ADC. This assumes that the DDS chips are changing before the next conversion. The DDS chips will change, and the ADC setup interval will start as soon as possible. The last ADC data is safely sitting in the ADC chip. It must be read before the next conversion is started, but the next conversion cannot start until the ADC setup time has elapsed, and that is relatively long compared to the time needed to read the ADC.
Averaging: One of the useful data collection techniques is averaging a series of readings with the same DDS state. This improves the signal to noise ratio. When within the set of readings, it is not necessary to wait for the ADC setup time, since, by definition, the DDS outputs are not changing. Within the samples in the average, the ADC can run uninterrupted, producing a set of time-concatenated samples.
Sleep (0): VNAccess calls can busy-wait for certain events. The busy-wait loops contain a Sleep (0) call. This call allows other ready to run processes on the computer to resume execution. This improves the responsiveness of the computer. If you are going to busy-wait, putting a Sleep (0) in the loop can be a good idea.
The two DDS chips, when active, consume nearly two-thirds of the total power consumed by the VNA. Some actual measurements, taken from my VNA, appear on another page. In the case of battery operation, entering the power down mode can prolong battery life. There are two different power down mode control models.
In the first model, the application program can control the power down state of either DDS chip explicitly, through appropriate parameters to VNAccessSetDDS.
In the second model, power down is managed automatically by VNAccess. A time interval, measured in milliseconds, is specified as an argument to VNAccessIdleDDSPowerDown. If the specified amount of time elapses, after the last call which sets the DDS state, or reads the ADC, VNAccess will automatically place the DDS chips into power down mode. Specify a time interval of zero to turn off automatic power down mode.
If the ADC is read while either DDS is powered down, a special result code, VNACCESS_DDSPOWEREDDOWN, will be returned.
If you wish to power up the DDS chips, simply set their values and do not assert the power down parameters.
At version 2.0 of VNAccess, a callback function was added which will be called when the DDS power down status changes. This can be used if the application program would like to be aware of the power down state.
If you have problems, questions, or comments (concerning this software), please contact me via email, at ordy@seed-solutions.com.
VNAccess was developed by, and is owned by Seed Solutions, Inc. Copyright ©, 2004, Seed Solutions, Inc. All rights reserved. No warranty of any kind is made as to performance, or fitness of use in any application. Your use of this software is your agreement with these terms. You agree to hold Seed Solutions, Inc. free from responsibility for any damages that may or may not be associated with the installation or operation of the program.
This software may be redistributed in original form. No fee may be charged for redistribution without the prior and specific written consent of Seed Solutions. Inc. This software is licensed for personal and non-commercial use only, and is subject to the export laws and regulations as defined by the State Department of the United States of America, and other applicable regulatory agencies.
Windows, Windows 95, Windows 98, Windows NT, Windows 2000, Windows ME, Windows XP are either registered trademarks or trademarks of Microsoft Corporation. Other product and company names mentioned on this site may be the trademarks of their respective owners.