1use crate::status::Status;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8pub enum RxPath {
9 LfPath = 0,
10 HfPath = 1,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub enum RxBoost {
17 Off = 0,
18 B1 = 1,
19 B2 = 2,
20 B3 = 3,
21 B4 = 4,
22 B5 = 5,
23 B6 = 6,
24 Max = 7,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub enum PaSel {
31 LfPa = 0,
32 HfPa = 1,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37#[cfg_attr(feature = "defmt", derive(defmt::Format))]
38pub enum PaLfMode {
39 LfPaFsm = 0,
40 LfPaFdm = 1,
41 LfPaHsmRfo1 = 2,
42 LfPaHsmRfo2 = 3,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47#[cfg_attr(feature = "defmt", derive(defmt::Format))]
48pub enum RampTime {
49 Ramp2u = 0,
50 Ramp4u = 1,
51 Ramp8u = 2,
52 Ramp16u = 3,
53 Ramp32u = 4,
54 Ramp48u = 5,
55 Ramp64u = 6,
56 Ramp80u = 7,
57 Ramp96u = 8,
58 Ramp112u = 9,
59 Ramp128u = 10,
60 Ramp144u = 11,
61 Ramp160u = 12,
62 Ramp176u = 13,
63 Ramp192u = 14,
64 Ramp208u = 15,
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70pub enum FallbackMode {
71 StandbyRc = 1,
72 StandbyXosc = 2,
73 Fs = 3,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78#[cfg_attr(feature = "defmt", derive(defmt::Format))]
79pub enum PacketType {
80 Lora = 0,
81 FskGeneric = 1,
82 FskLegacy = 2,
83 Ble = 3,
84 Ranging = 4,
85 Flrc = 5,
86 Bpsk = 6,
87 LrFhss = 7,
88 Wmbus = 8,
89 Wisun = 9,
90 Ook = 10,
91 Raw = 11,
92 Zwave = 12,
93 Zigbee = 13,
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
99pub enum TestMode {
100 Packet = 0,
101 Preamble = 1,
102 Tone = 2,
103 Prbs9 = 3,
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq)]
108#[cfg_attr(feature = "defmt", derive(defmt::Format))]
109pub enum AutoTxrxMode {
110 Disable = 0,
111 Always = 1,
112 RxOk = 2,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117#[cfg_attr(feature = "defmt", derive(defmt::Format))]
118pub enum TimestampIndex {
119 Ts0 = 0,
120 Ts1 = 1,
121 Ts2 = 2,
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126#[cfg_attr(feature = "defmt", derive(defmt::Format))]
127pub enum TimestampSource {
128 None = 0,
129 TxDone = 1,
130 RxDone = 2,
131 Sync = 3,
132 Header = 4,
133}
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137#[cfg_attr(feature = "defmt", derive(defmt::Format))]
138pub enum ExitMode {
139 Fallback = 0,
140 Tx = 1,
141 Rx = 2,
142}
143
144pub fn set_rf_frequency_cmd(rf_freq: u32) -> [u8; 6] {
146 let mut cmd = [0u8; 6];
147 cmd[0] = 0x02;
148 cmd[1] = 0x00;
149
150 cmd[2] |= ((rf_freq >> 24) & 0xFF) as u8;
151 cmd[3] |= ((rf_freq >> 16) & 0xFF) as u8;
152 cmd[4] |= ((rf_freq >> 8) & 0xFF) as u8;
153 cmd[5] |= (rf_freq & 0xFF) as u8;
154 cmd
155}
156
157pub fn set_rx_path_cmd(rx_path: RxPath) -> [u8; 3] {
159 let mut cmd = [0u8; 3];
160 cmd[0] = 0x02;
161 cmd[1] = 0x01;
162
163 cmd[2] |= (rx_path as u8) & 0x1;
164 cmd
165}
166
167pub fn set_rx_path_adv_cmd(rx_path: RxPath, rx_boost: RxBoost) -> [u8; 4] {
169 let mut cmd = [0u8; 4];
170 cmd[0] = 0x02;
171 cmd[1] = 0x01;
172
173 cmd[2] |= (rx_path as u8) & 0x1;
174 cmd[3] |= (rx_boost as u8) & 0x7;
175 cmd
176}
177
178pub fn set_pa_config_cmd(pa_sel: PaSel, pa_lf_mode: PaLfMode, pa_lf_duty_cycle: u8, pa_lf_slices: u8) -> [u8; 4] {
180 let mut cmd = [0u8; 4];
181 cmd[0] = 0x02;
182 cmd[1] = 0x02;
183
184 cmd[2] |= ((pa_sel as u8) & 0x1) << 7;
185 cmd[2] |= (pa_lf_mode as u8) & 0x3;
186 cmd[2] |= (pa_lf_duty_cycle & 0xF) << 4;
187 cmd[3] |= pa_lf_slices & 0xF;
188 cmd
189}
190
191pub fn set_pa_config_adv_cmd(pa_sel: PaSel, pa_lf_mode: PaLfMode, pa_lf_duty_cycle: u8, pa_lf_slices: u8, pa_hf_duty_cycle: u8) -> [u8; 5] {
193 let mut cmd = [0u8; 5];
194 cmd[0] = 0x02;
195 cmd[1] = 0x02;
196
197 cmd[2] |= ((pa_sel as u8) & 0x1) << 7;
198 cmd[2] |= (pa_lf_mode as u8) & 0x3;
199 cmd[2] |= (pa_lf_duty_cycle & 0xF) << 4;
200 cmd[3] |= pa_lf_slices & 0xF;
201 cmd[4] |= pa_hf_duty_cycle & 0x1F;
202 cmd
203}
204
205pub fn set_tx_params_cmd(tx_power: i8, ramp_time: RampTime) -> [u8; 4] {
207 let mut cmd = [0u8; 4];
208 cmd[0] = 0x02;
209 cmd[1] = 0x03;
210
211 cmd[2] |= (tx_power) as u8;
212 cmd[3] |= ramp_time as u8;
213 cmd
214}
215
216pub fn set_rx_tx_fallback_mode_cmd(fallback_mode: FallbackMode) -> [u8; 3] {
218 let mut cmd = [0u8; 3];
219 cmd[0] = 0x02;
220 cmd[1] = 0x06;
221
222 cmd[2] |= (fallback_mode as u8) & 0x3;
223 cmd
224}
225
226pub fn set_packet_type_cmd(packet_type: PacketType) -> [u8; 3] {
228 let mut cmd = [0u8; 3];
229 cmd[0] = 0x02;
230 cmd[1] = 0x07;
231
232 cmd[2] |= packet_type as u8;
233 cmd
234}
235
236pub fn get_packet_type_req() -> [u8; 2] {
238 [0x02, 0x08]
239}
240
241pub fn set_stop_timeout_cmd(stop_on_preamble: bool) -> [u8; 3] {
243 let mut cmd = [0u8; 3];
244 cmd[0] = 0x02;
245 cmd[1] = 0x09;
246
247 if stop_on_preamble { cmd[2] |= 1; }
248 cmd
249}
250
251pub fn reset_rx_stats_cmd() -> [u8; 2] {
253 [0x02, 0x0A]
254}
255
256pub fn get_rssi_inst_req() -> [u8; 2] {
258 [0x02, 0x0B]
259}
260
261pub fn set_rx_cmd() -> [u8; 2] {
263 [0x02, 0x0C]
264}
265
266pub fn set_rx_adv_cmd(rx_timeout: u32) -> [u8; 5] {
268 let mut cmd = [0u8; 5];
269 cmd[0] = 0x02;
270 cmd[1] = 0x0C;
271
272 cmd[2] |= ((rx_timeout >> 16) & 0xFF) as u8;
273 cmd[3] |= ((rx_timeout >> 8) & 0xFF) as u8;
274 cmd[4] |= (rx_timeout & 0xFF) as u8;
275 cmd
276}
277
278pub fn set_tx_cmd() -> [u8; 2] {
280 [0x02, 0x0D]
281}
282
283pub fn set_tx_adv_cmd(tx_timeout: u32) -> [u8; 5] {
285 let mut cmd = [0u8; 5];
286 cmd[0] = 0x02;
287 cmd[1] = 0x0D;
288
289 cmd[2] |= ((tx_timeout >> 16) & 0xFF) as u8;
290 cmd[3] |= ((tx_timeout >> 8) & 0xFF) as u8;
291 cmd[4] |= (tx_timeout & 0xFF) as u8;
292 cmd
293}
294
295pub fn set_tx_test_mode_cmd(test_mode: TestMode) -> [u8; 3] {
297 let mut cmd = [0u8; 3];
298 cmd[0] = 0x02;
299 cmd[1] = 0x0E;
300
301 cmd[2] |= test_mode as u8;
302 cmd
303}
304
305pub fn sel_pa_cmd(pa_sel: PaSel) -> [u8; 3] {
307 let mut cmd = [0u8; 3];
308 cmd[0] = 0x02;
309 cmd[1] = 0x0F;
310
311 cmd[2] |= (pa_sel as u8) & 0x1;
312 cmd
313}
314
315pub fn set_rx_duty_cycle_cmd(rx_max_time: u32, cycle_time: u32, use_lora_cad: bool, dram_ret: u8) -> [u8; 9] {
317 let mut cmd = [0u8; 9];
318 cmd[0] = 0x02;
319 cmd[1] = 0x10;
320
321 cmd[2] |= ((rx_max_time >> 16) & 0xFF) as u8;
322 cmd[3] |= ((rx_max_time >> 8) & 0xFF) as u8;
323 cmd[4] |= (rx_max_time & 0xFF) as u8;
324 cmd[5] |= ((cycle_time >> 16) & 0xFF) as u8;
325 cmd[6] |= ((cycle_time >> 8) & 0xFF) as u8;
326 cmd[7] |= (cycle_time & 0xFF) as u8;
327 if use_lora_cad { cmd[8] |= 16; }
328 cmd[8] |= dram_ret & 0x7;
329 cmd
330}
331
332pub fn set_auto_rx_tx_cmd(clear: bool, auto_txrx_mode: AutoTxrxMode, timeout: u32, delay: u32) -> [u8; 10] {
334 let mut cmd = [0u8; 10];
335 cmd[0] = 0x02;
336 cmd[1] = 0x11;
337
338 if clear { cmd[2] |= 128; }
339 cmd[2] |= (auto_txrx_mode as u8) & 0x3;
340 cmd[3] |= ((timeout >> 16) & 0xFF) as u8;
341 cmd[4] |= ((timeout >> 8) & 0xFF) as u8;
342 cmd[5] |= (timeout & 0xFF) as u8;
343 cmd[6] |= ((delay >> 24) & 0xFF) as u8;
344 cmd[7] |= ((delay >> 16) & 0xFF) as u8;
345 cmd[8] |= ((delay >> 8) & 0xFF) as u8;
346 cmd[9] |= (delay & 0xFF) as u8;
347 cmd
348}
349
350pub fn get_rx_pkt_length_req() -> [u8; 2] {
352 [0x02, 0x12]
353}
354
355pub fn set_power_offset_cmd(power_offset: u8) -> [u8; 3] {
357 let mut cmd = [0u8; 3];
358 cmd[0] = 0x02;
359 cmd[1] = 0x14;
360
361 cmd[2] |= power_offset & 0x3F;
362 cmd
363}
364
365pub fn set_default_rx_tx_timeout_cmd(rx_timeout: u32, tx_timeout: u32) -> [u8; 8] {
367 let mut cmd = [0u8; 8];
368 cmd[0] = 0x02;
369 cmd[1] = 0x15;
370
371 cmd[2] |= ((rx_timeout >> 16) & 0xFF) as u8;
372 cmd[3] |= ((rx_timeout >> 8) & 0xFF) as u8;
373 cmd[4] |= (rx_timeout & 0xFF) as u8;
374 cmd[5] |= ((tx_timeout >> 16) & 0xFF) as u8;
375 cmd[6] |= ((tx_timeout >> 8) & 0xFF) as u8;
376 cmd[7] |= (tx_timeout & 0xFF) as u8;
377 cmd
378}
379
380pub fn set_timestamp_source_cmd(timestamp_index: TimestampIndex, timestamp_source: TimestampSource) -> [u8; 3] {
382 let mut cmd = [0u8; 3];
383 cmd[0] = 0x02;
384 cmd[1] = 0x16;
385
386 cmd[2] |= ((timestamp_index as u8) & 0x3) << 4;
387 cmd[2] |= (timestamp_source as u8) & 0xF;
388 cmd
389}
390
391pub fn get_timestamp_value_req(timestamp_index: TimestampIndex) -> [u8; 3] {
393 let mut cmd = [0u8; 3];
394 cmd[0] = 0x02;
395 cmd[1] = 0x17;
396
397 cmd[2] |= (timestamp_index as u8) & 0x3;
398 cmd
399}
400
401pub fn set_cca_cmd(duration: u32) -> [u8; 5] {
403 let mut cmd = [0u8; 5];
404 cmd[0] = 0x02;
405 cmd[1] = 0x18;
406
407 cmd[2] |= ((duration >> 16) & 0xFF) as u8;
408 cmd[3] |= ((duration >> 8) & 0xFF) as u8;
409 cmd[4] |= (duration & 0xFF) as u8;
410 cmd
411}
412
413pub fn set_cca_adv_cmd(duration: u32, gain: u8) -> [u8; 6] {
415 let mut cmd = [0u8; 6];
416 cmd[0] = 0x02;
417 cmd[1] = 0x18;
418
419 cmd[2] |= ((duration >> 16) & 0xFF) as u8;
420 cmd[3] |= ((duration >> 8) & 0xFF) as u8;
421 cmd[4] |= (duration & 0xFF) as u8;
422 cmd[5] |= gain;
423 cmd
424}
425
426pub fn get_cca_result_req() -> [u8; 2] {
428 [0x02, 0x19]
429}
430
431pub fn set_agc_gain_manual_cmd(gain_step: u8) -> [u8; 3] {
433 let mut cmd = [0u8; 3];
434 cmd[0] = 0x02;
435 cmd[1] = 0x1A;
436
437 cmd[2] |= gain_step & 0xF;
438 cmd
439}
440
441pub fn set_cad_params_cmd(cad_timeout: u32, threshold: u8, exit_mode: ExitMode, trx_timeout: u32) -> [u8; 10] {
443 let mut cmd = [0u8; 10];
444 cmd[0] = 0x02;
445 cmd[1] = 0x1B;
446
447 cmd[2] |= ((cad_timeout >> 16) & 0xFF) as u8;
448 cmd[3] |= ((cad_timeout >> 8) & 0xFF) as u8;
449 cmd[4] |= (cad_timeout & 0xFF) as u8;
450 cmd[5] |= threshold;
451 cmd[6] |= (exit_mode as u8) & 0x3;
452 cmd[7] |= ((trx_timeout >> 16) & 0xFF) as u8;
453 cmd[8] |= ((trx_timeout >> 8) & 0xFF) as u8;
454 cmd[9] |= (trx_timeout & 0xFF) as u8;
455 cmd
456}
457
458pub fn set_cad_cmd() -> [u8; 2] {
460 [0x02, 0x1C]
461}
462
463#[derive(Default)]
467pub struct PacketTypeRsp([u8; 3]);
468
469impl PacketTypeRsp {
470 pub fn new() -> Self {
472 Self::default()
473 }
474
475 pub fn status(&mut self) -> Status {
477 Status::from_slice(&self.0[..2])
478 }
479
480 pub fn packet_type(&self) -> u8 {
482 self.0[2]
483 }
484}
485
486impl AsMut<[u8]> for PacketTypeRsp {
487 fn as_mut(&mut self) -> &mut [u8] {
488 &mut self.0
489 }
490}
491
492#[derive(Default)]
494pub struct RssiInstRsp([u8; 4]);
495
496impl RssiInstRsp {
497 pub fn new() -> Self {
499 Self::default()
500 }
501
502 pub fn status(&mut self) -> Status {
504 Status::from_slice(&self.0[..2])
505 }
506
507 pub fn rssi(&self) -> u16 {
509 ((self.0[3] & 0x1) as u16) |
510 ((self.0[2] as u16) << 1)
511 }
512}
513
514impl AsMut<[u8]> for RssiInstRsp {
515 fn as_mut(&mut self) -> &mut [u8] {
516 &mut self.0
517 }
518}
519
520#[derive(Default)]
522pub struct RxPktLengthRsp([u8; 4]);
523
524impl RxPktLengthRsp {
525 pub fn new() -> Self {
527 Self::default()
528 }
529
530 pub fn status(&mut self) -> Status {
532 Status::from_slice(&self.0[..2])
533 }
534
535 pub fn pkt_length(&self) -> u16 {
537 (self.0[3] as u16) |
538 ((self.0[2] as u16) << 8)
539 }
540}
541
542impl AsMut<[u8]> for RxPktLengthRsp {
543 fn as_mut(&mut self) -> &mut [u8] {
544 &mut self.0
545 }
546}
547
548#[derive(Default)]
550pub struct TimestampValueRsp([u8; 6]);
551
552impl TimestampValueRsp {
553 pub fn new() -> Self {
555 Self::default()
556 }
557
558 pub fn status(&mut self) -> Status {
560 Status::from_slice(&self.0[..2])
561 }
562
563 pub fn timestamp(&self) -> u32 {
565 (self.0[5] as u32) |
566 ((self.0[4] as u32) << 8) |
567 ((self.0[3] as u32) << 16) |
568 ((self.0[2] as u32) << 24)
569 }
570}
571
572impl AsMut<[u8]> for TimestampValueRsp {
573 fn as_mut(&mut self) -> &mut [u8] {
574 &mut self.0
575 }
576}
577
578#[derive(Default)]
580pub struct CcaResultRsp([u8; 6]);
581
582impl CcaResultRsp {
583 pub fn new() -> Self {
585 Self::default()
586 }
587
588 pub fn status(&mut self) -> Status {
590 Status::from_slice(&self.0[..2])
591 }
592
593 pub fn rssi_min(&self) -> u16 {
595 (((self.0[5] >> 2) & 0x1) as u16) |
596 ((self.0[2] as u16) << 1)
597 }
598
599 pub fn rssi_max(&self) -> u16 {
601 (((self.0[5] >> 1) & 0x1) as u16) |
602 ((self.0[3] as u16) << 1)
603 }
604
605 pub fn rssi_avg(&self) -> u16 {
607 ((self.0[5] & 0x1) as u16) |
608 ((self.0[4] as u16) << 1)
609 }
610}
611
612impl AsMut<[u8]> for CcaResultRsp {
613 fn as_mut(&mut self) -> &mut [u8] {
614 &mut self.0
615 }
616}
617
618