VSG60 API
VSG60 API Programming Manual

This document is a reference for the VSG60 application programming interface (API). The API provides a set of functions for controlling the VSG60 signal generator.

Examples

All code examples are located in the examples/ folder in the SDK.

Signal Generation

There are two main approaches to generating signals with the VSG60A:

Build/Version Notes

Versions are of the form major.minor.revision.

A major change signifies a significant change in functionality relating to one or more measurements, or the addition of significant functionality. Function prototypes have likely changed.

A minor change signifies additions that may improve existing functionality or fix major bugs but makes no changes that might affect existing user’s measurements. Function prototypes can change but do not change existing parameters meanings.

A revision change signifies minor changes or bug fixes. Function prototypes will not change. Users should be able to update by simply replacing DLL.

Version 1.0.0 – Official release

Development Requirements

  • Windows development
    • Windows 10/11 (Recommended)
    • Windows 7/8 (Minimum)
    • Windows C/C++ development tools and environment.
      • API was compiled using VS2012 and VS2019.
        • VS2012/VS2019 C++ redistributables are required.
    • Library files vsg_api.h, vsg_api.lib, and vsg_api.dll.
  • Linux development
    • Ubuntu 18.04/20.04.
    • Compiled with system GCC compiler on Ubuntu 18.04.
    • Library files vsg_api.h, vsg_api.so
  • VSG60 device
  • USB 3.0 connectivity provided through 4th generator or later Intel CPUs.
  • Dual core Intel i5/i7 processor minimum.

I/Q Data and Output Power

Waveforms are provided to the API as I/Q samples. I/Q samples should be provided as contiguous interleaved real and imaginary pairs.

Example: [re1, im1, re2, im2, …, reN, imN] would be an array of N I/Q samples, which would equal 2 * N contiguous floating-point values.

Each {re, im} pair represents a single sample. Each real and imaginary value should be a 32-bit floating point value. I/Q samples are provided in full scale. An I/Q magnitude equal to 1.0 will transmit at the output level set by the user.

Magnitude of I/Q sample is calculated as sqrt(I2 + Q2)

To measure the output power of a sample in dBm, use the formula:

Power of I/Q sample = Output power set in vsgSetLevel + 20 * log10(magnitude of I/Q sample)

Internally I/Q samples are scaled to achieve the user-selected output power. The default scaling is 0.5 and increases/decreases around this value to digitally scale where the internal amplifier and attenuator cannot. The internal scale can be queried through the API. Because we use a base scale of 0.5, this means magnitudes greater than 1.0 can be tolerated. Clipping occurs when either I or Q value exceeds 1.0 post scaling. The scaling is performed as such.

Scaled I/Q = { real * scaleFactor, imag * scaleFactor }

If you have a waveform with amplitudes much greater than 1.0, it is recommended to query the scale to verify clipping won’t occur or scale the entire waveform and adjust the output power to compensate.

Thread Safety

The VSG60 API is not thread safe. A multi-threaded application is free to call the API from any number of threads if the function calls are synchronized (i.e. using a mutex). Not synchronizing your function calls will lead to undefined behavior.

Multiple Devices and Multiple Processes

The API can manage multiple devices within one process. In each process the API manages a list of open devices to prevent a process from opening a device more than once. You may open multiple devices by specifying the serial number of the device directly or allowing the API to discover them automatically.

If you wish to use the API in multiple processes, it is the user’s responsibility to manage a list of devices to prevent the possibility of opening a device twice from two different processes. Two processes communicating to the same device will result in undefined behavior. One possible way to manage inter-process information is to use a named mutex on a Windows system.

If you wish to interface multiple devices on Linux, see Multiple Devices.

Status Codes and Error Handling

All functions return a VsgStatus error code. VsgStatus is an enumerated type representing the success of a given function call. The integer values associated with each status provides information about whether a function call succeeded or failed.

An integer value of zero indicates no error or warnings. Negative integer status values indicate errors and positive values represent warnings.

A descriptive string of each status type can be retrieved using the vsgGetErrorString function.

Functions

All functions other than initialization functions take a device handle as the first parameters. This integer is obtained after opening the device through either the vsgOpenDevice or vsgOpenDeviceBySerial function. This handle uniquely identifies the receiver for the duration of the application execution, or until vsgCloseDevice is called.

Each function returns an error code which can provide warnings or errors related to the execution of the function. There are many cases where you will need to monitor these codes to determine the success or failure of an operation. See a list of common error codes and their descriptions in the Appendix.

Linux Notes

Throughput

By default, Linux applications cannot increase the priority of individual threads unless ran with elevated privilege (root). On Windows this issue does not exist, and the API will elevate the USB data acquisition threads to a higher priority to ensure USB data loss does not occur. On Linux, the user will need to run their application as root to ensure USB data acquisition is performed at a higher priority.

If this is not done, there is a higher risk of USB data loss.

In our testing, if little additional processing is occurring outside the API, 1 or 2 devices typically will not experience data loss due to this issue. Once the user application increases the processing load or starts performing I/O such as storing data to disk, the occurrence of USB data loss increases and the need to run the application as root increases.

Multiple Devices

There are limitations that apply when attempting to use multiple devices on Linux. The maximum amount of memory that can be allocated for USB transfers on Linux is 16MB. A single VSG60A can stay within this limitation, but two devices will exceed this limitation and can cause the API to crash when you do. The USB allocation limit can be changed by writing to the file

/sys/module/usbcore/parameters/usbfs_memory_mb

A good value would be N * 16 where N is the number of devices you plan on interfacing.

One way to write to this file is with the command

sudo sh -c ‘echo 32 > /sys/module/usbcore/parameters/usbfs_memory_mb’

where 32 can be replaced with any value you wish.

Other Programming Languages

The VSG60 interface is C compatible which ensures it is possible to interface the API in most languages that can call C functions. These languages include C++, C#, Python, MATLAB, LabVIEW, Java, etc. Some examples of calling the VSG60 API in these other languages are included in the code examples folder.

The VSG60 API consists of several enumerated(enum) types, which are often used as parameters. These values can be treated as 32-bit integers when callings the API functions from other programming languages. You will need to match the enumerated values defined in the API header file.

Power Saving CPU Mode

Newer CPU models implement efficient power saving techniques that can interfere with and reduce USB bandwidth. If you are using one of these CPU models, you can experience issues with the VSG60 which might appear as data loss when inspecting the output of the VSG60.

We offer 2 potential solutions to this problem:

1) Enable the power saving CPU mode through the API. This has the effect of adding an artificial load to the API to keep the CPU from entering any low power CPU states that might affect the USB throughput. You will see an increase in CPU usage through this method.

2) Disable “C-States” in the BIOS of the PC. This prevents the OS from being able to put the CPU in these low power states which affect USB performance. This will increase power consumption of the PC which will affect battery life but will see lower CPU usage (since power saving CPU mode can be disabled).

The default state of this mode is disabled in the API.

PCs most affected are laptops and ultraportable devices running Windows 10.

Contact Information

For technical questions, email aj@signalhound.com.

For sales questions, email sales@signalhound.com.