Project_Detail
All_Projects

libresdr

Standalone C library for the LibreSDR (USRP B210 clone) — no UHD, no SoapySDR, pure libusb

View on GitHub
README.md

LibreSDR

A standalone C library for the LibreSDR (a USRP B210-compatible SDR with a Xilinx K325T FPGA and AD9361 RF transceiver), built directly on libusb-1.0 — no UHD, no SoapySDR required.

Hardware

Component Description
USB controller Cypress FX3
FPGA Xilinx Kintex-7 K325T
RF transceiver Analog Devices AD9361
Frequency range 42 MHz – 6 GHz
Channels 2× RX, 2× TX (full-duplex)
Interface USB 2.0 High-Speed (480 Mbps)

The LibreSDR uses the same FX3 firmware and CHDR register-access protocol as a stock USRP B210. The FPGA bitstream (LibreSDR_USRP/libresdr_b210.bin) is functionally equivalent to the Ettus B210 image.

Repository Layout

libresdr/          # The standalone C library
  include/         # Public API header (libresdr.h)
  src/             # Library source
    b210_hw.h      # Hardware constants (SIDs, endpoints, registers)
    b210_usb.c/h   # libusb transport layer
    b210_fx3.c/h   # FX3 vendor control requests
    b210_fpga.c/h  # FPGA bitstream loader
    b210_ctrl.c/h  # CHDR poke32/peek32 register access
    b210_spi.c/h   # SPI Core 3000 bridge → AD9361
    ad9361.c/h     # AD9361 RF driver (full UHD-derived init + calibration)
    b210_stream.c/h# Async RX/TX streaming engine
    libresdr.c     # Top-level public API
  tools/
    libresdr_probe.c  # CLI probe / info tool
  tests/
    test_loopback.c   # Basic RX streaming test
    test_tx.c         # TX streaming test (sine tone)
  CMakeLists.txt

LibreSDR_USRP/     # FPGA bitstream images
  libresdr_b210.bin    # LibreSDR-branded bitstream
  usrp_b210_fpga.bin   # Stock Ettus B210 bitstream (same content)
  patch.sh             # Utility patch script

libreconsole/      # (WIP) Dear ImGui SDR frontend

Dependencies

  • libusb-1.0 (runtime + dev headers)
  • cmake >= 3.10
  • gcc or clang with C11 support
  • pthreads (included in glibc)
sudo apt install libusb-1.0-0-dev cmake build-essential

Build

cd libresdr
mkdir build && cd build
cmake .. -DFPGA_IMAGE_PATH=/path/to/libresdr_b210.bin
make -j$(nproc)

Outputs:

  • libresdr.so / libresdr.a — shared and static libraries
  • libresdr_probe — CLI probe tool
  • test_loopback — RX streaming smoke test
  • test_tx — TX streaming test (100 kHz sine tone)

USB Permissions

Create a udev rule so the device is accessible without root:

echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2500", ATTRS{idProduct}=="0020", MODE="0666"' \
  | sudo tee /etc/udev/rules.d/99-libresdr.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

Quick Start

#include "libresdr.h"

libresdr_t *dev = libresdr_open(0);          // open first device
libresdr_set_rx_freq(dev, 0, 433.92e6);      // 433.92 MHz
libresdr_set_sample_rate(dev, 2e6);          // 2 MSPS
libresdr_set_rx_gain(dev, 0, 40.0);

libresdr_start_rx(dev, 0);

int16_t buf[2048];   // 1024 SC16 IQ pairs
libresdr_read_samples(dev, buf, 1024, 5000);

libresdr_stop_rx(dev, 0);
libresdr_close(dev);

Protocol Notes

The LibreSDR uses the CHDR (Compressed Header) protocol over USB bulk endpoints:

Endpoint Direction Purpose
0x04 OUT Control send (CHDR register poke/peek)
0x88 IN Control receive (CHDR ACK)
0x02 OUT TX data stream
0x86 IN RX data stream

Register access uses 16-byte CHDR control packets. The FPGA always responds with 24-byte ACKs (has_tsf=1). Data packets are SC16 samples prefixed with an 8-byte CHDR header.

What Works

  • FPGA bitstream loading over USB (FX3 vendor control)
  • CHDR register access (poke32 / peek32)
  • AD9361 SPI communication (product ID verified)
  • Full AD9361 initialization (UHD-derived: BBPLL/RFPLL, synth LUT, gain tables, calibrations)
  • Async RX streaming (SC16, verified at -32 dBFS)
  • TX streaming (sine tone test passes 100/100 bursts)
  • Full AGC / automatic gain control
  • libreconsole GUI frontend

License

MIT — see LICENSE