From 2d634d07e08650caf2c2940343a1a63e0bc66f05 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sat, 24 Feb 2024 18:31:05 +1000 Subject: [PATCH 1/6] FDCAN: Remove extra traits from. Comments Fix. --- embassy-stm32/src/can/fdcan.rs | 47 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index f1f6f935e..fc5d47ab7 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -861,22 +861,13 @@ pub(crate) mod sealed { } } -/// Trait for FDCAN interrupt channel 0 -pub trait IT0Instance { - /// Type for FDCAN interrupt channel 0 +/// Instance trait +pub trait Instance: sealed::Instance + RccPeripheral + 'static { + /// Interrupt 0 type IT0Interrupt: crate::interrupt::typelevel::Interrupt; -} - -/// Trait for FDCAN interrupt channel 1 -pub trait IT1Instance { - /// Type for FDCAN interrupt channel 1 + /// Interrupt 0 type IT1Interrupt: crate::interrupt::typelevel::Interrupt; } - -/// InterruptableInstance trait -pub trait InterruptableInstance: IT0Instance + IT1Instance {} -/// Instance trait -pub trait Instance: sealed::Instance + RccPeripheral + InterruptableInstance + 'static {} /// Fdcan Instance struct pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); @@ -921,22 +912,22 @@ fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { } - impl Instance for peripherals::$inst {} + #[allow(non_snake_case)] + pub(crate) mod $inst { - foreach_interrupt!( - ($inst,can,FDCAN,IT0,$irq:ident) => { - impl IT0Instance for peripherals::$inst { - type IT0Interrupt = crate::interrupt::typelevel::$irq; - } - }; - ($inst,can,FDCAN,IT1,$irq:ident) => { - impl IT1Instance for peripherals::$inst { - type IT1Interrupt = crate::interrupt::typelevel::$irq; - } - }; - ); - - impl InterruptableInstance for peripherals::$inst {} + foreach_interrupt!( + ($inst,can,FDCAN,IT0,$irq:ident) => { + pub type Interrupt0 = crate::interrupt::typelevel::$irq; + }; + ($inst,can,FDCAN,IT1,$irq:ident) => { + pub type Interrupt1 = crate::interrupt::typelevel::$irq; + }; + ); + } + impl Instance for peripherals::$inst { + type IT0Interrupt = $inst::Interrupt0; + type IT1Interrupt = $inst::Interrupt1; + } }; ($inst:ident, $msg_ram_inst:ident) => { From 779898c0e74d850f324528d2b2db3c9d76ec86d1 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sat, 24 Feb 2024 20:13:52 +1000 Subject: [PATCH 2/6] FDCAN: Expose some pub types in API --- embassy-stm32/src/can/fdcan.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index fc5d47ab7..817ee2115 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -18,16 +18,18 @@ use crate::{interrupt, peripherals, Peripheral}; pub mod enums; use enums::*; -pub mod util; +mod util; pub mod frame; use frame::*; +/// Timestamp for incoming packets. Use Embassy time when enabled. #[cfg(feature = "time")] -type Timestamp = embassy_time::Instant; +pub type Timestamp = embassy_time::Instant; +/// Timestamp for incoming packets. #[cfg(not(feature = "time"))] -type Timestamp = u16; +pub type Timestamp = u16; /// Interrupt handler channel 0. pub struct IT0InterruptHandler { @@ -139,7 +141,8 @@ pub enum FdcanOperatingMode { //TestMode, } -/// FDCAN Instance +/// FDCAN Configuration instance instance +/// Create instance of this first pub struct FdcanConfigurator<'d, T: Instance> { config: crate::can::fd::config::FdCanConfig, /// Reference to internals. @@ -868,6 +871,7 @@ pub trait Instance: sealed::Instance + RccPeripheral + 'static { /// Interrupt 0 type IT1Interrupt: crate::interrupt::typelevel::Interrupt; } + /// Fdcan Instance struct pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); From a061cf31334d7c1912528edecb4738c84d98e17a Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sat, 24 Feb 2024 20:23:34 +1000 Subject: [PATCH 3/6] FDCAN: Allow access to buffered senders and receivers. --- embassy-stm32/src/can/fdcan.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 817ee2115..d290295f5 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -434,6 +434,12 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S rx_buf: &'static RxBuf, } +/// Sender that can be used for sending CAN frames. +pub type BufferedCanSender = embassy_sync::channel::DynamicSender<'static, ClassicFrame>; + +/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. +pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; + impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { @@ -479,6 +485,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { Ok(self.rx_buf.receive().await) } + + /// Returns a sender that can be used for sending CAN frames. + pub fn writer(&self) -> BufferedCanSender { + self.tx_buf.sender().into() + } + + /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. + pub fn reader(&self) -> BufferedCanReceiver { + self.rx_buf.receiver().into() + } } impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop @@ -507,6 +523,12 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF rx_buf: &'static RxFdBuf, } +/// Sender that can be used for sending CAN frames. +pub type BufferedFdCanSender = embassy_sync::channel::DynamicSender<'static, FdFrame>; + +/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. +pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; + impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { @@ -552,6 +574,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> { Ok(self.rx_buf.receive().await) } + + /// Returns a sender that can be used for sending CAN frames. + pub fn writer(&self) -> BufferedFdCanSender { + self.tx_buf.sender().into() + } + + /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. + pub fn reader(&self) -> BufferedFdCanReceiver { + self.rx_buf.receiver().into() + } } impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop From 0565098b06f73b542369c4d4f97f34c78e9bd058 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sun, 25 Feb 2024 08:57:18 +1000 Subject: [PATCH 4/6] FDCAN: Fix some indenting in macros --- embassy-stm32/src/can/fdcan.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index d290295f5..4b76cc34d 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -929,22 +929,22 @@ macro_rules! impl_fdcan { unsafe { peripherals::$inst::mut_state() } } -#[cfg(feature = "time")] -fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { - let now_embassy = embassy_time::Instant::now(); - if ns_per_timer_tick == 0 { - return now_embassy; - } - let cantime = { Self::regs().tscv().read().tsc() }; - let delta = cantime.overflowing_sub(ts_val).0 as u64; - let ns = ns_per_timer_tick * delta as u64; - now_embassy - embassy_time::Duration::from_nanos(ns) -} + #[cfg(feature = "time")] + fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { + let now_embassy = embassy_time::Instant::now(); + if ns_per_timer_tick == 0 { + return now_embassy; + } + let cantime = { Self::regs().tscv().read().tsc() }; + let delta = cantime.overflowing_sub(ts_val).0 as u64; + let ns = ns_per_timer_tick * delta as u64; + now_embassy - embassy_time::Duration::from_nanos(ns) + } -#[cfg(not(feature = "time"))] -fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { - ts_val -} + #[cfg(not(feature = "time"))] + fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { + ts_val + } } From 1327a644b6194093e732372d2aab571214ef5717 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sun, 25 Feb 2024 09:57:30 +1000 Subject: [PATCH 5/6] FDCAN: Don't require internal module for public API. --- embassy-stm32/src/can/fdcan.rs | 11 ++++++----- examples/stm32g4/src/bin/can.rs | 4 ++-- tests/stm32/src/bin/fdcan.rs | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 4b76cc34d..744d756f5 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -3,12 +3,9 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -pub mod fd; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use fd::config::*; -use fd::filter::*; use crate::can::fd::peripheral::Registers; use crate::gpio::sealed::AFType; @@ -17,10 +14,14 @@ use crate::rcc::RccPeripheral; use crate::{interrupt, peripherals, Peripheral}; pub mod enums; -use enums::*; +pub(crate) mod fd; +pub mod frame; mod util; -pub mod frame; +use enums::*; +use fd::config::*; +use fd::filter::*; +pub use fd::{config, filter}; use frame::*; /// Timestamp for incoming packets. Use Embassy time when enabled. diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs index affa97039..a41f765c1 100644 --- a/examples/stm32g4/src/bin/can.rs +++ b/examples/stm32g4/src/bin/can.rs @@ -22,8 +22,8 @@ async fn main(_spawner: Spawner) { let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); can.set_extended_filter( - can::fd::filter::ExtendedFilterSlot::_0, - can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), + can::filter::ExtendedFilterSlot::_0, + can::filter::ExtendedFilter::accept_all_into_fifo1(), ); // 250k bps diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs index 398e31ffc..f21aa797c 100644 --- a/tests/stm32/src/bin/fdcan.rs +++ b/tests/stm32/src/bin/fdcan.rs @@ -81,8 +81,8 @@ async fn main(_spawner: Spawner) { can.set_bitrate(250_000); can.set_extended_filter( - can::fd::filter::ExtendedFilterSlot::_0, - can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), + can::filter::ExtendedFilterSlot::_0, + can::filter::ExtendedFilter::accept_all_into_fifo1(), ); let mut can = can.into_internal_loopback_mode(); From a737a7350e6aa42b867679dbb21c2d6fb8b22b91 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sun, 25 Feb 2024 10:00:17 +1000 Subject: [PATCH 6/6] FDCAN: Remove history from comments. --- embassy-stm32/src/can/fd/config.rs | 2 +- embassy-stm32/src/can/fd/filter.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/can/fd/config.rs b/embassy-stm32/src/can/fd/config.rs index 38b409121..f2401d92f 100644 --- a/embassy-stm32/src/can/fd/config.rs +++ b/embassy-stm32/src/can/fd/config.rs @@ -1,5 +1,5 @@ //! Configuration for FDCAN Module -//! Note: This file is copied and modified from fdcan crate by Richard Meadows +// Note: This file is copied and modified from fdcan crate by Richard Meadows use core::num::{NonZeroU16, NonZeroU8}; diff --git a/embassy-stm32/src/can/fd/filter.rs b/embassy-stm32/src/can/fd/filter.rs index 3e2129e6e..2023a2ef0 100644 --- a/embassy-stm32/src/can/fd/filter.rs +++ b/embassy-stm32/src/can/fd/filter.rs @@ -1,5 +1,5 @@ //! Definition of Filter structs for FDCAN Module -//! Note: This file is copied and modified from fdcan crate by Richard Meadows +// Note: This file is copied and modified from fdcan crate by Richard Meadows use embedded_can::{ExtendedId, StandardId};