Because of the fast increase of processing power of digital electronics, software-defined radio (SDR) offers a new implementation design architecture for radio communication that was usually implemented with hardware components. In order to digitize radio signals or to transmit them, the processing unit (typically a computer or an embedded processor), needs to connect with a radio hardware peripheral. The radio peripheral is used to do the conversion between the electrical radio frequency and its digitized baseband version.

SDR hardware peripheral suppliers generally offer with their radio peripheral an Application Programming Interface (API) to ease its configuration and the data transfer. It allows the user to quickly implement simple waveforms and run them in only a few minutes/hours. These APIs are often made of high-level functions that don’t require detailed knowledge of the hardware architecture of the peripheral or the register map of every electronic component it is composed of.

The API provided by Ettus Research with their USRP board, USRP Hardware Driver (UHD), is a widely used SDR API. In this blog post, the similarities and differences between the Nutaq API, which remotely controls Perseus-based systems like the PicoSDR, and the UHD will be outlined.

Implementation

The core of Nutaq’s API is written in C programming language. Since it is a compiled language, it allows for fast and optimized application development. On the other hand, UHD has chosen the C++, which is also a compiled language. The major difference between these languages is that C is function-driven and the C++ is object-driven. Libraries which are built in C can be used in C or C++ applications but the opposite is not true.

For example, to set the TX gain in Nutaq’s API, we need to call the fmc_radio_tx_gain_send function and supply arguments for the pointer to the connection_state structure:

Result fmc_radio_tx_gain_send(connection_state * state, char tx_vga1_gain, unsigned char tx_vga2_gain, char tx_gain3);

In the UHD, since the TX gain function is in the multi_usrp class, a multi_usrp object must be declared and the set_tx_gain function will be called from the object:

virtual void uhd::usrp::multi_usrp::set_tx_gain (double gain, const std::string & name, size_t chan = 0)

Radio Peripheral Configuration

Both APIs contain basic radio peripheral configuration functions. They are used to set parameters like frequency, data rate, bandwidth, gain and so on. The following table shows the function equivalence between the UHD and Nutaq’s API:

Functionalities

UHD functions

Nutaq API functions

Clock and data rateset_clock_source(&source)

set_master_clock_rate(rate)

set_rx_rate(rate)

set_tx_rate(rate)

fmc_radio_clockmux_set_send(&state, destination, source)

fmc_radio_pll_calculate(&parameter, reference, rate, loReference)

fmc_radio_pll_setparam_send(&state, &param)

Local oscillatorset_rx_freq(freq)

set_tx_freq(freq)

fmc_radio_lime_calculate(&parameter, loReference, freq)

fmc_radio_lime_setpllparam_send (&state, direction, &parameter)

fmc_radio_lime_calibratePLL_send(&state, direction)

Bandwidthset_rx_bandwidth(bandwidth)

set_tx_bandwidth(bandwidth)

fmc_radio_lpf_set_send(&state, direction, bandwidth)

fmc_radio_lpf_calibrate_send(&state, direction, reference)

fmc_radio_sdr_setrxfilter_send(&state, filter)

Gainset_rx_gain(gain, &name)

set_tx_gain(gain, &name)

fmc_radio_sdr_rx_gain_send(&state, lna_gain, gain1, gain2, gain3)

fmc_radio_rxvga_calibrate_send(&state)

fmc_radio_tx_gain_send(&state, gain1, gain2, gain3)

Calibrationset_rx_dc_offset(offset)

set_tx_dc_offset(offset)

set_rx_iq_balance(correction)

set_tx_iq_balance(correction)

fmc_radio_rx_dc_offset_calibration_send(&state)

fmc_radio_lo_leakage_calibration_send(&state, clk_freq, rate)

fmc_radio_ssb_calibration_send (&state, clk_freq, rate)

 

Most of the UHD radio front-end configuration functions have equivalent functions in the Nutaq API. By analyzing the above table, there are 2 main differences between the Nutaq API and the UHD:

  • Almost every functionality has a calibration function in the Nutaq API.
  • Calibration functions are automatic in the Nutaq API

Since Nutaq’s radio peripheral RF front-end (Radio420x) uses the LMS6002D (a field programmable RF transceiver IC), the front-end has a lot of flexibility and integrated calibration capabilities. For example, the local oscillator, the RX filter and RX gain can be calibrated and those calibrations are made available in the API.

Also, the Nutaq API automatically handles the calibration of the IQ imbalance and the DC offset. The whole automatic calibration routine is performed in the hardware peripheral and does not require user manipulations. Since UHD calibration functions only set the given input values, the calibration to cancel the RF imperfection of the front-end must be done manually or by the host application.

Streaming

Once the radio front-end is configured, in order to transmit and receive data with the hardware peripheral, data must be transferred to and from the host application. These data transfer functions are integrated in the API provided with the hardware peripheral. Usually, they are high-level functions and they aim to be independent from the physical link.

The UHD supports the USRP Gigabit Ethernet and USB version, while the Nutaq API supports the Gigabit Ethernet and PCIe interface of its hardware peripheral carrier board, the Perseus. Nutaq has chosen to support Gigabit Ethernet for its flexibility and the PCIe for its high performance and low latency.

The following table shows the UHD and Nutaq API streaming functions:

Functionalities

UHD functions

Nutaq API functions

Initializationrx_stream = rx_usrp-> get_rx_stream(stream_args)

tx_stream = tx_usrp-> get_tx_stream(stream_args)

rx_usrp->issue_stream_cmd(stream_cmd)

RTDExOpenHostAndFpga(connection, …)

RTDExOpenFpga2Fpga(connection, …)

RTDExStart(connection, frame_size, transfer_size)

Transferrx_stream->recv(&buffs, nsamps, &metadata)

tx_stream->send(&buffs, nsamps, &metadata)

RTDExReceive(connection ,&buffs, nsamps, mode)

RTDExSend(connection ,&buffs, nsamps)

Both APIs have their own initialization and transfer functions. Initialization functions are used to open a connection between a specific hardware peripheral and the host application. Once the connection is established, the user can send and receive data from the radio device.

Currently, one difference between the UHD and Nutaq transfer functions is that there is no metadata information sent or received with the buffer content. The Nutaq API only streams raw data with the hardware peripheral: no burst header or time information is included in the packet. Since raw information is transfered between the host and the peripheral with the Nutaq API, the user can create his custom header if his application requires time stamping and burst management. Otherwise, by the end of the summer 2013, the Nutaq API transfer function will support the timestamping.

Conclusion

SDR hardware peripherals come with their respective APIs. Their purpose is to ease the configuration of the radio front-end as well as the transfer of data between the host application and devices. In general, each API supports equivalent functions for the basic operations. They distinguish themselves with some specific functionalities like automatic calibration or data timestamping. When looking for a SDR hardware peripheral, once the hardware specification meets your needs, it is important to look at the API provided with it since it can significantly affect your time to be up and running and it can save you a lot of headaches.