aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-05-27 17:44:11 +0000
committerGitHub <[email protected]>2025-05-27 17:44:11 +0000
commit645883d8748995beb8b07f5cee93ac960f6d6a9f (patch)
tree195b4972d0242afb73f9df7b86a99bb85ff62195
parentaab043b0f3621ae5e1623e1eae2d77f47bc3ebe5 (diff)
parente0c5e93e78d48a2077578ac01d532066a638115a (diff)
Merge pull request #4223 from embedded-rust-iml/feature/drop-impl-for-stm32-fdcan
Cleanup Pins and RCC for FDCAN on STM32
-rw-r--r--embassy-stm32/src/can/fdcan.rs71
1 files changed, 62 insertions, 9 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 5467a40f1..a7815f79b 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -10,7 +10,7 @@ use 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;
13use crate::gpio::{AfType, OutputType, Pull, Speed}; 13use crate::gpio::{AfType, OutputType, Pull, SealedPin as _, Speed};
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral}; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peri}; 16use crate::{interrupt, peripherals, Peri};
@@ -187,13 +187,17 @@ impl<'d> CanConfigurator<'d> {
187 187
188 rcc::enable_and_reset::<T>(); 188 rcc::enable_and_reset::<T>();
189 189
190 let info = T::info();
191 let state = unsafe { T::mut_state() };
192 state.tx_pin_port = Some(tx.pin_port());
193 state.rx_pin_port = Some(rx.pin_port());
194 (info.internal_operation)(InternalOperation::NotifySenderCreated);
195 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
196
190 let mut config = crate::can::fd::config::FdCanConfig::default(); 197 let mut config = crate::can::fd::config::FdCanConfig::default();
191 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); 198 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
192 T::registers().into_config_mode(config); 199 T::registers().into_config_mode(config);
193 200
194 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
195 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
196
197 unsafe { 201 unsafe {
198 T::IT0Interrupt::unpend(); // Not unsafe 202 T::IT0Interrupt::unpend(); // Not unsafe
199 T::IT0Interrupt::enable(); 203 T::IT0Interrupt::enable();
@@ -204,8 +208,8 @@ impl<'d> CanConfigurator<'d> {
204 Self { 208 Self {
205 _phantom: PhantomData, 209 _phantom: PhantomData,
206 config, 210 config,
207 info: T::info(), 211 info,
208 state: T::state(), 212 state,
209 properties: Properties::new(T::info()), 213 properties: Properties::new(T::info()),
210 periph_clock: T::frequency(), 214 periph_clock: T::frequency(),
211 } 215 }
@@ -265,6 +269,8 @@ impl<'d> CanConfigurator<'d> {
265 } 269 }
266 }); 270 });
267 self.info.regs.into_mode(self.config, mode); 271 self.info.regs.into_mode(self.config, mode);
272 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
273 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
268 Can { 274 Can {
269 _phantom: PhantomData, 275 _phantom: PhantomData,
270 config: self.config, 276 config: self.config,
@@ -291,6 +297,13 @@ impl<'d> CanConfigurator<'d> {
291 } 297 }
292} 298}
293 299
300impl<'d> Drop for CanConfigurator<'d> {
301 fn drop(&mut self) {
302 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
303 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
304 }
305}
306
294/// FDCAN Instance 307/// FDCAN Instance
295pub struct Can<'d> { 308pub struct Can<'d> {
296 _phantom: PhantomData<&'d ()>, 309 _phantom: PhantomData<&'d ()>,
@@ -353,6 +366,8 @@ impl<'d> Can<'d> {
353 366
354 /// Split instance into separate portions: Tx(write), Rx(read), common properties 367 /// Split instance into separate portions: Tx(write), Rx(read), common properties
355 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) { 368 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
369 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
370 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
356 ( 371 (
357 CanTx { 372 CanTx {
358 _phantom: PhantomData, 373 _phantom: PhantomData,
@@ -367,11 +382,15 @@ impl<'d> Can<'d> {
367 state: self.state, 382 state: self.state,
368 _mode: self._mode, 383 _mode: self._mode,
369 }, 384 },
370 self.properties, 385 Properties {
386 info: self.properties.info,
387 },
371 ) 388 )
372 } 389 }
373 /// Join split rx and tx portions back together 390 /// Join split rx and tx portions back together
374 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self { 391 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
392 (tx.info.internal_operation)(InternalOperation::NotifySenderCreated);
393 (tx.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
375 Can { 394 Can {
376 _phantom: PhantomData, 395 _phantom: PhantomData,
377 config: tx.config, 396 config: tx.config,
@@ -401,6 +420,13 @@ impl<'d> Can<'d> {
401 } 420 }
402} 421}
403 422
423impl<'d> Drop for Can<'d> {
424 fn drop(&mut self) {
425 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
426 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
427 }
428}
429
404/// User supplied buffer for RX Buffering 430/// User supplied buffer for RX Buffering
405pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>; 431pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
406 432
@@ -426,6 +452,8 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
426 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 452 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
427 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 453 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
428 ) -> Self { 454 ) -> Self {
455 (info.internal_operation)(InternalOperation::NotifySenderCreated);
456 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
429 BufferedCan { 457 BufferedCan {
430 _phantom: PhantomData, 458 _phantom: PhantomData,
431 info, 459 info,
@@ -532,6 +560,8 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
532 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 560 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
533 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 561 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
534 ) -> Self { 562 ) -> Self {
563 (info.internal_operation)(InternalOperation::NotifySenderCreated);
564 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
535 BufferedCanFd { 565 BufferedCanFd {
536 _phantom: PhantomData, 566 _phantom: PhantomData,
537 info, 567 info,
@@ -627,6 +657,12 @@ impl<'d> CanRx<'d> {
627 } 657 }
628} 658}
629 659
660impl<'d> Drop for CanRx<'d> {
661 fn drop(&mut self) {
662 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
663 }
664}
665
630/// FDCAN Tx only Instance 666/// FDCAN Tx only Instance
631pub struct CanTx<'d> { 667pub struct CanTx<'d> {
632 _phantom: PhantomData<&'d ()>, 668 _phantom: PhantomData<&'d ()>,
@@ -654,6 +690,12 @@ impl<'c, 'd> CanTx<'d> {
654 } 690 }
655} 691}
656 692
693impl<'d> Drop for CanTx<'d> {
694 fn drop(&mut self) {
695 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
696 }
697}
698
657enum RxMode { 699enum RxMode {
658 NonBuffered(AtomicWaker), 700 NonBuffered(AtomicWaker),
659 ClassicBuffered(super::common::ClassicBufferedRxInner), 701 ClassicBuffered(super::common::ClassicBufferedRxInner),
@@ -898,6 +940,8 @@ struct State {
898 pub ns_per_timer_tick: u64, 940 pub ns_per_timer_tick: u64,
899 receiver_instance_count: usize, 941 receiver_instance_count: usize,
900 sender_instance_count: usize, 942 sender_instance_count: usize,
943 tx_pin_port: Option<u8>,
944 rx_pin_port: Option<u8>,
901 945
902 pub err_waker: AtomicWaker, 946 pub err_waker: AtomicWaker,
903} 947}
@@ -909,8 +953,10 @@ impl State {
909 tx_mode: TxMode::NonBuffered(AtomicWaker::new()), 953 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
910 ns_per_timer_tick: 0, 954 ns_per_timer_tick: 0,
911 err_waker: AtomicWaker::new(), 955 err_waker: AtomicWaker::new(),
912 receiver_instance_count: 1, 956 receiver_instance_count: 0,
913 sender_instance_count: 1, 957 sender_instance_count: 0,
958 tx_pin_port: None,
959 rx_pin_port: None,
914 } 960 }
915 } 961 }
916} 962}
@@ -998,6 +1044,13 @@ macro_rules! impl_fdcan {
998 } 1044 }
999 } 1045 }
1000 } 1046 }
1047 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
1048 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
1049 tx_pin.set_as_disconnected();
1050 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
1051 rx_pin.set_as_disconnected();
1052 rcc::disable::<peripherals::$inst>();
1053 }
1001 } 1054 }
1002 }); 1055 });
1003 } 1056 }