Software and Device Drivers

We recommend quickly skimming through this section, and moving on to a first example on the real hardware. After all, doing something on real hardware is more fun than reading some boring text. This section can be used as a reference to dig deeper while running the examples.

The first set of drivers we have implemented to control the SDR is based on a simple MATLAB interface. MATLAB can be used to open a connection to the SDR, configure it, transmit waveforms, capture and examine waveforms, and close the connections to the SDR. The Release_revA_v1.0 folder contains a file sdr.m. This file implements all the required drivers. Communication between the host computer (running MATLAB) and the SDR takes place over a simple TCP/IP socket interface. Let us open the sdr.m file to take a quick peek at what the drivers look like. The class sdr implements all the required functionality. Objects of this class correspond to unique SDR instances.

Properties

Sockets

Each SDR instance object requires three socket connections to communicate with the SDR. These socket servers run on the ARM cores of the RFSoC, and the socket clients run on the host computer. data_client is used for sending the transmit waveforms to the FPGA, and for receiving the captured receive waveforms from the FPGA. ctrl_client is used for configuring the various aspects of the RFSoC, including the DACs, ADCs, clocking, and multi-tile synchronization. Finally, piradio_client is used to configure various chips on the Pi-Radio transceiver board including the LO generator (Texas Instruments LMX2595), the mmWave up-converters (Analog Devices HMC6300), and the mmWave down-converters (Analog Devices HMC6301).

Node Specific Fields

Each SDR has a unique name and ip_addr. For debugging, the logs for each SDR are written to a file with the same name as the SDR; for example, an SDR with name trx-0001 will have its log file written into the directory Release_revA_v1.0 with file name trx-0001.txt. This log file is maintained and accessed by the sdr property logFileId. To visualize what each TX/RX channel on every SDR node is transmitting/receiving, this information will be plotted in a MATLAB figure with number fig_num; we will explain what information is plotted in a subsequent section.

TX and RX Waveforms

The raw TX and RX waveforms are accessed using tx_blob and rx_blob. Each of these is a matrix of complex numbers of size (4 by N), noting that there are 4 channels (8 DAC/ADCs) on the RFSoC, and N is the number of samples in the waveform. While we will drop this assumption later, for now, let us assume that N is equal to 8192.

An alternate way to set the TX waveform or receive the RX waveform is through tx_blob_user and rx_blob_user. Ignore these for now; we will revisit them later.

Calibration

Each sdr object also stores information related to its calibration factors. Upon startup, these calibration factors can be loaded from a set of files. When the calibration routines are explicitly run, the new calibration factors are applied, and the calibration-related files are overwritten with the new calibration factors. We will describe all the calibration routines in the section on Calibration, but for now, is suffices to note that all the sdr object properties beginning with cal_ store the calibration factors for that particular SDR node corresponding to the object.

Methods

There are a large number of methods in the class, many of which are helper functions. The important ones are descried below, while for the other ones, the source code is pretty self explanatory.

Opening and Closing Connections

zcu111_open opens a connection to the SDR. It performs the following: a) calls zcu111_open_sockets to initialize data_client and ctrl_client that are used to communicate with the RFSoC; b) initializes piradio_client that is used to configure the Pi-Radio transceiver board; and c) issues several commands (from the file commands.txt) to configure the RFSoC DACs, ADCs, and clocking.

zcu111_close closes the three sockets: data_client, ctrl_client, and piradio_client.

Writing and Reading Waveforms

zcu111_wr_data_blob takes the data in tx_blob and sends it over to the DACs on the RFSoC. As mentioned, tx_blob is a matrix of size (4 by N) that contains the 4 complex baseband time-domain waveforms to transmit. For now, assume that N = 8192. These 4 complex baseband waveforms map to the 8 DACs on the RFSoC, since each complex channel has an independent I and Q component. The RFSoC will transmit these waveforms continuously in a loop, until configured otherwise.

zcu111_rd_data_blob triggers the RFSoC to capture N samples from each of the 8 ADCs, corresponding to the 4 complex baseband time-domain received waveforms. This data is copied into rx_blob, which is a complex matrix of size (4 by N). For a new capture of the receive waveforms, this command needs to be reissued, and rx_blob will be over-written.

Configuring the Pi-Radio Transceiver Board

piradio_lmx_config is used to configure the Texas Instruments LMX2595 LO generator chip on the Pi-Radio transceiver board. This function accepts a configuration parameter like 57ghz, 58ghz, and so on. For each such desired center frequency (in 1 GHz increments), there is a register file that contains the configuration commands necessary to set the frequency. This configuration file has been generated on a per-node basis, based on the actual measured crystal frequency on that board (different nodes have crystals whose frequency varies slightly based on the tolerances and accuracy). For example, for node trx-0001 to be configured at 58ghz, the configuration file that gets used is at location Release_revA_v1.0/cal_data/trx-0001/lmx_registers_58ghz.txt. If you want to create a register file for some other non-standard center frequency (say, for example 60.1234 GHz), we will create a separate document describing how you can do this; if this document hasn't yet been published on our website, send us an email, and we will walk you through the procedure.

piradio_hmc6301_config configures the Analog Devices mmWave down-converter chips on the Pi-Radio transceiver board. The function accepts two parameters rxIndex and regfile. The parameter rxIndex can be set to 1, 2, 3, 4 to configure RX channels 1, 2, 3, 4 respectively; set rxIndex to 9 to configure all RX channels simultaneously. regfile contains the registers needed to configure the chips. The default file Release_revA_v1.0/hmc6301_registers.txt should work for all cases; recall that the carrier center frequency is changed through piradio_lmx_config.

piradio_hmc6300_config configures the Analog Devices mmWave up-converter chips on the Pi-Radio transceiver board. The function accepts two parameters txIndex and regfile. The parameter txIndex can be set to 1, 2, 3, 4 to configure TX channels 1, 2, 3, 4 respectively; set txIndex to 9 to configure all TX channels simultaneously. regfile contains the registers needed to configure the chips. The default file Release_revA_v1.0/hmc6300_registers.txt should work for all cases; recall that the carrier center frequency is changed through piradio_lmx_config.

piradio_hmc6300_pdn and piradio_hmc6301_pdn are used to power down all the TX and RX chips respectively.

piradio_hmc6300_set_att is used to set the attenuation on all the TX chips. It accepts two parameters: ifatt is the IF stage attenuation, and takes values of 0, 5, 10, 15, 20 dB; rfatt is the RF stage attenuation, and takes values of 0, 4, 8, 12, 15 dB. In our experience, keeping both values set to 0 works well, especially since the TX power can be controlled by digitally scaling the transmitted baseband waveform.

piradio_hmc6301_set_att is used to set the attenuation on all the RX chips. It accepts three parameters: bbatt is the baseband stage attenuation, and takes values of 0, 6, 12, 18, 24, 30, 36 dB; ifatt is the IF stage attenuation, and takes values of 0, 5, 10, 15, 20 dB; rfatt is the RF stage attenuation, and takes values of 0, 6, 12, 18 dB. We recommend keeping ifatt and rfatt fixed at 0, and varying only bbatt. Typical values for bbatt can be set at 18dB for close-in operation, and can be lowered if the receive signal power is weaker. However, do keep in mind that the self-interference from the TX chips on a node to its own RX chips can be fairly strong. Therefore, please observe the received waveform and adjust bbatt as appropriate. We have not yet implemented an automatic gain control (AGC), but you can do so fairly quickly. We use default values of bbatt, ifatt, and rfatt of 18, 0, and 0 dB respectively.

There are other functions that we might document at a later date. But the code is fairly straightforward (each function is just a few lines of MATLAB code, after all), so we are confident that you can figure it out fairly easily. Write us with any questions.