Remove the OperatingMode typestates
Instead have two explcit types(without the mode generic arg)types: - One for config - One for all operating modes
This commit is contained in:
parent
5ad291b708
commit
eafa90cd07
6 changed files with 133 additions and 162 deletions
|
@ -481,6 +481,19 @@ impl Registers {
|
||||||
while self.regs.cccr().read().init() == true {}
|
while self.regs.cccr().read().init() == true {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves out of ConfigMode and into specified mode
|
||||||
|
#[inline]
|
||||||
|
pub fn into_mode(mut self, config: FdCanConfig, mode: crate::can::_version::FdcanOperatingMode) {
|
||||||
|
match mode {
|
||||||
|
crate::can::FdcanOperatingMode::InternalLoopbackMode => self.set_loopback_mode(LoopbackMode::Internal),
|
||||||
|
crate::can::FdcanOperatingMode::ExternalLoopbackMode => self.set_loopback_mode(LoopbackMode::External),
|
||||||
|
crate::can::FdcanOperatingMode::NormalOperationMode => self.set_normal_operations(true),
|
||||||
|
crate::can::FdcanOperatingMode::RestrictedOperationMode => self.set_restricted_operations(true),
|
||||||
|
crate::can::FdcanOperatingMode::BusMonitoringMode => self.set_bus_monitoring_mode(true),
|
||||||
|
}
|
||||||
|
self.leave_init_mode(config);
|
||||||
|
}
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into InternalLoopbackMode
|
/// Moves out of ConfigMode and into InternalLoopbackMode
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_internal_loopback(mut self, config: FdCanConfig) {
|
pub fn into_internal_loopback(mut self, config: FdCanConfig) {
|
||||||
|
|
|
@ -100,75 +100,50 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT1Interrupt> for IT1Interrup
|
||||||
unsafe fn on_interrupt() {}
|
unsafe fn on_interrupt() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows for Transmit Operations
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub trait Transmit {}
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
/// Allows for Receive Operations
|
/// Different operating modes
|
||||||
pub trait Receive {}
|
pub enum FdcanOperatingMode {
|
||||||
|
//PoweredDownMode,
|
||||||
/// Allows for the FdCan Instance to be released or to enter ConfigMode
|
//ConfigMode,
|
||||||
pub struct PoweredDownMode;
|
/// This mode can be used for a “Hot Selftest”, meaning the FDCAN can be tested without
|
||||||
/// Allows for the configuration for the Instance
|
/// affecting a running CAN system connected to the FDCAN_TX and FDCAN_RX pins. In this
|
||||||
pub struct ConfigMode;
|
/// mode, FDCAN_RX pin is disconnected from the FDCAN and FDCAN_TX pin is held
|
||||||
/// This mode can be used for a “Hot Selftest”, meaning the FDCAN can be tested without
|
/// recessive.
|
||||||
/// affecting a running CAN system connected to the FDCAN_TX and FDCAN_RX pins. In this
|
InternalLoopbackMode,
|
||||||
/// mode, FDCAN_RX pin is disconnected from the FDCAN and FDCAN_TX pin is held
|
/// This mode is provided for hardware self-test. To be independent from external stimulation,
|
||||||
/// recessive.
|
/// the FDCAN ignores acknowledge errors (recessive bit sampled in the acknowledge slot of a
|
||||||
pub struct InternalLoopbackMode;
|
/// data / remote frame) in Loop Back mode. In this mode the FDCAN performs an internal
|
||||||
impl Transmit for InternalLoopbackMode {}
|
/// feedback from its transmit output to its receive input. The actual value of the FDCAN_RX
|
||||||
impl Receive for InternalLoopbackMode {}
|
/// input pin is disregarded by the FDCAN. The transmitted messages can be monitored at the
|
||||||
/// This mode is provided for hardware self-test. To be independent from external stimulation,
|
/// FDCAN_TX transmit pin.
|
||||||
/// the FDCAN ignores acknowledge errors (recessive bit sampled in the acknowledge slot of a
|
ExternalLoopbackMode,
|
||||||
/// data / remote frame) in Loop Back mode. In this mode the FDCAN performs an internal
|
/// The normal use of the Fdcan instance after configurations
|
||||||
/// feedback from its transmit output to its receive input. The actual value of the FDCAN_RX
|
NormalOperationMode,
|
||||||
/// input pin is disregarded by the FDCAN. The transmitted messages can be monitored at the
|
/// In Restricted operation mode the node is able to receive data and remote frames and to give
|
||||||
/// FDCAN_TX transmit pin.
|
/// acknowledge to valid frames, but it does not send data frames, remote frames, active error
|
||||||
pub struct ExternalLoopbackMode;
|
/// frames, or overload frames. In case of an error condition or overload condition, it does not
|
||||||
impl Transmit for ExternalLoopbackMode {}
|
/// send dominant bits, instead it waits for the occurrence of bus idle condition to resynchronize
|
||||||
impl Receive for ExternalLoopbackMode {}
|
/// itself to the CAN communication. The error counters for transmit and receive are frozen while
|
||||||
/// The normal use of the FdCan instance after configurations
|
/// error logging (can_errors) is active. TODO: automatically enter in this mode?
|
||||||
pub struct NormalOperationMode;
|
RestrictedOperationMode,
|
||||||
impl Transmit for NormalOperationMode {}
|
/// In Bus monitoring mode (for more details refer to ISO11898-1, 10.12 Bus monitoring),
|
||||||
impl Receive for NormalOperationMode {}
|
/// the FDCAN is able to receive valid data frames and valid remote frames, but cannot start a
|
||||||
/// In Restricted operation mode the node is able to receive data and remote frames and to give
|
/// transmission. In this mode, it sends only recessive bits on the CAN bus. If the FDCAN is
|
||||||
/// acknowledge to valid frames, but it does not send data frames, remote frames, active error
|
/// required to send a dominant bit (ACK bit, overload flag, active error flag), the bit is
|
||||||
/// frames, or overload frames. In case of an error condition or overload condition, it does not
|
/// rerouted internally so that the FDCAN can monitor it, even if the CAN bus remains in recessive
|
||||||
/// send dominant bits, instead it waits for the occurrence of bus idle condition to resynchronize
|
/// state. In Bus monitoring mode the TXBRP register is held in reset state. The Bus monitoring
|
||||||
/// itself to the CAN communication. The error counters for transmit and receive are frozen while
|
/// mode can be used to analyze the traffic on a CAN bus without affecting it by the transmission
|
||||||
/// error logging (can_errors) is active. TODO: automatically enter in this mode?
|
/// of dominant bits.
|
||||||
pub struct RestrictedOperationMode;
|
BusMonitoringMode,
|
||||||
impl Receive for RestrictedOperationMode {}
|
//TestMode,
|
||||||
/// In Bus monitoring mode (for more details refer to ISO11898-1, 10.12 Bus monitoring),
|
}
|
||||||
/// the FDCAN is able to receive valid data frames and valid remote frames, but cannot start a
|
|
||||||
/// transmission. In this mode, it sends only recessive bits on the CAN bus. If the FDCAN is
|
|
||||||
/// required to send a dominant bit (ACK bit, overload flag, active error flag), the bit is
|
|
||||||
/// rerouted internally so that the FDCAN can monitor it, even if the CAN bus remains in recessive
|
|
||||||
/// state. In Bus monitoring mode the TXBRP register is held in reset state. The Bus monitoring
|
|
||||||
/// mode can be used to analyze the traffic on a CAN bus without affecting it by the transmission
|
|
||||||
/// of dominant bits.
|
|
||||||
pub struct BusMonitoringMode;
|
|
||||||
impl Receive for BusMonitoringMode {}
|
|
||||||
/// Test mode must be used for production tests or self test only. The software control for
|
|
||||||
/// FDCAN_TX pin interferes with all CAN protocol functions. It is not recommended to use test
|
|
||||||
/// modes for application.
|
|
||||||
pub struct TestMode;
|
|
||||||
|
|
||||||
/// Operating modes trait
|
|
||||||
pub trait FdcanOperatingMode {}
|
|
||||||
impl FdcanOperatingMode for PoweredDownMode {}
|
|
||||||
impl FdcanOperatingMode for ConfigMode {}
|
|
||||||
impl FdcanOperatingMode for InternalLoopbackMode {}
|
|
||||||
impl FdcanOperatingMode for ExternalLoopbackMode {}
|
|
||||||
impl FdcanOperatingMode for NormalOperationMode {}
|
|
||||||
impl FdcanOperatingMode for RestrictedOperationMode {}
|
|
||||||
impl FdcanOperatingMode for BusMonitoringMode {}
|
|
||||||
impl FdcanOperatingMode for TestMode {}
|
|
||||||
|
|
||||||
/// FDCAN Instance
|
/// FDCAN Instance
|
||||||
pub struct Fdcan<'d, T: Instance, M: FdcanOperatingMode> {
|
pub struct FdcanConfigurator<'d, T: Instance> {
|
||||||
config: crate::can::fd::config::FdCanConfig,
|
config: crate::can::fd::config::FdCanConfig,
|
||||||
/// Reference to internals.
|
/// Reference to internals.
|
||||||
instance: FdcanInstance<'d, T>,
|
instance: FdcanInstance<'d, T>,
|
||||||
_mode: PhantomData<M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 {
|
fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 {
|
||||||
|
@ -186,7 +161,7 @@ fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
|
impl<'d, T: Instance> FdcanConfigurator<'d, T> {
|
||||||
/// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
|
/// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
|
||||||
/// You must call [Fdcan::enable_non_blocking] to use the peripheral.
|
/// You must call [Fdcan::enable_non_blocking] to use the peripheral.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -196,7 +171,7 @@ impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
|
||||||
_irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
|
_irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
|
||||||
+ interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
|
+ interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
|
||||||
+ 'd,
|
+ 'd,
|
||||||
) -> Fdcan<'d, T, ConfigMode> {
|
) -> FdcanConfigurator<'d, T> {
|
||||||
into_ref!(peri, rx, tx);
|
into_ref!(peri, rx, tx);
|
||||||
|
|
||||||
rx.set_as_af(rx.af_num(), AFType::Input);
|
rx.set_as_af(rx.af_num(), AFType::Input);
|
||||||
|
@ -245,7 +220,6 @@ impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
|
||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
instance: FdcanInstance(peri),
|
instance: FdcanInstance(peri),
|
||||||
_mode: PhantomData::<ConfigMode>,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +246,7 @@ impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
|
||||||
self.config = self.config.set_nominal_bit_timing(nbtr);
|
self.config = self.config.set_nominal_bit_timing(nbtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configures the bit timings for VBR data calculated from supplied bitrate.
|
/// Configures the bit timings for VBR data calculated from supplied bitrate. This also sets confit to allow can FD and VBR
|
||||||
pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) {
|
pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) {
|
||||||
let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap();
|
let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap();
|
||||||
// Note, used existing calcluation for normal(non-VBR) bitrate, appears to work for 250k/1M
|
// Note, used existing calcluation for normal(non-VBR) bitrate, appears to work for 250k/1M
|
||||||
|
@ -312,51 +286,47 @@ impl<'d, T: Instance> Fdcan<'d, T, ConfigMode> {
|
||||||
T::registers().msg_ram_mut().filters.flesa[i].activate(*f);
|
T::registers().msg_ram_mut().filters.flesa[i].activate(*f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start in mode.
|
||||||
|
pub fn start(self, mode: FdcanOperatingMode) -> Fdcan<'d, T> {
|
||||||
|
let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit);
|
||||||
|
critical_section::with(|_| unsafe {
|
||||||
|
T::mut_state().ns_per_timer_tick = ns_per_timer_tick;
|
||||||
|
});
|
||||||
|
T::registers().into_mode(self.config, mode);
|
||||||
|
let ret = Fdcan {
|
||||||
|
config: self.config,
|
||||||
|
instance: self.instance,
|
||||||
|
_mode: mode,
|
||||||
|
};
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start, entering mode. Does same as start(mode)
|
||||||
|
pub fn into_normal_mode(self) -> Fdcan<'d, T> {
|
||||||
|
self.start(FdcanOperatingMode::NormalOperationMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start, entering mode. Does same as start(mode)
|
||||||
|
pub fn into_internal_loopback_mode(self) -> Fdcan<'d, T> {
|
||||||
|
self.start(FdcanOperatingMode::InternalLoopbackMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start, entering mode. Does same as start(mode)
|
||||||
|
pub fn into_external_loopback_mode(self) -> Fdcan<'d, T> {
|
||||||
|
self.start(FdcanOperatingMode::ExternalLoopbackMode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_transition {
|
/// FDCAN Instance
|
||||||
($from_mode:ident, $to_mode:ident, $name:ident, $func: ident) => {
|
pub struct Fdcan<'d, T: Instance> {
|
||||||
impl<'d, T: Instance> Fdcan<'d, T, $from_mode> {
|
config: crate::can::fd::config::FdCanConfig,
|
||||||
/// Transition from $from_mode:ident mode to $to_mode:ident mode
|
/// Reference to internals.
|
||||||
pub fn $name(self) -> Fdcan<'d, T, $to_mode> {
|
instance: FdcanInstance<'d, T>,
|
||||||
let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit);
|
_mode: FdcanOperatingMode,
|
||||||
critical_section::with(|_| unsafe {
|
|
||||||
T::mut_state().ns_per_timer_tick = ns_per_timer_tick;
|
|
||||||
});
|
|
||||||
T::registers().$func(self.config);
|
|
||||||
let ret = Fdcan {
|
|
||||||
config: self.config,
|
|
||||||
instance: self.instance,
|
|
||||||
_mode: PhantomData::<$to_mode>,
|
|
||||||
};
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_transition!(PoweredDownMode, ConfigMode, into_config_mode, into_config_mode);
|
impl<'d, T: Instance> Fdcan<'d, T> {
|
||||||
impl_transition!(InternalLoopbackMode, ConfigMode, into_config_mode, into_config_mode);
|
|
||||||
|
|
||||||
impl_transition!(ConfigMode, NormalOperationMode, into_normal_mode, into_normal);
|
|
||||||
impl_transition!(
|
|
||||||
ConfigMode,
|
|
||||||
ExternalLoopbackMode,
|
|
||||||
into_external_loopback_mode,
|
|
||||||
into_external_loopback
|
|
||||||
);
|
|
||||||
impl_transition!(
|
|
||||||
ConfigMode,
|
|
||||||
InternalLoopbackMode,
|
|
||||||
into_internal_loopback_mode,
|
|
||||||
into_internal_loopback
|
|
||||||
);
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: FdcanOperatingMode> Fdcan<'d, T, M>
|
|
||||||
where
|
|
||||||
M: Transmit,
|
|
||||||
M: Receive,
|
|
||||||
{
|
|
||||||
/// Flush one of the TX mailboxes.
|
/// Flush one of the TX mailboxes.
|
||||||
pub async fn flush(&self, idx: usize) {
|
pub async fn flush(&self, idx: usize) {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
|
@ -401,18 +371,8 @@ where
|
||||||
T::state().rx_mode.read_fd::<T>().await
|
T::state().rx_mode.read_fd::<T>().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join split rx and tx portions back together
|
|
||||||
pub fn join(tx: FdcanTx<'d, T, M>, rx: FdcanRx<'d, T, M>) -> Self {
|
|
||||||
Fdcan {
|
|
||||||
config: tx.config,
|
|
||||||
//_instance2: T::regs(),
|
|
||||||
instance: tx._instance,
|
|
||||||
_mode: rx._mode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Split instance into separate Tx(write) and Rx(read) portions
|
/// Split instance into separate Tx(write) and Rx(read) portions
|
||||||
pub fn split(self) -> (FdcanTx<'d, T, M>, FdcanRx<'d, T, M>) {
|
pub fn split(self) -> (FdcanTx<'d, T>, FdcanRx<'d, T>) {
|
||||||
(
|
(
|
||||||
FdcanTx {
|
FdcanTx {
|
||||||
config: self.config,
|
config: self.config,
|
||||||
|
@ -427,12 +387,22 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Join split rx and tx portions back together
|
||||||
|
pub fn join(tx: FdcanTx<'d, T>, rx: FdcanRx<'d, T>) -> Self {
|
||||||
|
Fdcan {
|
||||||
|
config: tx.config,
|
||||||
|
//_instance2: T::regs(),
|
||||||
|
instance: tx._instance,
|
||||||
|
_mode: rx._mode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return a buffered instance of driver without CAN FD support. User must supply Buffers
|
/// Return a buffered instance of driver without CAN FD support. User must supply Buffers
|
||||||
pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
|
pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
|
||||||
&self,
|
&self,
|
||||||
tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
|
tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
|
||||||
rxb: &'static mut RxBuf<RX_BUF_SIZE>,
|
rxb: &'static mut RxBuf<RX_BUF_SIZE>,
|
||||||
) -> BufferedCan<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE> {
|
) -> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> {
|
||||||
BufferedCan::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb)
|
BufferedCan::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +411,7 @@ where
|
||||||
&self,
|
&self,
|
||||||
tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
|
tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
|
||||||
rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
|
rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
|
||||||
) -> BufferedCanFd<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE> {
|
) -> BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> {
|
||||||
BufferedCanFd::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb)
|
BufferedCanFd::new(PhantomData::<T>, T::regs(), self._mode, tx_buf, rxb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,24 +423,21 @@ pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (Classi
|
||||||
pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>;
|
pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>;
|
||||||
|
|
||||||
/// Buffered FDCAN Instance
|
/// Buffered FDCAN Instance
|
||||||
#[allow(dead_code)]
|
pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
|
||||||
pub struct BufferedCan<'d, T: Instance, M: FdcanOperatingMode, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
|
|
||||||
_instance1: PhantomData<T>,
|
_instance1: PhantomData<T>,
|
||||||
_instance2: &'d crate::pac::can::Fdcan,
|
_instance2: &'d crate::pac::can::Fdcan,
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M: Transmit, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
||||||
BufferedCan<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE>
|
BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
where
|
|
||||||
M: FdcanOperatingMode,
|
|
||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
_instance1: PhantomData<T>,
|
_instance1: PhantomData<T>,
|
||||||
_instance2: &'d crate::pac::can::Fdcan,
|
_instance2: &'d crate::pac::can::Fdcan,
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
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 {
|
||||||
|
@ -511,10 +478,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop
|
||||||
for BufferedCan<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE>
|
for BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
where
|
|
||||||
M: FdcanOperatingMode,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
|
@ -531,24 +496,21 @@ pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (FdFr
|
||||||
pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
|
pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
|
||||||
|
|
||||||
/// Buffered FDCAN Instance
|
/// Buffered FDCAN Instance
|
||||||
#[allow(dead_code)]
|
pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
|
||||||
pub struct BufferedCanFd<'d, T: Instance, M: FdcanOperatingMode, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
|
|
||||||
_instance1: PhantomData<T>,
|
_instance1: PhantomData<T>,
|
||||||
_instance2: &'d crate::pac::can::Fdcan,
|
_instance2: &'d crate::pac::can::Fdcan,
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M: Transmit, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
||||||
BufferedCanFd<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE>
|
BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
where
|
|
||||||
M: FdcanOperatingMode,
|
|
||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
_instance1: PhantomData<T>,
|
_instance1: PhantomData<T>,
|
||||||
_instance2: &'d crate::pac::can::Fdcan,
|
_instance2: &'d crate::pac::can::Fdcan,
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
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 {
|
||||||
|
@ -589,10 +551,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop
|
||||||
for BufferedCanFd<'d, T, M, TX_BUF_SIZE, RX_BUF_SIZE>
|
for BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
where
|
|
||||||
M: FdcanOperatingMode,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
|
@ -603,21 +563,20 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FDCAN Rx only Instance
|
/// FDCAN Rx only Instance
|
||||||
#[allow(dead_code)]
|
pub struct FdcanRx<'d, T: Instance> {
|
||||||
pub struct FdcanRx<'d, T: Instance, M: Receive> {
|
|
||||||
_instance1: PhantomData<T>,
|
_instance1: PhantomData<T>,
|
||||||
_instance2: &'d crate::pac::can::Fdcan,
|
_instance2: &'d crate::pac::can::Fdcan,
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FDCAN Tx only Instance
|
/// FDCAN Tx only Instance
|
||||||
pub struct FdcanTx<'d, T: Instance, M: Transmit> {
|
pub struct FdcanTx<'d, T: Instance> {
|
||||||
config: crate::can::fd::config::FdCanConfig,
|
config: crate::can::fd::config::FdCanConfig,
|
||||||
_instance: FdcanInstance<'d, T>, //(PeripheralRef<'a, T>);
|
_instance: FdcanInstance<'d, T>, //(PeripheralRef<'a, T>);
|
||||||
_mode: PhantomData<M>,
|
_mode: FdcanOperatingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M: Transmit> FdcanTx<'d, T, M> {
|
impl<'c, 'd, T: Instance> FdcanTx<'d, T> {
|
||||||
/// Queues the message to be sent but exerts backpressure. If a lower-priority
|
/// Queues the message to be sent but exerts backpressure. If a lower-priority
|
||||||
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
||||||
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
||||||
|
@ -635,7 +594,7 @@ impl<'c, 'd, T: Instance, M: Transmit> FdcanTx<'d, T, M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance, M: Receive> FdcanRx<'d, T, M> {
|
impl<'c, 'd, T: Instance> FdcanRx<'d, T> {
|
||||||
/// Returns the next received message frame
|
/// Returns the next received message frame
|
||||||
pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
||||||
T::state().rx_mode.read::<T>().await
|
T::state().rx_mode.read::<T>().await
|
||||||
|
|
|
@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) {
|
||||||
|
|
||||||
let peripherals = embassy_stm32::init(config);
|
let peripherals = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
||||||
|
|
||||||
can.set_extended_filter(
|
can.set_extended_filter(
|
||||||
can::fd::filter::ExtendedFilterSlot::_0,
|
can::fd::filter::ExtendedFilterSlot::_0,
|
||||||
|
@ -38,8 +38,10 @@ async fn main(_spawner: Spawner) {
|
||||||
|
|
||||||
info!("Configured");
|
info!("Configured");
|
||||||
|
|
||||||
let mut can = can.into_normal_mode();
|
let mut can = can.start(match use_fd {
|
||||||
//let mut can = can.into_internal_loopback_mode();
|
true => can::FdcanOperatingMode::InternalLoopbackMode,
|
||||||
|
false => can::FdcanOperatingMode::NormalOperationMode,
|
||||||
|
});
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut last_read_ts = embassy_time::Instant::now();
|
let mut last_read_ts = embassy_time::Instant::now();
|
||||||
|
@ -106,7 +108,6 @@ async fn main(_spawner: Spawner) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
let (mut tx, mut rx) = can.split();
|
let (mut tx, mut rx) = can.split();
|
||||||
// With split
|
// With split
|
||||||
|
|
|
@ -24,8 +24,7 @@ async fn main(_spawner: Spawner) {
|
||||||
|
|
||||||
let peripherals = embassy_stm32::init(config);
|
let peripherals = embassy_stm32::init(config);
|
||||||
|
|
||||||
//let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs);
|
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
||||||
let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
|
||||||
|
|
||||||
// 250k bps
|
// 250k bps
|
||||||
can.set_bitrate(250_000);
|
can.set_bitrate(250_000);
|
||||||
|
|
|
@ -24,8 +24,7 @@ async fn main(_spawner: Spawner) {
|
||||||
|
|
||||||
let peripherals = embassy_stm32::init(config);
|
let peripherals = embassy_stm32::init(config);
|
||||||
|
|
||||||
//let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs);
|
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
||||||
let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
|
||||||
|
|
||||||
// 250k bps
|
// 250k bps
|
||||||
can.set_bitrate(250_000);
|
can.set_bitrate(250_000);
|
||||||
|
|
|
@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) {
|
||||||
let options = options();
|
let options = options();
|
||||||
let peripherals = embassy_stm32::init(options.config);
|
let peripherals = embassy_stm32::init(options.config);
|
||||||
|
|
||||||
let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs);
|
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs);
|
||||||
|
|
||||||
// 250k bps
|
// 250k bps
|
||||||
can.set_bitrate(250_000);
|
can.set_bitrate(250_000);
|
||||||
|
|
Loading…
Add table
Reference in a new issue