![]() |
libbladeRF
2.5.0
Nuand bladeRF library
|
This page presents an overview on how to configure a bladeRF device via the libbladeRF API. A complete boilerplate code listing may be found at the end of this page.
First, one must acquire a handle to a bladeRF device. Four common approaches to this are:
The first three approaches can be implemented via a call to bladerf_open() or bladerf_open_with_devinfo(). Both of these functions offer the same functionality, but through a slightly different interface. Note that per the documentation of each of these functions, NULL can be specified as one of the arguments to specify, "open any available bladeRF device."
bladerf_open() takes a specially formatted "device identifier" string as an argument. This provides a simple means to give the user full control over how the desired device is specified, perhaps through a command-line argument or GUI text field.
bladerf_open_with_devinfo() uses a bladerf_devinfo structure to identify the device to open. This is generally a better choice when programatically deciding which device to open, as it alleviates the need to craft a device identifier string. This approach is taken in the below snippet, where argv[1] may contain a serial number string. In the case when argc < 2, the dev_info.serial
field is left as its wildcard ("any value") field from the bladerf_init_devinfo() call.
The last approach in the beginning of this section is a good choice for programs that need to present a list of available devices to a user. A list of connected bladeRF devices may be retrieved via bladerf_get_device_list(). The contents of each bladerf_devinfo could then be presented to a user for selection, and the desired device's bladerf_devinfo can then be passed to bladerf_open_with_devinfo(). The device list can then be freed using bladerf_free_device_list().
After acquiring a handle to a bladeRF device, the following must be configured prior to transmitting or receiving samples.
Note that all of the above are configured on a per-channel (i.e, RX0 or TX1) basis.
RX and TX channels are specified by the BLADERF_CHANNEL_RX()
and BLADERF_CHANNEL_TX()
macros. These channel macros are provided as arguments to various methods to control frequency, gain, sample rate, and bandwidth of the specified channel of the bladeRF device.
The bladeRF1 is a SISO SDR with one receiver and transmiter (1x1). It supports the following channels: BLADERF_CHANNEL_RX(0)
, BLADERF_CHANNEL_TX(0)
.
The bladeRF2 is a MIMO SDR with two receivers and two transmitters (2x2). It supports the following channels: BLADERF_CHANNEL_RX(0)
, BLADERF_CHANNEL_RX(1)
, BLADERF_CHANNEL_TX(0)
, BLADERF_CHANNEL_TX(1)
.
Gain can be controlled in a coarse or fine manner. With coarse control of gain, bladerf_set_gain() sets an overall gain for the specified channel, and the underlying gain stages are configured appropriately to distribute the overall gain. With fine control of gain, bladerf_set_gain_stage() sets an individual gain for the specified gain stage and channel. The device's supported range of overall and individual gains can be queried with bladerf_get_gain_range() and bladerf_get_gain_stage_range(), respectively.
The selection of sample rate and bandwidth are tightly coupled. In general, the sample rate must be high enough to ensure that all desired signals can be sampled without aliasing. However, note that the RF transciever IC provides a discrete set of bandwidth options. This implies that one's sample rate selection will largely be influenced by the bandwidth option that most closely matches the desired value. The device's supported range of sample rates can be queried with bladerf_get_sample_rate_range().
The bandwidth parameter controls the RF front-end (RFFE) low-pass filter (LPF) setting. This should be configured to be less than the sample rate to ensure that the filter has reached maximum attenuation before reaching the desired sample rate value. Otherwise, noise and aliases may "fold" into the frequency range of interest. The device's supported range of bandwidths can be queried with bladerf_get_frequency_range().
lna
, rxvga1
, rxvga2
txvga1
, txvga2
To better understand each of the available gains controls, see Figures 1, 2, and 3 in the LMS6002D datasheet. In general, when configuring individual gain stages, one stage should be increased prior to increasing the following stage. For RX, increase the LNA gain, followed by RX VGA1, then RX VGA2. Similarly, increase TX VGA1 first, then TX VGA2.
Consult the plots in Figure 5 of the LMS6002D datasheet for the RX/TX filter responses. Note that the filter ranges are listed in the datasheet are listed in terms of 0 to Fs/2, whereas bladerf_set_bandwidth() assumes the total bandwidth (-Fs/2 to Fs/2) is being specified. Consider the plot for the 0.75 MHz filter (which corresponds to 1.5 MHz of total BW). At 1 MHz (2 MHZ of total BW), this filter offers over -45 dB of rejection. At ~1.8 MHz (3.6 MHz of total BW), this filter offers over -60 dB of rejection.
Therefore, when calling bladerf_set_bandwidth() with a value of 1.5 MHz, a sample rate 2 MHz would be a preferred minimum, and a sample rate >= 3.6 MHz would be an even better choice.
It is common for a program to apply all of these settings during its initialization. Therefore, the example in this page groups these parameters into a structure and then uses a configure_channel()
helper function to apply them:
As shown in the below implementation of configure_channel()
, the general procedure for applying a parameter involves calling the corresponding function and checking the return value.
Note that some functions, such as bladerf_set_sample_rate() and bladerf_set_bandwidth(), have optional actual
output parameters that are set to NULL in this example. These actual
values are used to provide feedback about the differences between the requested value and the actual value applied. Some error may occur in converting the sample rate into a rational fraction, as required by the underlying hardware. As previously, mentioned, the RF transceiver provides a discrete set of bandwidth settings. bladerf_set_bandwidth() will choose the closest bandwidth setting, and report this via the optional actual
parameter.