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