BB API
Measurement Types

Please also see the C++ programming examples for an example of interfacing the device for each measurement type.

Swept Spectrum Analysis

Swept analysis represents the most traditional form of spectrum analysis. This mode offers the largest amount of configuration options and returns traditional frequency domain sweeps. A frequency domain sweep displays amplitude on the vertical axis and frequency on the horizontal axis.

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
/*
This example demonstrates using the API to perform a sweep
*/
void bbExampleSweep()
{
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
// Configure a sweep from 850MHz to 950MHz with a 10kHz
// RBW/VBW and an expected input of at most -20dBm.
bbConfigureRefLevel(handle, -20.0);
bbConfigureCenterSpan(handle, 900.0e6, 100.0e6);
// Configuration complete, initialize the device
status = bbInitiate(handle, BB_SWEEPING, 0);
if(status < bbNoError) {
std::cout << "Error configuring device\n";
std::cout << bbGetErrorString(status);
exit(-1);
}
// Get sweep characteristics and allocate memory for sweep
uint32_t sweepSize;
double binSize, startFreq;
bbQueryTraceInfo(handle, &sweepSize, &binSize, &startFreq);
std::vector<float> sweep(sweepSize);
// Get the sweep
// Pass NULL for the min parameter. For most scenarios, the min sweep can be ignored.
status = bbFetchTrace_32f(handle, sweepSize, 0, sweep.data());
if(status != bbNoError) {
std::cout << "Sweep status: " << bbGetErrorString(status) << "\n";
}
// If the sweep status is not an error, the sweep is now stored in the sweep
// vector. The frequency of the first index in the vector is startFreq.
// To get the frequency of any bin in the vector use the equation
// freqHz = startFreq + binSize * index;
// From this point, you can continue to get sweeps with this configuration
// by calling bbFetchTrace again, or reconfigure and initiate the
// device for a new sweep configuration.
// Finished/close device
bbAbort(handle);
bbCloseDevice(handle);
}
API functions for the BB60 spectrum analyzers.
#define BB_NO_SPUR_REJECT
Definition: bb_api.h:141
#define BB_AVERAGE
Definition: bb_api.h:164
#define BB_LOG_SCALE
Definition: bb_api.h:146
BB_API bbStatus bbConfigureProcUnits(int device, uint32_t units)
BB_API bbStatus bbAbort(int device)
BB_API bbStatus bbConfigureAcquisition(int device, uint32_t detector, uint32_t scale)
BB_API bbStatus bbQueryTraceInfo(int device, uint32_t *traceLen, double *binSize, double *start)
#define BB_RBW_SHAPE_FLATTOP
Definition: bb_api.h:157
BB_API bbStatus bbConfigureSweepCoupling(int device, double rbw, double vbw, double sweepTime, uint32_t rbwShape, uint32_t rejection)
BB_API bbStatus bbConfigureCenterSpan(int device, double center, double span)
#define BB_POWER
Definition: bb_api.h:171
BB_API bbStatus bbInitiate(int device, uint32_t mode, uint32_t flag)
#define BB_SWEEPING
Definition: bb_api.h:130
BB_API const char * bbGetErrorString(bbStatus status)
BB_API bbStatus bbOpenDevice(int *device)
bbStatus
Definition: bb_api.h:344
@ bbNoError
Definition: bb_api.h:423
BB_API bbStatus bbCloseDevice(int device)
BB_API bbStatus bbConfigureRefLevel(int device, double refLevel)
BB_API bbStatus bbFetchTrace_32f(int device, int arraySize, float *traceMin, float *traceMax)

Configuration

The configuration routines which affect the sweep results are:

Once you have configured the device, you will initialize the device using the BB_SWEEPING flag.

Usage

This mode is driven by the programmer, causing a sweep to be collected only when the program requests one through the bbFetchTrace functions. The length of the sweep is determined by a combination of resolution bandwidth, video bandwidth and sweep time.

Once the device is initialized you can determine the characteristics of the sweep you will be collecting with bbQueryTraceInfo. This function returns the length of the sweep, the frequency of the first bin, and the bin size (difference in frequency between any two samples). You will then need to allocate memory for the sweep.

Now you can call bbFetchTrace. This is a blocking call that does not begin the sweep until the function is called.

Determining the frequency of any point returned is determined by the function below, where ‘n’ starts at zero for the first sample point.

Frequency of nth sample point in returned sweep = startFreq + n * binSize

Real-Time Spectrum Analysis

The API provides the functionality of a real-time spectrum analyzer for the full instantaneous bandwidth of the device (20MHz for the BB60A, 27MHz for the BB60C and BB60D). Using FFTs at an overlapping rate of 50%, the spectrum results have no blind time (100% probability of intercept) for events as short as 4.8us at full amplitude (at 631kHz RBW). The RBW shape is restricted to the Nuttall window, and VBW is not configurable.

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
/*
This example illustrates how to perform real-time spectrum analysis
with the API. The sweep and and persistence frames are retrieved.
*/
void bbExampleRealTime()
{
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
// Configure a 27MHz real-time stream at a 2.44GHz center
bbConfigureRefLevel(handle, -20.0);
bbConfigureCenterSpan(handle, 2.44e9, 20.0e6);
bbConfigureSweepCoupling(handle, 10.e3, 10.0e3, 0.001,
// Configure a frame rate of 30fps and 100dB scale for the frame
bbConfigureRealTime(handle, 100.0, 30);
// Configuration complete, initialize the device
status = bbInitiate(handle, BB_REAL_TIME, 0);
if(status < bbNoError) {
std::cout << "Error configuring device\n";
std::cout << bbGetErrorString(status);
exit(-1);
}
// Get sweep characteristics and allocate memory for sweep and
// real-time frames.
uint32_t sweepSize;
double binSize, startFreq;
bbQueryTraceInfo(handle, &sweepSize, &binSize, &startFreq);
int frameWidth, frameHeight;
bbQueryRealTimeInfo(handle, &frameWidth, &frameHeight);
std::vector<float> sweep(sweepSize);
std::vector<float> frame(frameWidth * frameHeight);
std::vector<float> alphaFrame(frameWidth * frameHeight);
// Retrieve roughly 1 second worth of real-time persistence frames and sweeps.
// Ignore min sweep, pass NULL as parameter.
int frameCount = 0;
while(frameCount++ < 30) {
bbFetchRealTimeFrame(handle, nullptr, sweep.data(), frame.data(), alphaFrame.data());
}
// Finished/close device
bbAbort(handle);
bbCloseDevice(handle);
}
#define BB_RBW_SHAPE_NUTTALL
Definition: bb_api.h:155
#define BB_REAL_TIME
Definition: bb_api.h:132
#define BB_MIN_AND_MAX
Definition: bb_api.h:162
BB_API bbStatus bbFetchRealTimeFrame(int device, float *traceMin, float *traceMax, float *frame, float *alphaFrame)
BB_API bbStatus bbQueryRealTimeInfo(int device, int *frameWidth, int *frameHeight)
BB_API bbStatus bbConfigureRealTime(int device, double frameScale, int frameRate)

Configuration

The configuration routines which affect the spectrum results are:

Once you have configured the device, you will initialize the device using the BB_REAL_TIME flag.

Usage

The number of sweep results far exceeds a program’s capability to acquire, view, and process, therefore the API combines sweeps results for a user specified amount of time. It does this in two ways. One, is the API either max holds or averages the sweep results into a standard sweep.

Also, the API creates an image frame which acts as a density map for every sweep result processed during a period. Both the sweep and density map are returned at rate specified by the function bbConfigureRealTime.

An alpha frame is also provided by the API. The alphaFrame is the same size as the frame and each index correlates to the same index in the frame. The alphaFrame values represent activity in the frame. When activity occurs in the frame, the index correlating to that activity is set to 1. As time passes and no further activity occurs in that bin, the alphaFrame exponentially decays from 1 to 0. The alpha frame is useful to determine how recent the activity in the frame is and useful for plotting the frames.

I/Q Streaming

The API can be used to stream I/Q data up to 40 MS/s. I/Q data can be retrieved as 32-bit complex floats or 16-bit complex shorts. I/Q data provided as 32-bit floats are corrected for IF flatness and RF leveling. I/Q data returned as 16-bit shorts is provided as full scale, only correcting for IF flatness and the user must apply a correction value to recover the fully amplitude corrected I/Q data.

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
/*
This example demonstrates how to configure, initialize, and retrieve data
in I/Q streaming mode. I/Q streaming mode provides continuous I/Q data
at a fixed center frequency with a selectable sample rate.
*/
void bbExampleIQStreaming()
{
// Connect device
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
// Configure the measurement parameters
// Specify 32-bit floating point complex values
// Set center frequency
bbConfigureIQCenter(handle, 1.0e9);
// Set reference level, maximum expected input amplitude
bbConfigureRefLevel(handle, -20.0);
// Set a sample rate of 40MS/s and a bandwidth of 27MHz
bbConfigureIQ(handle, 1, 27.0e6);
// Initiate the device, once this function returns the device
// will be streaming I/Q.
status = bbInitiate(handle, BB_STREAMING, BB_STREAM_IQ);
if(status != bbNoError) {
std::cout << "Initiate error\n";
std::cout << bbGetErrorString(status) << "\n";
bbCloseDevice(handle);
return;
}
// Get I/Q stream characteristics
double sampleRate, bandwidth;
bbQueryIQParameters(handle, &sampleRate, &bandwidth);
// Allocate memory for BLOCK_SIZE number of complex values
// This is the number of I/Q samples we will request each function call.
const int BLOCK_SIZE = 262144;
std::vector<float> buffer(BLOCK_SIZE * 2);
// Perform the capture, pass NULL for any parameters we don't care about
status = bbGetIQUnpacked(handle, buffer.data(), BLOCK_SIZE, 0, 0,
BB_FALSE, 0, 0, 0, 0);
// Check status here
// At this point, BLOCK_SIZE IQ data samples have been retrieved and
// stored in the buffer array. Any processing on the data should happen here.
// Continue to call bbGetIQ with the purge flag set to false, which ensures
// I/Q data is continuous from the last call.
for(int i = 0; i < 10; i++) {
status = bbGetIQUnpacked(handle, buffer.data(), BLOCK_SIZE, 0, 0,
BB_FALSE, 0, 0, 0, 0);
// Check status here
// Do processing
}
// When done, stop streaming and close device.
bbAbort(handle);
bbCloseDevice(handle);
}
@ bbDataType32fc
Definition: bb_api.h:452
#define BB_STREAM_IQ
Definition: bb_api.h:187
#define BB_FALSE
Definition: bb_api.h:53
BB_API bbStatus bbConfigureIQ(int device, int downsampleFactor, double bandwidth)
BB_API bbStatus bbConfigureIQCenter(int device, double centerFreq)
#define BB_STREAMING
Definition: bb_api.h:134
BB_API bbStatus bbGetIQUnpacked(int device, void *iqData, int iqCount, int *triggers, int triggerCount, int purge, int *dataRemaining, int *sampleLoss, int *sec, int *nano)
BB_API bbStatus bbConfigureIQDataType(int device, bbDataType dataType)
BB_API bbStatus bbQueryIQParameters(int device, double *sampleRate, double *bandwidth)

Configuration

See the following functions for configuring and retrieving I/Q data:

Once configured, initialize the device with the BB_STREAMING flag.

Usage

The I/Q data can be decimated by powers of 2 up to a decimation of 8192. The API provides users a customizable bandpass filter cutoff frequency at any sample rate.

The I/Q data stream can be tuned to any frequency within the BB60 frequency range.

Data acquisition begins immediately. The API buffers ~3/4 second worth of I/Q samples in a circular buffer. Samples can be retrieved with the bbGetIQ function. If you wish to retrieve all samples, it is the responsibility of the user’s application to poll the samples fast enough to prevent the APIs internal buffers from accumulating too much I/Q data. We suggest a separate polling thread and synchronized data structure (buffer) for retrieving the samples and using them in your application.

NOTE: Decimation and filtering occur on the PC and can be processor intensive on certain hardware. Please characterize the processor load.

External Triggering

External trigger information can be retrieved when I/Q streaming. Trigger information is provided through the triggers buffer in the bbGetIQ function.

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <complex>
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
/*
This example demonstrates using the BB60 to look for an external trigger.
This example waits for an external trigger, and captures N I/Q samples after
that trigger. If no trigger arrives this example will loop indefinitely.
*/
const int TRIGGER_SENTINEL = -1;
void bbExampleIQExtTrigger()
{
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
int deviceType;
bbGetDeviceType(handle, &deviceType);
// Configure BNC port 2 for rising edge trigger detection
if(deviceType == BB_DEVICE_BB60D) {
// BB60D
} else {
// BB60C/A devices
}
// Now configure the measurement parameters
// We want 32-bit floating point complex values
// Set center frequency to 1GHz
bbConfigureIQCenter(handle, 1.0e9);
// Set reference level
bbConfigureRefLevel(handle, -20.0);
// Set a sample rate of 40.0e6 / 2 = 20.0e6 MS/s and bandwidth of 15 MHz
bbConfigureIQ(handle, 2, 15.0e6);
// By default the sentinel is zero, set to -1
bbConfigureIQTriggerSentinel(TRIGGER_SENTINEL);
// Initiate the device, once this function returns the device
// will be streaming I/Q.
status = bbInitiate(handle, BB_STREAMING, BB_STREAM_IQ);
if(status != bbNoError) {
std::cout << "Initiate error\n";
std::cout << bbGetErrorString(status) << "\n";
bbCloseDevice(handle);
return;
}
// Get I/Q stream characteristics
double sampleRate, bandwidth;
bbQueryIQParameters(handle, &sampleRate, &bandwidth);
// This is how much data we want after the external trigger
const int N = 1e6;
// I/Q capture buffer
std::vector<std::complex<float>> buffer(N);
// We only care about the first trigger we see. If you need more triggers,
// this can be an array.
int triggerPos = 0;
while(true) {
// Perform the capture, pass NULL for any parameters we don't care about
status = bbGetIQUnpacked(handle, &buffer[0], N, &triggerPos, 1,
BB_FALSE, 0, 0, 0, 0);
// At this point, N I/Q samples have been retrieved and
// stored in the buffer array. If any triggers were seen during the capture
// of the returned samples, the trigger parameter will contain an index into
// the buffer array at which the trigger was seen.
// A trigger value not equal to the sentinel means a trigger is present
if(triggerPos != TRIGGER_SENTINEL) {
// We have a trigger, now finish capture
break;
}
}
// Unless trigger was at beginning, we still need to capture some data
// to retrive N samples.
int samplesAfterTrigger = N - triggerPos;
int samplesLeft = N - samplesAfterTrigger;
// Move the samples after the trigger to the beginning of the buffer.
for(int i = 0; i < samplesAfterTrigger; i++) {
buffer[i] = buffer[i + triggerPos];
}
// Get the rest of the contiguous samples
bbGetIQUnpacked(handle, &buffer[samplesAfterTrigger], samplesLeft,
0, 0, BB_FALSE, 0, 0, 0, 0);
// When done, stop streaming and close device.
bbAbort(handle);
bbCloseDevice(handle);
}
BB_API bbStatus bbConfigureIQTriggerSentinel(int sentinel)
#define BB_DEVICE_BB60D
Definition: bb_api.h:62
#define BB60C_PORT2_IN_TRIG_RISING_EDGE
Definition: bb_api.h:217
BB_API bbStatus bbConfigureIO(int device, uint32_t port1, uint32_t port2)
#define BB60D_PORT2_IN_TRIG_RISING_EDGE
Definition: bb_api.h:232
#define BB60D_PORT1_DISABLED
Definition: bb_api.h:223
BB_API bbStatus bbGetDeviceType(int device, int *deviceType)

Usage

If a trigger buffer is provided to bbGetIQ, any external trigger events seen during the acquisition of the returned I/Q data will be placed in the trigger buffer. External trigger events are returned as indices into the I/Q data at which the trigger event occurred. For example, if 1000 I/Q samples are requested and a trigger buffer of size 3 is provided, and the function returns with the trigger buffer set to [12,300,876], this indicates that an external trigger event occurred at I/Q sample index 12, 300, and 876 in the I/Q data returned from this function call.

If fewer external triggers were seen during the I/Q acquisition than the size of the trigger buffer provided, the remainder of the trigger buffer is set to the sentinel value. The default sentinel value is 0, so for example, if a trigger buffer of size 3 is provided, and only a single trigger event was seen, the trigger buffer will return [N, 0, 0] where N is the single trigger index returned.

If more trigger events were seen during the I/Q acquisition than the size of the trigger buffer, those trigger events that cannot fit in the buffer are discarded.

A note on trigger sentinel values: the default sentinel value of 0 does not allow the detection of triggers occurring at the first sample point. If this is an issue, set the sentinel value to -1 or some other negative value which cannot be normally returned. The default value of 0 is the result of historical choices and will remain the default value.

Audio Demodulation

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
/*
This example demonstrates how to configure, initialize, and retrieve data
in audio demodulation mode.
*/
void bbExampleAudioDemod()
{
// Connect device
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
// Configure the measurement parameters
// Set the demodulation scheme, center frequency, IF bandwidth,
// post demodulation low & hi pass filter frequencies, and FM deemphasis in microseconds
status = bbConfigureDemod(handle, BB_DEMOD_FM, 97.1e6, 120.0e3, 8.0e3, 20.0, 75.0);
// Initiate the device, once this function returns the device
// will be streaming demodulated audio data.
status = bbInitiate(handle, BB_AUDIO_DEMOD, 0);
if(status != bbNoError) {
std::cout << "Initiate error\n";
std::cout << bbGetErrorString(status) << "\n";
bbCloseDevice(handle);
return;
}
// Allocate memory for 4096 audio samples for an audio sample rate of 32k.
// This is the number of audio samples we will acquire each function call.
std::vector<float> buffer(4096);
// Perform the capture
status = bbFetchAudio(handle, buffer.data());
// Check status here
// At this point, 4096 audio samples have been retrieved and
// stored in the buffer array. Any processing on the data should happen here.
// Continue to call bbFetchAudio.
// While streaming, it is possible to continue to change the audio settings via
// bbConfigureDemod() as long as the updated center frequency is not +/- 8 MHz
// of the value specified when bbInitiate() was called.
for(int i = 0; i < 10; i++) {
status = bbFetchAudio(handle, buffer.data());
// Check status here
// Do processing
}
// When done, stop streaming and close device.
bbAbort(handle);
bbCloseDevice(handle);
}
#define BB_AUDIO_DEMOD
Definition: bb_api.h:136
BB_API bbStatus bbConfigureDemod(int device, int modulationType, double freq, float IFBW, float audioLowPassFreq, float audioHighPassFreq, float FMDeemphasis)
BB_API bbStatus bbFetchAudio(int device, float *audio)
#define BB_DEMOD_FM
Definition: bb_api.h:178

Configuration

Initialize the device with the BB_AUDIO_DEMOD flag.

Usage

When audio is being performed, no other measurements can take place. If you need the I/Q data and the ability to demodulate audio, consider using the I/Q streaming functionality and performing the audio demodulation on the I/Q data from there.

Once the device is streaming audio it is possible to continue to change the audio settings via bbConfigureDemod if the updated center frequency does not exceed +/- 8 MHz of the value specified when bbInitiate was called. The center frequency is specified in bbConfigureDemod.

Once the device is streaming, use bbFetchAudio to retrieve 4096 audio samples for an audio sample rate of 32k.

Scalar Network Analysis

When a Signal Hound tracking generator is paired together with a BB60D, BB60C, or BB60A spectrum analyzer, the products can function as a scalar network analyzer to perform insertion loss measurements or return loss measurements by adding a directional coupler. Throughout this document, this functionality will be referred to as tracking generator (or TG) sweeps.

Example

For a list of all examples, please see the examples/ folder in the SDK.

#include "bb_api.h"
#include <iostream>
#include <vector>
#ifdef _WIN32
#pragma comment(lib, "bb_api.lib")
#endif
// This example demonstrates how to use the API to perform a single tracking generator sweep.
// See the manual for a full description of each step of the process in the
// Scalar Network Analysis section.
void bbExampleScalarNetworkAnalysis()
{
// Connect device
int handle;
bbStatus status = bbOpenDevice(&handle);
if(status != bbNoError) {
std::cout << "Issue opening device\n";
std::cout << bbGetErrorString(status) << "\n";
return;
}
if(bbAttachTg(handle) != bbNoError) {
std::cout << "Unable to find tracking generator\n";
return;
}
// Sweep some device at 900 MHz center with 1 MHz span
bbConfigureCenterSpan(handle, 900.0e6, 1.0e6);
bbConfigureRefLevel(handle, -10.0);
// Additional configuration routine
// Configure a 100 point sweep
// The size of the sweep is a suggestion to the API, it will attempt to get near the requested size
// Optimized for high dynamic range and passive devices
bbConfigTgSweep(handle, 100, true, true);
// Configuration complete, initialize the device
status = bbInitiate(handle, BB_TG_SWEEPING, 0);
if(status < bbNoError) {
std::cout << "Error configuring device\n";
std::cout << bbGetErrorString(status);
exit(-1);
}
// Get sweep characteristics and allocate memory for sweep
uint32_t sweepSize;
double binSize, startFreq;
bbQueryTraceInfo(handle, &sweepSize, &binSize, &startFreq);
std::vector<float> sweep(sweepSize);
// Create test set-up without DUT present
// Get one sweep
// Pass NULL for the min parameter. For most scenarios, the min sweep can be ignored.
status = bbFetchTrace_32f(handle, sweepSize, 0, sweep.data());
if(status != bbNoError) {
std::cout << "Sweep status: " << bbGetErrorString(status) << "\n";
return;
}
// Store baseline
// Should pause here, and insert DUT into test set-up
bbFetchTrace_32f(handle, sweepSize, 0, sweep.data());
// From here, you can sweep several times without needing to restore the thru.
// Once you change your setup, you should reconfigure the device and
// store the thru again without the DUT inline.
// Finished/close device
bbAbort(handle);
bbCloseDevice(handle);
}
#define TG_THRU_0DB
Definition: bb_api.h:274
BB_API bbStatus bbAttachTg(int device)
BB_API bbStatus bbStoreTgThru(int device, int flag)
#define BB_TG_SWEEPING
Definition: bb_api.h:138
BB_API bbStatus bbConfigTgSweep(int device, int sweepSize, bool highDynamicRange, bool passiveDevice)
#define BB_SPUR_REJECT
Definition: bb_api.h:143

Configuration and Usage

Initialize the device with the BB_TG_SWEEPING flag.

Scalar Network Analysis can be realized by following these steps:

  1. Ensure the Signal Hound BB60 spectrum analyzer and tracking generator are connected to your PC.
  2. Open the spectrum analyzer through the bbOpenDevice function.
  3. Associate a tracking generator to a spectrum analyzer by calling bbAttachTg. At this point, if a TG is present, it is claimed by the API and cannot be discovered again until bbCloseDevice is called.
  4. Configure the device as normal, setting sweep frequencies and reference level (or manually setting gain and attenuation).
  5. Configure the TG sweep with the bbConfigTgSweep function. This function configures TG sweep specific parameters.
  6. Call bbInitiate with the BB_TG_SWEEPING mode flag.
  7. Get the sweep characteristics with bbQueryTraceInfo.
  8. Connect the BB and TG device into the final test state without the DUT and perform one sweep with bbFetchTrace. After one full sweep has returned, call bbStoreTgThru with the TG_THRU_0DB flag.
  9. (Optional) Configure the setup again still without the DUT but with a 20dB pad inserted into the system. Perform an additional full sweep and call bbStoreTgThru with the TG_THRU_20DB.
  10. Once store through has been called, insert your DUT into the system and then you can freely call the get sweep function until you modify the configuration or settings.

If you modify the test setup or want to re-initialize the device with a new configuration, the store through must be performed again.