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