Merge pull request #2623 from cschuhen/feature/fdcan_pac_cleanup
Cleanup of FDCAN module, mostly review comments.
This commit is contained in:
		
						commit
						326e32adc4
					
				@ -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};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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,17 +14,23 @@ use crate::rcc::RccPeripheral;
 | 
			
		||||
use crate::{interrupt, peripherals, Peripheral};
 | 
			
		||||
 | 
			
		||||
pub mod enums;
 | 
			
		||||
use enums::*;
 | 
			
		||||
pub mod util;
 | 
			
		||||
 | 
			
		||||
pub(crate) mod fd;
 | 
			
		||||
pub mod frame;
 | 
			
		||||
mod util;
 | 
			
		||||
 | 
			
		||||
use enums::*;
 | 
			
		||||
use fd::config::*;
 | 
			
		||||
use fd::filter::*;
 | 
			
		||||
pub use fd::{config, filter};
 | 
			
		||||
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<T: Instance> {
 | 
			
		||||
@ -139,7 +142,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.
 | 
			
		||||
@ -431,6 +435,12 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S
 | 
			
		||||
    rx_buf: &'static RxBuf<RX_BUF_SIZE>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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>
 | 
			
		||||
{
 | 
			
		||||
@ -476,6 +486,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
 | 
			
		||||
@ -504,6 +524,12 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF
 | 
			
		||||
    rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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>
 | 
			
		||||
{
 | 
			
		||||
@ -549,6 +575,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
 | 
			
		||||
@ -861,22 +897,14 @@ 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>);
 | 
			
		||||
 | 
			
		||||
@ -902,41 +930,41 @@ 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
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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) => {
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user