dw3000_ng/configs.rs
1//! Configuration structs for sending and receiving
2//!
3//! This module houses the datastructures that control how frames are
4//! transmitted and received. The configs are passed to the send and receive
5//! functions.
6
7#[derive(Copy, Clone, Debug, Eq, PartialEq)]
8/// General configuration for TX and RX
9pub struct Config {
10 /// The channel that the DW3000 will transmit at.
11 pub channel: UwbChannel,
12 /// The SFD sequence that is used to transmit a frame.
13 pub sfd_sequence: SfdSequence,
14 /// Sets the PRF value of the transmission.
15 pub pulse_repetition_frequency: PulseRepetitionFrequency,
16 /// The length of the preamble.
17 pub preamble_length: PreambleLength,
18 /// Sets the bitrate of the transmission.
19 pub bitrate: BitRate,
20 /// Defaults to `true`.
21 pub frame_filtering: bool,
22 /// Sets the ranging bit in the transmitted frame.
23 /// This has no effect on the capabilities of the DW3000.
24 pub ranging_enable: bool,
25 /// Defaults to mode off
26 pub sts_mode: StsMode,
27 /// Defaults to 64
28 pub sts_len: StsLen,
29 /// SFD_timeout = Preamble length + 1 + sfdlength - pac size
30 pub sfd_timeout: u32,
31 /// TX preamble code, optional
32 /// If not set, the recommended value will be used (see `get_recommended_preamble_code`)
33 pub tx_preamble_code: Option<u8>,
34 /// RX preamble code, optional
35 /// If not set, the recommended value will be used (see `get_recommended_preamble_code`)
36 pub rx_preamble_code: Option<u8>,
37 /// PHR mode
38 pub phr_mode: PhrMode,
39 /// PHR rate
40 pub phr_rate: PhrRate,
41 /// PDoA mode
42 pub pdoa_mode: PdoaMode,
43}
44
45impl Default for Config {
46 fn default() -> Self {
47 Config {
48 channel: Default::default(),
49 sfd_sequence: Default::default(),
50 pulse_repetition_frequency: Default::default(),
51 preamble_length: Default::default(),
52 bitrate: Default::default(),
53 frame_filtering: false,
54 ranging_enable: false,
55 sts_mode: Default::default(), //mode off
56 sts_len: Default::default(),
57 sfd_timeout: 129,
58 tx_preamble_code: None,
59 rx_preamble_code: None,
60 phr_mode: Default::default(),
61 phr_rate: Default::default(),
62 pdoa_mode: Default::default(),
63 }
64 }
65}
66
67#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
68/// The bitrate at which a message is transmitted
69pub enum BitRate {
70 /// 850 kilobits per second.
71 #[default]
72 Kbps850 = 0,
73 /// 6.8 megabits per second.
74 Kbps6800 = 1,
75}
76
77#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
78/// The PRF value
79pub enum PulseRepetitionFrequency {
80 /// 16 megahertz
81 Mhz16 = 0b01,
82 /// 64 megahertz
83 #[default]
84 Mhz64 = 0b10,
85}
86
87/// imple
88impl PulseRepetitionFrequency {
89 /// activate rx_tune_en if prf = 64MHz
90 pub fn get_recommended_rx_tune_en(&self) -> u8 {
91 match self {
92 PulseRepetitionFrequency::Mhz16 => 0,
93 PulseRepetitionFrequency::Mhz64 => 1,
94 }
95 }
96}
97
98#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
99/// An enum that specifies the length of the preamble.
100///
101/// Longer preambles improve the reception quality and thus range.
102/// This comes at the cost of longer transmission times and thus power
103/// consumption and bandwidth use.
104///
105/// For the bit pattern, see table 16 in the user manual. Two bits TXPSR,then
106/// two bits PE.
107pub enum PreambleLength {
108 /// 64 symbols of preamble.
109 /// Only supported at Bitrate::Kbps6800.
110 Symbols64 = 0b0001,
111 /// 1024 symbols of preamble.
112 /// Only supported at Bitrate::Kbps850 & Bitrate::Kbps6800.
113 Symbols1024 = 0b0010,
114 /// 128 symbols of preamble.
115 /// Only supported at Bitrate::Kbps850 & Bitrate::Kbps6800.
116 /// Unofficial extension from decawave.
117 Symbols4096 = 0b0011,
118 /// 4096 symbols of preamble.
119 Symbols32 = 0b0100,
120 /// 32 symbols of preamble.
121 #[default]
122 Symbols128 = 0b0101,
123 /// 128 symbols of preamble.
124 Symbols1536 = 0b0110,
125 /// 1536 symbols of preamble.
126 Symbols256 = 0b1001,
127 /// 256 symbols of preamble.
128 Symbols2048 = 0b1010,
129 /// 512 symbols of preamble.
130 Symbols512 = 0b1101,
131 /// 72 symbols of preamble.
132 Symbols72 = 0b0111,
133}
134
135impl PreambleLength {
136 /// Gets the recommended PAC size based on the preamble length.
137 pub fn get_recommended_pac_size(&self) -> u8 {
138 // Values are taken from Table 6 of the DW3000 User manual
139 match self {
140 PreambleLength::Symbols32 => 3, // 4
141 PreambleLength::Symbols64 => 0, // 8
142 PreambleLength::Symbols128 => 1, // 16 // MODIF JULIE THOMAS -> 1
143 PreambleLength::Symbols256 => 1,
144 PreambleLength::Symbols512 => 1,
145 PreambleLength::Symbols1024 => 1,
146 PreambleLength::Symbols1536 => 1,
147 PreambleLength::Symbols2048 => 1,
148 PreambleLength::Symbols4096 => 1,
149 PreambleLength::Symbols72 => 1, // AJOUT ULIE THOMAS
150 }
151 }
152
153 /// Get the number of symbols in the preamble
154 pub fn get_num_of_symbols(&self) -> usize {
155 match self {
156 PreambleLength::Symbols32 => 32,
157 PreambleLength::Symbols64 => 64,
158 PreambleLength::Symbols128 => 128,
159 PreambleLength::Symbols256 => 256,
160 PreambleLength::Symbols512 => 512,
161 PreambleLength::Symbols1024 => 1024,
162 PreambleLength::Symbols1536 => 1536,
163 PreambleLength::Symbols2048 => 2048,
164 PreambleLength::Symbols4096 => 4096,
165 PreambleLength::Symbols72 => 72,
166 }
167 }
168}
169
170#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
171/// An enum that allows the selection between different SFD sequences
172///
173/// The difference between the two Decawave sequences is that there are two ways
174/// to enable it in the chip. Decawave will only set the DWSFD bit and
175/// DecawaveAlt set the DWSFD and the \[T,R\]NSSFD bits.
176pub enum SfdSequence {
177 /// The standard sequence defined by the IEEE standard.
178 /// Most likely the best choice for 6.8 Mbps connections.
179 #[default]
180 IeeeShort = 0b00,
181 /// A sequence defined by Decawave that is supposed to be more robust.
182 /// This is an unofficial addition.
183 /// Most likely the best choice for 110 Kbps connections.
184 Decawave8 = 0b01,
185 /// A sequence defined by Decawave that is supposed to be more robust.
186 /// This is an unofficial addition.
187 /// Most likely the best choice for 850 Kbps connections.
188 Decawave16 = 0b10,
189 /// Uses the sequence that is programmed in by the user.
190 /// This is an unofficial addition.
191 Ieee = 0b11,
192}
193
194#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
195/// All the available UWB channels.
196///
197/// Note that while a channel may have more bandwidth than ~900 Mhz, the DW3000
198/// can only send up to ~900 Mhz
199pub enum UwbChannel {
200 /// Channel 5
201 /// - Center frequency: 6489.6 Mhz
202 /// - Bandwidth: 499.2 Mhz
203 /// - Preamble Codes (16 MHz PRF) : 3, 4
204 /// - Preamble Codes (64 MHz PRF) : 9, 10, 11, 12
205 #[default]
206 Channel5 = 0,
207 /// Channel 9
208 /// - Center frequency: 7987.2 Mhz
209 /// - Bandwidth: 499.2 Mhz
210 /// - Preamble Codes (16 MHz PRF) : 3, 4
211 /// - Preamble Codes (64 MHz PRF) : 9, 10, 11, 12
212 Channel9 = 1,
213}
214
215impl UwbChannel {
216 /// Gets the recommended preamble code
217 pub fn get_recommended_preamble_code(&self, prf_value: PulseRepetitionFrequency) -> u8 {
218 // Many have overlapping possibilities, so the numbers have been chosen so that
219 // there's no overlap here
220 match (self, prf_value) {
221 (UwbChannel::Channel5, PulseRepetitionFrequency::Mhz16) => 4, // ou 3
222 (UwbChannel::Channel9, PulseRepetitionFrequency::Mhz16) => 4, // ou 3
223 (UwbChannel::Channel5, PulseRepetitionFrequency::Mhz64) => 9, // ou 10,11,12
224 (UwbChannel::Channel9, PulseRepetitionFrequency::Mhz64) => 9, // ou 10,11,12
225 }
226 }
227
228 /// Gets the recommended value for rf_tx_ctrl_2
229 pub fn get_recommended_rf_tx_ctrl_2(&self) -> u32 {
230 match self {
231 UwbChannel::Channel5 => 0x1C071134,
232 UwbChannel::Channel9 => 0x1C010034,
233 }
234 }
235
236 /// Gets the recommended value for pll conf
237 pub fn get_recommended_pll_conf(&self) -> u16 {
238 match self {
239 UwbChannel::Channel5 => 0x1F3C,
240 UwbChannel::Channel9 => 0x0F3C,
241 }
242 }
243
244 /// Gets the recommended value for pll conf
245 pub fn get_recommended_dgc_lut_0(&self) -> u32 {
246 match self {
247 UwbChannel::Channel5 => 0x0001C0FD,
248 UwbChannel::Channel9 => 0x0002A8FE,
249 }
250 }
251
252 /// Gets the recommended value for pll conf
253 pub fn get_recommended_dgc_lut_1(&self) -> u32 {
254 match self {
255 UwbChannel::Channel5 => 0x0001C43E,
256 UwbChannel::Channel9 => 0x0002AC36,
257 }
258 }
259
260 /// Gets the recommended value for pll conf
261 pub fn get_recommended_dgc_lut_2(&self) -> u32 {
262 match self {
263 UwbChannel::Channel5 => 0x0001C6BE,
264 UwbChannel::Channel9 => 0x0002A5FE,
265 }
266 }
267
268 /// Gets the recommended value for pll conf
269 pub fn get_recommended_dgc_lut_3(&self) -> u32 {
270 match self {
271 UwbChannel::Channel5 => 0x0001C77E,
272 UwbChannel::Channel9 => 0x0002AF3E,
273 }
274 }
275
276 /// Gets the recommended value for pll conf
277 pub fn get_recommended_dgc_lut_4(&self) -> u32 {
278 match self {
279 UwbChannel::Channel5 => 0x0001CF36,
280 UwbChannel::Channel9 => 0x0002AF7D,
281 }
282 }
283
284 /// Gets the recommended value for pll conf
285 pub fn get_recommended_dgc_lut_5(&self) -> u32 {
286 match self {
287 UwbChannel::Channel5 => 0x0001CFB5,
288 UwbChannel::Channel9 => 0x0002AFB5,
289 }
290 }
291
292 /// Gets the recommended value for pll conf
293 pub fn get_recommended_dgc_lut_6(&self) -> u32 {
294 match self {
295 UwbChannel::Channel5 => 0x0001CFF5,
296 UwbChannel::Channel9 => 0x0002AFB5,
297 }
298 }
299}
300
301#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
302#[repr(u8)]
303/// An enum that allows the selection of StsMode
304///
305pub enum StsMode {
306 /// Sts disabled
307 #[default]
308 StsModeOff = 0,
309
310 /// Sts activated : STS follows SFD with PHR and PHY Payload
311 StsMode1 = 1,
312
313 /// Sts activated : STS is after PHY Payload
314 StsMode2 = 2,
315
316 /// Sts activated : STS with no PHR or PHY Payload
317 StsModeND = 3,
318}
319
320#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
321/// An enum that allows the selection of Sts length
322/// Value step is a block of eight (user manual 8.2.3.1)
323pub enum StsLen {
324 /// STS length = 32 bits
325 StsLen32 = 4,
326
327 /// STS length = 64 bits
328 #[default]
329 StsLen64 = 8,
330
331 /// STS length = 128 bits
332 StsLen128 = 16,
333
334 /// STS length = 256 bits
335 StsLen256 = 32,
336
337 /// STS length = 512 bits
338 StsLen512 = 64,
339
340 /// STS length = 1024 bits
341 StsLen1024 = 128,
342
343 /// STS length = 2048 bits
344 StsLn2048 = 256,
345}
346
347impl StsLen {
348 /// Get the STS length in bits
349 pub fn get_sts_length(&self) -> u16 {
350 match self {
351 StsLen::StsLen32 => 32,
352 StsLen::StsLen64 => 64,
353 StsLen::StsLen128 => 128,
354 StsLen::StsLen256 => 256,
355 StsLen::StsLen512 => 512,
356 StsLen::StsLen1024 => 1024,
357 StsLen::StsLn2048 => 2048,
358 }
359 }
360
361 /// Get the STS Minimum Threshold (STS_MNTH in offical driver)
362 ///
363 /// This can be computed using the following formula:
364 ///
365 /// STS_MNTH = sqrt(x/y)*DEFAULT_STS_MNTH
366 ///
367 /// where:
368 /// - DEFAULT_STS_MNTH = 0x10
369 /// - x: length of the STS in units of 8 (i.e. 8 for 64 length, 16 for 128 length etc.)
370 /// - y: either 8 or 16, 8 when no PDOA or PDOA mode 1 and 16 for PDOA mode 3
371 pub fn get_sts_mnth(&self, pdoa_mode: PdoaMode) -> u16 {
372 let sts_length_8 = match self {
373 StsLen::StsLen32 => 4,
374 StsLen::StsLen64 => 8,
375 StsLen::StsLen128 => 16,
376 StsLen::StsLen256 => 32,
377 StsLen::StsLen512 => 64,
378 StsLen::StsLen1024 => 128,
379 StsLen::StsLn2048 => 256,
380 };
381 let y = match pdoa_mode {
382 PdoaMode::Mode0 | PdoaMode::Mode1 => 8,
383 PdoaMode::Mode3 => 16,
384 };
385 let squared = 0x10 * 0x10 * sts_length_8 / y;
386
387 // Compute the square root of the squared value with Newton's method
388 let sqrt = |x: u32| -> u32 {
389 let mut z = (x + 1) / 2;
390 let mut y = x;
391 while z < y {
392 y = z;
393 z = (x / z + z) / 2;
394 }
395 y
396 };
397
398 sqrt(squared as u32) as u16
399 }
400}
401
402#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
403/// PHR mode
404pub enum PhrMode {
405 /// Standard PHR mode
406 #[default]
407 Standard = 0,
408
409 /// Extended PHR mode (Decawave proprietary mode)
410 Extended = 1,
411}
412
413#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
414/// PDoA mode
415#[repr(u8)]
416pub enum PdoaMode {
417 /// PDoA disabled
418 #[default]
419 Mode0 = 0x0,
420 /// Mode 1
421 Mode1 = 0x1,
422 /// Mode 3
423 Mode3 = 0x3,
424}
425
426#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
427/// PHR rate
428#[repr(u8)]
429pub enum PhrRate {
430 #[default]
431 /// PHR at standard rate
432 Standard = 0,
433 /// PHR at data rate (6.8 Mbps)
434 DataRate = 1,
435}