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}