-
Notifications
You must be signed in to change notification settings - Fork 459
DC offset and IQ Imbalance Correction
This page describes how to use the bladeRF's built-in DC offset and IQ imbalance corrections, as well as the automatic calibration & correction functionality provided by libbladeRF
and the bladeRF-cli
program.
Direct conversion (homodyne or zero-IF) receivers have become very popular recently especially in the realm of software defined radio. There are many benefits to direct conversion receivers, but there are also some serious drawbacks, the largest being DC offset and IQ imbalances.
DC offset manifests itself as a large spike in the center of the spectrum. This happens in direct conversion receivers due to a few different factors. One is at the ADC where being off by a single LSB will yield a DC offset. Another is at the output of the low-pass filters where any DC bias will propagate through. The last is at the mixer where the local oscillator (LO) being on the center of the desired frequency will leak through to the receiver.
IQ imbalances occur due to the slightest mismatches in sections of the receiver chain when dealing with the I and Q signal paths. The LO is generated and then delayed by 90 degrees. When mixed with the original signal, the original LO produces the I signal and the 90-degree delayed LO produces the Q signal. In the analog domain, it is much harder to guarantee the delay is exactly 90 degrees. Similarly, the gain component is a slight mismatch in overall gain for each of the signal paths.
To make matters worse, these impairments need to be corrected over both frequency and temperature.
For further information, check out the following:
- DC Offsets in Direct-Conversion Receivers: Characterization and Implications by R. Svitek and S. Raman
- Direct Conversion: No Pain, No Gain by Jon Strange and Doug Grant
Currently, a table-based automatic DC calibration/correction is in the mainline codebase.
IQ imbalance auto calibration/correction is not currently implemented. However, you can manually adjust IQ balance parameters via bladerf_set_correction().
If you plan to be operating at a single frequency and gain, you can perform the following steps via bladeRF-cli
. Note that you would need to do this each time you power up the device. See the next subsection if this is not sufficient.
- Run
bladeRF-cli -i
- Configure the device for the desired frequency and gain settings.
- You may instead wish to do this from outside the CLI, using your favorite program for viewing the spectrum.
- Run
cal lms
- This runs the LMS6002D's DC offset calibration routines. You only need to do this once after powering up the device. See the next section for a less involved approach.
- To automatically calibrate and set appropriate corrections the RX module, run
cal dc rx
- Ideally, you should see the "error" values near zero, and certainly less than 10.
- Values any higher may indicate that it may not be possible to bring the DC offset close to zero for the current frequency and gain settings. If this happens, it is recommended that you confirm this to be the case via the manual approaches described later in this page. If you are able to manually tune the DC offset where the auto-calibration fails, please report it to developers with the settings you are using.
- Ideally, you should see the "error" values near zero, and certainly less than 10.
- To calibrate the TX module, run
cal dc tx
- Again, you should see fairly low error values and the same comments apply if you find this not to be the case.
bladeRF> set frequency 455.55M Set RX frequency: 455550000Hz Set TX frequency: 455550000Hz bladeRF> print rxvga2 RXVGA2 Gain: 3dB bladeRF> set rxvga2 8 bladeRF> cal lms Calibrating LMS LPF tuning module... LPF tuning module: 23 Calibrating LMS TX LPF modules... TX LPF I filter: 35 TX LPF Q filter: 33 Calibrating LMS RX LPF modules... RX LPF I filter: 25 RX LPF Q filter: 25 Calibrating LMS RXVGA2 modules... RX VGA2 DC reference module: 27 RX VGA2 stage 1, I channel: 31 RX VGA2 stage 1, Q channel: 35 RX VGA2 stage 2, I channel: 23 RX VGA2 stage 2, Q channel: 29 bladeRF> cal dc rx RX DC I Setting = -4, error ~= 0 RX DC Q Setting = 156, error ~= 0
bladeRF-cli
may be used to generate a table of DC correction values over a range of frequency values. When a device is opened, libbladeRF
can then automatically load this table from a known location on the host machine.
It is recommended that you allow the device to "warm up" to its normal operating temperature before generating a calibration table.
Currently, the DC offset table functionality is limited to variations in frequency; it does not yet account for the effects of various gain settings on the DC offset (but this is a planned task). For the time being, you can take a few different approaches:
- Generate and keep separate DC calibration tables for the gain configurations you plan to operate at.
- This would require that you move/rename files each time you want to use a different table.
- Generate the DC calibration table at the max gain you intend to operate at.
- This will not yield as nearly optimal results as having a separate correction table at each gain setting. However, you should see some degree of improvements for the lower gain settings.
- Run
bladeRF-cli -i
- Perform the LMS calibration routines via:
cal lms
- See the above section for known issues with these routines
- Run
cal table dc rx
and to generate an RX DC offset correction table, and wait for this command to complete. It will take some time.- You can speed up table generation by using larger frequency step sizes or a smaller frequency range. See
help cal
for more info.
- You can speed up table generation by using larger frequency step sizes or a smaller frequency range. See
- Upon completion of the above command, a calibration table file will be generated in the current working directory, named:
<serial #>_dc_rx.tbl
- Move the aforementioned file to one of the following locations:
- Linux, OSX:
~/.config/Nuand/bladeRF
~/.Nuand/bladeRF
~/etc/Nuand/bladeRF
~/usr/share/Nuand/bladeRF
- Windows:
%APPDATA%\Nuand\bladeRF
- Linux, OSX:
.backup
extension to the table filename.
Each time you tune to a different frequency, libbladeRF
will look up and apply the closest correction value. Keep this in mind if you manually adjust the DC corrections at a particular frequency; the library will reset them underneath you if you change the device's frequency.
This table contains the LMS6002D parameters generated by cal lms
, so you do not need to run cal lms
while the table is in use. Because the LMS calibration values are tightly coupled with the generated correction values, attempting to generate or use a different LMS calibration would yield suboptimal results.
Example:
bladeRF> cal lms Calibrating LMS LPF tuning module... LPF tuning module: 23 Calibrating LMS TX LPF modules... TX LPF I filter: 35 TX LPF Q filter: 33 Calibrating LMS RX LPF modules... RX LPF I filter: 25 RX LPF Q filter: 25 Calibrating LMS RXVGA2 modules... RX VGA2 DC reference module: 27 RX VGA2 stage 1, I channel: 33 RX VGA2 stage 1, Q channel: 35 RX VGA2 stage 2, I channel: 23 RX VGA2 stage 2, Q channel: 29 bladeRF> cal table dc rx Calibrating @ 3800000000 Hz... I=358 (avg. val: -1 ), Q=37 (avg. val: 0 ) Done. bladeRF> q $ mkdir -p ~/.config/Nuand/bladeRF $ mv *_dc_rx.tbl ~/.config/Nuand/bladeRF/
It is also possible to manually dial in the correction parameters required for a certain frequency and gain. Even if you are using the automatic corrections, you may find that you can dial in the correction parameters slightly better manually.
Below is am image showing a spectrum containing a tone before (left) and after (right) manually adjusting the DC offset and IQ imbalance correction parameters.
- Ensure the bladeRF's FPGA is loaded
- Run osmocom_siggen for the desired frequency:
osmocom_siggen -s 4M -f 450M --sine
- Specify a frequency offset for the sinusoid
- A spike at DC
- An image of the tone at -F Hz
- Move the DC Offset Correction Real slider until the amplitude DC spike reaches a minimum
- Move the DC Offset Correction Imag slider to further reduce the DC spike
- Repeat until the DC spike is sufficiently canceled
- Record these settings for reference as an initial starting point in the future.
- Move the IQ Imbalance Correction Mag slider until the amplitude of the image reaches a minimum
- Move the IQ Imbalance Phase slider to further reduce the amplitude of the image
- Repeat until the image spike is sufficiently canceled
- Record these settings for reference as an initial starting point in the future.
The RX-side can be tuned in a manner similar to what's described above for the TX procedure.
The basic procedure is to:
- Enable RF loopback mode (via rf_lna1 for under 1.5GHz, or rf_lna2 for 1.5GHz or greater)
- RX at some frequency f
- Transmit a carrier at some frequency f + offset
- View the received signal on an FFT plot
- Adjust the DC offset parameters to reduce the spike at DC
- Adjust the IQ imbalance parameters to reduce the image of the carrier from the TX side
If you have access to a signal generator (or another SDR that's pretty well calibrated for TX), you can follow a procedure very similar to that for calibrating the TX module via osmocom_siggen and a spectrum analyzer.
- Run
osmocom_fft --dc-offset-mode=0 --iq-balance-mode=0
. - Tune the bladeRF to some frequency f1
- Using the signal generator to generate a tone at some f2 = f1 + small_offset
- Follow the same general procedure used in the above "Using a spectrum analyzer and osmocom_siggen" section.