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#[atomic_enum::atomic_enum]
43#[derive(PartialEq)]
44#[repr(u16)]
45pub enum Mode {
46 Off = 0,
48 Receive = 1,
50 Transmit = 2,
52 }
54
55#[derive(Debug)]
57pub struct Config {
58 pub vga_db: u16,
60 pub txvga_db: u16,
62
63 pub lna_db: u16,
66 pub amp_enable: bool,
68
69 pub antenna_enable: bool,
72 pub frequency_hz: u64,
74 pub sample_rate_hz: u32,
76 pub sample_rate_div: u32,
79}
80
81impl Config {
82 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 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#[derive(thiserror::Error, Debug)]
113pub enum Error {
114 #[error("io")]
116 Io(#[from] std::io::Error),
117 #[error("transfer")]
119 Transfer(#[from] nusb::transfer::TransferError),
120 #[error("transfer truncated")]
122 TransferTruncated {
123 actual: usize,
125 expected: usize,
127 },
128 #[error("no api")]
132 NoApi {
133 device: UsbVersion,
135 min: UsbVersion,
137 },
138 #[error("{0}")]
140 Argument(&'static str),
141 #[error("HackRF in invalid mode. Required: {required:?}, actual: {actual:?}")]
143 WrongMode {
144 required: Mode,
146 actual: Mode,
148 },
149 #[error("Device not found")]
151 NotFound,
152}
153
154pub type Result<T> = std::result::Result<T, Error>;
156
157#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
162pub struct UsbVersion(pub u8, pub u8, pub u8);
165
166impl UsbVersion {
167 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 pub fn major(self) -> u8 {
188 let UsbVersion(major, _, _) = self;
189 major
190 }
191
192 pub fn minor(self) -> u8 {
194 let UsbVersion(_, minor, _) = self;
195 minor
196 }
197
198 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}