The ZBX daughterboard is a two-channel superheterodyne transceiver with a focus of telecommunication applications in the frequency range below 8 GHz. It supports analog bandwidths of up to 400 MHz.
The ZBX daughterboard is the daughterboard for the Ettus USRP X410.
Feature list:
See the RF section in the Ettus USRP X410 Specifications for a comprehensive ZBX daughterboard specifications list.
The ZBX daughterboard has two transceiver chains. The following simplified block diagram shows their structure:
It is a superheterodyne transceiver with up to two IF stages. The second IF stage is only used for center frequencies below 3 GHz. Above that frequency, the desired center frequency becomes the first intermediate frequency (IF1). The second LO stage is always enabled, and moves the IF to a value between 1 and 2 GHz. The USRP ADC/DAC (running at a sampling rate of approx. 3 GHz) will sample the IF directly, and downconvert to or from DC digitally.
The TX and RX paths are almost symmetric, with slight variations on the various frequency bands. The various gain stages are spread out along the TX and RX paths (see also Gain Control; note that the TX path includes selectable amplifiers as well as DSAs). All LO synthesizers are identical (LMX2572).
For digital controls, the ZBX includes a CPLD (its source code is part of the UHD repository, and can be found under fpga/usrp3/top/x400/dboards/zbx/cpld/
). The CPLD is controlled via registers. Its register space is exposed as a subset of the Radio RFNoC block register space (starting at address 0x80000). The CPLD is used to control all switches, DSAs, amplifiers, LEDs, LO synthesizers and power rails. The CPLD also controls state-dependent behaviour of the ZBX (i.e., behaviour depending on the RX/TX state). For this purpose, ATR signals from the FPGA are routed to the CPLD. Parts of the CPLD feature set are also described in Gain Control.
The normal operation of the ZBX daughterboard is to simply tune it to a desired center frequency, and UHD will internally calculate frequencies for the individual LOs as well as the NCO. UHD uses a few rules when calculating LO and NCO frequencies:
The state of individual LOs can be queried and configured independently. Use the following API calls to do so:
Note that manually modifying LOs is considered advanced behaviour, and may result in a bad state of the device. To undo manual changes, use the regular API calls to set a center frequency.
The ZBX has two SMA ports per channel, called "TX/RX0" and "RX1". In addition, the antenna values can be set to "CAL_LOOPBACK" to loop back the Tx path into the Rx path (this is sometimes required for calibration purposes). The Rx antenna value can also be set to "TERMINATION" to terminate the Rx path.
Use the uhd::usrp::multi_usrp::get_rx_antennas() or uhd::usrp::multi_usrp::get_tx_antennas() API calls to enumerate the valid antenna names. When using RFNoC API, use the uhd::rfnoc::radio_control::get_rx_antennas() and uhd::rfnoc::radio_control::get_tx_antennas() calls, respectively.
The ZBX daughterboard is equipped with two LEDs per channel, one for "TX/RX0" and one for "RX1". These LEDs behave as follows:
LED State | TX/RX0 | RX1 |
---|---|---|
Off | Port is inactive | Port is inactive |
Green | Port is receiving | Port is receiving |
Red | Port is transmitting | N/A |
The ZBX supports the UHD power API (see also Power Level Controls). UHD ships with nominal calibration data which will allow setting the reference power levels without previously manually calibrating the device.
Every channel has three "locked" sensors for the LO stages (lo1_locked
, lo2_locked
, and nco_locked
). A "virtual" sensor called lo_locked
confirms that all LOs that are currently engaged are locked. The "NCO lock" sensor is a special case: The NCO is not on the daughterboard (it is part of the RFSoC FPGA), but to simplify the API it was placed together with the LO lock sensors. Unlike the (analog) synthesizers on the daughterboard, the NCO "unlock" is not used to signify a loss of reference lock, but to signal that the NCO is still in reset.
Additionally, the ZBX has a temperature sensor: temperature
. While the UHD API allows addressing a sensor based on direction (RX/TX) and channel (0/1), there is only one physical temperature sensor, and it will return the same value regardless of which channel or direction is selected.
The following API calls can be used to enumerate available sensors, and query their values:
The ZBX has a sophisticated gain control, capable of controlling either an overall gain, or manually controlling its individual gain stages. Furthermore, the onboard CPLD can store gain tables as well, which can be accessed from other RFNoC blocks via RFNoC commands.
The TX path has three gain-related components: Two DSAs, as well an amplifier path. The former have an individual gain range of 31 dB. The amplifier path allows selecting one of two amplifiers, one with a nominal gain of 14 dB for lower frequencies, and one with a nominal gain of 21 dB for higher frequencies. Their actual amplification values depend on the specific frequency, and may also vary from device to device. The amplifiers can be bypassed.
The RX path consists of four DSAs, each with a gain range of 15 dB.
Different gain behaviours of the ZBX daughterboard are controlled by gain profiles, which may be set independently for TX and RX. Different gain profiles have different API behaviours as explained in the rest of this section.
To switch between gain profiles, use the uhd::usrp::multi_usrp::set_tx_gain_profile() or uhd::usrp::multi_usrp::set_rx_gain_profile() API calls. When using the RFNoC API, use the uhd::rfnoc::radio_control::set_tx_gain_profile() or uhd::rfnoc::radio_control::set_rx_gain_profile() API calls. The main difference between these APIs is that the multi_usrp API calls allow a default channel value, which the RFNoC API calls do not.
As with all other devices, the following API calls set or query gain values:
These API calls come in different flavours, with an optional 'gain name' argument. Note the multi_usrp API calls default to setting the overall gain value, which is not allowed in all gain profiles. All API calls have a corresponding API call to query the allowable gain range.
Note: The RX gain range is not consistent on ZBX. Below 500 MHz, the gain range is reduced to 0-38 dB. It is recommended to use get_rx_gain_range() to query the currently valid gain range.
Note: Some gain profiles require changing on both TX and RX. For example, changing from default
to table_noatr
must happen on TX and RX at the same time. UHD will automatically change the gain profile accordingly. It is therefore recommended to call get_rx_gain_profile() or get_tx_gain_profile() to verify the correct gain profile when in doubt.
This gain profile is active by default. It allows setting a single, scalar gain value. UHD will internally use a gain table to linearize the overall gain (meaning that a 1 dB gain increase will also increase the transmit or receive power by 1 dB). However, the UHD-internal gain table is not calibrated per-device, nor does it take into account temperature or other changes.
In this gain mode, it is not possible to set the individual gain stages directly, but it is possible to read them back. This may be helpful when trying to fine-tune gain settings in software.
ATR Behaviour: The gains will apply to their respective ATR state, i.e., RX gains will be applied to both the RX and full-duplex state, and TX gains will be applied to the TX and full-duplex state. In the idle state, gains are set to minimum gain.
RFNoC Commands: All DSA values are on one register for a given ATR state, and the TX amplifier shares a register with the antenna controls. That means that changing the DSA values in this gain profile will cause two register writes (one for RX/TX, and one for full-duplex). Changing the TX amplifier gain value will incur another two writes.
When more control is desired, the manual gain profile can be applied. Here, it is no longer possible to request an overall gain value. However, it is now possible to set the DSA and amplifier values directly.
In this profile, UHD exposes access to the gain table stored on the CPLD. By default, the CPLD is initialized with the same gain table as UHD uses internally, i.e., there is no difference in behaviour when using this profile, unless the gain table is modified.
Setting DSA values directly from UHD is not possible in this profile, nor is setting an overall gain value. However, it is now possible to load an entry from the CPLD gain table and apply it to the current DSA settings. In this profile, the ATR behaviour for the DSAs is the same as in the 'default' or 'manual' profiles. That means loading a DSA table entry requires two writes to the CPLD, one for TX/RX, and one for full-duplex.
The gain "values" are no longer interpreted as dB values, but refer to DSA table indices.
An important use case of this gain profile is when testing CPLD gain tables, but not changing other aspects of the software control. Often, this is an intermediate debugging step while developing applications that use RFNoC commands to control the gain.
Another use case of this profile is when running RFNoC applications, where the gain is controlled from another RFNoC block, but the ATR behaviour is left in its default state.
When running applications where the FPGA has full control over the gain, and the ATR behaviour should also be replaced by register writes, this profile may be used.
The main difference to the previous profile is that when the radio switches between RX, TX, full duplex, and idle states, there is no automatic update of the gain values. Instead, the current gain values are selected by writing to the SW_RF0_DSA_CONFIG
and SW_RF1_DSA_CONFIG
registers. Changing these registers will select an entry from the RX/TX DSA
tables. Unlike the gain tables, these are not prepopulated.
Like other USRPs, the X410 provides GPIOs to the daughterboards that communicate the RX/TX state. The ZBX is, by default, configured to switch settings based on the current state (RX, TX, full duplex, idle). For example, the TX/RX antenna is switched between the TX and RX channels depending on the state. A total of 4 GPIOs between the motherboard FPGA and the daughterboard CPLD are used for this purpose, two pins per channel.
ZBX uses these pins to select between different RF control values (e.g., the aforementioned TX/RX antenna switch position; this also includes the front-panel LEDs) as well as DSA controls (e.g., when doing RX only, the TX gain stages can be set to zero to minimize leakage). Internally, this works by converting the ATR pins into a control word. This control word is used to index tables that contain different values for RF control/LEDs as well as DSAs.
Example: Assume the device is transmitting, but not receiving, on channel 0. The FPGA will set the ATR pins for channel 0 to a binary value of 0b10, which equals a decimal value of 2. The transmit gain is controlled by DSA values that are stored in tables called TX0_DSA1 and TX0_DSA2, respectively. For the duration of the transmission, the DSA values at table position TX0_DSA1[2] and TX0_DSA2[2] will thus be used. Similarly, tables for RF path control and LEDs are used to configure those. This mode of using the ATR pins is called the "classic ATR" mode and is the default behaviour.
The ZBX daughterboard provides two additional modes of utilizing those pins:
The ATR pin mode can be set independently for channel 0 and 1, and also for DSA tables vs. RF control/LED tables. Note that combining the "FPGA controlled" mode on one channel with the "classic" mode on the other channel would yield a possibly conflicting configuration.
Usage of these modes is considered highly advanced usage of ZBX. The "FPGA controlled" mode is not supported by UHD without custom modifications (it is possible, however, to manually write to the appropriate registers to use this mode). Using this mode would also require modifications of the FPGA image to add custom controls to the ATR GPIO pins.
The "software defined" mode can be enabled for the DSA tables by using the table_noatr
gain profile (see the previous section).
Note: You may need to update the ZBX CPLD after updating filesystems. If an update is required, MPM will fail to initialize, and provide a corresponding error message.
If you need to update the ZBX CPLD, you can do so by running the following command on the device:
zbx_update_cpld
By default, this command will update the the CPLDs on both daughterboards with the image from the default path. To specify the image or daughterboards to program, use the following options:
--dboards=0,1
--file=<path_to_cpld_image>
By default, the cpld-zbx.rpd
file will be provided at /lib/firmware/ni/cpld-zbx.rpd
. Note that after downloading the ZBX CPLD, you will need to completely shut down and power-cycle the device.
If you are updating the image during a filesystem update, i.e., after installing the new filesystem with Mender, but before rebooting, you will need to mount the new filesystem first and copy the image over:
mkdir /mnt/other mount /dev/mmcblk0p3 /mnt/other cp /mnt/other/lib/firmware/ni/cpld-zbx.rpd ~ umount /mnt/other
Note that the other filesystem may be either /dev/mmcblk0p2
or /dev/mmcblk0p3
. You can now update to the new CPLD image:
zbx_update_cpld --file=~/cpld-zbx.rpd
Read this section if you want to create your own ZBX CPLD image, or require more information on how the CPLD image is updated.
The source code for the ZBX CPLD is provided within the UHD code repository, at fpga/usrp3/top/x400/dboards/zbx/cpld
. Read the Makefile for more instructions on how to build images.
The build process will produce two CPLD bitfiles: A .rpd
file and a .svf
file. Both are required for different programming methods. There are two programming methods:
.rpd
file. It uses the motherboard CPLD as a programming device. This is the default mode..svf
file.Before running the updater, ensure that MPM is installed on your device as some resources from MPM code are used.
You should also ensure that the power rails to the daughterboard are up and that MPM can successfully communicate with the daughterboard when running (running uhd_usrp_probe
successfully is sufficient).
MPM does not need to be running when the updater script is executed, but you should start it once to ensure a valid FPGA image is loaded and communication to the daughterboard is working before attempting this.
To specify a programming mode, use the --updater
argument. For example, to force the legacy mode, use the following command:
zbx_update_cpld --updater=legacy --file=/lib/firmware/ni/cpld-zbx.svf
This will program the image from the default location onto the CPLD using the 'legacy' method.
Every ZBX daughterboard has 2 MB of non-volatile flash memory which can be used to store data such as daughterboard-specific information. When logged into the X410 Linux system, the flash memory is mounted into the filesystem under /mnt/db0_flash
and /mnt/db1_flash
, respectively. The daughterboard also uses a separate EEPROM to store revision, serial, and product ID of the daughterboard.