aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Schuhen <[email protected]>2025-03-09 13:17:39 +1000
committerCorey Schuhen <[email protected]>2025-03-09 17:03:28 +1000
commit424d20727eb3d2b2bda6b6a8f42306a57e93c9f2 (patch)
tree70043cca2d7e3a30cfc20211fb93c318fbcfc74c
parent7c49f482d71d594d7b48c3393cc98d03a9e7c9e2 (diff)
Reference count senders and receivers so that we don't close down early.
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs64
-rw-r--r--embassy-stm32/src/can/common.rs86
-rw-r--r--embassy-stm32/src/can/enums.rs14
-rw-r--r--embassy-stm32/src/can/fdcan.rs104
4 files changed, 199 insertions, 69 deletions
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 8165364f5..c0b3c730b 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -17,7 +17,7 @@ use self::registers::{Registers, RxFifo};
17pub use super::common::{BufferedCanReceiver, BufferedCanSender}; 17pub use super::common::{BufferedCanReceiver, BufferedCanSender};
18use super::frame::{Envelope, Frame}; 18use super::frame::{Envelope, Frame};
19use super::util; 19use super::util;
20use crate::can::enums::{BusError, TryReadError}; 20use crate::can::enums::{BusError, InternalOperation, TryReadError};
21use crate::gpio::{AfType, OutputType, Pull, Speed}; 21use crate::gpio::{AfType, OutputType, Pull, Speed};
22use crate::interrupt::typelevel::Interrupt; 22use crate::interrupt::typelevel::Interrupt;
23use crate::rcc::{self, RccPeripheral}; 23use crate::rcc::{self, RccPeripheral};
@@ -685,22 +685,18 @@ impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
685 685
686 /// Returns a sender that can be used for sending CAN frames. 686 /// Returns a sender that can be used for sending CAN frames.
687 pub fn writer(&self) -> BufferedCanSender { 687 pub fn writer(&self) -> BufferedCanSender {
688 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
688 BufferedCanSender { 689 BufferedCanSender {
689 tx_buf: self.tx_buf.sender().into(), 690 tx_buf: self.tx_buf.sender().into(),
690 waker: self.info.tx_waker, 691 waker: self.info.tx_waker,
692 internal_operation: self.info.internal_operation,
691 } 693 }
692 } 694 }
693} 695}
694 696
695impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> { 697impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> {
696 fn drop(&mut self) { 698 fn drop(&mut self) {
697 critical_section::with(|_| { 699 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
698 let state = self.state as *const State;
699 unsafe {
700 let mut_state = state as *mut State;
701 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
702 }
703 });
704 } 700 }
705} 701}
706 702
@@ -825,7 +821,11 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
825 821
826 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 822 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
827 pub fn reader(&self) -> BufferedCanReceiver { 823 pub fn reader(&self) -> BufferedCanReceiver {
828 self.rx_buf.receiver().into() 824 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
825 BufferedCanReceiver {
826 rx_buf: self.rx_buf.receiver().into(),
827 internal_operation: self.info.internal_operation,
828 }
829 } 829 }
830 830
831 /// Accesses the filter banks owned by this CAN peripheral. 831 /// Accesses the filter banks owned by this CAN peripheral.
@@ -839,13 +839,7 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
839 839
840impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> { 840impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> {
841 fn drop(&mut self) { 841 fn drop(&mut self) {
842 critical_section::with(|_| { 842 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
843 let state = self.state as *const State;
844 unsafe {
845 let mut_state = state as *mut State;
846 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
847 }
848 });
849 } 843 }
850} 844}
851 845
@@ -1048,6 +1042,8 @@ pub(crate) struct State {
1048 pub(crate) rx_mode: RxMode, 1042 pub(crate) rx_mode: RxMode,
1049 pub(crate) tx_mode: TxMode, 1043 pub(crate) tx_mode: TxMode,
1050 pub err_waker: AtomicWaker, 1044 pub err_waker: AtomicWaker,
1045 receiver_instance_count: usize,
1046 sender_instance_count: usize,
1051} 1047}
1052 1048
1053impl State { 1049impl State {
@@ -1056,6 +1052,8 @@ impl State {
1056 rx_mode: RxMode::NonBuffered(AtomicWaker::new()), 1052 rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
1057 tx_mode: TxMode::NonBuffered(AtomicWaker::new()), 1053 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
1058 err_waker: AtomicWaker::new(), 1054 err_waker: AtomicWaker::new(),
1055 receiver_instance_count: 1,
1056 sender_instance_count: 1,
1059 } 1057 }
1060 } 1058 }
1061} 1059}
@@ -1067,6 +1065,7 @@ pub(crate) struct Info {
1067 rx1_interrupt: crate::interrupt::Interrupt, 1065 rx1_interrupt: crate::interrupt::Interrupt,
1068 sce_interrupt: crate::interrupt::Interrupt, 1066 sce_interrupt: crate::interrupt::Interrupt,
1069 tx_waker: fn(), 1067 tx_waker: fn(),
1068 internal_operation: fn(InternalOperation),
1070 1069
1071 /// The total number of filter banks available to the instance. 1070 /// The total number of filter banks available to the instance.
1072 /// 1071 ///
@@ -1079,6 +1078,7 @@ trait SealedInstance {
1079 fn regs() -> crate::pac::can::Can; 1078 fn regs() -> crate::pac::can::Can;
1080 fn state() -> &'static State; 1079 fn state() -> &'static State;
1081 unsafe fn mut_state() -> &'static mut State; 1080 unsafe fn mut_state() -> &'static mut State;
1081 fn internal_operation(val: InternalOperation);
1082} 1082}
1083 1083
1084/// CAN instance trait. 1084/// CAN instance trait.
@@ -1136,6 +1136,7 @@ foreach_peripheral!(
1136 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ, 1136 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ,
1137 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, 1137 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
1138 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, 1138 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
1139 internal_operation: peripherals::$inst::internal_operation,
1139 num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS, 1140 num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
1140 }; 1141 };
1141 &INFO 1142 &INFO
@@ -1151,6 +1152,37 @@ foreach_peripheral!(
1151 fn state() -> &'static State { 1152 fn state() -> &'static State {
1152 unsafe { peripherals::$inst::mut_state() } 1153 unsafe { peripherals::$inst::mut_state() }
1153 } 1154 }
1155
1156
1157 fn internal_operation(val: InternalOperation) {
1158 critical_section::with(|_| {
1159 //let state = self.state as *const State;
1160 unsafe {
1161 //let mut_state = state as *mut State;
1162 let mut_state = peripherals::$inst::mut_state();
1163 match val {
1164 InternalOperation::NotifySenderCreated => {
1165 mut_state.sender_instance_count += 1;
1166 }
1167 InternalOperation::NotifySenderDestroyed => {
1168 mut_state.sender_instance_count -= 1;
1169 if ( 0 == mut_state.sender_instance_count) {
1170 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1171 }
1172 }
1173 InternalOperation::NotifyReceiverCreated => {
1174 mut_state.receiver_instance_count += 1;
1175 }
1176 InternalOperation::NotifyReceiverDestroyed => {
1177 mut_state.receiver_instance_count -= 1;
1178 if ( 0 == mut_state.receiver_instance_count) {
1179 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1180 }
1181 }
1182 }
1183 }
1184 });
1185 }
1154 } 1186 }
1155 1187
1156 impl Instance for peripherals::$inst { 1188 impl Instance for peripherals::$inst {
diff --git a/embassy-stm32/src/can/common.rs b/embassy-stm32/src/can/common.rs
index a54b54f6e..e12111910 100644
--- a/embassy-stm32/src/can/common.rs
+++ b/embassy-stm32/src/can/common.rs
@@ -22,22 +22,22 @@ pub(crate) struct FdBufferedTxInner {
22} 22}
23 23
24/// Sender that can be used for sending CAN frames. 24/// Sender that can be used for sending CAN frames.
25#[derive(Copy, Clone)] 25pub struct BufferedSender<'ch, FRAME> {
26pub struct BufferedCanSender { 26 pub(crate) tx_buf: embassy_sync::channel::DynamicSender<'ch, FRAME>,
27 pub(crate) tx_buf: embassy_sync::channel::DynamicSender<'static, Frame>,
28 pub(crate) waker: fn(), 27 pub(crate) waker: fn(),
28 pub(crate) internal_operation: fn(InternalOperation),
29} 29}
30 30
31impl BufferedCanSender { 31impl<'ch, FRAME> BufferedSender<'ch, FRAME> {
32 /// Async write frame to TX buffer. 32 /// Async write frame to TX buffer.
33 pub fn try_write(&mut self, frame: Frame) -> Result<(), embassy_sync::channel::TrySendError<Frame>> { 33 pub fn try_write(&mut self, frame: FRAME) -> Result<(), embassy_sync::channel::TrySendError<FRAME>> {
34 self.tx_buf.try_send(frame)?; 34 self.tx_buf.try_send(frame)?;
35 (self.waker)(); 35 (self.waker)();
36 Ok(()) 36 Ok(())
37 } 37 }
38 38
39 /// Async write frame to TX buffer. 39 /// Async write frame to TX buffer.
40 pub async fn write(&mut self, frame: Frame) { 40 pub async fn write(&mut self, frame: FRAME) {
41 self.tx_buf.send(frame).await; 41 self.tx_buf.send(frame).await;
42 (self.waker)(); 42 (self.waker)();
43 } 43 }
@@ -48,5 +48,77 @@ impl BufferedCanSender {
48 } 48 }
49} 49}
50 50
51impl<'ch, FRAME> Clone for BufferedSender<'ch, FRAME> {
52 fn clone(&self) -> Self {
53 (self.internal_operation)(InternalOperation::NotifySenderCreated);
54 Self {
55 tx_buf: self.tx_buf,
56 waker: self.waker,
57 internal_operation: self.internal_operation,
58 }
59 }
60}
61
62impl<'ch, FRAME> Drop for BufferedSender<'ch, FRAME> {
63 fn drop(&mut self) {
64 (self.internal_operation)(InternalOperation::NotifySenderDestroyed);
65 }
66}
67
68/// Sender that can be used for sending Classic CAN frames.
69pub type BufferedCanSender = BufferedSender<'static, Frame>;
70
51/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 71/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
52pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, Result<Envelope, BusError>>; 72pub struct BufferedReceiver<'ch, ENVELOPE> {
73 pub(crate) rx_buf: embassy_sync::channel::DynamicReceiver<'ch, Result<ENVELOPE, BusError>>,
74 pub(crate) internal_operation: fn(InternalOperation),
75}
76
77impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> {
78 /// Receive the next frame.
79 ///
80 /// See [`Channel::receive()`].
81 pub fn receive(&self) -> embassy_sync::channel::DynamicReceiveFuture<'_, Result<ENVELOPE, BusError>> {
82 self.rx_buf.receive()
83 }
84
85 /// Attempt to immediately receive the next frame.
86 ///
87 /// See [`Channel::try_receive()`]
88 pub fn try_receive(&self) -> Result<Result<ENVELOPE, BusError>, embassy_sync::channel::TryReceiveError> {
89 self.rx_buf.try_receive()
90 }
91
92 /// Allows a poll_fn to poll until the channel is ready to receive
93 ///
94 /// See [`Channel::poll_ready_to_receive()`]
95 pub fn poll_ready_to_receive(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
96 self.rx_buf.poll_ready_to_receive(cx)
97 }
98
99 /// Poll the channel for the next frame
100 ///
101 /// See [`Channel::poll_receive()`]
102 pub fn poll_receive(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<Result<ENVELOPE, BusError>> {
103 self.rx_buf.poll_receive(cx)
104 }
105}
106
107impl<'ch, ENVELOPE> Clone for BufferedReceiver<'ch, ENVELOPE> {
108 fn clone(&self) -> Self {
109 (self.internal_operation)(InternalOperation::NotifyReceiverCreated);
110 Self {
111 rx_buf: self.rx_buf,
112 internal_operation: self.internal_operation,
113 }
114 }
115}
116
117impl<'ch, ENVELOPE> Drop for BufferedReceiver<'ch, ENVELOPE> {
118 fn drop(&mut self) {
119 (self.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
120 }
121}
122
123/// A BufferedCanReceiver for Classic CAN frames.
124pub type BufferedCanReceiver = BufferedReceiver<'static, Envelope>;
diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs
index a5cca424d..97cb47640 100644
--- a/embassy-stm32/src/can/enums.rs
+++ b/embassy-stm32/src/can/enums.rs
@@ -68,3 +68,17 @@ pub enum TryReadError {
68 /// Receive buffer is empty 68 /// Receive buffer is empty
69 Empty, 69 Empty,
70} 70}
71
72/// Internal Operation
73#[derive(Debug)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75pub enum InternalOperation {
76 /// Notify receiver created
77 NotifyReceiverCreated,
78 /// Notify receiver destroyed
79 NotifyReceiverDestroyed,
80 /// Notify sender created
81 NotifySenderCreated,
82 /// Notify sender destroyed
83 NotifySenderDestroyed,
84}
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index c549313f3..f950b6f99 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -6,7 +6,7 @@ use core::task::Poll;
6use embassy_hal_internal::interrupt::InterruptExt; 6use embassy_hal_internal::interrupt::InterruptExt;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender}; 9use embassy_sync::channel::Channel;
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use crate::can::fd::peripheral::Registers; 12use crate::can::fd::peripheral::Registers;
@@ -478,28 +478,28 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
478 478
479 /// Returns a sender that can be used for sending CAN frames. 479 /// Returns a sender that can be used for sending CAN frames.
480 pub fn writer(&self) -> BufferedCanSender { 480 pub fn writer(&self) -> BufferedCanSender {
481 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
481 BufferedCanSender { 482 BufferedCanSender {
482 tx_buf: self.tx_buf.sender().into(), 483 tx_buf: self.tx_buf.sender().into(),
483 waker: self.info.tx_waker, 484 waker: self.info.tx_waker,
485 internal_operation: self.info.internal_operation,
484 } 486 }
485 } 487 }
486 488
487 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 489 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
488 pub fn reader(&self) -> BufferedCanReceiver { 490 pub fn reader(&self) -> BufferedCanReceiver {
489 self.rx_buf.receiver().into() 491 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
492 BufferedCanReceiver {
493 rx_buf: self.rx_buf.receiver().into(),
494 internal_operation: self.info.internal_operation,
495 }
490 } 496 }
491} 497}
492 498
493impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 499impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
494 fn drop(&mut self) { 500 fn drop(&mut self) {
495 critical_section::with(|_| { 501 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
496 let state = self.state as *const State; 502 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
497 unsafe {
498 let mut_state = state as *mut State;
499 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
500 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
501 }
502 });
503 } 503 }
504} 504}
505 505
@@ -509,35 +509,11 @@ pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Resul
509/// User supplied buffer for TX buffering 509/// User supplied buffer for TX buffering
510pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>; 510pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
511 511
512/// Sender that can be used for sending CAN frames. 512/// Sender that can be used for sending Classic CAN frames.
513#[derive(Copy, Clone)] 513pub type BufferedFdCanSender = super::common::BufferedSender<'static, FdFrame>;
514pub struct BufferedFdCanSender {
515 tx_buf: DynamicSender<'static, FdFrame>,
516 waker: fn(),
517}
518
519impl BufferedFdCanSender {
520 /// Async write frame to TX buffer.
521 pub fn try_write(&mut self, frame: FdFrame) -> Result<(), embassy_sync::channel::TrySendError<FdFrame>> {
522 self.tx_buf.try_send(frame)?;
523 (self.waker)();
524 Ok(())
525 }
526
527 /// Async write frame to TX buffer.
528 pub async fn write(&mut self, frame: FdFrame) {
529 self.tx_buf.send(frame).await;
530 (self.waker)();
531 }
532
533 /// Allows a poll_fn to poll until the channel is ready to write
534 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
535 self.tx_buf.poll_ready_to_send(cx)
536 }
537}
538 514
539/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 515/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
540pub type BufferedFdCanReceiver = DynamicReceiver<'static, Result<FdEnvelope, BusError>>; 516pub type BufferedFdCanReceiver = super::common::BufferedReceiver<'static, FdEnvelope>;
541 517
542/// Buffered FDCAN Instance 518/// Buffered FDCAN Instance
543pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 519pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
@@ -608,28 +584,28 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
608 584
609 /// Returns a sender that can be used for sending CAN frames. 585 /// Returns a sender that can be used for sending CAN frames.
610 pub fn writer(&self) -> BufferedFdCanSender { 586 pub fn writer(&self) -> BufferedFdCanSender {
587 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
611 BufferedFdCanSender { 588 BufferedFdCanSender {
612 tx_buf: self.tx_buf.sender().into(), 589 tx_buf: self.tx_buf.sender().into(),
613 waker: self.info.tx_waker, 590 waker: self.info.tx_waker,
591 internal_operation: self.info.internal_operation,
614 } 592 }
615 } 593 }
616 594
617 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 595 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
618 pub fn reader(&self) -> BufferedFdCanReceiver { 596 pub fn reader(&self) -> BufferedFdCanReceiver {
619 self.rx_buf.receiver().into() 597 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
598 BufferedFdCanReceiver {
599 rx_buf: self.rx_buf.receiver().into(),
600 internal_operation: self.info.internal_operation,
601 }
620 } 602 }
621} 603}
622 604
623impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 605impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
624 fn drop(&mut self) { 606 fn drop(&mut self) {
625 critical_section::with(|_| { 607 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
626 let state = self.state as *const State; 608 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
627 unsafe {
628 let mut_state = state as *mut State;
629 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
630 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
631 }
632 });
633 } 609 }
634} 610}
635 611
@@ -922,6 +898,8 @@ struct State {
922 pub rx_mode: RxMode, 898 pub rx_mode: RxMode,
923 pub tx_mode: TxMode, 899 pub tx_mode: TxMode,
924 pub ns_per_timer_tick: u64, 900 pub ns_per_timer_tick: u64,
901 receiver_instance_count: usize,
902 sender_instance_count: usize,
925 903
926 pub err_waker: AtomicWaker, 904 pub err_waker: AtomicWaker,
927} 905}
@@ -933,6 +911,8 @@ impl State {
933 tx_mode: TxMode::NonBuffered(AtomicWaker::new()), 911 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
934 ns_per_timer_tick: 0, 912 ns_per_timer_tick: 0,
935 err_waker: AtomicWaker::new(), 913 err_waker: AtomicWaker::new(),
914 receiver_instance_count: 1,
915 sender_instance_count: 1,
936 } 916 }
937 } 917 }
938} 918}
@@ -942,6 +922,7 @@ struct Info {
942 interrupt0: crate::interrupt::Interrupt, 922 interrupt0: crate::interrupt::Interrupt,
943 _interrupt1: crate::interrupt::Interrupt, 923 _interrupt1: crate::interrupt::Interrupt,
944 tx_waker: fn(), 924 tx_waker: fn(),
925 internal_operation: fn(InternalOperation),
945} 926}
946 927
947impl Info { 928impl Info {
@@ -970,6 +951,7 @@ trait SealedInstance {
970 fn registers() -> crate::can::fd::peripheral::Registers; 951 fn registers() -> crate::can::fd::peripheral::Registers;
971 fn state() -> &'static State; 952 fn state() -> &'static State;
972 unsafe fn mut_state() -> &'static mut State; 953 unsafe fn mut_state() -> &'static mut State;
954 fn internal_operation(val: InternalOperation);
973 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; 955 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
974} 956}
975 957
@@ -992,12 +974,42 @@ macro_rules! impl_fdcan {
992 impl SealedInstance for peripherals::$inst { 974 impl SealedInstance for peripherals::$inst {
993 const MSG_RAM_OFFSET: usize = $msg_ram_offset; 975 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
994 976
977 fn internal_operation(val: InternalOperation) {
978 critical_section::with(|_| {
979 //let state = self.state as *const State;
980 unsafe {
981 //let mut_state = state as *mut State;
982 let mut_state = peripherals::$inst::mut_state();
983 match val {
984 InternalOperation::NotifySenderCreated => {
985 mut_state.sender_instance_count += 1;
986 }
987 InternalOperation::NotifySenderDestroyed => {
988 mut_state.sender_instance_count -= 1;
989 if ( 0 == mut_state.sender_instance_count) {
990 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
991 }
992 }
993 InternalOperation::NotifyReceiverCreated => {
994 mut_state.receiver_instance_count += 1;
995 }
996 InternalOperation::NotifyReceiverDestroyed => {
997 mut_state.receiver_instance_count -= 1;
998 if ( 0 == mut_state.receiver_instance_count) {
999 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1000 }
1001 }
1002 }
1003 }
1004 });
1005 }
995 fn info() -> &'static Info { 1006 fn info() -> &'static Info {
996 static INFO: Info = Info { 1007 static INFO: Info = Info {
997 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset}, 1008 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset},
998 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ, 1009 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
999 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ, 1010 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
1000 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend, 1011 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
1012 internal_operation: peripherals::$inst::internal_operation,
1001 }; 1013 };
1002 &INFO 1014 &INFO
1003 } 1015 }