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#[derive(Copy, Clone, Debug, PartialEq)]
43#[repr(u16)]
44pub enum Mode {
45 Off = 0,
47 Receive = 1,
49 Transmit = 2,
51 }
53
54#[derive(Debug)]
56pub struct Config {
57 pub vga_db: u16,
59 pub txvga_db: u16,
61
62 pub lna_db: u16,
65 pub amp_enable: bool,
67
68 pub antenna_enable: bool,
71 pub frequency_hz: u64,
73 pub sample_rate_hz: u32,
75 pub sample_rate_div: u32,
78}
79
80impl Config {
81 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 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#[derive(thiserror::Error, Debug)]
112pub enum Error {
113 #[error("io")]
115 Io(#[from] std::io::Error),
116 #[error("transfer")]
118 Transfer(#[from] nusb::transfer::TransferError),
119 #[error("transfer truncated")]
121 TransferTruncated {
122 actual: usize,
124 expected: usize,
126 },
127 #[error("no api")]
131 NoApi {
132 device: UsbVersion,
134 min: UsbVersion,
136 },
137 #[error("{0}")]
139 Argument(&'static str),
140 #[error("HackRF in invalid mode. Required: {required:?}, actual: {actual:?}")]
142 WrongMode {
143 required: Mode,
145 actual: Mode,
147 },
148 #[error("Device not found")]
150 NotFound,
151 #[error("Streamer instance already created")]
153 StreamerExists,
154}
155
156pub type Result<T> = std::result::Result<T, Error>;
158
159#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
164pub struct UsbVersion(pub u8, pub u8, pub u8);
167
168impl UsbVersion {
169 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 pub fn major(self) -> u8 {
190 let UsbVersion(major, _, _) = self;
191 major
192 }
193
194 pub fn minor(self) -> u8 {
196 let UsbVersion(_, minor, _) = self;
197 minor
198 }
199
200 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}