libbladerf-rs 0.3.0

Fully Rust native BladeRF driver
docs.rs failed to build libbladerf-rs-0.3.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: libbladerf-rs-0.2.0

Crates.io Documentation License Build Status Downloads

A pure Rust driver for the Nuand BladeRF1 SDR, based on nusb USB backend. No C libbladeRF dependency. Supports BladeRF1 on Windows, macOS, and Linux.

Use libbladerf-rs to control your BladeRF1 from your Rust application. This software is not yet a full replacement for the official libbladeRF — some features are still missing.

VCTCXO Oscillator Calibration

The BladeRF1 uses a 38.4 MHz VCTCXO (temperature-compensated voltage-controlled crystal oscillator) as its master clock reference. The oscillator's tuning voltage is generated by a DAC161S055 (16-bit voltage-output DAC) and set by a DAC trim value.

  • DAC trim is a 16-bit value (0–65535) written to the DAC161S055. It maps to a control voltage in the range of 0.4 V to 2.4 V at the VCTCXO tuning pin.
  • The VCTCXO (ASV TX12) can be pulled approximately ±5 PPM to ±9.5 PPM from its 38.4 MHz nominal frequency across the full control-voltage span. This gives a total tuning range of roughly ±20 PPM (±386 Hz at 38.4 MHz). The exact band varies per unit due to manufacturing tolerance.
  • At the center of the DAC range (about code 0x8000 ≈ 32768), the oscillator is closest to its rated 38.4 MHz. Moving the DAC code up or down shifts the output frequency proportionally.
  • If the DAC trim is wrong, the oscillator drifts from its nominal frequency. At a few PPM, signals are still detectable but demodulation quality degrades. If the required correction exceeds the VCTCXO's pull range (the DAC hits its rail), no code value can compensate — the board's clock is fundamentally out of spec.
  • Over time, ambient conditions (temperature, sunlight, aging) cause the oscillator to drift, necessitating re-calibration.

The kalibrate example in this repository demonstrates VCTCXO calibration using GSM FCCH signals as an external frequency reference. It performs a binary search over the 16-bit DAC trim range to minimize detected frequency offset, then optionally writes the corrected value to the device's calibration flash. See examples/kalibrate/README.md for details.

Usage overview

After a BladeRF1 is connected via USB (High or SuperSpeed required) and fully booted, open a device using [bladerf1::BladeRf1::from_first], [bladerf1::BladeRf1::from_bus_addr], or [bladerf1::BladeRf1::from_serial].

After obtaining an instance of a [bladerf1::BladeRf1], you can set basic parameters like Gain, Frequency and Sample Rate or Bandwidth.

Examples

The info example demonstrates basic device access:

cargo run --package info

The rx_tx example demonstrates the streaming API:

use anyhow::Result;
use libbladerf_rs::bladerf1::{BladeRf1, SampleFormat};
use libbladerf_rs::Channel;

fn main() -> Result<()> {
    let mut device = BladeRf1::from_first()?;
    device.initialize()?;

    let mut rx = BladeRf1::rx_builder(&mut device)
        .buffer_size(65536)
        .buffer_count(8)
        .format(SampleFormat::Sc16Q11)
        .build()?;

    let buf = rx.read(None)?;
    println!("Got {} bytes", buf.len());
    rx.recycle(buf)?;

    rx.close(&mut device)?;
    Ok(())
}

More examples can be found in the examples/ directory.

Limitations

libbladerf-rs currently only supports the BladeRF1. Support for BladeRF2 is currently not possible, as the maintainer is not in possession of one.

Missing Features

  • Support for BladeRF2
  • Support for Firmware and FPGA flashing/validation
  • AGC DC calibration table support (see AGC_PLAN.md)
  • Usage from both async and blocking contexts (currently sync only)

Developers

Contributions of any kind are welcome!

If possible, method names should adhere to the documented methods in libbladeRF-doc

For debugging purposes, it is useful to compare the communication between the SDR and the original libbladeRF with the communication of libbladerf-rs. Hand tooling for this purpose is Wireshark. Allow wireshark to monitor USB traffic:

sudo usermod -a -G wireshark <your_user>
sudo modprobe usbmon
sudo setfacl -m u:<your_user>:r /dev/usbmon*

Filter out unwanted traffic by using a Wireshark filter like e.g.

usb.bus_id == 1 and usb.device_address == 2

Datasheets for the BladeRF1 hardware are available at the following resources:

SI5338

SI5338 Datasheet

SI5338 Reference Manual

LMS6002D

LMS6002D Datasheet

LMS6002D Programming and Calibration Guide

DAC161S055

DAC Datasheet

Documentation

Build and open the docs locally:

cargo doc --features bladerf1 --open

Testing

Run unit tests (no hardware required)

cargo test --lib

Run integration tests (requires BladeRF1 connected)

cargo test --features bladerf1 --tests -- --test-threads=1

Run a specific test with output

cargo test --features bladerf1 --test integration_bladerf1_frequency -- --nocapture --test-threads=1