aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Schuhen <[email protected]>2025-06-07 17:25:15 +1000
committerCorey Schuhen <[email protected]>2025-06-21 12:31:56 +1000
commit8b280688e18bd92b126601d9af26d73e147edeac (patch)
tree289ff2cf62c3138c13aaef7472f23e6b0a283f31
parente75b344089df76aa89d7fd4463a509c0bc58de2c (diff)
FDCAN/BXCAN: Finish implementation of RAII instance counters.
- Use DeRef in all types - Change Name of internal_operation and its enum - move into Info to avoid macro code dup
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs191
-rw-r--r--embassy-stm32/src/can/common.rs108
-rw-r--r--embassy-stm32/src/can/enums.rs2
-rw-r--r--embassy-stm32/src/can/fdcan.rs163
4 files changed, 243 insertions, 221 deletions
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index e2d1c8182..4c0795a2a 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -15,9 +15,10 @@ pub use embedded_can::{ExtendedId, Id, StandardId};
15use self::filter::MasterFilters; 15use self::filter::MasterFilters;
16use self::registers::{Registers, RxFifo}; 16use self::registers::{Registers, RxFifo};
17pub use super::common::{BufferedCanReceiver, BufferedCanSender}; 17pub use super::common::{BufferedCanReceiver, BufferedCanSender};
18use super::common::{InfoRef, RxInfoRef, TxInfoRef};
18use super::frame::{Envelope, Frame}; 19use super::frame::{Envelope, Frame};
19use super::util; 20use super::util;
20use crate::can::enums::{BusError, InternalOperation, TryReadError}; 21use crate::can::enums::{BusError, RefCountOp, TryReadError};
21use crate::gpio::{AfType, OutputType, Pull, Speed}; 22use crate::gpio::{AfType, OutputType, Pull, Speed};
22use crate::interrupt::typelevel::Interrupt; 23use crate::interrupt::typelevel::Interrupt;
23use crate::rcc::{self, RccPeripheral}; 24use crate::rcc::{self, RccPeripheral};
@@ -90,7 +91,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
90 // an indefinite amount of time. 91 // an indefinite amount of time.
91 let ier = T::regs().ier(); 92 let ier = T::regs().ier();
92 ier.modify(|i| i.set_errie(false)); 93 ier.modify(|i| i.set_errie(false));
93
94 T::info().state.lock(|state| { 94 T::info().state.lock(|state| {
95 state.borrow().err_waker.wake(); 95 state.borrow().err_waker.wake();
96 }); 96 });
@@ -101,7 +101,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
101/// Configuration proxy returned by [`Can::modify_config`]. 101/// Configuration proxy returned by [`Can::modify_config`].
102pub struct CanConfig<'a> { 102pub struct CanConfig<'a> {
103 phantom: PhantomData<&'a ()>, 103 phantom: PhantomData<&'a ()>,
104 info: &'static Info, 104 info: InfoRef,
105 periph_clock: crate::time::Hertz, 105 periph_clock: crate::time::Hertz,
106} 106}
107 107
@@ -166,7 +166,7 @@ impl Drop for CanConfig<'_> {
166/// CAN driver 166/// CAN driver
167pub struct Can<'d> { 167pub struct Can<'d> {
168 phantom: PhantomData<&'d ()>, 168 phantom: PhantomData<&'d ()>,
169 info: &'static Info, 169 info: InfoRef,
170 periph_clock: crate::time::Hertz, 170 periph_clock: crate::time::Hertz,
171} 171}
172 172
@@ -236,7 +236,7 @@ impl<'d> Can<'d> {
236 236
237 Self { 237 Self {
238 phantom: PhantomData, 238 phantom: PhantomData,
239 info: T::info(), 239 info: InfoRef::new(T::info()),
240 periph_clock: T::frequency(), 240 periph_clock: T::frequency(),
241 } 241 }
242 } 242 }
@@ -256,7 +256,7 @@ impl<'d> Can<'d> {
256 256
257 CanConfig { 257 CanConfig {
258 phantom: self.phantom, 258 phantom: self.phantom,
259 info: self.info, 259 info: InfoRef::new(&self.info),
260 periph_clock: self.periph_clock, 260 periph_clock: self.periph_clock,
261 } 261 }
262 } 262 }
@@ -305,8 +305,8 @@ impl<'d> Can<'d> {
305 self.info.regs.0.mcr().modify(|m| m.set_sleep(true)); 305 self.info.regs.0.mcr().modify(|m| m.set_sleep(true));
306 306
307 poll_fn(|cx| { 307 poll_fn(|cx| {
308 self.info.state.lock(|state| { 308 self.info.state.lock(|s| {
309 state.borrow().err_waker.register(cx.waker()); 309 s.borrow().err_waker.register(cx.waker());
310 }); 310 });
311 if self.is_sleeping() { 311 if self.is_sleeping() {
312 Poll::Ready(()) 312 Poll::Ready(())
@@ -360,7 +360,7 @@ impl<'d> Can<'d> {
360 pub async fn flush(&self, mb: Mailbox) { 360 pub async fn flush(&self, mb: Mailbox) {
361 CanTx { 361 CanTx {
362 _phantom: PhantomData, 362 _phantom: PhantomData,
363 info: self.info, 363 info: TxInfoRef::new(&self.info),
364 } 364 }
365 .flush_inner(mb) 365 .flush_inner(mb)
366 .await; 366 .await;
@@ -375,7 +375,7 @@ impl<'d> Can<'d> {
375 pub async fn flush_any(&self) { 375 pub async fn flush_any(&self) {
376 CanTx { 376 CanTx {
377 _phantom: PhantomData, 377 _phantom: PhantomData,
378 info: self.info, 378 info: TxInfoRef::new(&self.info),
379 } 379 }
380 .flush_any_inner() 380 .flush_any_inner()
381 .await 381 .await
@@ -385,7 +385,7 @@ impl<'d> Can<'d> {
385 pub async fn flush_all(&self) { 385 pub async fn flush_all(&self) {
386 CanTx { 386 CanTx {
387 _phantom: PhantomData, 387 _phantom: PhantomData,
388 info: self.info, 388 info: TxInfoRef::new(&self.info),
389 } 389 }
390 .flush_all_inner() 390 .flush_all_inner()
391 .await 391 .await
@@ -413,19 +413,19 @@ impl<'d> Can<'d> {
413 /// 413 ///
414 /// Returns a tuple of the time the message was received and the message frame 414 /// Returns a tuple of the time the message was received and the message frame
415 pub async fn read(&mut self) -> Result<Envelope, BusError> { 415 pub async fn read(&mut self) -> Result<Envelope, BusError> {
416 RxMode::read(self.info).await 416 RxMode::read(&self.info).await
417 } 417 }
418 418
419 /// Attempts to read a CAN frame without blocking. 419 /// Attempts to read a CAN frame without blocking.
420 /// 420 ///
421 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 421 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
422 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 422 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
423 RxMode::try_read(self.info) 423 RxMode::try_read(&self.info)
424 } 424 }
425 425
426 /// Waits while receive queue is empty. 426 /// Waits while receive queue is empty.
427 pub async fn wait_not_empty(&mut self) { 427 pub async fn wait_not_empty(&mut self) {
428 RxMode::wait_not_empty(self.info).await 428 RxMode::wait_not_empty(&self.info).await
429 } 429 }
430 430
431 /// Split the CAN driver into transmit and receive halves. 431 /// Split the CAN driver into transmit and receive halves.
@@ -435,11 +435,11 @@ impl<'d> Can<'d> {
435 ( 435 (
436 CanTx { 436 CanTx {
437 _phantom: PhantomData, 437 _phantom: PhantomData,
438 info: self.info, 438 info: TxInfoRef::new(&self.info),
439 }, 439 },
440 CanRx { 440 CanRx {
441 _phantom: PhantomData, 441 _phantom: PhantomData,
442 info: self.info, 442 info: RxInfoRef::new(&self.info),
443 }, 443 },
444 ) 444 )
445 } 445 }
@@ -464,7 +464,7 @@ impl<'d> Can<'d> {
464 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master 464 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
465 /// peripheral instead. 465 /// peripheral instead.
466 pub fn modify_filters(&mut self) -> MasterFilters<'_> { 466 pub fn modify_filters(&mut self) -> MasterFilters<'_> {
467 unsafe { MasterFilters::new(self.info) } 467 unsafe { MasterFilters::new(&self.info) }
468 } 468 }
469} 469}
470 470
@@ -519,7 +519,7 @@ impl<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_
519/// CAN driver, transmit half. 519/// CAN driver, transmit half.
520pub struct CanTx<'d> { 520pub struct CanTx<'d> {
521 _phantom: PhantomData<&'d ()>, 521 _phantom: PhantomData<&'d ()>,
522 info: &'static Info, 522 info: TxInfoRef,
523} 523}
524 524
525impl<'d> CanTx<'d> { 525impl<'d> CanTx<'d> {
@@ -528,8 +528,8 @@ impl<'d> CanTx<'d> {
528 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. 528 /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
529 pub async fn write(&mut self, frame: &Frame) -> TransmitStatus { 529 pub async fn write(&mut self, frame: &Frame) -> TransmitStatus {
530 poll_fn(|cx| { 530 poll_fn(|cx| {
531 self.info.state.lock(|state| { 531 self.info.state.lock(|s| {
532 state.borrow().tx_mode.register(cx.waker()); 532 s.borrow().tx_mode.register(cx.waker());
533 }); 533 });
534 if let Ok(status) = self.info.regs.transmit(frame) { 534 if let Ok(status) = self.info.regs.transmit(frame) {
535 return Poll::Ready(status); 535 return Poll::Ready(status);
@@ -555,8 +555,8 @@ impl<'d> CanTx<'d> {
555 555
556 async fn flush_inner(&self, mb: Mailbox) { 556 async fn flush_inner(&self, mb: Mailbox) {
557 poll_fn(|cx| { 557 poll_fn(|cx| {
558 self.info.state.lock(|state| { 558 self.info.state.lock(|s| {
559 state.borrow().tx_mode.register(cx.waker()); 559 s.borrow().tx_mode.register(cx.waker());
560 }); 560 });
561 if self.info.regs.0.tsr().read().tme(mb.index()) { 561 if self.info.regs.0.tsr().read().tme(mb.index()) {
562 return Poll::Ready(()); 562 return Poll::Ready(());
@@ -574,8 +574,8 @@ impl<'d> CanTx<'d> {
574 574
575 async fn flush_any_inner(&self) { 575 async fn flush_any_inner(&self) {
576 poll_fn(|cx| { 576 poll_fn(|cx| {
577 self.info.state.lock(|state| { 577 self.info.state.lock(|s| {
578 state.borrow().tx_mode.register(cx.waker()); 578 s.borrow().tx_mode.register(cx.waker());
579 }); 579 });
580 580
581 let tsr = self.info.regs.0.tsr().read(); 581 let tsr = self.info.regs.0.tsr().read();
@@ -603,8 +603,8 @@ impl<'d> CanTx<'d> {
603 603
604 async fn flush_all_inner(&self) { 604 async fn flush_all_inner(&self) {
605 poll_fn(|cx| { 605 poll_fn(|cx| {
606 self.info.state.lock(|state| { 606 self.info.state.lock(|s| {
607 state.borrow().tx_mode.register(cx.waker()); 607 s.borrow().tx_mode.register(cx.waker());
608 }); 608 });
609 609
610 let tsr = self.info.regs.0.tsr().read(); 610 let tsr = self.info.regs.0.tsr().read();
@@ -646,7 +646,7 @@ impl<'d> CanTx<'d> {
646 self, 646 self,
647 txb: &'static mut TxBuf<TX_BUF_SIZE>, 647 txb: &'static mut TxBuf<TX_BUF_SIZE>,
648 ) -> BufferedCanTx<'d, TX_BUF_SIZE> { 648 ) -> BufferedCanTx<'d, TX_BUF_SIZE> {
649 BufferedCanTx::new(self.info, self, txb) 649 BufferedCanTx::new(&self.info, self, txb)
650 } 650 }
651} 651}
652 652
@@ -655,23 +655,30 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame,
655 655
656/// Buffered CAN driver, transmit half. 656/// Buffered CAN driver, transmit half.
657pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> { 657pub struct BufferedCanTx<'d, const TX_BUF_SIZE: usize> {
658 info: &'static Info, 658 info: TxInfoRef,
659 _tx: CanTx<'d>, 659 _tx: CanTx<'d>,
660 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 660 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
661} 661}
662 662
663impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> { 663impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
664 fn new(info: &'static Info, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self { 664 fn new(info: &'static Info, _tx: CanTx<'d>, tx_buf: &'static TxBuf<TX_BUF_SIZE>) -> Self {
665 Self { info, _tx, tx_buf }.setup() 665 Self {
666 info: TxInfoRef::new(info),
667 _tx,
668 tx_buf,
669 }
670 .setup()
666 } 671 }
667 672
668 fn setup(self) -> Self { 673 fn setup(self) -> Self {
669 // We don't want interrupts being processed while we change modes. 674 // We don't want interrupts being processed while we change modes.
670 let tx_inner = super::common::ClassicBufferedTxInner { 675 critical_section::with(|_| {
671 tx_receiver: self.tx_buf.receiver().into(), 676 let tx_inner = super::common::ClassicBufferedTxInner {
672 }; 677 tx_receiver: self.tx_buf.receiver().into(),
673 self.info.state.lock(|state| { 678 };
674 state.borrow_mut().tx_mode = TxMode::Buffered(tx_inner); 679 self.info.state.lock(|s| {
680 s.borrow_mut().tx_mode = TxMode::Buffered(tx_inner);
681 });
675 }); 682 });
676 self 683 self
677 } 684 }
@@ -685,26 +692,18 @@ impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
685 692
686 /// Returns a sender that can be used for sending CAN frames. 693 /// Returns a sender that can be used for sending CAN frames.
687 pub fn writer(&self) -> BufferedCanSender { 694 pub fn writer(&self) -> BufferedCanSender {
688 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
689 BufferedCanSender { 695 BufferedCanSender {
690 tx_buf: self.tx_buf.sender().into(), 696 tx_buf: self.tx_buf.sender().into(),
691 waker: self.info.tx_waker, 697 info: TxInfoRef::new(&self.info),
692 internal_operation: self.info.internal_operation,
693 } 698 }
694 } 699 }
695} 700}
696 701
697impl<'d, const TX_BUF_SIZE: usize> Drop for BufferedCanTx<'d, TX_BUF_SIZE> {
698 fn drop(&mut self) {
699 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
700 }
701}
702
703/// CAN driver, receive half. 702/// CAN driver, receive half.
704#[allow(dead_code)] 703#[allow(dead_code)]
705pub struct CanRx<'d> { 704pub struct CanRx<'d> {
706 _phantom: PhantomData<&'d ()>, 705 _phantom: PhantomData<&'d ()>,
707 info: &'static Info, 706 info: RxInfoRef,
708} 707}
709 708
710impl<'d> CanRx<'d> { 709impl<'d> CanRx<'d> {
@@ -714,19 +713,19 @@ impl<'d> CanRx<'d> {
714 /// 713 ///
715 /// Returns a tuple of the time the message was received and the message frame 714 /// Returns a tuple of the time the message was received and the message frame
716 pub async fn read(&mut self) -> Result<Envelope, BusError> { 715 pub async fn read(&mut self) -> Result<Envelope, BusError> {
717 RxMode::read(self.info).await 716 RxMode::read(&self.info).await
718 } 717 }
719 718
720 /// Attempts to read a CAN frame without blocking. 719 /// Attempts to read a CAN frame without blocking.
721 /// 720 ///
722 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. 721 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
723 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { 722 pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
724 RxMode::try_read(self.info) 723 RxMode::try_read(&self.info)
725 } 724 }
726 725
727 /// Waits while receive queue is empty. 726 /// Waits while receive queue is empty.
728 pub async fn wait_not_empty(&mut self) { 727 pub async fn wait_not_empty(&mut self) {
729 RxMode::wait_not_empty(self.info).await 728 RxMode::wait_not_empty(&self.info).await
730 } 729 }
731 730
732 /// Return a buffered instance of driver. User must supply Buffers 731 /// Return a buffered instance of driver. User must supply Buffers
@@ -734,7 +733,7 @@ impl<'d> CanRx<'d> {
734 self, 733 self,
735 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 734 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
736 ) -> BufferedCanRx<'d, RX_BUF_SIZE> { 735 ) -> BufferedCanRx<'d, RX_BUF_SIZE> {
737 BufferedCanRx::new(self.info, self, rxb) 736 BufferedCanRx::new(&self.info, self, rxb)
738 } 737 }
739 738
740 /// Accesses the filter banks owned by this CAN peripheral. 739 /// Accesses the filter banks owned by this CAN peripheral.
@@ -742,7 +741,7 @@ impl<'d> CanRx<'d> {
742 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master 741 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
743 /// peripheral instead. 742 /// peripheral instead.
744 pub fn modify_filters(&mut self) -> MasterFilters<'_> { 743 pub fn modify_filters(&mut self) -> MasterFilters<'_> {
745 unsafe { MasterFilters::new(self.info) } 744 unsafe { MasterFilters::new(&self.info) }
746 } 745 }
747} 746}
748 747
@@ -751,23 +750,30 @@ pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<
751 750
752/// CAN driver, receive half in Buffered mode. 751/// CAN driver, receive half in Buffered mode.
753pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> { 752pub struct BufferedCanRx<'d, const RX_BUF_SIZE: usize> {
754 info: &'static Info, 753 info: RxInfoRef,
755 rx: CanRx<'d>, 754 rx: CanRx<'d>,
756 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 755 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
757} 756}
758 757
759impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> { 758impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
760 fn new(info: &'static Info, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self { 759 fn new(info: &'static Info, rx: CanRx<'d>, rx_buf: &'static RxBuf<RX_BUF_SIZE>) -> Self {
761 BufferedCanRx { info, rx, rx_buf }.setup() 760 BufferedCanRx {
761 info: RxInfoRef::new(info),
762 rx,
763 rx_buf,
764 }
765 .setup()
762 } 766 }
763 767
764 fn setup(self) -> Self { 768 fn setup(self) -> Self {
765 // We don't want interrupts being processed while we change modes. 769 // We don't want interrupts being processed while we change modes.
766 let rx_inner = super::common::ClassicBufferedRxInner { 770 critical_section::with(|_| {
767 rx_sender: self.rx_buf.sender().into(), 771 let rx_inner = super::common::ClassicBufferedRxInner {
768 }; 772 rx_sender: self.rx_buf.sender().into(),
769 self.info.state.lock(|state| { 773 };
770 state.borrow_mut().rx_mode = RxMode::Buffered(rx_inner); 774 self.info.state.lock(|s| {
775 s.borrow_mut().rx_mode = RxMode::Buffered(rx_inner);
776 });
771 }); 777 });
772 self 778 self
773 } 779 }
@@ -809,10 +815,9 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
809 815
810 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 816 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
811 pub fn reader(&self) -> BufferedCanReceiver { 817 pub fn reader(&self) -> BufferedCanReceiver {
812 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
813 BufferedCanReceiver { 818 BufferedCanReceiver {
814 rx_buf: self.rx_buf.receiver().into(), 819 rx_buf: self.rx_buf.receiver().into(),
815 internal_operation: self.info.internal_operation, 820 info: RxInfoRef::new(&self.info),
816 } 821 }
817 } 822 }
818 823
@@ -825,12 +830,6 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
825 } 830 }
826} 831}
827 832
828impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> {
829 fn drop(&mut self) {
830 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
831 }
832}
833
834impl Drop for Can<'_> { 833impl Drop for Can<'_> {
835 fn drop(&mut self) { 834 fn drop(&mut self) {
836 // Cannot call `free()` because it moves the instance. 835 // Cannot call `free()` because it moves the instance.
@@ -1005,6 +1004,7 @@ impl TxMode {
1005 pub fn on_interrupt<T: Instance>(&self) { 1004 pub fn on_interrupt<T: Instance>(&self) {
1006 T::info().state.lock(|state| { 1005 T::info().state.lock(|state| {
1007 let tx_mode = &state.borrow().tx_mode; 1006 let tx_mode = &state.borrow().tx_mode;
1007
1008 match tx_mode { 1008 match tx_mode {
1009 TxMode::NonBuffered(waker) => waker.wake(), 1009 TxMode::NonBuffered(waker) => waker.wake(),
1010 TxMode::Buffered(buf) => { 1010 TxMode::Buffered(buf) => {
@@ -1062,8 +1062,7 @@ pub(crate) struct Info {
1062 rx0_interrupt: crate::interrupt::Interrupt, 1062 rx0_interrupt: crate::interrupt::Interrupt,
1063 rx1_interrupt: crate::interrupt::Interrupt, 1063 rx1_interrupt: crate::interrupt::Interrupt,
1064 sce_interrupt: crate::interrupt::Interrupt, 1064 sce_interrupt: crate::interrupt::Interrupt,
1065 tx_waker: fn(), 1065 pub(crate) tx_waker: fn(),
1066 internal_operation: fn(InternalOperation),
1067 state: SharedState, 1066 state: SharedState,
1068 1067
1069 /// The total number of filter banks available to the instance. 1068 /// The total number of filter banks available to the instance.
@@ -1072,10 +1071,37 @@ pub(crate) struct Info {
1072 num_filter_banks: u8, 1071 num_filter_banks: u8,
1073} 1072}
1074 1073
1074impl Info {
1075 pub(crate) fn adjust_reference_counter(&self, val: RefCountOp) {
1076 self.state.lock(|s| {
1077 let mut mut_state = s.borrow_mut();
1078 match val {
1079 RefCountOp::NotifySenderCreated => {
1080 mut_state.sender_instance_count += 1;
1081 }
1082 RefCountOp::NotifySenderDestroyed => {
1083 mut_state.sender_instance_count -= 1;
1084 if 0 == mut_state.sender_instance_count {
1085 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1086 }
1087 }
1088 RefCountOp::NotifyReceiverCreated => {
1089 mut_state.receiver_instance_count += 1;
1090 }
1091 RefCountOp::NotifyReceiverDestroyed => {
1092 mut_state.receiver_instance_count -= 1;
1093 if 0 == mut_state.receiver_instance_count {
1094 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1095 }
1096 }
1097 }
1098 });
1099 }
1100}
1101
1075trait SealedInstance { 1102trait SealedInstance {
1076 fn info() -> &'static Info; 1103 fn info() -> &'static Info;
1077 fn regs() -> crate::pac::can::Can; 1104 fn regs() -> crate::pac::can::Can;
1078 fn internal_operation(val: InternalOperation);
1079} 1105}
1080 1106
1081/// CAN instance trait. 1107/// CAN instance trait.
@@ -1133,43 +1159,16 @@ foreach_peripheral!(
1133 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ, 1159 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ,
1134 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, 1160 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
1135 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, 1161 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
1136 internal_operation: peripherals::$inst::internal_operation,
1137 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
1138 num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS, 1162 num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
1163 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
1139 }; 1164 };
1140 &INFO 1165 &INFO
1141 } 1166 }
1142 fn regs() -> crate::pac::can::Can { 1167 fn regs() -> crate::pac::can::Can {
1143 crate::pac::$inst 1168 crate::pac::$inst
1144 } 1169 }
1145
1146 fn internal_operation(val: InternalOperation) {
1147 peripherals::$inst::info().state.lock(|s| {
1148 let mut mut_state = s.borrow_mut();
1149 //let mut_state = state as *mut State;
1150 match val {
1151 InternalOperation::NotifySenderCreated => {
1152 mut_state.sender_instance_count += 1;
1153 }
1154 InternalOperation::NotifySenderDestroyed => {
1155 mut_state.sender_instance_count -= 1;
1156 if ( 0 == mut_state.sender_instance_count) {
1157 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1158 }
1159 }
1160 InternalOperation::NotifyReceiverCreated => {
1161 mut_state.receiver_instance_count += 1;
1162 }
1163 InternalOperation::NotifyReceiverDestroyed => {
1164 mut_state.receiver_instance_count -= 1;
1165 if ( 0 == mut_state.receiver_instance_count) {
1166 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1167 }
1168 }
1169 }
1170 });
1171 }
1172 } 1170 }
1171
1173 impl Instance for peripherals::$inst { 1172 impl Instance for peripherals::$inst {
1174 type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX; 1173 type TXInterrupt = crate::_generated::peripheral_interrupts::$inst::TX;
1175 type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0; 1174 type RX0Interrupt = crate::_generated::peripheral_interrupts::$inst::RX0;
diff --git a/embassy-stm32/src/can/common.rs b/embassy-stm32/src/can/common.rs
index 651fa12d5..980f33a04 100644
--- a/embassy-stm32/src/can/common.rs
+++ b/embassy-stm32/src/can/common.rs
@@ -24,22 +24,21 @@ pub(crate) struct FdBufferedTxInner {
24/// Sender that can be used for sending CAN frames. 24/// Sender that can be used for sending CAN frames.
25pub struct BufferedSender<'ch, FRAME> { 25pub struct BufferedSender<'ch, FRAME> {
26 pub(crate) tx_buf: embassy_sync::channel::SendDynamicSender<'ch, FRAME>, 26 pub(crate) tx_buf: embassy_sync::channel::SendDynamicSender<'ch, FRAME>,
27 pub(crate) waker: fn(), 27 pub(crate) info: TxInfoRef,
28 pub(crate) tx_guard: TxGuard,
29} 28}
30 29
31impl<'ch, FRAME> BufferedSender<'ch, FRAME> { 30impl<'ch, FRAME> BufferedSender<'ch, FRAME> {
32 /// Async write frame to TX buffer. 31 /// Async write frame to TX buffer.
33 pub fn try_write(&mut self, frame: FRAME) -> Result<(), embassy_sync::channel::TrySendError<FRAME>> { 32 pub fn try_write(&mut self, frame: FRAME) -> Result<(), embassy_sync::channel::TrySendError<FRAME>> {
34 self.tx_buf.try_send(frame)?; 33 self.tx_buf.try_send(frame)?;
35 (self.waker)(); 34 (self.info.tx_waker)();
36 Ok(()) 35 Ok(())
37 } 36 }
38 37
39 /// Async write frame to TX buffer. 38 /// Async write frame to TX buffer.
40 pub async fn write(&mut self, frame: FRAME) { 39 pub async fn write(&mut self, frame: FRAME) {
41 self.tx_buf.send(frame).await; 40 self.tx_buf.send(frame).await;
42 (self.waker)(); 41 (self.info.tx_waker)();
43 } 42 }
44 43
45 /// Allows a poll_fn to poll until the channel is ready to write 44 /// Allows a poll_fn to poll until the channel is ready to write
@@ -52,8 +51,7 @@ impl<'ch, FRAME> Clone for BufferedSender<'ch, FRAME> {
52 fn clone(&self) -> Self { 51 fn clone(&self) -> Self {
53 Self { 52 Self {
54 tx_buf: self.tx_buf, 53 tx_buf: self.tx_buf,
55 waker: self.waker, 54 info: TxInfoRef::new(&self.info),
56 tx_guard: TxGuard::new(self.tx_guard.internal_operation),
57 } 55 }
58 } 56 }
59} 57}
@@ -64,7 +62,7 @@ pub type BufferedCanSender = BufferedSender<'static, Frame>;
64/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 62/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
65pub struct BufferedReceiver<'ch, ENVELOPE> { 63pub struct BufferedReceiver<'ch, ENVELOPE> {
66 pub(crate) rx_buf: embassy_sync::channel::SendDynamicReceiver<'ch, Result<ENVELOPE, BusError>>, 64 pub(crate) rx_buf: embassy_sync::channel::SendDynamicReceiver<'ch, Result<ENVELOPE, BusError>>,
67 pub(crate) rx_guard: RxGuard, 65 pub(crate) info: RxInfoRef,
68} 66}
69 67
70impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> { 68impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> {
@@ -101,7 +99,7 @@ impl<'ch, ENVELOPE> Clone for BufferedReceiver<'ch, ENVELOPE> {
101 fn clone(&self) -> Self { 99 fn clone(&self) -> Self {
102 Self { 100 Self {
103 rx_buf: self.rx_buf, 101 rx_buf: self.rx_buf,
104 rx_guard: RxGuard::new(self.rx_guard.internal_operation), 102 info: RxInfoRef::new(&self.info),
105 } 103 }
106 } 104 }
107} 105}
@@ -109,37 +107,89 @@ impl<'ch, ENVELOPE> Clone for BufferedReceiver<'ch, ENVELOPE> {
109/// A BufferedCanReceiver for Classic CAN frames. 107/// A BufferedCanReceiver for Classic CAN frames.
110pub type BufferedCanReceiver = BufferedReceiver<'static, Envelope>; 108pub type BufferedCanReceiver = BufferedReceiver<'static, Envelope>;
111 109
112/// Implements RAII for the internal reference counting (TX side). Each TX type should contain one 110/// Provides a reference to the driver internals and implements RAII for the internal reference
113/// of these. The new method and the Drop impl will automatically call the reference counting 111/// counting. Each type that can operate on the driver should contain either InfoRef
114/// function. Like this, the reference counting function does not need to be called manually for 112/// or the similar TxInfoRef or RxInfoRef. The new method and the Drop impl will automatically
115/// each TX type. Transceiver types (TX and RX) should contain one TxGuard and one RxGuard. 113/// call the reference counting function. Like this, the reference counting function does not
116pub(crate) struct TxGuard { 114/// need to be called manually for each type.
117 internal_operation: fn(InternalOperation), 115pub(crate) struct InfoRef {
116 info: &'static super::Info,
117}
118impl InfoRef {
119 pub(crate) fn new(info: &'static super::Info) -> Self {
120 info.adjust_reference_counter(RefCountOp::NotifyReceiverCreated);
121 info.adjust_reference_counter(RefCountOp::NotifySenderCreated);
122 Self { info }
123 }
124}
125
126impl Drop for InfoRef {
127 fn drop(&mut self) {
128 self.info.adjust_reference_counter(RefCountOp::NotifyReceiverDestroyed);
129 self.info.adjust_reference_counter(RefCountOp::NotifySenderDestroyed);
130 }
131}
132
133impl core::ops::Deref for InfoRef {
134 type Target = &'static super::Info;
135
136 fn deref(&self) -> &Self::Target {
137 &self.info
138 }
118} 139}
119impl TxGuard { 140
120 pub(crate) fn new(internal_operation: fn(InternalOperation)) -> Self { 141/// Provides a reference to the driver internals and implements RAII for the internal reference
121 internal_operation(InternalOperation::NotifySenderCreated); 142/// counting for Tx only types.
122 Self { internal_operation } 143/// See InfoRef for further doc.
144pub(crate) struct TxInfoRef {
145 info: &'static super::Info,
146}
147
148impl TxInfoRef {
149 pub(crate) fn new(info: &'static super::Info) -> Self {
150 info.adjust_reference_counter(RefCountOp::NotifySenderCreated);
151 Self { info }
123 } 152 }
124} 153}
125impl Drop for TxGuard { 154
155impl Drop for TxInfoRef {
126 fn drop(&mut self) { 156 fn drop(&mut self) {
127 (self.internal_operation)(InternalOperation::NotifySenderDestroyed); 157 self.info.adjust_reference_counter(RefCountOp::NotifySenderDestroyed);
158 }
159}
160
161impl core::ops::Deref for TxInfoRef {
162 type Target = &'static super::Info;
163
164 fn deref(&self) -> &Self::Target {
165 &self.info
128 } 166 }
129} 167}
130 168
131/// Implements RAII for the internal reference counting (RX side). See TxGuard for further doc. 169/// Provides a reference to the driver internals and implements RAII for the internal reference
132pub(crate) struct RxGuard { 170/// counting for Rx only types.
133 internal_operation: fn(InternalOperation), 171/// See InfoRef for further doc.
172pub(crate) struct RxInfoRef {
173 info: &'static super::Info,
134} 174}
135impl RxGuard { 175
136 pub(crate) fn new(internal_operation: fn(InternalOperation)) -> Self { 176impl RxInfoRef {
137 internal_operation(InternalOperation::NotifyReceiverCreated); 177 pub(crate) fn new(info: &'static super::Info) -> Self {
138 Self { internal_operation } 178 info.adjust_reference_counter(RefCountOp::NotifyReceiverCreated);
179 Self { info }
139 } 180 }
140} 181}
141impl Drop for RxGuard { 182
183impl Drop for RxInfoRef {
142 fn drop(&mut self) { 184 fn drop(&mut self) {
143 (self.internal_operation)(InternalOperation::NotifyReceiverDestroyed); 185 self.info.adjust_reference_counter(RefCountOp::NotifyReceiverDestroyed);
186 }
187}
188
189impl core::ops::Deref for RxInfoRef {
190 type Target = &'static super::Info;
191
192 fn deref(&self) -> &Self::Target {
193 &self.info
144 } 194 }
145} 195}
diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs
index 97cb47640..6d91020fc 100644
--- a/embassy-stm32/src/can/enums.rs
+++ b/embassy-stm32/src/can/enums.rs
@@ -72,7 +72,7 @@ pub enum TryReadError {
72/// Internal Operation 72/// Internal Operation
73#[derive(Debug)] 73#[derive(Debug)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))] 74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75pub enum InternalOperation { 75pub enum RefCountOp {
76 /// Notify receiver created 76 /// Notify receiver created
77 NotifyReceiverCreated, 77 NotifyReceiverCreated,
78 /// Notify receiver destroyed 78 /// Notify receiver destroyed
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 2846fb44a..99e40ba62 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -21,7 +21,7 @@ use self::fd::config::*;
21use self::fd::filter::*; 21use self::fd::filter::*;
22pub use self::fd::{config, filter}; 22pub use self::fd::{config, filter};
23pub use super::common::{BufferedCanReceiver, BufferedCanSender}; 23pub use super::common::{BufferedCanReceiver, BufferedCanSender};
24use super::common::{RxGuard, TxGuard}; 24use super::common::{InfoRef, RxInfoRef, TxInfoRef};
25use super::enums::*; 25use super::enums::*;
26use super::frame::*; 26use super::frame::*;
27use super::util; 27use super::util;
@@ -168,11 +168,10 @@ fn calc_ns_per_timer_tick(
168pub struct CanConfigurator<'d> { 168pub struct CanConfigurator<'d> {
169 _phantom: PhantomData<&'d ()>, 169 _phantom: PhantomData<&'d ()>,
170 config: crate::can::fd::config::FdCanConfig, 170 config: crate::can::fd::config::FdCanConfig,
171 info: &'static Info,
172 /// Reference to internals. 171 /// Reference to internals.
173 properties: Properties, 172 properties: Properties,
174 periph_clock: crate::time::Hertz, 173 periph_clock: crate::time::Hertz,
175 raii_guards: (TxGuard, RxGuard), 174 info: InfoRef,
176} 175}
177 176
178impl<'d> CanConfigurator<'d> { 177impl<'d> CanConfigurator<'d> {
@@ -211,13 +210,9 @@ impl<'d> CanConfigurator<'d> {
211 Self { 210 Self {
212 _phantom: PhantomData, 211 _phantom: PhantomData,
213 config, 212 config,
214 info,
215 properties: Properties::new(T::info()), 213 properties: Properties::new(T::info()),
216 periph_clock: T::frequency(), 214 periph_clock: T::frequency(),
217 raii_guards: ( 215 info: InfoRef::new(info),
218 TxGuard::new(info.internal_operation),
219 RxGuard::new(info.internal_operation),
220 ),
221 } 216 }
222 } 217 }
223 218
@@ -266,7 +261,7 @@ impl<'d> CanConfigurator<'d> {
266 261
267 /// Start in mode. 262 /// Start in mode.
268 pub fn start(self, mode: OperatingMode) -> Can<'d> { 263 pub fn start(self, mode: OperatingMode) -> Can<'d> {
269 let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit); 264 let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit);
270 self.info.state.lock(|s| { 265 self.info.state.lock(|s| {
271 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick; 266 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick;
272 }); 267 });
@@ -274,10 +269,9 @@ impl<'d> CanConfigurator<'d> {
274 Can { 269 Can {
275 _phantom: PhantomData, 270 _phantom: PhantomData,
276 config: self.config, 271 config: self.config,
277 info: self.info,
278 _mode: mode, 272 _mode: mode,
279 properties: Properties::new(self.info), 273 properties: Properties::new(&self.info),
280 raii_guards: self.raii_guards, 274 info: InfoRef::new(&self.info),
281 } 275 }
282 } 276 }
283 277
@@ -301,10 +295,9 @@ impl<'d> CanConfigurator<'d> {
301pub struct Can<'d> { 295pub struct Can<'d> {
302 _phantom: PhantomData<&'d ()>, 296 _phantom: PhantomData<&'d ()>,
303 config: crate::can::fd::config::FdCanConfig, 297 config: crate::can::fd::config::FdCanConfig,
304 info: &'static Info,
305 _mode: OperatingMode, 298 _mode: OperatingMode,
306 properties: Properties, 299 properties: Properties,
307 raii_guards: (TxGuard, RxGuard), 300 info: InfoRef,
308} 301}
309 302
310impl<'d> Can<'d> { 303impl<'d> Can<'d> {
@@ -338,12 +331,12 @@ impl<'d> Can<'d> {
338 /// can be replaced, this call asynchronously waits for a frame to be successfully 331 /// can be replaced, this call asynchronously waits for a frame to be successfully
339 /// transmitted, then tries again. 332 /// transmitted, then tries again.
340 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 333 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
341 TxMode::write(self.info, frame).await 334 TxMode::write(&self.info, frame).await
342 } 335 }
343 336
344 /// Returns the next received message frame 337 /// Returns the next received message frame
345 pub async fn read(&mut self) -> Result<Envelope, BusError> { 338 pub async fn read(&mut self) -> Result<Envelope, BusError> {
346 RxMode::read_classic(self.info).await 339 RxMode::read_classic(&self.info).await
347 } 340 }
348 341
349 /// Queues the message to be sent but exerts backpressure. If a lower-priority 342 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -351,12 +344,12 @@ impl<'d> Can<'d> {
351 /// can be replaced, this call asynchronously waits for a frame to be successfully 344 /// can be replaced, this call asynchronously waits for a frame to be successfully
352 /// transmitted, then tries again. 345 /// transmitted, then tries again.
353 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 346 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
354 TxMode::write_fd(self.info, frame).await 347 TxMode::write_fd(&self.info, frame).await
355 } 348 }
356 349
357 /// Returns the next received message frame 350 /// Returns the next received message frame
358 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { 351 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
359 RxMode::read_fd(self.info).await 352 RxMode::read_fd(&self.info).await
360 } 353 }
361 354
362 /// Split instance into separate portions: Tx(write), Rx(read), common properties 355 /// Split instance into separate portions: Tx(write), Rx(read), common properties
@@ -364,16 +357,14 @@ impl<'d> Can<'d> {
364 ( 357 (
365 CanTx { 358 CanTx {
366 _phantom: PhantomData, 359 _phantom: PhantomData,
367 info: self.info,
368 config: self.config, 360 config: self.config,
369 _mode: self._mode, 361 _mode: self._mode,
370 tx_guard: self.raii_guards.0, 362 info: TxInfoRef::new(&self.info),
371 }, 363 },
372 CanRx { 364 CanRx {
373 _phantom: PhantomData, 365 _phantom: PhantomData,
374 info: self.info,
375 _mode: self._mode, 366 _mode: self._mode,
376 rx_guard: self.raii_guards.1, 367 info: RxInfoRef::new(&self.info),
377 }, 368 },
378 Properties { 369 Properties {
379 info: self.properties.info, 370 info: self.properties.info,
@@ -385,10 +376,9 @@ impl<'d> Can<'d> {
385 Can { 376 Can {
386 _phantom: PhantomData, 377 _phantom: PhantomData,
387 config: tx.config, 378 config: tx.config,
388 info: tx.info,
389 _mode: rx._mode, 379 _mode: rx._mode,
390 properties: Properties::new(tx.info), 380 properties: Properties::new(&tx.info),
391 raii_guards: (tx.tx_guard, rx.rx_guard), 381 info: InfoRef::new(&tx.info),
392 } 382 }
393 } 383 }
394 384
@@ -398,7 +388,7 @@ impl<'d> Can<'d> {
398 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>, 388 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
399 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 389 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
400 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 390 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
401 BufferedCan::new(self.info, self._mode, tx_buf, rxb) 391 BufferedCan::new(&self.info, self._mode, tx_buf, rxb)
402 } 392 }
403 393
404 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers 394 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers
@@ -407,7 +397,7 @@ impl<'d> Can<'d> {
407 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>, 397 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
408 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>, 398 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
409 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 399 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
410 BufferedCanFd::new(self.info, self._mode, tx_buf, rxb) 400 BufferedCanFd::new(&self.info, self._mode, tx_buf, rxb)
411 } 401 }
412} 402}
413 403
@@ -420,12 +410,11 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame,
420/// Buffered FDCAN Instance 410/// Buffered FDCAN Instance
421pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 411pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
422 _phantom: PhantomData<&'d ()>, 412 _phantom: PhantomData<&'d ()>,
423 info: &'static Info,
424 _mode: OperatingMode, 413 _mode: OperatingMode,
425 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 414 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
426 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 415 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
427 properties: Properties, 416 properties: Properties,
428 _raii_guards: (TxGuard, RxGuard), 417 info: InfoRef,
429} 418}
430 419
431impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 420impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
@@ -437,15 +426,11 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
437 ) -> Self { 426 ) -> Self {
438 BufferedCan { 427 BufferedCan {
439 _phantom: PhantomData, 428 _phantom: PhantomData,
440 info,
441 _mode, 429 _mode,
442 tx_buf, 430 tx_buf,
443 rx_buf, 431 rx_buf,
444 properties: Properties::new(info), 432 properties: Properties::new(info),
445 _raii_guards: ( 433 info: InfoRef::new(info),
446 TxGuard::new(info.internal_operation),
447 RxGuard::new(info.internal_operation),
448 ),
449 } 434 }
450 .setup() 435 .setup()
451 } 436 }
@@ -486,8 +471,7 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
486 pub fn writer(&self) -> BufferedCanSender { 471 pub fn writer(&self) -> BufferedCanSender {
487 BufferedCanSender { 472 BufferedCanSender {
488 tx_buf: self.tx_buf.sender().into(), 473 tx_buf: self.tx_buf.sender().into(),
489 waker: self.info.tx_waker, 474 info: TxInfoRef::new(&self.info),
490 tx_guard: TxGuard::new(self.info.internal_operation),
491 } 475 }
492 } 476 }
493 477
@@ -495,7 +479,7 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
495 pub fn reader(&self) -> BufferedCanReceiver { 479 pub fn reader(&self) -> BufferedCanReceiver {
496 BufferedCanReceiver { 480 BufferedCanReceiver {
497 rx_buf: self.rx_buf.receiver().into(), 481 rx_buf: self.rx_buf.receiver().into(),
498 rx_guard: RxGuard::new(self.info.internal_operation), 482 info: RxInfoRef::new(&self.info),
499 } 483 }
500 } 484 }
501} 485}
@@ -515,12 +499,11 @@ pub type BufferedFdCanReceiver = super::common::BufferedReceiver<'static, FdEnve
515/// Buffered FDCAN Instance 499/// Buffered FDCAN Instance
516pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 500pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
517 _phantom: PhantomData<&'d ()>, 501 _phantom: PhantomData<&'d ()>,
518 info: &'static Info,
519 _mode: OperatingMode, 502 _mode: OperatingMode,
520 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 503 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
521 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 504 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
522 properties: Properties, 505 properties: Properties,
523 _raii_guards: (TxGuard, RxGuard), 506 info: InfoRef,
524} 507}
525 508
526impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 509impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
@@ -532,15 +515,11 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
532 ) -> Self { 515 ) -> Self {
533 BufferedCanFd { 516 BufferedCanFd {
534 _phantom: PhantomData, 517 _phantom: PhantomData,
535 info,
536 _mode, 518 _mode,
537 tx_buf, 519 tx_buf,
538 rx_buf, 520 rx_buf,
539 properties: Properties::new(info), 521 properties: Properties::new(info),
540 _raii_guards: ( 522 info: InfoRef::new(info),
541 TxGuard::new(info.internal_operation),
542 RxGuard::new(info.internal_operation),
543 ),
544 } 523 }
545 .setup() 524 .setup()
546 } 525 }
@@ -579,20 +558,17 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
579 558
580 /// Returns a sender that can be used for sending CAN frames. 559 /// Returns a sender that can be used for sending CAN frames.
581 pub fn writer(&self) -> BufferedFdCanSender { 560 pub fn writer(&self) -> BufferedFdCanSender {
582 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
583 BufferedFdCanSender { 561 BufferedFdCanSender {
584 tx_buf: self.tx_buf.sender().into(), 562 tx_buf: self.tx_buf.sender().into(),
585 waker: self.info.tx_waker, 563 info: TxInfoRef::new(&self.info),
586 tx_guard: TxGuard::new(self.info.internal_operation),
587 } 564 }
588 } 565 }
589 566
590 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 567 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
591 pub fn reader(&self) -> BufferedFdCanReceiver { 568 pub fn reader(&self) -> BufferedFdCanReceiver {
592 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
593 BufferedFdCanReceiver { 569 BufferedFdCanReceiver {
594 rx_buf: self.rx_buf.receiver().into(), 570 rx_buf: self.rx_buf.receiver().into(),
595 rx_guard: RxGuard::new(self.info.internal_operation), 571 info: RxInfoRef::new(&self.info),
596 } 572 }
597 } 573 }
598} 574}
@@ -600,9 +576,8 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
600/// FDCAN Rx only Instance 576/// FDCAN Rx only Instance
601pub struct CanRx<'d> { 577pub struct CanRx<'d> {
602 _phantom: PhantomData<&'d ()>, 578 _phantom: PhantomData<&'d ()>,
603 info: &'static Info,
604 _mode: OperatingMode, 579 _mode: OperatingMode,
605 rx_guard: RxGuard, 580 info: RxInfoRef,
606} 581}
607 582
608impl<'d> CanRx<'d> { 583impl<'d> CanRx<'d> {
@@ -620,10 +595,9 @@ impl<'d> CanRx<'d> {
620/// FDCAN Tx only Instance 595/// FDCAN Tx only Instance
621pub struct CanTx<'d> { 596pub struct CanTx<'d> {
622 _phantom: PhantomData<&'d ()>, 597 _phantom: PhantomData<&'d ()>,
623 info: &'static Info,
624 config: crate::can::fd::config::FdCanConfig, 598 config: crate::can::fd::config::FdCanConfig,
625 _mode: OperatingMode, 599 _mode: OperatingMode,
626 tx_guard: TxGuard, 600 info: TxInfoRef,
627} 601}
628 602
629impl<'c, 'd> CanTx<'d> { 603impl<'c, 'd> CanTx<'d> {
@@ -632,7 +606,7 @@ impl<'c, 'd> CanTx<'d> {
632 /// can be replaced, this call asynchronously waits for a frame to be successfully 606 /// can be replaced, this call asynchronously waits for a frame to be successfully
633 /// transmitted, then tries again. 607 /// transmitted, then tries again.
634 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 608 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
635 TxMode::write(self.info, frame).await 609 TxMode::write(&self.info, frame).await
636 } 610 }
637 611
638 /// Queues the message to be sent but exerts backpressure. If a lower-priority 612 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -640,7 +614,7 @@ impl<'c, 'd> CanTx<'d> {
640 /// can be replaced, this call asynchronously waits for a frame to be successfully 614 /// can be replaced, this call asynchronously waits for a frame to be successfully
641 /// transmitted, then tries again. 615 /// transmitted, then tries again.
642 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 616 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
643 TxMode::write_fd(self.info, frame).await 617 TxMode::write_fd(&self.info, frame).await
644 } 618 }
645} 619}
646 620
@@ -907,21 +881,56 @@ impl State {
907} 881}
908 882
909type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>; 883type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>;
910struct Info { 884pub(crate) struct Info {
911 regs: Registers, 885 regs: Registers,
912 interrupt0: crate::interrupt::Interrupt, 886 interrupt0: crate::interrupt::Interrupt,
913 _interrupt1: crate::interrupt::Interrupt, 887 _interrupt1: crate::interrupt::Interrupt,
914 tx_waker: fn(), 888 pub(crate) tx_waker: fn(),
915 internal_operation: fn(InternalOperation),
916 state: SharedState, 889 state: SharedState,
917} 890}
918 891
892impl Info {
893 pub(crate) fn adjust_reference_counter(&self, val: RefCountOp) {
894 self.state.lock(|s| {
895 let mut mut_state = s.borrow_mut();
896 match val {
897 RefCountOp::NotifySenderCreated => {
898 mut_state.sender_instance_count += 1;
899 }
900 RefCountOp::NotifySenderDestroyed => {
901 mut_state.sender_instance_count -= 1;
902 if 0 == mut_state.sender_instance_count {
903 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
904 }
905 }
906 RefCountOp::NotifyReceiverCreated => {
907 mut_state.receiver_instance_count += 1;
908 }
909 RefCountOp::NotifyReceiverDestroyed => {
910 mut_state.receiver_instance_count -= 1;
911 if 0 == mut_state.receiver_instance_count {
912 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
913 }
914 }
915 }
916 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
917 unsafe {
918 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
919 tx_pin.set_as_disconnected();
920 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
921 rx_pin.set_as_disconnected();
922 self.interrupt0.disable();
923 }
924 }
925 });
926 }
927}
928
919trait SealedInstance { 929trait SealedInstance {
920 const MSG_RAM_OFFSET: usize; 930 const MSG_RAM_OFFSET: usize;
921 931
922 fn info() -> &'static Info; 932 fn info() -> &'static Info;
923 fn registers() -> crate::can::fd::peripheral::Registers; 933 fn registers() -> crate::can::fd::peripheral::Registers;
924 fn internal_operation(val: InternalOperation);
925} 934}
926 935
927/// Instance trait 936/// Instance trait
@@ -943,41 +952,6 @@ macro_rules! impl_fdcan {
943 impl SealedInstance for peripherals::$inst { 952 impl SealedInstance for peripherals::$inst {
944 const MSG_RAM_OFFSET: usize = $msg_ram_offset; 953 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
945 954
946 fn internal_operation(val: InternalOperation) {
947 peripherals::$inst::info().state.lock(|s| {
948 let mut mut_state = s.borrow_mut();
949 match val {
950 InternalOperation::NotifySenderCreated => {
951 mut_state.sender_instance_count += 1;
952 }
953 InternalOperation::NotifySenderDestroyed => {
954 mut_state.sender_instance_count -= 1;
955 if ( 0 == mut_state.sender_instance_count) {
956 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
957 }
958 }
959 InternalOperation::NotifyReceiverCreated => {
960 mut_state.receiver_instance_count += 1;
961 }
962 InternalOperation::NotifyReceiverDestroyed => {
963 mut_state.receiver_instance_count -= 1;
964 if ( 0 == mut_state.receiver_instance_count) {
965 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
966 }
967 }
968 }
969 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
970 unsafe {
971 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
972 tx_pin.set_as_disconnected();
973 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
974 rx_pin.set_as_disconnected();
975 rcc::disable::<peripherals::$inst>();
976 }
977 }
978 });
979 }
980
981 fn info() -> &'static Info { 955 fn info() -> &'static Info {
982 956
983 static INFO: Info = Info { 957 static INFO: Info = Info {
@@ -985,7 +959,6 @@ macro_rules! impl_fdcan {
985 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ, 959 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
986 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ, 960 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
987 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend, 961 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
988 internal_operation: peripherals::$inst::internal_operation,
989 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())), 962 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
990 }; 963 };
991 &INFO 964 &INFO