seify_hackrfone/
types.rs

1#[repr(u8)]
2#[allow(dead_code)]
3pub(crate) enum Request {
4    SetTransceiverMode = 1,
5    Max2837Write = 2,
6    Max2837Read = 3,
7    Si5351CWrite = 4,
8    Si5351CRead = 5,
9    SampleRateSet = 6,
10    BasebandFilterBandwidthSet = 7,
11    Rffc5071Write = 8,
12    Rffc5071Read = 9,
13    SpiflashErase = 10,
14    SpiflashWrite = 11,
15    SpiflashRead = 12,
16    BoardIdRead = 14,
17    VersionStringRead = 15,
18    SetFreq = 16,
19    AmpEnable = 17,
20    BoardPartidSerialnoRead = 18,
21    SetLnaGain = 19,
22    SetVgaGain = 20,
23    SetTxvgaGain = 21,
24    AntennaEnable = 23,
25    SetFreqExplicit = 24,
26    UsbWcidVendorReq = 25,
27    InitSweep = 26,
28    OperacakeGetBoards = 27,
29    OperacakeSetPorts = 28,
30    SetHwSyncMode = 29,
31    Reset = 30,
32    OperacakeSetRanges = 31,
33    ClkoutEnable = 32,
34    SpiflashStatus = 33,
35    SpiflashClearStatus = 34,
36    OperacakeGpioTest = 35,
37    CpldChecksum = 36,
38    UiEnable = 37,
39}
40
41/// Operating modes of the HackRF One.
42#[derive(Copy, Clone, Debug, PartialEq)]
43#[repr(u16)]
44pub enum Mode {
45    /// Transceiver is off.
46    Off = 0,
47    /// Transceiver is in receive mode.
48    Receive = 1,
49    /// Transceiver is in transmit mode.
50    Transmit = 2,
51    // TODO: HACKRF_TRANSCEIVER_MODE_SS, TRANSCEIVER_MODE_CPLD_UPDATE, TRANSCEIVER_MODE_RX_SWEEP
52}
53
54/// Configurable parameters on the hackrf
55#[derive(Debug)]
56pub struct Config {
57    /// Baseband gain, 0-62dB in 2dB increments (rx only)
58    pub vga_db: u16,
59    /// 0 - 47 dB in 1dB increments (tx only)
60    pub txvga_db: u16,
61
62    /// Low-noise amplifier gain, in 0-40dB in 8dB increments (rx only)
63    // Pre baseband receive
64    pub lna_db: u16,
65    /// RF amplifier (on/off)
66    pub amp_enable: bool,
67
68    /// Antenna power port control
69    // Power enable on antenna
70    pub antenna_enable: bool,
71    /// Frequency in hz
72    pub frequency_hz: u64,
73    /// Sample rate in Hz.
74    pub sample_rate_hz: u32,
75    // TODO: provide helpers for setting this up
76    /// Sample rate divider.
77    pub sample_rate_div: u32,
78}
79
80impl Config {
81    /// Returns the default configuration for transmitting.
82    pub fn tx_default() -> Self {
83        Self {
84            vga_db: 0,
85            lna_db: 0,
86            txvga_db: 40,
87            amp_enable: false,
88            antenna_enable: false,
89            frequency_hz: 908_000_000,
90            sample_rate_hz: 2_500_000,
91            sample_rate_div: 1,
92        }
93    }
94
95    /// Returns the default configuration for receiving.
96    pub fn rx_default() -> Self {
97        Self {
98            vga_db: 24,
99            lna_db: 0,
100            txvga_db: 0,
101            amp_enable: false,
102            antenna_enable: false,
103            frequency_hz: 908_000_000,
104            sample_rate_hz: 2_500_000,
105            sample_rate_div: 1,
106        }
107    }
108}
109
110/// HackRF One errors.
111#[derive(thiserror::Error, Debug)]
112pub enum Error {
113    /// I/O error occurred.
114    #[error("io")]
115    Io(#[from] std::io::Error),
116    /// USB transfer error.
117    #[error("transfer")]
118    Transfer(#[from] nusb::transfer::TransferError),
119    /// Transfer truncated.
120    #[error("transfer truncated")]
121    TransferTruncated {
122        /// Actual amount of bytes transferred.
123        actual: usize,
124        /// Expected number of bytes transferred.
125        expected: usize,
126    },
127    /// An API call is not supported by your hardware.
128    ///
129    /// Try updating the firmware on your device.
130    #[error("no api")]
131    NoApi {
132        /// Current device version.
133        device: UsbVersion,
134        /// Minimum version required.
135        min: UsbVersion,
136    },
137    /// Invalid argument provided.
138    #[error("{0}")]
139    Argument(&'static str),
140    /// HackRF is in an invalid mode.
141    #[error("HackRF in invalid mode. Required: {required:?}, actual: {actual:?}")]
142    WrongMode {
143        /// The mode required for this operation.
144        required: Mode,
145        /// The actual mode of the device which differs from `required`.
146        actual: Mode,
147    },
148    /// Device not found.
149    #[error("Device not found")]
150    NotFound,
151    /// Another streamer instance already exists.
152    #[error("Streamer instance already created")]
153    StreamerExists,
154}
155
156/// Result type for operations that may return an `Error`.
157pub type Result<T> = std::result::Result<T, Error>;
158
159/// A three-part version consisting of major, minor, and sub minor components.
160///
161/// The intended use case of `Version` is to extract meaning from the version fields in USB
162/// descriptors, such as `bcdUSB` and `bcdDevice` in device descriptors.
163#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
164// Taken from rusb::Version: https://github.com/a1ien/rusb/blob/8f8c3c6bff6a494a140da4d93dd946bf1e564d66/src/fields.rs#L142-L203
165// nusb doesnt currently have this
166pub struct UsbVersion(pub u8, pub u8, pub u8);
167
168impl UsbVersion {
169    /// Extracts a version from a binary coded decimal (BCD) field. BCD fields exist in USB
170    /// descriptors as 16-bit integers encoding a version as `0xJJMN`, where `JJ` is the major
171    /// version, `M` is the minor version, and `N` is the sub minor version. For example, 2.0 is
172    /// encoded as `0x0200` and 1.1 is encoded as `0x0110`.
173    pub fn from_bcd(mut raw: u16) -> Self {
174        let sub_minor: u8 = (raw & 0x000F) as u8;
175        raw >>= 4;
176
177        let minor: u8 = (raw & 0x000F) as u8;
178        raw >>= 4;
179
180        let mut major: u8 = (raw & 0x000F) as u8;
181        raw >>= 4;
182
183        major += (10 * raw) as u8;
184
185        UsbVersion(major, minor, sub_minor)
186    }
187
188    /// Returns the major version.
189    pub fn major(self) -> u8 {
190        let UsbVersion(major, _, _) = self;
191        major
192    }
193
194    /// Returns the minor version.
195    pub fn minor(self) -> u8 {
196        let UsbVersion(_, minor, _) = self;
197        minor
198    }
199
200    /// Returns the sub minor version.
201    pub fn sub_minor(self) -> u8 {
202        let UsbVersion(_, _, sub_minor) = self;
203        sub_minor
204    }
205}
206
207impl std::fmt::Display for UsbVersion {
208    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209        write!(f, "{}.{}.{}", self.major(), self.minor(), self.sub_minor())
210    }
211}