aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Schuhen <[email protected]>2024-02-17 18:10:45 +1000
committerCorey Schuhen <[email protected]>2024-02-17 18:26:57 +1000
commit91c75c92a0e67c93550a163ae62b22a652bf2012 (patch)
tree67105c6f0b044f227f14ed407a9ce7b4d2290635
parent5d8c54fdea752d4a52b33a7f776b436f5934409c (diff)
Clean up and prep for buffered IRQ mode.
- Reduce code duplicaiton in read/write methods - General clean-up - Prepare for buffered mode
-rw-r--r--embassy-stm32/src/can/fdcan.rs347
1 files changed, 188 insertions, 159 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 987748e06..42ce73ded 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -39,14 +39,17 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
39 39
40 let ir = regs.ir().read(); 40 let ir = regs.ir().read();
41 41
42 if ir.tc() { 42 {
43 regs.ir().write(|w| w.set_tc(true)); 43 if ir.tc() {
44 T::state().tx_waker.wake(); 44 regs.ir().write(|w| w.set_tc(true));
45 } 45 }
46 if ir.tefn() {
47 regs.ir().write(|w| w.set_tefn(true));
48 }
46 49
47 if ir.tefn() { 50 match &T::state().tx_mode {
48 regs.ir().write(|w| w.set_tefn(true)); 51 sealed::TxMode::NonBuffered(waker) => waker.wake(),
49 T::state().tx_waker.wake(); 52 }
50 } 53 }
51 54
52 if ir.ped() || ir.pea() { 55 if ir.ped() || ir.pea() {
@@ -57,15 +60,11 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
57 } 60 }
58 61
59 if ir.rfn(0) { 62 if ir.rfn(0) {
60 let fifonr = 0 as usize; 63 T::state().rx_mode.on_interrupt::<T>(0);
61 regs.ir().write(|w| w.set_rfn(fifonr, true));
62
63 T::state().rx_waker.wake();
64 } 64 }
65 65
66 if ir.rfn(1) { 66 if ir.rfn(1) {
67 regs.ir().write(|w| w.set_rfn(1, true)); 67 T::state().rx_mode.on_interrupt::<T>(1);
68 T::state().rx_waker.wake();
69 } 68 }
70 } 69 }
71} 70}
@@ -148,7 +147,6 @@ pub struct Fdcan<'d, T: Instance, M: FdcanOperatingMode> {
148 /// Reference to internals. 147 /// Reference to internals.
149 instance: FdcanInstance<'d, T>, 148 instance: FdcanInstance<'d, T>,
150 _mode: PhantomData<M>, 149 _mode: PhantomData<M>,
151 ns_per_timer_tick: u64, // For FDCAN internal timer
152} 150}
153 151
154fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { 152fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 {
@@ -166,23 +164,6 @@ fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransm
166 } 164 }
167} 165}
168 166
169#[cfg(feature = "time")]
170fn calc_timestamp<T: Instance>(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
171 let now_embassy = embassy_time::Instant::now();
172 if ns_per_timer_tick == 0 {
173 return now_embassy;
174 }
175 let cantime = { T::regs().tscv().read().tsc() };
176 let delta = cantime.overflowing_sub(ts_val).0 as u64;
177 let ns = ns_per_timer_tick * delta as u64;
178 now_embassy - embassy_time::Duration::from_nanos(ns)
179}
180
181#[cfg(not(feature = "time"))]
182fn calc_timestamp<T: Instance>(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
183 ts_val
184}
185
186impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> { 167impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
187 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode. 168 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
188 /// You must call [Fdcan::enable_non_blocking] to use the peripheral. 169 /// You must call [Fdcan::enable_non_blocking] to use the peripheral.
@@ -239,12 +220,10 @@ impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
239 w.set_eint1(true); // Interrupt Line 1 220 w.set_eint1(true); // Interrupt Line 1
240 }); 221 });
241 222
242 let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(config.frame_transmit);
243 Self { 223 Self {
244 config, 224 config,
245 instance: FdcanInstance(peri), 225 instance: FdcanInstance(peri),
246 _mode: PhantomData::<ConfigMode>, 226 _mode: PhantomData::<ConfigMode>,
247 ns_per_timer_tick,
248 } 227 }
249 } 228 }
250 229
@@ -319,12 +298,14 @@ macro_rules! impl_transition {
319 /// Transition from $from_mode:ident mode to $to_mode:ident mode 298 /// Transition from $from_mode:ident mode to $to_mode:ident mode
320 pub fn $name(self) -> Fdcan<'d, T, $to_mode> { 299 pub fn $name(self) -> Fdcan<'d, T, $to_mode> {
321 let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); 300 let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit);
301 critical_section::with(|_| unsafe {
302 T::mut_state().ns_per_timer_tick = ns_per_timer_tick;
303 });
322 T::registers().$func(self.config); 304 T::registers().$func(self.config);
323 let ret = Fdcan { 305 let ret = Fdcan {
324 config: self.config, 306 config: self.config,
325 instance: self.instance, 307 instance: self.instance,
326 _mode: PhantomData::<$to_mode>, 308 _mode: PhantomData::<$to_mode>,
327 ns_per_timer_tick,
328 }; 309 };
329 ret 310 ret
330 } 311 }
@@ -357,7 +338,8 @@ where
357 /// Flush one of the TX mailboxes. 338 /// Flush one of the TX mailboxes.
358 pub async fn flush(&self, idx: usize) { 339 pub async fn flush(&self, idx: usize) {
359 poll_fn(|cx| { 340 poll_fn(|cx| {
360 T::state().tx_waker.register(cx.waker()); 341 T::state().tx_mode.register(cx.waker());
342
361 if idx > 3 { 343 if idx > 3 {
362 panic!("Bad mailbox"); 344 panic!("Bad mailbox");
363 } 345 }
@@ -376,39 +358,12 @@ where
376 /// can be replaced, this call asynchronously waits for a frame to be successfully 358 /// can be replaced, this call asynchronously waits for a frame to be successfully
377 /// transmitted, then tries again. 359 /// transmitted, then tries again.
378 pub async fn write(&mut self, frame: &ClassicFrame) -> Option<ClassicFrame> { 360 pub async fn write(&mut self, frame: &ClassicFrame) -> Option<ClassicFrame> {
379 poll_fn(|cx| { 361 T::state().tx_mode.write::<T>(frame).await
380 T::state().tx_waker.register(cx.waker());
381
382 if let Ok(dropped) = T::registers().write_classic(frame) {
383 return Poll::Ready(dropped);
384 }
385
386 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
387 // to clear.
388 Poll::Pending
389 })
390 .await
391 } 362 }
392 363
393 /// Returns the next received message frame 364 /// Returns the next received message frame
394 pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { 365 pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
395 poll_fn(|cx| { 366 T::state().rx_mode.read::<T>().await
396 T::state().err_waker.register(cx.waker());
397 T::state().rx_waker.register(cx.waker());
398
399 if let Some((msg, ts)) = T::registers().read_classic(0) {
400 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
401 return Poll::Ready(Ok((msg, ts)));
402 } else if let Some((msg, ts)) = T::registers().read_classic(1) {
403 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
404 return Poll::Ready(Ok((msg, ts)));
405 } else if let Some(err) = T::registers().curr_error() {
406 // TODO: this is probably wrong
407 return Poll::Ready(Err(err));
408 }
409 Poll::Pending
410 })
411 .await
412 } 367 }
413 368
414 /// Queues the message to be sent but exerts backpressure. If a lower-priority 369 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -416,45 +371,29 @@ where
416 /// can be replaced, this call asynchronously waits for a frame to be successfully 371 /// can be replaced, this call asynchronously waits for a frame to be successfully
417 /// transmitted, then tries again. 372 /// transmitted, then tries again.
418 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 373 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
419 poll_fn(|cx| { 374 T::state().tx_mode.write_fd::<T>(frame).await
420 T::state().tx_waker.register(cx.waker());
421
422 if let Ok(dropped) = T::registers().write_fd(frame) {
423 return Poll::Ready(dropped);
424 }
425
426 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
427 // to clear.
428 Poll::Pending
429 })
430 .await
431 } 375 }
432 376
433 /// Returns the next received message frame 377 /// Returns the next received message frame
434 pub async fn read_fd(&mut self) -> Result<(FdFrame, Timestamp), BusError> { 378 pub async fn read_fd(&mut self) -> Result<(FdFrame, Timestamp), BusError> {
435 poll_fn(|cx| { 379 T::state().rx_mode.read_fd::<T>().await
436 T::state().err_waker.register(cx.waker()); 380 }
437 T::state().rx_waker.register(cx.waker()); 381
438 382 /// Join split rx and tx portions back together
439 if let Some((msg, ts)) = T::registers().read_fd(0) { 383 pub fn join(tx: FdcanTx<'d, T, M>, rx: FdcanRx<'d, T, M>) -> Self {
440 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts); 384 Fdcan {
441 return Poll::Ready(Ok((msg, ts))); 385 config: tx.config,
442 } else if let Some((msg, ts)) = T::registers().read_fd(1) { 386 //_instance2: T::regs(),
443 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts); 387 instance: tx._instance,
444 return Poll::Ready(Ok((msg, ts))); 388 _mode: rx._mode,
445 } else if let Some(err) = T::registers().curr_error() { 389 }
446 // TODO: this is probably wrong
447 return Poll::Ready(Err(err));
448 }
449 Poll::Pending
450 })
451 .await
452 } 390 }
453 391
454 /// Split instance into separate Tx(write) and Rx(read) portions 392 /// Split instance into separate Tx(write) and Rx(read) portions
455 pub fn split(self) -> (FdcanTx<'d, T, M>, FdcanRx<'d, T, M>) { 393 pub fn split(self) -> (FdcanTx<'d, T, M>, FdcanRx<'d, T, M>) {
456 ( 394 (
457 FdcanTx { 395 FdcanTx {
396 config: self.config,
458 _instance: self.instance, 397 _instance: self.instance,
459 _mode: self._mode, 398 _mode: self._mode,
460 }, 399 },
@@ -462,10 +401,10 @@ where
462 _instance1: PhantomData::<T>, 401 _instance1: PhantomData::<T>,
463 _instance2: T::regs(), 402 _instance2: T::regs(),
464 _mode: self._mode, 403 _mode: self._mode,
465 ns_per_timer_tick: self.ns_per_timer_tick,
466 }, 404 },
467 ) 405 )
468 } 406 }
407
469} 408}
470 409
471/// FDCAN Rx only Instance 410/// FDCAN Rx only Instance
@@ -474,11 +413,11 @@ pub struct FdcanRx<'d, T: Instance, M: Receive> {
474 _instance1: PhantomData<T>, 413 _instance1: PhantomData<T>,
475 _instance2: &'d crate::pac::can::Fdcan, 414 _instance2: &'d crate::pac::can::Fdcan,
476 _mode: PhantomData<M>, 415 _mode: PhantomData<M>,
477 ns_per_timer_tick: u64, // For FDCAN internal timer
478} 416}
479 417
480/// FDCAN Tx only Instance 418/// FDCAN Tx only Instance
481pub struct FdcanTx<'d, T: Instance, M: Transmit> { 419pub struct FdcanTx<'d, T: Instance, M: Transmit> {
420 config: crate::can::fd::config::FdCanConfig,
482 _instance: FdcanInstance<'d, T>, //(PeripheralRef<'a, T>); 421 _instance: FdcanInstance<'d, T>, //(PeripheralRef<'a, T>);
483 _mode: PhantomData<M>, 422 _mode: PhantomData<M>,
484} 423}
@@ -489,18 +428,7 @@ impl<'c, 'd, T: Instance, M: Transmit> FdcanTx<'d, T, M> {
489 /// can be replaced, this call asynchronously waits for a frame to be successfully 428 /// can be replaced, this call asynchronously waits for a frame to be successfully
490 /// transmitted, then tries again. 429 /// transmitted, then tries again.
491 pub async fn write(&mut self, frame: &ClassicFrame) -> Option<ClassicFrame> { 430 pub async fn write(&mut self, frame: &ClassicFrame) -> Option<ClassicFrame> {
492 poll_fn(|cx| { 431 T::state().tx_mode.write::<T>(frame).await
493 T::state().tx_waker.register(cx.waker());
494
495 if let Ok(dropped) = T::registers().write_classic(frame) {
496 return Poll::Ready(dropped);
497 }
498
499 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
500 // to clear.
501 Poll::Pending
502 })
503 .await
504 } 432 }
505 433
506 /// Queues the message to be sent but exerts backpressure. If a lower-priority 434 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -508,80 +436,158 @@ impl<'c, 'd, T: Instance, M: Transmit> FdcanTx<'d, T, M> {
508 /// can be replaced, this call asynchronously waits for a frame to be successfully 436 /// can be replaced, this call asynchronously waits for a frame to be successfully
509 /// transmitted, then tries again. 437 /// transmitted, then tries again.
510 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 438 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
511 poll_fn(|cx| { 439 T::state().tx_mode.write_fd::<T>(frame).await
512 T::state().tx_waker.register(cx.waker());
513
514 if let Ok(dropped) = T::registers().write_fd(frame) {
515 return Poll::Ready(dropped);
516 }
517
518 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
519 // to clear.
520 Poll::Pending
521 })
522 .await
523 } 440 }
524} 441}
525 442
526impl<'c, 'd, T: Instance, M: Receive> FdcanRx<'d, T, M> { 443impl<'c, 'd, T: Instance, M: Receive> FdcanRx<'d, T, M> {
527 /// Returns the next received message frame 444 /// Returns the next received message frame
528 pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { 445 pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
529 poll_fn(|cx| { 446 T::state().rx_mode.read::<T>().await
530 T::state().err_waker.register(cx.waker());
531 T::state().rx_waker.register(cx.waker());
532
533 if let Some((msg, ts)) = T::registers().read_classic(0) {
534 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
535 return Poll::Ready(Ok((msg, ts)));
536 } else if let Some((msg, ts)) = T::registers().read_classic(1) {
537 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
538 return Poll::Ready(Ok((msg, ts)));
539 } else if let Some(err) = T::registers().curr_error() {
540 // TODO: this is probably wrong
541 return Poll::Ready(Err(err));
542 }
543 Poll::Pending
544 })
545 .await
546 } 447 }
547 448
548 /// Returns the next received message frame 449 /// Returns the next received message frame
549 pub async fn read_fd(&mut self) -> Result<(FdFrame, Timestamp), BusError> { 450 pub async fn read_fd(&mut self) -> Result<(FdFrame, Timestamp), BusError> {
550 poll_fn(|cx| { 451 T::state().rx_mode.read_fd::<T>().await
551 T::state().err_waker.register(cx.waker());
552 T::state().rx_waker.register(cx.waker());
553
554 if let Some((msg, ts)) = T::registers().read_fd(0) {
555 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
556 return Poll::Ready(Ok((msg, ts)));
557 } else if let Some((msg, ts)) = T::registers().read_fd(1) {
558 let ts = calc_timestamp::<T>(self.ns_per_timer_tick, ts);
559 return Poll::Ready(Ok((msg, ts)));
560 } else if let Some(err) = T::registers().curr_error() {
561 // TODO: this is probably wrong
562 return Poll::Ready(Err(err));
563 }
564 Poll::Pending
565 })
566 .await
567 } 452 }
568} 453}
569 454
570pub(crate) mod sealed { 455pub(crate) mod sealed {
456 use core::future::poll_fn;
457 use core::task::Poll;
458
571 use embassy_sync::waitqueue::AtomicWaker; 459 use embassy_sync::waitqueue::AtomicWaker;
572 460
461 use crate::can::_version::{BusError, Timestamp};
462 use crate::can::frame::{ClassicFrame, FdFrame};
463 pub enum RxMode {
464 NonBuffered(AtomicWaker),
465 }
466
467 impl RxMode {
468 pub fn register(&self, arg: &core::task::Waker) {
469 match self {
470 RxMode::NonBuffered(waker) => waker.register(arg),
471 }
472 }
473
474 pub fn on_interrupt<T: Instance>(&self, fifonr: usize) {
475 T::regs().ir().write(|w| w.set_rfn(fifonr, true));
476 match self {
477 RxMode::NonBuffered(waker) => {
478 waker.wake();
479 }
480 }
481 }
482
483 pub async fn read<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
484 poll_fn(|cx| {
485 T::state().err_waker.register(cx.waker());
486 self.register(cx.waker());
487
488 if let Some((msg, ts)) = T::registers().read_classic(0) {
489 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
490 return Poll::Ready(Ok((msg, ts)));
491 } else if let Some((msg, ts)) = T::registers().read_classic(1) {
492 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
493 return Poll::Ready(Ok((msg, ts)));
494 } else if let Some(err) = T::registers().curr_error() {
495 // TODO: this is probably wrong
496 return Poll::Ready(Err(err));
497 }
498 Poll::Pending
499 })
500 .await
501 }
502
503 pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
504 poll_fn(|cx| {
505 T::state().err_waker.register(cx.waker());
506 self.register(cx.waker());
507
508 if let Some((msg, ts)) = T::registers().read_fd(0) {
509 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
510 return Poll::Ready(Ok((msg, ts)));
511 } else if let Some((msg, ts)) = T::registers().read_fd(1) {
512 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
513 return Poll::Ready(Ok((msg, ts)));
514 } else if let Some(err) = T::registers().curr_error() {
515 // TODO: this is probably wrong
516 return Poll::Ready(Err(err));
517 }
518 Poll::Pending
519 })
520 .await
521 }
522 }
523
524 pub enum TxMode {
525 NonBuffered(AtomicWaker),
526 }
527
528 impl TxMode {
529 pub fn register(&self, arg: &core::task::Waker) {
530 match self {
531 TxMode::NonBuffered(waker) => {
532 waker.register(arg);
533 }
534 }
535 }
536
537 /// Queues the message to be sent but exerts backpressure. If a lower-priority
538 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
539 /// can be replaced, this call asynchronously waits for a frame to be successfully
540 /// transmitted, then tries again.
541 pub async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
542 poll_fn(|cx| {
543 self.register(cx.waker());
544
545 if let Ok(dropped) = T::registers().write_classic(frame) {
546 return Poll::Ready(dropped);
547 }
548
549 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
550 // to clear.
551 Poll::Pending
552 })
553 .await
554 }
555
556 /// Queues the message to be sent but exerts backpressure. If a lower-priority
557 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
558 /// can be replaced, this call asynchronously waits for a frame to be successfully
559 /// transmitted, then tries again.
560 pub async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
561 poll_fn(|cx| {
562 self.register(cx.waker());
563
564 if let Ok(dropped) = T::registers().write_fd(frame) {
565 return Poll::Ready(dropped);
566 }
567
568 // Couldn't replace any lower priority frames. Need to wait for some mailboxes
569 // to clear.
570 Poll::Pending
571 })
572 .await
573 }
574 }
575
573 pub struct State { 576 pub struct State {
574 pub tx_waker: AtomicWaker, 577 pub rx_mode: RxMode,
578 pub tx_mode: TxMode,
579 pub ns_per_timer_tick: u64,
580
575 pub err_waker: AtomicWaker, 581 pub err_waker: AtomicWaker,
576 pub rx_waker: AtomicWaker,
577 } 582 }
578 583
579 impl State { 584 impl State {
580 pub const fn new() -> Self { 585 pub const fn new() -> Self {
581 Self { 586 Self {
582 tx_waker: AtomicWaker::new(), 587 rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
588 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
589 ns_per_timer_tick: 0,
583 err_waker: AtomicWaker::new(), 590 err_waker: AtomicWaker::new(),
584 rx_waker: AtomicWaker::new(),
585 } 591 }
586 } 592 }
587 } 593 }
@@ -593,6 +599,8 @@ pub(crate) mod sealed {
593 fn registers() -> crate::can::fd::peripheral::Registers; 599 fn registers() -> crate::can::fd::peripheral::Registers;
594 fn ram() -> &'static crate::pac::fdcanram::Fdcanram; 600 fn ram() -> &'static crate::pac::fdcanram::Fdcanram;
595 fn state() -> &'static State; 601 fn state() -> &'static State;
602 unsafe fn mut_state() -> &'static mut State;
603 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
596 604
597 #[cfg(not(stm32h7))] 605 #[cfg(not(stm32h7))]
598 fn configure_msg_ram() {} 606 fn configure_msg_ram() {}
@@ -694,10 +702,31 @@ macro_rules! impl_fdcan {
694 fn ram() -> &'static crate::pac::fdcanram::Fdcanram { 702 fn ram() -> &'static crate::pac::fdcanram::Fdcanram {
695 &crate::pac::$msg_ram_inst 703 &crate::pac::$msg_ram_inst
696 } 704 }
705 unsafe fn mut_state() -> & 'static mut sealed::State {
706 static mut STATE: sealed::State = sealed::State::new();
707 & mut STATE
708 }
697 fn state() -> &'static sealed::State { 709 fn state() -> &'static sealed::State {
698 static STATE: sealed::State = sealed::State::new(); 710 unsafe { peripherals::$inst::mut_state() }
699 &STATE
700 } 711 }
712
713#[cfg(feature = "time")]
714fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
715 let now_embassy = embassy_time::Instant::now();
716 if ns_per_timer_tick == 0 {
717 return now_embassy;
718 }
719 let cantime = { Self::regs().tscv().read().tsc() };
720 let delta = cantime.overflowing_sub(ts_val).0 as u64;
721 let ns = ns_per_timer_tick * delta as u64;
722 now_embassy - embassy_time::Duration::from_nanos(ns)
723}
724
725#[cfg(not(feature = "time"))]
726fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
727 ts_val
728}
729
701 } 730 }
702 731
703 impl Instance for peripherals::$inst {} 732 impl Instance for peripherals::$inst {}