1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::{
ll, mac,
time::{Duration, Instant},
Error, DW1000,
};
use embedded_hal::{blocking::spi, digital::v2::OutputPin};
use super::Awake;
impl<SPI, CS, State> DW1000<SPI, CS, State>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
State: Awake,
{
/// Returns the TX antenna delay
pub fn get_tx_antenna_delay(&mut self) -> Result<Duration, Error<SPI, CS>> {
let tx_antenna_delay = self.ll.tx_antd().read()?.value();
// Since `tx_antenna_delay` is `u16`, the following will never panic.
let tx_antenna_delay = Duration::new(tx_antenna_delay.into()).unwrap();
Ok(tx_antenna_delay)
}
/// Returns the RX antenna delay
pub fn get_rx_antenna_delay(&mut self) -> Result<Duration, Error<SPI, CS>> {
let rx_antenna_delay = self.ll.lde_rxantd().read()?.value();
// Since `rx_antenna_delay` is `u16`, the following will never panic.
let rx_antenna_delay = Duration::new(rx_antenna_delay.into()).unwrap();
Ok(rx_antenna_delay)
}
/// Returns the network id and address used for sending and receiving
pub fn get_address(&mut self) -> Result<mac::Address, Error<SPI, CS>> {
let panadr = self.ll.panadr().read()?;
Ok(mac::Address::Short(
mac::PanId(panadr.pan_id()),
mac::ShortAddress(panadr.short_addr()),
))
}
/// Returns the current system time
pub fn sys_time(&mut self) -> Result<Instant, Error<SPI, CS>> {
let sys_time = self.ll.sys_time().read()?.value();
// Since hardware timestamps fit within 40 bits, the following should
// never panic.
Ok(Instant::new(sys_time).unwrap())
}
/// Provides direct access to the register-level API
///
/// Be aware that by using the register-level API, you can invalidate
/// various assumptions that the high-level API makes about the operation of
/// the DW1000. Don't use the register-level and high-level APIs in tandem,
/// unless you know what you're doing.
pub fn ll(&mut self) -> &mut ll::DW1000<SPI, CS> {
&mut self.ll
}
/// Force the DW1000 into IDLE mode
///
/// Any ongoing RX/TX operations will be aborted.
pub(super) fn force_idle(&mut self, double_buffered: bool) -> Result<(), Error<SPI, CS>> {
let mut saved_sys_mask = [0; 5];
if double_buffered {
// Mask the double buffered status bits
self.ll.sys_mask().modify(|r, w| {
saved_sys_mask = r.0.clone();
w.mrxfce(0).mrxfcg(0).mrxdfr(0).mldedone(0)
})?;
}
self.ll.sys_ctrl().write(|w| w.trxoff(0b1))?;
while self.ll.sys_ctrl().read()?.trxoff() == 0b1 {}
if double_buffered {
// Clear the bits
self.ll().sys_status().write(
|w| {
w.rxprd(0b1) // Receiver Preamble Detected
.rxsfdd(0b1) // Receiver SFD Detected
.ldedone(0b1) // LDE Processing Done
.rxphd(0b1) // Receiver PHY Header Detected
.rxphe(0b1) // Receiver PHY Header Error
.rxdfr(0b1) // Receiver Data Frame Ready
.rxfcg(0b1) // Receiver FCS Good
.rxfce(0b1) // Receiver FCS Error
.rxrfsl(0b1) // Receiver Reed Solomon Frame Sync Loss
.rxrfto(0b1) // Receiver Frame Wait Timeout
.ldeerr(0b1) // Leading Edge Detection Processing Error
.rxovrr(0b1) // Receiver Overrun
.rxpto(0b1) // Preamble Detection Timeout
.rxsfdto(0b1) // Receiver SFD Timeout
.rxrscs(0b1) // Receiver Reed-Solomon Correction Status
.rxprej(0b1)
}, // Receiver Preamble Rejection
)?;
// Restore the mask
self.ll.sys_mask().write(|w| {
w.0.copy_from_slice(&saved_sys_mask);
w
})?;
}
Ok(())
}
pub(crate) fn read_otp(&mut self, address: u16) -> Result<u32, Error<SPI, CS>> {
// Set address
self.ll.otp_addr().write(|w| w.value(address))?;
// Switch into read mode
self.ll.otp_ctrl().write(|w| w.otprden(0b1).otpread(0b1))?;
self.ll.otp_ctrl().write(|w| w.otprden(0b1))?;
// Read back value
let value = self.ll.otp_rdat().read()?.value();
// End read mode
self.ll.otp_ctrl().write(|w| w)?;
Ok(value)
}
}