1use std::ops::Range;
2
3use nusb::transfer::{ControlIn, ControlOut, ControlType, Recipient};
4
5use crate::{ControlRequest, Error, HackRf, TransceiverMode};
6
7#[repr(C)]
8#[derive(Clone, Copy, Debug, bytemuck::Zeroable, bytemuck::Pod)]
9pub struct M0State {
10 pub requested_mode: u16,
13 pub request_flag: u16,
16 pub active_mode: u32,
19 pub m0_count: u32,
21 pub m4_count: u32,
23 pub num_shortfalls: u32,
25 pub longest_shortfall: u32,
27 pub shortfall_limit: u32,
29 pub threshold: u32,
31 pub next_mode: u32,
33 pub error: u32,
36}
37
38impl M0State {
39 fn le_convert(&mut self) {
40 self.requested_mode = self.requested_mode.to_le();
41 self.request_flag = self.request_flag.to_le();
42 self.active_mode = self.active_mode.to_le();
43 self.m0_count = self.m0_count.to_le();
44 self.m4_count = self.m4_count.to_le();
45 self.num_shortfalls = self.num_shortfalls.to_le();
46 self.longest_shortfall = self.longest_shortfall.to_le();
47 self.shortfall_limit = self.shortfall_limit.to_le();
48 self.threshold = self.threshold.to_le();
49 self.next_mode = self.next_mode.to_le();
50 self.error = self.error.to_le();
51 }
52}
53
54pub struct Debug<'a> {
58 inner: &'a mut HackRf,
59}
60
61impl<'a> Debug<'a> {
62 pub(crate) fn new(inner: &'a mut HackRf) -> Debug<'a> {
63 Self { inner }
64 }
65
66 pub async fn get_m0_state(&self) -> Result<M0State, Error> {
70 self.inner.api_check(0x0106)?;
71 let mut v: M0State = self.inner.read_struct(ControlRequest::GetM0State).await?;
72 v.le_convert();
73 Ok(v)
74 }
75
76 pub fn spi_flash(&self) -> SpiFlash<'_> {
78 SpiFlash { inner: self.inner }
79 }
80
81 pub async fn cpld_write<F>(&mut self, data: &[u8], mut callback: Option<F>) -> Result<(), Error>
87 where
88 F: FnMut(usize, usize),
89 {
90 const CHUNK_SIZE: usize = 512;
91 self.inner
92 .set_transceiver_mode(TransceiverMode::CpldUpdate)
93 .await?;
94 let mut queue = self
95 .inner
96 .interface
97 .bulk_out_queue(crate::consts::TX_ENDPOINT_ADDRESS);
98 let mut sent = 0;
99 let total = data.len();
100 for chunk in data.chunks(CHUNK_SIZE) {
101 let mut buf = if queue.pending() != 0 {
102 let resp = queue.next_complete().await.into_result()?;
103 sent += resp.actual_length();
104 if let Some(ref mut c) = callback {
105 c(sent, total);
106 }
107 resp.reuse()
108 } else {
109 Vec::with_capacity(CHUNK_SIZE)
110 };
111 buf.copy_from_slice(chunk);
112 queue.submit(buf);
113 }
114 while queue.pending() != 0 {
115 let resp = queue.next_complete().await.into_result()?;
116 sent += resp.actual_length();
117 if let Some(ref mut c) = callback {
118 c(sent, total);
119 }
120 }
121 self.inner
122 .set_transceiver_mode(TransceiverMode::Off)
123 .await?;
124 Ok(())
125 }
126
127 pub async fn cpld_checksum(&self) -> Result<u32, Error> {
131 self.inner.api_check(0x0103)?;
132 let ret = self
133 .inner
134 .read_bytes(ControlRequest::CpldChecksum, 4)
135 .await?;
136 let ret: [u8; 4] = ret.as_slice().try_into().map_err(|_| Error::ReturnData)?;
137 Ok(u32::from_le_bytes(ret))
138 }
139
140 pub async fn si5351c_read(&self, register: u8) -> Result<u8, Error> {
142 self.inner
143 .read_u8(ControlRequest::Si5351cRead, register as u16)
144 .await
145 }
146
147 pub async fn si5351c_write(&self, register: u8, value: u8) -> Result<(), Error> {
149 self.inner
150 .write_u8(ControlRequest::Si5351cWrite, register as u16, value)
151 .await
152 }
153
154 pub async fn rffc5071_read(&self, register: u8) -> Result<u16, Error> {
156 if register >= 31 {
157 return Err(Error::AddressRange {
158 range: Range { start: 0, end: 31 },
159 addr: register as u32,
160 });
161 }
162
163 self.inner
164 .read_u16(ControlRequest::Rffc5071Read, register as u16)
165 .await
166 }
167
168 pub async fn rffc5071_write(&self, register: u8, value: u16) -> Result<(), Error> {
170 if register >= 31 {
171 return Err(Error::AddressRange {
172 range: Range { start: 0, end: 31 },
173 addr: register as u32,
174 });
175 }
176
177 self.inner
178 .write_u16(ControlRequest::Rffc5071Write, register as u16, value)
179 .await
180 }
181
182 pub async fn max2837_read(&self, register: u8) -> Result<u16, Error> {
184 if register >= 32 {
185 return Err(Error::AddressRange {
186 range: Range { start: 0, end: 32 },
187 addr: register as u32,
188 });
189 }
190
191 self.inner
192 .read_u16(ControlRequest::Max2837Read, register as u16)
193 .await
194 }
195
196 pub async fn max2837_write(&self, register: u8, value: u16) -> Result<(), Error> {
198 if register >= 32 {
199 return Err(Error::AddressRange {
200 range: Range { start: 0, end: 32 },
201 addr: register as u32,
202 });
203 }
204
205 if value >= 0x400 {
206 return Err(Error::ValueRange {
207 range: Range {
208 start: 0,
209 end: 0x400,
210 },
211 val: value as u32,
212 });
213 }
214
215 self.inner
216 .write_u16(ControlRequest::Max2837Write, register as u16, value)
217 .await
218 }
219}
220
221pub struct SpiFlash<'a> {
223 inner: &'a HackRf,
224}
225
226impl SpiFlash<'_> {
227 pub async fn erase(&self) -> Result<(), Error> {
232 self.inner
233 .write_u8(ControlRequest::SpiflashErase, 0, 0)
234 .await
235 }
236
237 pub async fn write(&self, addr: u32, data: &[u8]) -> Result<(), Error> {
245 const END_ADDR: u32 = 0x100000;
246 if addr >= END_ADDR {
247 return Err(Error::AddressRange {
248 range: Range {
249 start: 0,
250 end: END_ADDR,
251 },
252 addr,
253 });
254 }
255
256 if (data.len() + addr as usize) > (END_ADDR as usize) {
257 let end = END_ADDR - addr;
258 return Err(Error::ValueRange {
259 range: Range { start: 0, end },
260 val: data.len() as u32,
261 });
262 }
263
264 let mut addr = addr;
265 let mut data = data;
266 let mut chunk: &[u8];
267 while !data.is_empty() {
268 let len = (0x100 - ((addr & 0xff) as usize)).min(data.len());
270 (chunk, data) = data.split_at(len);
271 self.inner
272 .interface
273 .control_out(ControlOut {
274 control_type: ControlType::Vendor,
275 recipient: Recipient::Device,
276 request: ControlRequest::SpiflashWrite as u8,
277 value: (addr >> 16) as u16,
278 index: (addr & 0xFFFF) as u16,
279 data: chunk,
280 })
281 .await
282 .into_result()?;
283 addr += len as u32;
284 }
285 Ok(())
286 }
287
288 pub async fn read(&self, addr: u32, len: usize) -> Result<Vec<u8>, Error> {
295 const END_ADDR: u32 = 0x10_0000;
296 if addr >= END_ADDR {
297 return Err(Error::AddressRange {
298 range: Range {
299 start: 0,
300 end: END_ADDR,
301 },
302 addr,
303 });
304 }
305
306 if (len + addr as usize) > (END_ADDR as usize) {
307 let end = END_ADDR - addr;
308 return Err(Error::ValueRange {
309 range: Range { start: 0, end },
310 val: len as u32,
311 });
312 }
313
314 let mut addr = addr;
315 let mut data = Vec::with_capacity(len);
316 while data.len() < len {
317 let block_len = (0x100 - ((addr & 0xff) as usize)).min(len - data.len());
319 let resp = self
320 .inner
321 .interface
322 .control_in(ControlIn {
323 control_type: ControlType::Vendor,
324 recipient: Recipient::Device,
325 request: ControlRequest::SpiflashRead as u8,
326 value: (addr >> 16) as u16,
327 index: (addr & 0xFFFF) as u16,
328 length: block_len as u16,
329 })
330 .await
331 .into_result()?;
332 data.extend_from_slice(&resp);
333 addr += resp.len() as u32;
334 }
335 Ok(data)
336 }
337
338 pub async fn status(&self) -> Result<[u8; 2], Error> {
342 self.inner.api_check(0x0103)?;
343 let val = self
344 .inner
345 .read_u16(ControlRequest::SpiflashStatus, 0)
346 .await?;
347 Ok(val.to_le_bytes())
348 }
349
350 pub async fn clear_status(&self) -> Result<(), Error> {
352 self.inner.api_check(0x0103)?;
353 self.inner
354 .write_u16(ControlRequest::SpiflashClearStatus, 0, 0)
355 .await
356 }
357}