1use crate::status::Status;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8pub enum PulseShape {
9 None = 0,
10 Custom = 1,
11 Bt0p3 = 4,
12 Bt0p5 = 5,
13 Bt0p7 = 6,
14 Bt1p0 = 7,
15 Bt2p0 = 2,
16 Rc0p3 = 8,
17 Rc0p5 = 9,
18 Rc0p7 = 10,
19 Rc1p0 = 11,
20 Rrc0p3 = 12,
21 Rrc0p4 = 3,
22 Rrc0p5 = 13,
23 Rrc0p7 = 14,
24 Rrc1p0 = 15,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub enum RxBw {
31 BwAuto = 255,
32 Bw3076 = 0,
33 Bw2857 = 64,
34 Bw2666 = 128,
35 Bw2222 = 192,
36 Bw1333 = 136,
37 Bw1111 = 200,
38 Bw888 = 144,
39 Bw769 = 24,
40 Bw740 = 208,
41 Bw714 = 88,
42 Bw666 = 152,
43 Bw615 = 32,
44 Bw571 = 96,
45 Bw555 = 216,
46 Bw533 = 160,
47 Bw512 = 17,
48 Bw476 = 81,
49 Bw444 = 224,
50 Bw384 = 25,
51 Bw370 = 209,
52 Bw357 = 89,
53 Bw333 = 153,
54 Bw307 = 33,
55 Bw285 = 97,
56 Bw277 = 217,
57 Bw266 = 161,
58 Bw256 = 18,
59 Bw238 = 82,
60 Bw222 = 225,
61 Bw192 = 26,
62 Bw185 = 210,
63 Bw178 = 90,
64 Bw166 = 154,
65 Bw153 = 34,
66 Bw142 = 98,
67 Bw138 = 218,
68 Bw133 = 162,
69 Bw128 = 19,
70 Bw119 = 83,
71 Bw111 = 226,
72 Bw96 = 27,
73 Bw92 = 211,
74 Bw89 = 91,
75 Bw83 = 155,
76 Bw76 = 35,
77 Bw71 = 99,
78 Bw69 = 219,
79 Bw66 = 163,
80 Bw64 = 20,
81 Bw59 = 84,
82 Bw55 = 227,
83 Bw48 = 28,
84 Bw46 = 212,
85 Bw44 = 92,
86 Bw41 = 156,
87 Bw38 = 36,
88 Bw35 = 100,
89 Bw34 = 220,
90 Bw33 = 164,
91 Bw32 = 21,
92 Bw29 = 85,
93 Bw27 = 228,
94 Bw24 = 29,
95 Bw23 = 213,
96 Bw22 = 93,
97 Bw20 = 157,
98 Bw19 = 37,
99 Bw17 = 101,
100 Bw16 = 165,
101 Bw14 = 86,
102 Bw13 = 229,
103 Bw12 = 30,
104 Bw11 = 94,
105 Bw10 = 158,
106 Bw9p6 = 38,
107 Bw8p9 = 102,
108 Bw8p7 = 222,
109 Bw8p3 = 166,
110 Bw8 = 23,
111 Bw7p4 = 87,
112 Bw6p9 = 230,
113 Bw6 = 31,
114 Bw5p8 = 215,
115 Bw5p6 = 95,
116 Bw5p2 = 159,
117 Bw4p8 = 39,
118 Bw4p5 = 103,
119 Bw4p3 = 223,
120 Bw4p2 = 167,
121 Bw3p5 = 231,
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126#[cfg_attr(feature = "defmt", derive(defmt::Format))]
127pub enum PblLenDetect {
128 None = 0,
129 Len8Bits = 8,
130 Len16Bits = 16,
131 Len24Bits = 24,
132 Len32Bits = 32,
133}
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137#[cfg_attr(feature = "defmt", derive(defmt::Format))]
138pub enum PldLenUnit {
139 Bytes = 0,
140 Bits = 1,
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq)]
145#[cfg_attr(feature = "defmt", derive(defmt::Format))]
146pub enum AddrComp {
147 Off = 0,
148 Node = 1,
149 NodeBcast = 2,
150}
151
152#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154#[cfg_attr(feature = "defmt", derive(defmt::Format))]
155pub enum FskPktFormat {
156 FixedLength = 0,
157 Variable8bit = 1,
158 Variable9bit = 2,
159 Variable16bit = 3,
160}
161
162#[derive(Debug, Clone, Copy, PartialEq, Eq)]
164#[cfg_attr(feature = "defmt", derive(defmt::Format))]
165pub enum Crc {
166 CrcOff = 0,
167 Crc1Byte = 1,
168 Crc2Byte = 2,
169 Crc3Byte = 3,
170 Crc4Byte = 4,
171 Crc1ByteInv = 9,
172 Crc2ByteInv = 10,
173 Crc3ByteInv = 11,
174 Crc4ByteInv = 12,
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179#[cfg_attr(feature = "defmt", derive(defmt::Format))]
180pub enum WhitenType {
181 Sx126xLr11xx = 0,
182 Sx128x = 1,
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
187#[cfg_attr(feature = "defmt", derive(defmt::Format))]
188pub enum BitOrder {
189 LsbFirst = 0,
190 MsbFirst = 1,
191}
192
193pub fn set_fsk_modulation_params_cmd(bitrate: u32, pulse_shape: PulseShape, rx_bw: RxBw, fdev: u32) -> [u8; 11] {
195 let mut cmd = [0u8; 11];
196 cmd[0] = 0x02;
197 cmd[1] = 0x40;
198
199 cmd[2] |= ((bitrate >> 24) & 0xFF) as u8;
200 cmd[3] |= ((bitrate >> 16) & 0xFF) as u8;
201 cmd[4] |= ((bitrate >> 8) & 0xFF) as u8;
202 cmd[5] |= (bitrate & 0xFF) as u8;
203 cmd[6] |= (pulse_shape as u8) & 0xF;
204 cmd[7] |= rx_bw as u8;
205 cmd[8] |= ((fdev >> 16) & 0xFF) as u8;
206 cmd[9] |= ((fdev >> 8) & 0xFF) as u8;
207 cmd[10] |= (fdev & 0xFF) as u8;
208 cmd
209}
210
211#[allow(clippy::too_many_arguments)]
212pub fn set_fsk_packet_params_cmd(pbl_len_tx: u16, pbl_len_detect: PblLenDetect, pbl_long: bool, pld_len_unit: PldLenUnit, addr_comp: AddrComp, fsk_pkt_format: FskPktFormat, pld_len: u16, crc: Crc, dc_free: bool) -> [u8; 9] {
214 let mut cmd = [0u8; 9];
215 cmd[0] = 0x02;
216 cmd[1] = 0x41;
217
218 cmd[2] |= ((pbl_len_tx >> 8) & 0xFF) as u8;
219 cmd[3] |= (pbl_len_tx & 0xFF) as u8;
220 cmd[4] |= pbl_len_detect as u8;
221 if pbl_long { cmd[5] |= 16; }
222 cmd[5] |= ((pld_len_unit as u8) & 0x1) << 4;
223 cmd[5] |= ((addr_comp as u8) & 0x3) << 2;
224 cmd[5] |= (fsk_pkt_format as u8) & 0x3;
225 cmd[6] |= ((pld_len >> 8) & 0xFF) as u8;
226 cmd[7] |= (pld_len & 0xFF) as u8;
227 cmd[8] |= ((crc as u8) & 0xF) << 4;
228 if dc_free { cmd[8] |= 1; }
229 cmd
230}
231
232pub fn set_fsk_whitening_params_cmd(whiten_type: WhitenType, init: u16) -> [u8; 4] {
234 let mut cmd = [0u8; 4];
235 cmd[0] = 0x02;
236 cmd[1] = 0x42;
237
238 cmd[2] |= ((whiten_type as u8) & 0x1) << 4;
239 cmd[2] |= ((init >> 8) & 0xFF) as u8;
240 cmd[3] |= (init & 0xFF) as u8;
241 cmd
242}
243
244pub fn set_fsk_crc_params_cmd(polynom: u32, init: u32) -> [u8; 10] {
246 let mut cmd = [0u8; 10];
247 cmd[0] = 0x02;
248 cmd[1] = 0x43;
249
250 cmd[2] |= ((polynom >> 24) & 0xFF) as u8;
251 cmd[3] |= ((polynom >> 16) & 0xFF) as u8;
252 cmd[4] |= ((polynom >> 8) & 0xFF) as u8;
253 cmd[5] |= (polynom & 0xFF) as u8;
254 cmd[6] |= ((init >> 24) & 0xFF) as u8;
255 cmd[7] |= ((init >> 16) & 0xFF) as u8;
256 cmd[8] |= ((init >> 8) & 0xFF) as u8;
257 cmd[9] |= (init & 0xFF) as u8;
258 cmd
259}
260
261pub fn set_fsk_sync_word_cmd(syncword: u64, bit_order: BitOrder, nb_bits: u8) -> [u8; 11] {
263 let mut cmd = [0u8; 11];
264 cmd[0] = 0x02;
265 cmd[1] = 0x44;
266
267 cmd[2] |= ((syncword >> 56) & 0xFF) as u8;
268 cmd[3] |= ((syncword >> 48) & 0xFF) as u8;
269 cmd[4] |= ((syncword >> 40) & 0xFF) as u8;
270 cmd[5] |= ((syncword >> 32) & 0xFF) as u8;
271 cmd[6] |= ((syncword >> 24) & 0xFF) as u8;
272 cmd[7] |= ((syncword >> 16) & 0xFF) as u8;
273 cmd[8] |= ((syncword >> 8) & 0xFF) as u8;
274 cmd[9] |= (syncword & 0xFF) as u8;
275 cmd[10] |= ((bit_order as u8) & 0x1) << 7;
276 cmd[10] |= nb_bits & 0x7F;
277 cmd
278}
279
280pub fn set_fsk_address_cmd(addr_node: u8, addr_bcast: u8) -> [u8; 4] {
282 let mut cmd = [0u8; 4];
283 cmd[0] = 0x02;
284 cmd[1] = 0x45;
285
286 cmd[2] |= addr_node;
287 cmd[3] |= addr_bcast;
288 cmd
289}
290
291pub fn get_fsk_rx_stats_req() -> [u8; 2] {
293 [0x02, 0x46]
294}
295
296pub fn get_fsk_packet_status_req() -> [u8; 2] {
298 [0x02, 0x47]
299}
300
301#[derive(Default)]
305pub struct FskRxStatsRsp([u8; 16]);
306
307impl FskRxStatsRsp {
308 pub fn new() -> Self {
310 Self::default()
311 }
312
313 pub fn status(&mut self) -> Status {
315 Status::from_slice(&self.0[..2])
316 }
317
318 pub fn pkt_rx(&self) -> u16 {
320 (self.0[3] as u16) |
321 ((self.0[2] as u16) << 8)
322 }
323
324 pub fn crc_error(&self) -> u16 {
326 (self.0[5] as u16) |
327 ((self.0[4] as u16) << 8)
328 }
329
330 pub fn len_error(&self) -> u16 {
332 (self.0[7] as u16) |
333 ((self.0[6] as u16) << 8)
334 }
335
336 pub fn pbl_det(&self) -> u16 {
338 (self.0[9] as u16) |
339 ((self.0[8] as u16) << 8)
340 }
341
342 pub fn sync_ok(&self) -> u16 {
344 (self.0[11] as u16) |
345 ((self.0[10] as u16) << 8)
346 }
347
348 pub fn sync_fail(&self) -> u16 {
350 (self.0[13] as u16) |
351 ((self.0[12] as u16) << 8)
352 }
353
354 pub fn timeout(&self) -> u16 {
356 (self.0[15] as u16) |
357 ((self.0[14] as u16) << 8)
358 }
359}
360
361impl AsMut<[u8]> for FskRxStatsRsp {
362 fn as_mut(&mut self) -> &mut [u8] {
363 &mut self.0
364 }
365}
366
367#[derive(Default)]
369pub struct FskPacketStatusRsp([u8; 8]);
370
371impl FskPacketStatusRsp {
372 pub fn new() -> Self {
374 Self::default()
375 }
376
377 pub fn status(&mut self) -> Status {
379 Status::from_slice(&self.0[..2])
380 }
381
382 pub fn pkt_len(&self) -> u16 {
384 (self.0[3] as u16) |
385 ((self.0[2] as u16) << 8)
386 }
387
388 pub fn rssi_avg(&self) -> u16 {
390 (((self.0[6] >> 2) & 0x1) as u16) |
391 ((self.0[4] as u16) << 1)
392 }
393
394 pub fn rssi_sync(&self) -> u16 {
396 ((self.0[6] & 0x1) as u16) |
397 ((self.0[5] as u16) << 1)
398 }
399
400 pub fn addr_match_bcast(&self) -> bool {
402 (self.0[6] >> 5) & 0x1 != 0
403 }
404
405 pub fn addr_match_node(&self) -> bool {
407 (self.0[6] >> 4) & 0x1 != 0
408 }
409
410 pub fn lqi(&self) -> u8 {
412 self.0[7]
413 }
414}
415
416impl AsMut<[u8]> for FskPacketStatusRsp {
417 fn as_mut(&mut self) -> &mut [u8] {
418 &mut self.0
419 }
420}