@@ -17,7 +17,7 @@ use self::registers::{Registers, RxFifo};
17
17
pub use super :: common:: { BufferedCanReceiver , BufferedCanSender } ;
18
18
use super :: frame:: { Envelope , Frame } ;
19
19
use super :: util;
20
- use crate :: can:: enums:: { BusError , TryReadError } ;
20
+ use crate :: can:: enums:: { BusError , InternalOperation , TryReadError } ;
21
21
use crate :: gpio:: { AfType , OutputType , Pull , Speed } ;
22
22
use crate :: interrupt:: typelevel:: Interrupt ;
23
23
use crate :: rcc:: { self , RccPeripheral } ;
@@ -685,22 +685,18 @@ impl<'d, const TX_BUF_SIZE: usize> BufferedCanTx<'d, TX_BUF_SIZE> {
685
685
686
686
/// Returns a sender that can be used for sending CAN frames.
687
687
pub fn writer ( & self ) -> BufferedCanSender {
688
+ ( self . info . internal_operation ) ( InternalOperation :: NotifySenderCreated ) ;
688
689
BufferedCanSender {
689
690
tx_buf : self . tx_buf . sender ( ) . into ( ) ,
690
691
waker : self . info . tx_waker ,
692
+ internal_operation : self . info . internal_operation ,
691
693
}
692
694
}
693
695
}
694
696
695
697
impl < ' d , const TX_BUF_SIZE : usize > Drop for BufferedCanTx < ' d , TX_BUF_SIZE > {
696
698
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 ) ;
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
822
/// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
827
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
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
840
840
impl < ' d , const RX_BUF_SIZE : usize > Drop for BufferedCanRx < ' d , RX_BUF_SIZE > {
841
841
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 ) ;
849
843
}
850
844
}
851
845
@@ -1048,6 +1042,8 @@ pub(crate) struct State {
1048
1042
pub ( crate ) rx_mode : RxMode ,
1049
1043
pub ( crate ) tx_mode : TxMode ,
1050
1044
pub err_waker : AtomicWaker ,
1045
+ receiver_instance_count : usize ,
1046
+ sender_instance_count : usize ,
1051
1047
}
1052
1048
1053
1049
impl State {
@@ -1056,6 +1052,8 @@ impl State {
1056
1052
rx_mode : RxMode :: NonBuffered ( AtomicWaker :: new ( ) ) ,
1057
1053
tx_mode : TxMode :: NonBuffered ( AtomicWaker :: new ( ) ) ,
1058
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
1065
rx1_interrupt : crate :: interrupt:: Interrupt ,
1068
1066
sce_interrupt : crate :: interrupt:: Interrupt ,
1069
1067
tx_waker : fn ( ) ,
1068
+ internal_operation : fn ( InternalOperation ) ,
1070
1069
1071
1070
/// The total number of filter banks available to the instance.
1072
1071
///
@@ -1079,6 +1078,7 @@ trait SealedInstance {
1079
1078
fn regs ( ) -> crate :: pac:: can:: Can ;
1080
1079
fn state ( ) -> & ' static State ;
1081
1080
unsafe fn mut_state ( ) -> & ' static mut State ;
1081
+ fn internal_operation ( val : InternalOperation ) ;
1082
1082
}
1083
1083
1084
1084
/// CAN instance trait.
@@ -1136,6 +1136,7 @@ foreach_peripheral!(
1136
1136
rx1_interrupt: crate :: _generated:: peripheral_interrupts:: $inst:: RX1 :: IRQ ,
1137
1137
sce_interrupt: crate :: _generated:: peripheral_interrupts:: $inst:: SCE :: IRQ ,
1138
1138
tx_waker: crate :: _generated:: peripheral_interrupts:: $inst:: TX :: pend,
1139
+ internal_operation: peripherals:: $inst:: internal_operation,
1139
1140
num_filter_banks: peripherals:: $inst:: NUM_FILTER_BANKS ,
1140
1141
} ;
1141
1142
& INFO
@@ -1151,6 +1152,37 @@ foreach_peripheral!(
1151
1152
fn state( ) -> & ' static State {
1152
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
1188
impl Instance for peripherals:: $inst {
0 commit comments