@@ -17,7 +17,7 @@ use self::registers::{Registers, RxFifo};
1717pub use super :: common:: { BufferedCanReceiver , BufferedCanSender } ;
1818use super :: frame:: { Envelope , Frame } ;
1919use super :: util;
20- use crate :: can:: enums:: { BusError , TryReadError } ;
20+ use crate :: can:: enums:: { BusError , InternalOperation , TryReadError } ;
2121use crate :: gpio:: { AfType , OutputType , Pull , Speed } ;
2222use crate :: interrupt:: typelevel:: Interrupt ;
2323use crate :: rcc:: { self , RccPeripheral } ;
@@ -685,22 +685,18 @@ impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
685685
686686 /// Returns a sender that can be used for sending CAN frames.
687687 pub fn writer ( & self ) -> BufferedCanSender {
688+ ( self . info . internal_operation ) ( InternalOperation :: NotifySenderCreated ) ;
688689 BufferedCanSender {
689690 tx_buf : self . tx_buf . sender ( ) . into ( ) ,
690691 waker : self . info . tx_waker ,
692+ internal_operation : self . info . internal_operation ,
691693 }
692694 }
693695}
694696
695697impl < ' d , const TX_BUF_SIZE : usize > Drop for BufferedCanTx < ' d , TX_BUF_SIZE > {
696698 fn drop ( & mut self ) {
697- critical_section:: with ( |_| {
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- } ) ;
699+ ( self . info . internal_operation ) ( InternalOperation :: NotifySenderDestroyed ) ;
704700 }
705701}
706702
@@ -825,7 +821,11 @@ impl<'d, const RX_BUF_SIZE: usize> BufferedCanRx<'d, RX_BUF_SIZE> {
825821
826822 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
827823 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+ }
829829 }
830830
831831 /// 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> {
839839
840840impl < ' d , const RX_BUF_SIZE : usize > Drop for BufferedCanRx < ' d , RX_BUF_SIZE > {
841841 fn drop ( & mut self ) {
842- critical_section:: with ( |_| {
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- } ) ;
842+ ( self . info . internal_operation ) ( InternalOperation :: NotifyReceiverDestroyed ) ;
849843 }
850844}
851845
@@ -1048,6 +1042,8 @@ pub(crate) struct State {
10481042 pub ( crate ) rx_mode : RxMode ,
10491043 pub ( crate ) tx_mode : TxMode ,
10501044 pub err_waker : AtomicWaker ,
1045+ receiver_instance_count : usize ,
1046+ sender_instance_count : usize ,
10511047}
10521048
10531049impl State {
@@ -1056,6 +1052,8 @@ impl State {
10561052 rx_mode : RxMode :: NonBuffered ( AtomicWaker :: new ( ) ) ,
10571053 tx_mode : TxMode :: NonBuffered ( AtomicWaker :: new ( ) ) ,
10581054 err_waker : AtomicWaker :: new ( ) ,
1055+ receiver_instance_count : 1 ,
1056+ sender_instance_count : 1 ,
10591057 }
10601058 }
10611059}
@@ -1067,6 +1065,7 @@ pub(crate) struct Info {
10671065 rx1_interrupt : crate :: interrupt:: Interrupt ,
10681066 sce_interrupt : crate :: interrupt:: Interrupt ,
10691067 tx_waker : fn ( ) ,
1068+ internal_operation : fn ( InternalOperation ) ,
10701069
10711070 /// The total number of filter banks available to the instance.
10721071 ///
@@ -1079,6 +1078,7 @@ trait SealedInstance {
10791078 fn regs ( ) -> crate :: pac:: can:: Can ;
10801079 fn state ( ) -> & ' static State ;
10811080 unsafe fn mut_state ( ) -> & ' static mut State ;
1081+ fn internal_operation ( val : InternalOperation ) ;
10821082}
10831083
10841084/// CAN instance trait.
@@ -1136,6 +1136,7 @@ foreach_peripheral!(
11361136 rx1_interrupt: crate :: _generated:: peripheral_interrupts:: $inst:: RX1 :: IRQ ,
11371137 sce_interrupt: crate :: _generated:: peripheral_interrupts:: $inst:: SCE :: IRQ ,
11381138 tx_waker: crate :: _generated:: peripheral_interrupts:: $inst:: TX :: pend,
1139+ internal_operation: peripherals:: $inst:: internal_operation,
11391140 num_filter_banks: peripherals:: $inst:: NUM_FILTER_BANKS ,
11401141 } ;
11411142 & INFO
@@ -1151,6 +1152,37 @@ foreach_peripheral!(
11511152 fn state( ) -> & ' static State {
11521153 unsafe { peripherals:: $inst:: mut_state( ) }
11531154 }
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+ }
11541186 }
11551187
11561188 impl Instance for peripherals:: $inst {
0 commit comments