aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-25 21:06:59 +0000
committerGitHub <[email protected]>2024-02-25 21:06:59 +0000
commit326e32adc4f5035a122fa12d3111026d27d48e63 (patch)
tree1072dc278dd52bd6c6a41bbbb5b05cc5bb33e27d
parent4657c105473122017a2df0fec6449ffb401927f4 (diff)
parenta737a7350e6aa42b867679dbb21c2d6fb8b22b91 (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.rs2
-rw-r--r--embassy-stm32/src/can/fd/filter.rs2
-rw-r--r--embassy-stm32/src/can/fdcan.rs132
-rw-r--r--examples/stm32g4/src/bin/can.rs4
-rw-r--r--tests/stm32/src/bin/fdcan.rs4
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
4use core::num::{NonZeroU16, NonZeroU8}; 4use 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
4use embedded_can::{ExtendedId, StandardId}; 4use 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;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6pub mod fd;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel; 8use embassy_sync::channel::Channel;
10use fd::config::*;
11use fd::filter::*;
12 9
13use crate::can::fd::peripheral::Registers; 10use crate::can::fd::peripheral::Registers;
14use crate::gpio::sealed::AFType; 11use crate::gpio::sealed::AFType;
@@ -17,17 +14,23 @@ use crate::rcc::RccPeripheral;
17use crate::{interrupt, peripherals, Peripheral}; 14use crate::{interrupt, peripherals, Peripheral};
18 15
19pub mod enums; 16pub mod enums;
20use enums::*; 17pub(crate) mod fd;
21pub mod util;
22
23pub mod frame; 18pub mod frame;
19mod util;
20
21use enums::*;
22use fd::config::*;
23use fd::filter::*;
24pub use fd::{config, filter};
24use frame::*; 25use frame::*;
25 26
27/// Timestamp for incoming packets. Use Embassy time when enabled.
26#[cfg(feature = "time")] 28#[cfg(feature = "time")]
27type Timestamp = embassy_time::Instant; 29pub type Timestamp = embassy_time::Instant;
28 30
31/// Timestamp for incoming packets.
29#[cfg(not(feature = "time"))] 32#[cfg(not(feature = "time"))]
30type Timestamp = u16; 33pub type Timestamp = u16;
31 34
32/// Interrupt handler channel 0. 35/// Interrupt handler channel 0.
33pub struct IT0InterruptHandler<T: Instance> { 36pub 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
143pub struct FdcanConfigurator<'d, T: Instance> { 147pub 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.
439pub 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.
442pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>;
443
434impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 444impl<'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
481impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop 501impl<'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.
528pub 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.
531pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>;
532
507impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 533impl<'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
554impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop 590impl<'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
865pub trait IT0Instance { 901pub 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
871pub 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
877pub trait InterruptableInstance: IT0Instance + IT1Instance {}
878/// Instance trait
879pub trait Instance: sealed::Instance + RccPeripheral + InterruptableInstance + 'static {}
880/// Fdcan Instance struct 908/// Fdcan Instance struct
881pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); 909pub 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")]
906fn 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"))]
918fn 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();