Skip to content

Commit 790fdd6

Browse files
fromeijndiondoktertdittr
authored
Adding Auto Acknowledgements (#24)
* Fix the systime-stamp * Add auto acks * Add tx continuations * fix: fix overflow in rssi calc * docs: corrected and added docs * fix: when frame filtering is enabled also enable RX Auto-Re-enable for failed/filtered frames otherwise filtered frames will stop RX * Make indirect usage of defmt through smoltcp optional --------- Co-authored-by: Dion Dokter <diondokter@gmail.com> Co-authored-by: Tamme Dittrich <tamme@tweedegolf.com>
1 parent 9d6d4f9 commit 790fdd6

File tree

11 files changed

+216
-102
lines changed

11 files changed

+216
-102
lines changed

examples/init_tracing.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// This example uses a dummy SPI/GPIO implementation to test what happens when
22
// the `dw3000_ng` driver is initialized.
3-
use dw3000_ng::{hl::SendTime, Config, DW3000};
3+
use dw3000_ng::{configs::TxContinuation, hl::SendTime, Config, DW3000};
44

55
use embedded_hal_bus::spi::ExclusiveDevice;
66

@@ -208,7 +208,10 @@ async fn main() {
208208
log::info!("DW3000 finished receiving");
209209

210210
let data = [0xDE, 0xAD, 0xBE, 0xEF];
211-
let sending = dw3000.send(&data, SendTime::Now, config).await.unwrap();
211+
let sending = dw3000
212+
.send(&data, SendTime::Now, TxContinuation::Ready, config)
213+
.await
214+
.unwrap();
212215

213216
log::info!("DW3000 is now sending");
214217

src/configs.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub struct Config {
2727
/// Defaults to 64
2828
pub sts_len: StsLen,
2929
/// SFD_timeout = Preamble length + 1 + sfdlength - pac size
30-
pub sfd_timeout: u32,
30+
pub sfd_timeout: u16,
3131
/// TX preamble code, optional
3232
/// If not set, the recommended value will be used (see `get_recommended_preamble_code`)
3333
pub tx_preamble_code: Option<u8>,
@@ -40,6 +40,8 @@ pub struct Config {
4040
pub phr_rate: PhrRate,
4141
/// PDoA mode
4242
pub pdoa_mode: PdoaMode,
43+
/// When enabled, the radio itself will send acks to messages with the ack bit enabled.
44+
pub auto_ack: AutoAck,
4345
}
4446

4547
impl Default for Config {
@@ -60,10 +62,41 @@ impl Default for Config {
6062
phr_mode: Default::default(),
6163
phr_rate: Default::default(),
6264
pdoa_mode: Default::default(),
65+
auto_ack: Default::default(),
6366
}
6467
}
6568
}
6669

70+
/// Setting for how the transmission should be continued
71+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
72+
pub enum TxContinuation {
73+
#[default]
74+
/// After the transmission the radio should go back to ready
75+
Ready,
76+
/// After the transmission the radio should go to the receiving state
77+
Rx,
78+
}
79+
80+
/// The auto acknowledge behavior
81+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
82+
pub enum AutoAck {
83+
#[default]
84+
/// No automatic acks are sent
85+
Disabled,
86+
/// An automatic Ack will be sent if:
87+
/// - Frame filtering is on
88+
/// - The received frame passes through the filter
89+
/// - The frame has the ack bit set
90+
Enabled {
91+
/// The turnaround time in number of symbols.
92+
///
93+
/// Recommended minimal value:
94+
/// - 850 kbps: 2
95+
/// - 6.8 Mbps: 3
96+
turnaround_time: u8,
97+
},
98+
}
99+
67100
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
68101
/// The bitrate at which a message is transmitted
69102
pub enum BitRate {
@@ -386,7 +419,7 @@ impl StsLen {
386419

387420
// Compute the square root of the squared value with Newton's method
388421
let sqrt = |x: u32| -> u32 {
389-
let mut z = (x + 1) / 2;
422+
let mut z = (x + 1).div_ceil(2);
390423
let mut y = x;
391424
while z < y {
392425
y = z;

src/hl/awake.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use super::Awake;
2-
use crate::{fast_command, ll, time::Duration, Error, DW3000};
2+
use crate::{
3+
fast_command, ll,
4+
time::{Duration, Instant},
5+
Error, DW3000,
6+
};
37

48
use smoltcp::wire::{Ieee802154Address, Ieee802154Pan};
59

@@ -43,12 +47,13 @@ where
4347
))
4448
}
4549

46-
/// Returns the current system time (32-bit)
50+
/// Returns the current system time (accurate to the upper 32-bit)
4751
#[maybe_async_attr]
48-
pub async fn sys_time(&mut self) -> Result<u32, Error<SPI>> {
52+
pub async fn sys_time(&mut self) -> Result<Instant, Error<SPI>> {
4953
let sys_time = self.ll.sys_time().read().await?.value();
5054

51-
Ok(sys_time)
55+
// The systime read the upper 32-bits from the 40-bit timer
56+
Ok(Instant((sys_time as u64) << 8))
5257
}
5358

5459
/// Returns the state of the DW3000
@@ -98,7 +103,7 @@ where
98103
pub async fn force_idle(&mut self) -> Result<(), Error<SPI>> {
99104
// our probleme on this function is that we never come back to IDLE_PLL with a locked PLL after usng fast command 0
100105

101-
self.ll.fast_command(0).await?;
106+
self.fast_cmd(crate::FastCommand::CMD_TXRXOFF).await?;
102107

103108
Ok(())
104109
}

src/hl/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ where
9292

9393
/// Failed to calibrate the PGF values
9494
PGFCalibrationFailed,
95+
96+
/// The wrong continuation was called on the radio
97+
WrongTxContinuation,
98+
99+
/// The transmission has not yet finished
100+
TxNotFinishedYet,
95101
}
96102

97103
impl<SPI> From<ll::Error<SPI>> for Error<SPI>
@@ -148,6 +154,8 @@ where
148154
}
149155
Error::InitializationFailed => write!(f, "InitializationFailed"),
150156
Error::PGFCalibrationFailed => write!(f, "PGFCalibrationFailed"),
157+
Error::WrongTxContinuation => write!(f, "WrongTxContinuation"),
158+
Error::TxNotFinishedYet => write!(f, "TxNotFinishedYet"),
151159
}
152160
}
153161
}
@@ -187,6 +195,8 @@ where
187195
}
188196
Error::InitializationFailed => defmt::write!(f, "InitializationFailed"),
189197
Error::PGFCalibrationFailed => defmt::write!(f, "PGFCalibrationFailed"),
198+
Error::WrongTxContinuation => defmt::write!(f, "WrongTxContinuation"),
199+
Error::TxNotFinishedYet => defmt::write!(f, "TxNotFinishedYet"),
190200
}
191201
}
192202
}

src/hl/ready.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use byte::BytesExt as _;
66

77
use super::AutoDoubleBufferReceiving;
88
use crate::{
9-
configs::{PdoaMode, SfdSequence},
9+
configs::{PdoaMode, SfdSequence, TxContinuation},
1010
maybe_async_attr, spi_type,
1111
time::Instant,
1212
Config, Error, FastCommand, Ready, Sending, SingleBufferReceiving, Sleeping, DW3000,
@@ -233,6 +233,7 @@ where
233233
mut self,
234234
data: &[u8],
235235
send_time: SendTime,
236+
continuation: TxContinuation,
236237
config: Config,
237238
) -> Result<DW3000<SPI, Sending>, Error<SPI>> {
238239
self.clear_event_counter().await?;
@@ -291,19 +292,33 @@ where
291292
.modify(|_, w| // 32-bits value of the most significant bits
292293
w.value( (time.value() >> 8) as u32 ))
293294
.await?;
294-
self.fast_cmd(FastCommand::CMD_DTX).await?;
295+
if matches!(continuation, TxContinuation::Ready) {
296+
self.fast_cmd(FastCommand::CMD_DTX).await?;
297+
} else {
298+
self.fast_cmd(FastCommand::CMD_DTX_W4R).await?;
299+
}
295300
}
296301
SendTime::OnSync => {
297302
self.ll.ec_ctrl().modify(|_, w| w.ostr_mode(1)).await?;
298303
self.ll.ec_ctrl().modify(|_, w| w.osts_wait(33)).await?;
299304
}
300-
SendTime::Now => self.fast_cmd(FastCommand::CMD_TX).await?,
305+
SendTime::Now => {
306+
if matches!(continuation, TxContinuation::Ready) {
307+
self.fast_cmd(FastCommand::CMD_TX).await?
308+
} else {
309+
self.fast_cmd(FastCommand::CMD_TX_W4R).await?
310+
}
311+
}
301312
}
302313

303314
Ok(DW3000 {
304315
ll: self.ll,
305316
seq: self.seq,
306-
state: Sending { finished: false },
317+
state: Sending {
318+
finished: false,
319+
continuation,
320+
config,
321+
},
307322
})
308323
}
309324

@@ -330,12 +345,13 @@ where
330345
self,
331346
frame: Ieee802154Frame<T>,
332347
send_time: SendTime,
348+
continuation: TxContinuation,
333349
config: Config,
334350
) -> Result<DW3000<SPI, Sending>, Error<SPI>>
335351
where
336352
T: AsRef<[u8]>,
337353
{
338-
self.send_raw(frame.into_inner().as_ref(), send_time, config)
354+
self.send_raw(frame.into_inner().as_ref(), send_time, continuation, config)
339355
.await
340356
}
341357

@@ -363,6 +379,7 @@ where
363379
self,
364380
data: &[u8],
365381
send_time: SendTime,
382+
continuation: TxContinuation,
366383
config: Config,
367384
) -> Result<DW3000<SPI, Sending>, Error<SPI>> {
368385
return self
@@ -371,6 +388,7 @@ where
371388
send_time,
372389
Ieee802154Pan::BROADCAST,
373390
Ieee802154Address::BROADCAST,
391+
continuation,
374392
config,
375393
)
376394
.await;
@@ -402,14 +420,17 @@ where
402420
send_time: SendTime,
403421
pan_id: Ieee802154Pan,
404422
address: Ieee802154Address,
423+
continuation: TxContinuation,
405424
config: Config,
406425
) -> Result<DW3000<SPI, Sending>, Error<SPI>> {
407426
let mut buffer = [0_u8; 127];
408427
let len = self
409428
.build_frame(&mut buffer, data, Some(address), Some(pan_id))
410429
.await?;
411430

412-
return self.send_raw(&buffer[0..len + 2], send_time, config).await;
431+
return self
432+
.send_raw(&buffer[0..len + 2], send_time, continuation, config)
433+
.await;
413434
}
414435

415436
/// Attempt to receive a single IEEE 802.15.4 MAC frame
@@ -490,20 +511,14 @@ where
490511
self.ll()
491512
.sys_enable()
492513
.modify(|_, w| {
493-
w
494-
// .rxprd_en(0b1)
495-
// .rxsfdd_en(0b1)
496-
// .rxphd_en(0b1)
497-
.rxphe_en(0b1)
514+
w.rxphe_en(0b1)
498515
.rxfr_en(0b1)
499-
// .rxfcg_en(0b1)
500516
.rxfce_en(0b1)
501517
.rxrfsl_en(0b1)
502518
.rxfto_en(0b1)
503519
.rxovrr_en(0b1)
504520
.rxpto_en(0b1)
505521
.rxsto_en(0b1)
506-
// .rxprej_en(0b1)
507522
})
508523
.await?;
509524
Ok(())

0 commit comments

Comments
 (0)