Skip to main content

libbladerf_rs/
lib.rs

1//! A reimplementation of basic libbladeRF functions in Rust, based on [nusb].
2//!
3//! [nusb]: https://github.com/kevinmehall/nusb
4//!
5//! Use [libbladerf-rs] to control your bladeRF from your Rust application.
6//! [libbladerf-rs] shall currently not be considered as a replacement for the official [libbladeRF]
7//! due to several features not being available.
8//!
9//! [libbladeRF]: https://github.com/Nuand/bladeRF
10//! [libbladerf-rs]: https://github.com/ratzrattillo/libbladerf-rs
11//!
12//!
13//! ## Usage overview
14//!
15//! After a BladeRF is connected via USB (High or SuperSpeed USB port required) and fully booted,
16//! an instance to a BladeRF can be opened using [`bladerf1::BladeRf1::from_first`]. A handle to a specific BladeRF
17//! can also be obtained by its [`bladerf1::BladeRf1::from_bus_addr`] or its [`bladerf1::BladeRf1::from_serial`] or
18//! [`bladerf1::BladeRf1::from_fd`] on Android.
19//!
20//! After obtaining an instance of a [`bladerf1::BladeRf1`], you can set basic parameters like Gain, Frequency
21//! and Sample Rate or Bandwidth.
22//!
23//! ## Examples
24//! An example exists to demonstrate the current functionality of [libbladerf-rs]:
25//! ```bash
26//! cargo run --package info
27//! ```
28//!
29//! ## Limitations
30//!
31//! [libbladerf-rs] currently only supports the BladeRF1. Support for BladeRF2 is currently not
32//! possible, as I am not in the possession of named SDR.
33//!
34//! ### Implemented Features
35//! - Getting/Setting gain levels of individual stages like rxvga1, rxvga2, lna, txvga1 and txvga2.
36//! - Getting/Setting RX/TX frequency
37//! - Getting/Setting Bandwidth
38//! - Getting/Setting Sample Rate
39//! - Support for BladeRF1 Expansion boards (XB100, XB200, XB300)
40//! - Interface for sending and receiving I/Q samples
41//!
42//! ### Missing Features
43//! - Support for BladeRF2
44//! - Support for Firmware and FPGA flashing/validation
45//! - Support for different I/Q sample formats and timestamps
46//! - DC calibration table support
47//! - Usage from both async and blocking contexts (currently sync only)
48//! - Extensive documentation
49//! - AGC enablement
50//!
51//! ## Developers
52//! Contributions of any kind are welcome!
53//!
54//! If possible, method names should adhere to the documented methods in [libbladeRF-doc]
55//!
56//! [libbladeRF-doc]: https://www.nuand.com/libbladeRF-doc/v2.5.0/modules.html
57//! [Wireshark]: https://www.wireshark.org/download.html
58//!
59//! For debugging purposes, it is useful to compare the communication between the SDR and
60//! the original [libbladeRF] with the communication of [libbladerf-rs].
61//! Hand tooling for this purpose is [Wireshark]. Allow wireshark to monitor USB traffic:
62//!
63//! ```bash
64//! sudo usermod -a -G wireshark <your_user>
65//! sudo modprobe usbmon
66//! sudo setfacl -m u:<your_user>:r /dev/usbmon*
67//! ```
68//!
69//! Filter out unwanted traffic by using a Wireshark filter like e.g.
70//!
71//! ```wireshark
72//! usb.bus_id == 1 and usb.device_address == 2
73//! ```
74//!
75//! Datasheets for the BladeRF1 hardware are available at the following resources:
76//! ### SI5338
77//! [SI5338 Datasheet](https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si5338.pdf)
78//!
79//! [SI5338 Reference Manual](https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/reference-manuals/Si5338-RM.pdf)
80//!
81//! ### LMS6002D
82//! [LMS6002D Datasheet](https://cdn.sanity.io/files/yv2p7ubm/production/47449c61cd388c058561bfd3121b8a10b3d2c987.pdf)
83//!
84//! [LMS6002D Programming and Calibration Guide](https://cdn.sanity.io/files/yv2p7ubm/production/d20182c51057add570a74bd51d9c1336e814ea90.pdf)
85//!
86//! ### DAC161S055
87//! [DAC Datasheet](https://www.ti.com/lit/ds/symlink/dac161s055.pdf?ts=1739140548819&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252Fde-de%252FDAC161S055)
88
89mod bladerf;
90mod board;
91pub mod hardware;
92pub mod nios;
93pub mod range;
94mod usb;
95
96pub use bladerf::{Channel, Direction};
97pub use board::bladerf1;
98pub use hardware::lms6002d::{Band, Tune};
99
100use std::fmt::{Display, Formatter};
101
102/// Version structure for FPGA, firmware, libbladeRF, and associated utilities
103#[derive(Debug)]
104pub struct SemanticVersion {
105    /// Major version
106    pub major: u16,
107    /// Minor version
108    pub minor: u16,
109    /// Patch version
110    pub patch: u16,
111}
112
113impl Display for SemanticVersion {
114    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115        f.write_fmt(format_args!("{}.{}.{}", self.major, self.minor, self.patch))
116    }
117}
118
119#[derive(thiserror::Error, Debug)]
120pub enum Error {
121    /// I/O error occurred.
122    #[error("io")]
123    Io(#[from] std::io::Error),
124    #[error("nusb")]
125    Nusb(#[from] nusb::Error),
126    /// USB transfer error.
127    #[error("transfer")]
128    Transfer(#[from] nusb::transfer::TransferError),
129    // /// Transfer truncated.
130    // #[error("transfer truncated")]
131    // TransferTruncated {
132    //     /// Actual amount of bytes transferred.
133    //     actual: usize,
134    //     /// Expected number of bytes transferred.
135    //     expected: usize,
136    // },
137    // /// An API call is not supported by your hardware.
138    // ///
139    // /// Try updating the firmware on your device.
140    // #[error("no api")]
141    // NoApi {
142    //     /// Current device version.
143    //     device: String,
144    //     /// Minimum version required.
145    //     min: String,
146    // },
147    /// Invalid argument provided.
148    #[error("{0}")]
149    Argument(&'static str),
150    /// BladeRF is in an invalid mode.
151    // #[error("BladeRF in invalid mode. Required: {required:?}, actual: {actual:?}")]
152    // WrongMode {
153    //     /// The mode required for this operation.
154    //     required: Mode,
155    //     /// The actual mode of the device which differs from `required`.
156    //     actual: Mode,
157    // },
158    /// Invalid value provided
159    #[error("invalid")]
160    Invalid,
161    /// Device not found
162    #[error("not found")]
163    NotFound,
164}
165/// Result type for operations that may return an `Error`.
166pub type Result<T> = std::result::Result<T, Error>;