mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-30 13:50:37 +00:00
Merge pull request #4223 from embedded-rust-iml/feature/drop-impl-for-stm32-fdcan
Cleanup Pins and RCC for FDCAN on STM32
This commit is contained in:
commit
645883d874
@ -10,7 +10,7 @@ use embassy_sync::channel::Channel;
|
|||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use crate::can::fd::peripheral::Registers;
|
use crate::can::fd::peripheral::Registers;
|
||||||
use crate::gpio::{AfType, OutputType, Pull, Speed};
|
use crate::gpio::{AfType, OutputType, Pull, SealedPin as _, Speed};
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::rcc::{self, RccPeripheral};
|
use crate::rcc::{self, RccPeripheral};
|
||||||
use crate::{interrupt, peripherals, Peri};
|
use crate::{interrupt, peripherals, Peri};
|
||||||
@ -187,13 +187,17 @@ impl<'d> CanConfigurator<'d> {
|
|||||||
|
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
|
|
||||||
|
let info = T::info();
|
||||||
|
let state = unsafe { T::mut_state() };
|
||||||
|
state.tx_pin_port = Some(tx.pin_port());
|
||||||
|
state.rx_pin_port = Some(rx.pin_port());
|
||||||
|
(info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
|
|
||||||
let mut config = crate::can::fd::config::FdCanConfig::default();
|
let mut config = crate::can::fd::config::FdCanConfig::default();
|
||||||
config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
|
config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
|
||||||
T::registers().into_config_mode(config);
|
T::registers().into_config_mode(config);
|
||||||
|
|
||||||
rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
|
|
||||||
tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
T::IT0Interrupt::unpend(); // Not unsafe
|
T::IT0Interrupt::unpend(); // Not unsafe
|
||||||
T::IT0Interrupt::enable();
|
T::IT0Interrupt::enable();
|
||||||
@ -204,8 +208,8 @@ impl<'d> CanConfigurator<'d> {
|
|||||||
Self {
|
Self {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
config,
|
config,
|
||||||
info: T::info(),
|
info,
|
||||||
state: T::state(),
|
state,
|
||||||
properties: Properties::new(T::info()),
|
properties: Properties::new(T::info()),
|
||||||
periph_clock: T::frequency(),
|
periph_clock: T::frequency(),
|
||||||
}
|
}
|
||||||
@ -265,6 +269,8 @@ impl<'d> CanConfigurator<'d> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.info.regs.into_mode(self.config, mode);
|
self.info.regs.into_mode(self.config, mode);
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
Can {
|
Can {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
config: self.config,
|
config: self.config,
|
||||||
@ -291,6 +297,13 @@ impl<'d> CanConfigurator<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for CanConfigurator<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// FDCAN Instance
|
/// FDCAN Instance
|
||||||
pub struct Can<'d> {
|
pub struct Can<'d> {
|
||||||
_phantom: PhantomData<&'d ()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
@ -353,6 +366,8 @@ impl<'d> Can<'d> {
|
|||||||
|
|
||||||
/// Split instance into separate portions: Tx(write), Rx(read), common properties
|
/// Split instance into separate portions: Tx(write), Rx(read), common properties
|
||||||
pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
|
pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
(
|
(
|
||||||
CanTx {
|
CanTx {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
@ -367,11 +382,15 @@ impl<'d> Can<'d> {
|
|||||||
state: self.state,
|
state: self.state,
|
||||||
_mode: self._mode,
|
_mode: self._mode,
|
||||||
},
|
},
|
||||||
self.properties,
|
Properties {
|
||||||
|
info: self.properties.info,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/// Join split rx and tx portions back together
|
/// Join split rx and tx portions back together
|
||||||
pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
|
pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
|
||||||
|
(tx.info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(tx.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
Can {
|
Can {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
config: tx.config,
|
config: tx.config,
|
||||||
@ -401,6 +420,13 @@ impl<'d> Can<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for Can<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// User supplied buffer for RX Buffering
|
/// User supplied buffer for RX Buffering
|
||||||
pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
|
pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
|
||||||
|
|
||||||
@ -426,6 +452,8 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
|
|||||||
tx_buf: &'static TxBuf<TX_BUF_SIZE>,
|
tx_buf: &'static TxBuf<TX_BUF_SIZE>,
|
||||||
rx_buf: &'static RxBuf<RX_BUF_SIZE>,
|
rx_buf: &'static RxBuf<RX_BUF_SIZE>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
(info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
BufferedCan {
|
BufferedCan {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info,
|
info,
|
||||||
@ -532,6 +560,8 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
|
|||||||
tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
|
tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
|
||||||
rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
|
rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
(info.internal_operation)(InternalOperation::NotifySenderCreated);
|
||||||
|
(info.internal_operation)(InternalOperation::NotifyReceiverCreated);
|
||||||
BufferedCanFd {
|
BufferedCanFd {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
info,
|
info,
|
||||||
@ -627,6 +657,12 @@ impl<'d> CanRx<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for CanRx<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// FDCAN Tx only Instance
|
/// FDCAN Tx only Instance
|
||||||
pub struct CanTx<'d> {
|
pub struct CanTx<'d> {
|
||||||
_phantom: PhantomData<&'d ()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
@ -654,6 +690,12 @@ impl<'c, 'd> CanTx<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for CanTx<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
(self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum RxMode {
|
enum RxMode {
|
||||||
NonBuffered(AtomicWaker),
|
NonBuffered(AtomicWaker),
|
||||||
ClassicBuffered(super::common::ClassicBufferedRxInner),
|
ClassicBuffered(super::common::ClassicBufferedRxInner),
|
||||||
@ -898,6 +940,8 @@ struct State {
|
|||||||
pub ns_per_timer_tick: u64,
|
pub ns_per_timer_tick: u64,
|
||||||
receiver_instance_count: usize,
|
receiver_instance_count: usize,
|
||||||
sender_instance_count: usize,
|
sender_instance_count: usize,
|
||||||
|
tx_pin_port: Option<u8>,
|
||||||
|
rx_pin_port: Option<u8>,
|
||||||
|
|
||||||
pub err_waker: AtomicWaker,
|
pub err_waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
@ -909,8 +953,10 @@ impl State {
|
|||||||
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
|
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
|
||||||
ns_per_timer_tick: 0,
|
ns_per_timer_tick: 0,
|
||||||
err_waker: AtomicWaker::new(),
|
err_waker: AtomicWaker::new(),
|
||||||
receiver_instance_count: 1,
|
receiver_instance_count: 0,
|
||||||
sender_instance_count: 1,
|
sender_instance_count: 0,
|
||||||
|
tx_pin_port: None,
|
||||||
|
rx_pin_port: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,6 +1044,13 @@ macro_rules! impl_fdcan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
|
||||||
|
let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
|
||||||
|
tx_pin.set_as_disconnected();
|
||||||
|
let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
|
||||||
|
rx_pin.set_as_disconnected();
|
||||||
|
rcc::disable::<peripherals::$inst>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user