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.
| 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.
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
libusb-1.0(runtime + dev headers)cmake >= 3.10gccorclangwith C11 supportpthreads(included in glibc)
sudo apt install libusb-1.0-0-dev cmake build-essentialcd 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 librarieslibresdr_probe— CLI probe tooltest_loopback— RX streaming smoke testtest_tx— TX streaming test (100 kHz sine tone)
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#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);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.
- 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
MIT — see LICENSE