diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-25 21:06:59 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-25 21:06:59 +0000 |
| commit | 326e32adc4f5035a122fa12d3111026d27d48e63 (patch) | |
| tree | 1072dc278dd52bd6c6a41bbbb5b05cc5bb33e27d | |
| parent | 4657c105473122017a2df0fec6449ffb401927f4 (diff) | |
| parent | a737a7350e6aa42b867679dbb21c2d6fb8b22b91 (diff) | |
Merge pull request #2623 from cschuhen/feature/fdcan_pac_cleanup
Cleanup of FDCAN module, mostly review comments.
| -rw-r--r-- | embassy-stm32/src/can/fd/config.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/can/fd/filter.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 132 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/can.rs | 4 | ||||
| -rw-r--r-- | tests/stm32/src/bin/fdcan.rs | 4 |
5 files changed, 86 insertions, 58 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 @@ | |||
| 1 | //! Configuration for FDCAN Module | 1 | //! Configuration for FDCAN Module |
| 2 | //! Note: This file is copied and modified from fdcan crate by Richard Meadows | 2 | // Note: This file is copied and modified from fdcan crate by Richard Meadows |
| 3 | 3 | ||
| 4 | use core::num::{NonZeroU16, NonZeroU8}; | 4 | use core::num::{NonZeroU16, NonZeroU8}; |
| 5 | 5 | ||
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 @@ | |||
| 1 | //! Definition of Filter structs for FDCAN Module | 1 | //! Definition of Filter structs for FDCAN Module |
| 2 | //! Note: This file is copied and modified from fdcan crate by Richard Meadows | 2 | // Note: This file is copied and modified from fdcan crate by Richard Meadows |
| 3 | 3 | ||
| 4 | use embedded_can::{ExtendedId, StandardId}; | 4 | use embedded_can::{ExtendedId, StandardId}; |
| 5 | 5 | ||
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index f1f6f935e..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; | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | pub mod fd; | ||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 7 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 9 | use embassy_sync::channel::Channel; | 8 | use embassy_sync::channel::Channel; |
| 10 | use fd::config::*; | ||
| 11 | use fd::filter::*; | ||
| 12 | 9 | ||
| 13 | use crate::can::fd::peripheral::Registers; | 10 | use crate::can::fd::peripheral::Registers; |
| 14 | use crate::gpio::sealed::AFType; | 11 | use crate::gpio::sealed::AFType; |
| @@ -17,17 +14,23 @@ use crate::rcc::RccPeripheral; | |||
| 17 | use crate::{interrupt, peripherals, Peripheral}; | 14 | use crate::{interrupt, peripherals, Peripheral}; |
| 18 | 15 | ||
| 19 | pub mod enums; | 16 | pub mod enums; |
| 20 | use enums::*; | 17 | pub(crate) mod fd; |
| 21 | pub mod util; | ||
| 22 | |||
| 23 | pub mod frame; | 18 | pub mod frame; |
| 19 | mod util; | ||
| 20 | |||
| 21 | use enums::*; | ||
| 22 | use fd::config::*; | ||
| 23 | use fd::filter::*; | ||
| 24 | pub use fd::{config, filter}; | ||
| 24 | use frame::*; | 25 | use frame::*; |
| 25 | 26 | ||
| 27 | /// Timestamp for incoming packets. Use Embassy time when enabled. | ||
| 26 | #[cfg(feature = "time")] | 28 | #[cfg(feature = "time")] |
| 27 | type Timestamp = embassy_time::Instant; | 29 | pub type Timestamp = embassy_time::Instant; |
| 28 | 30 | ||
| 31 | /// Timestamp for incoming packets. | ||
| 29 | #[cfg(not(feature = "time"))] | 32 | #[cfg(not(feature = "time"))] |
| 30 | type Timestamp = u16; | 33 | pub type Timestamp = u16; |
| 31 | 34 | ||
| 32 | /// Interrupt handler channel 0. | 35 | /// Interrupt handler channel 0. |
| 33 | pub struct IT0InterruptHandler<T: Instance> { | 36 | pub struct IT0InterruptHandler<T: Instance> { |
| @@ -139,7 +142,8 @@ pub enum FdcanOperatingMode { | |||
| 139 | //TestMode, | 142 | //TestMode, |
| 140 | } | 143 | } |
| 141 | 144 | ||
| 142 | /// FDCAN Instance | 145 | /// FDCAN Configuration instance instance |
| 146 | /// Create instance of this first | ||
| 143 | pub struct FdcanConfigurator<'d, T: Instance> { | 147 | pub struct FdcanConfigurator<'d, T: Instance> { |
| 144 | config: crate::can::fd::config::FdCanConfig, | 148 | config: crate::can::fd::config::FdCanConfig, |
| 145 | /// Reference to internals. | 149 | /// Reference to internals. |
| @@ -431,6 +435,12 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S | |||
| 431 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, | 435 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, |
| 432 | } | 436 | } |
| 433 | 437 | ||
| 438 | /// Sender that can be used for sending CAN frames. | ||
| 439 | pub type BufferedCanSender = embassy_sync::channel::DynamicSender<'static, ClassicFrame>; | ||
| 440 | |||
| 441 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | ||
| 442 | pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; | ||
| 443 | |||
| 434 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | 444 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> |
| 435 | BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> | 445 | BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> |
| 436 | { | 446 | { |
| @@ -476,6 +486,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 476 | pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { | 486 | pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { |
| 477 | Ok(self.rx_buf.receive().await) | 487 | Ok(self.rx_buf.receive().await) |
| 478 | } | 488 | } |
| 489 | |||
| 490 | /// Returns a sender that can be used for sending CAN frames. | ||
| 491 | pub fn writer(&self) -> BufferedCanSender { | ||
| 492 | self.tx_buf.sender().into() | ||
| 493 | } | ||
| 494 | |||
| 495 | /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | ||
| 496 | pub fn reader(&self) -> BufferedCanReceiver { | ||
| 497 | self.rx_buf.receiver().into() | ||
| 498 | } | ||
| 479 | } | 499 | } |
| 480 | 500 | ||
| 481 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop | 501 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop |
| @@ -504,6 +524,12 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF | |||
| 504 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, | 524 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, |
| 505 | } | 525 | } |
| 506 | 526 | ||
| 527 | /// Sender that can be used for sending CAN frames. | ||
| 528 | pub type BufferedFdCanSender = embassy_sync::channel::DynamicSender<'static, FdFrame>; | ||
| 529 | |||
| 530 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | ||
| 531 | pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; | ||
| 532 | |||
| 507 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | 533 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> |
| 508 | BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> | 534 | BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> |
| 509 | { | 535 | { |
| @@ -549,6 +575,16 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 549 | pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> { | 575 | pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> { |
| 550 | Ok(self.rx_buf.receive().await) | 576 | Ok(self.rx_buf.receive().await) |
| 551 | } | 577 | } |
| 578 | |||
| 579 | /// Returns a sender that can be used for sending CAN frames. | ||
| 580 | pub fn writer(&self) -> BufferedFdCanSender { | ||
| 581 | self.tx_buf.sender().into() | ||
| 582 | } | ||
| 583 | |||
| 584 | /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | ||
| 585 | pub fn reader(&self) -> BufferedFdCanReceiver { | ||
| 586 | self.rx_buf.receiver().into() | ||
| 587 | } | ||
| 552 | } | 588 | } |
| 553 | 589 | ||
| 554 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop | 590 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop |
| @@ -861,22 +897,14 @@ pub(crate) mod sealed { | |||
| 861 | } | 897 | } |
| 862 | } | 898 | } |
| 863 | 899 | ||
| 864 | /// Trait for FDCAN interrupt channel 0 | 900 | /// Instance trait |
| 865 | pub trait IT0Instance { | 901 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { |
| 866 | /// Type for FDCAN interrupt channel 0 | 902 | /// Interrupt 0 |
| 867 | type IT0Interrupt: crate::interrupt::typelevel::Interrupt; | 903 | type IT0Interrupt: crate::interrupt::typelevel::Interrupt; |
| 868 | } | 904 | /// Interrupt 0 |
| 869 | |||
| 870 | /// Trait for FDCAN interrupt channel 1 | ||
| 871 | pub trait IT1Instance { | ||
| 872 | /// Type for FDCAN interrupt channel 1 | ||
| 873 | type IT1Interrupt: crate::interrupt::typelevel::Interrupt; | 905 | type IT1Interrupt: crate::interrupt::typelevel::Interrupt; |
| 874 | } | 906 | } |
| 875 | 907 | ||
| 876 | /// InterruptableInstance trait | ||
| 877 | pub trait InterruptableInstance: IT0Instance + IT1Instance {} | ||
| 878 | /// Instance trait | ||
| 879 | pub trait Instance: sealed::Instance + RccPeripheral + InterruptableInstance + 'static {} | ||
| 880 | /// Fdcan Instance struct | 908 | /// Fdcan Instance struct |
| 881 | pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); | 909 | pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); |
| 882 | 910 | ||
| @@ -902,41 +930,41 @@ macro_rules! impl_fdcan { | |||
| 902 | unsafe { peripherals::$inst::mut_state() } | 930 | unsafe { peripherals::$inst::mut_state() } |
| 903 | } | 931 | } |
| 904 | 932 | ||
| 905 | #[cfg(feature = "time")] | 933 | #[cfg(feature = "time")] |
| 906 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { | 934 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { |
| 907 | let now_embassy = embassy_time::Instant::now(); | 935 | let now_embassy = embassy_time::Instant::now(); |
| 908 | if ns_per_timer_tick == 0 { | 936 | if ns_per_timer_tick == 0 { |
| 909 | return now_embassy; | 937 | return now_embassy; |
| 910 | } | 938 | } |
| 911 | let cantime = { Self::regs().tscv().read().tsc() }; | 939 | let cantime = { Self::regs().tscv().read().tsc() }; |
| 912 | let delta = cantime.overflowing_sub(ts_val).0 as u64; | 940 | let delta = cantime.overflowing_sub(ts_val).0 as u64; |
| 913 | let ns = ns_per_timer_tick * delta as u64; | 941 | let ns = ns_per_timer_tick * delta as u64; |
| 914 | now_embassy - embassy_time::Duration::from_nanos(ns) | 942 | now_embassy - embassy_time::Duration::from_nanos(ns) |
| 915 | } | 943 | } |
| 916 | 944 | ||
| 917 | #[cfg(not(feature = "time"))] | 945 | #[cfg(not(feature = "time"))] |
| 918 | fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { | 946 | fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp { |
| 919 | ts_val | 947 | ts_val |
| 920 | } | 948 | } |
| 921 | 949 | ||
| 922 | } | 950 | } |
| 923 | 951 | ||
| 924 | impl Instance for peripherals::$inst {} | 952 | #[allow(non_snake_case)] |
| 925 | 953 | pub(crate) mod $inst { | |
| 926 | foreach_interrupt!( | 954 | |
| 927 | ($inst,can,FDCAN,IT0,$irq:ident) => { | 955 | foreach_interrupt!( |
| 928 | impl IT0Instance for peripherals::$inst { | 956 | ($inst,can,FDCAN,IT0,$irq:ident) => { |
| 929 | type IT0Interrupt = crate::interrupt::typelevel::$irq; | 957 | pub type Interrupt0 = crate::interrupt::typelevel::$irq; |
| 930 | } | 958 | }; |
| 931 | }; | 959 | ($inst,can,FDCAN,IT1,$irq:ident) => { |
| 932 | ($inst,can,FDCAN,IT1,$irq:ident) => { | 960 | pub type Interrupt1 = crate::interrupt::typelevel::$irq; |
| 933 | impl IT1Instance for peripherals::$inst { | 961 | }; |
| 934 | type IT1Interrupt = crate::interrupt::typelevel::$irq; | 962 | ); |
| 935 | } | 963 | } |
| 936 | }; | 964 | impl Instance for peripherals::$inst { |
| 937 | ); | 965 | type IT0Interrupt = $inst::Interrupt0; |
| 938 | 966 | type IT1Interrupt = $inst::Interrupt1; | |
| 939 | impl InterruptableInstance for peripherals::$inst {} | 967 | } |
| 940 | }; | 968 | }; |
| 941 | 969 | ||
| 942 | ($inst:ident, $msg_ram_inst:ident) => { | 970 | ($inst:ident, $msg_ram_inst:ident) => { |
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) { | |||
| 22 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | 22 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); |
| 23 | 23 | ||
| 24 | can.set_extended_filter( | 24 | can.set_extended_filter( |
| 25 | can::fd::filter::ExtendedFilterSlot::_0, | 25 | can::filter::ExtendedFilterSlot::_0, |
| 26 | can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), | 26 | can::filter::ExtendedFilter::accept_all_into_fifo1(), |
| 27 | ); | 27 | ); |
| 28 | 28 | ||
| 29 | // 250k bps | 29 | // 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) { | |||
| 81 | can.set_bitrate(250_000); | 81 | can.set_bitrate(250_000); |
| 82 | 82 | ||
| 83 | can.set_extended_filter( | 83 | can.set_extended_filter( |
| 84 | can::fd::filter::ExtendedFilterSlot::_0, | 84 | can::filter::ExtendedFilterSlot::_0, |
| 85 | can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), | 85 | can::filter::ExtendedFilter::accept_all_into_fifo1(), |
| 86 | ); | 86 | ); |
| 87 | 87 | ||
| 88 | let mut can = can.into_internal_loopback_mode(); | 88 | let mut can = can.into_internal_loopback_mode(); |
