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
|
//! 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};
|
use core::num::{NonZeroU16, NonZeroU8};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//! Definition of Filter structs for FDCAN Module
|
//! 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};
|
use embedded_can::{ExtendedId, StandardId};
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,9 @@ use core::future::poll_fn;
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
pub mod fd;
|
|
||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
use fd::config::*;
|
|
||||||
use fd::filter::*;
|
|
||||||
|
|
||||||
use crate::can::fd::peripheral::Registers;
|
use crate::can::fd::peripheral::Registers;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::sealed::AFType;
|
||||||
@ -17,17 +14,23 @@ use crate::rcc::RccPeripheral;
|
|||||||
use crate::{interrupt, peripherals, Peripheral};
|
use crate::{interrupt, peripherals, Peripheral};
|
||||||
|
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
use enums::*;
|
pub(crate) mod fd;
|
||||||
pub mod util;
|
|
||||||
|
|
||||||
pub mod frame;
|
pub mod frame;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
use enums::*;
|
||||||
|
use fd::config::*;
|
||||||
|
use fd::filter::*;
|
||||||
|
pub use fd::{config, filter};
|
||||||
use frame::*;
|
use frame::*;
|
||||||
|
|
||||||
|
/// Timestamp for incoming packets. Use Embassy time when enabled.
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
type Timestamp = embassy_time::Instant;
|
pub type Timestamp = embassy_time::Instant;
|
||||||
|
|
||||||
|
/// Timestamp for incoming packets.
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
type Timestamp = u16;
|
pub type Timestamp = u16;
|
||||||
|
|
||||||
/// Interrupt handler channel 0.
|
/// Interrupt handler channel 0.
|
||||||
pub struct IT0InterruptHandler<T: Instance> {
|
pub struct IT0InterruptHandler<T: Instance> {
|
||||||
@ -139,7 +142,8 @@ pub enum FdcanOperatingMode {
|
|||||||
//TestMode,
|
//TestMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FDCAN Instance
|
/// FDCAN Configuration instance instance
|
||||||
|
/// Create instance of this first
|
||||||
pub struct FdcanConfigurator<'d, T: Instance> {
|
pub struct FdcanConfigurator<'d, T: Instance> {
|
||||||
config: crate::can::fd::config::FdCanConfig,
|
config: crate::can::fd::config::FdCanConfig,
|
||||||
/// Reference to internals.
|
/// 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>,
|
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>
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
||||||
BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
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> {
|
pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
||||||
Ok(self.rx_buf.receive().await)
|
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
|
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>,
|
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>
|
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
||||||
BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
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> {
|
pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> {
|
||||||
Ok(self.rx_buf.receive().await)
|
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
|
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
|
/// Instance trait
|
||||||
pub trait IT0Instance {
|
pub trait Instance: sealed::Instance + RccPeripheral + 'static {
|
||||||
/// Type for FDCAN interrupt channel 0
|
/// Interrupt 0
|
||||||
type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
|
type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
}
|
/// Interrupt 0
|
||||||
|
|
||||||
/// Trait for FDCAN interrupt channel 1
|
|
||||||
pub trait IT1Instance {
|
|
||||||
/// Type for FDCAN interrupt channel 1
|
|
||||||
type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
|
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
|
/// Fdcan Instance struct
|
||||||
pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
|
pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
|
||||||
|
|
||||||
@ -902,41 +930,41 @@ macro_rules! impl_fdcan {
|
|||||||
unsafe { peripherals::$inst::mut_state() }
|
unsafe { peripherals::$inst::mut_state() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
|
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
|
||||||
let now_embassy = embassy_time::Instant::now();
|
let now_embassy = embassy_time::Instant::now();
|
||||||
if ns_per_timer_tick == 0 {
|
if ns_per_timer_tick == 0 {
|
||||||
return now_embassy;
|
return now_embassy;
|
||||||
}
|
}
|
||||||
let cantime = { Self::regs().tscv().read().tsc() };
|
let cantime = { Self::regs().tscv().read().tsc() };
|
||||||
let delta = cantime.overflowing_sub(ts_val).0 as u64;
|
let delta = cantime.overflowing_sub(ts_val).0 as u64;
|
||||||
let ns = ns_per_timer_tick * delta as u64;
|
let ns = ns_per_timer_tick * delta as u64;
|
||||||
now_embassy - embassy_time::Duration::from_nanos(ns)
|
now_embassy - embassy_time::Duration::from_nanos(ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
|
fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
|
||||||
ts_val
|
ts_val
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance for peripherals::$inst {}
|
#[allow(non_snake_case)]
|
||||||
|
pub(crate) mod $inst {
|
||||||
|
|
||||||
foreach_interrupt!(
|
foreach_interrupt!(
|
||||||
($inst,can,FDCAN,IT0,$irq:ident) => {
|
($inst,can,FDCAN,IT0,$irq:ident) => {
|
||||||
impl IT0Instance for peripherals::$inst {
|
pub type Interrupt0 = crate::interrupt::typelevel::$irq;
|
||||||
type IT0Interrupt = crate::interrupt::typelevel::$irq;
|
};
|
||||||
}
|
($inst,can,FDCAN,IT1,$irq:ident) => {
|
||||||
};
|
pub type Interrupt1 = crate::interrupt::typelevel::$irq;
|
||||||
($inst,can,FDCAN,IT1,$irq:ident) => {
|
};
|
||||||
impl IT1Instance for peripherals::$inst {
|
);
|
||||||
type IT1Interrupt = crate::interrupt::typelevel::$irq;
|
}
|
||||||
}
|
impl Instance for peripherals::$inst {
|
||||||
};
|
type IT0Interrupt = $inst::Interrupt0;
|
||||||
);
|
type IT1Interrupt = $inst::Interrupt1;
|
||||||
|
}
|
||||||
impl InterruptableInstance for peripherals::$inst {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
($inst:ident, $msg_ram_inst:ident) => {
|
($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);
|
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::filter::ExtendedFilterSlot::_0,
|
||||||
can::fd::filter::ExtendedFilter::accept_all_into_fifo1(),
|
can::filter::ExtendedFilter::accept_all_into_fifo1(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 250k bps
|
// 250k bps
|
||||||
|
|||||||
@ -81,8 +81,8 @@ async fn main(_spawner: Spawner) {
|
|||||||
can.set_bitrate(250_000);
|
can.set_bitrate(250_000);
|
||||||
|
|
||||||
can.set_extended_filter(
|
can.set_extended_filter(
|
||||||
can::fd::filter::ExtendedFilterSlot::_0,
|
can::filter::ExtendedFilterSlot::_0,
|
||||||
can::fd::filter::ExtendedFilter::accept_all_into_fifo1(),
|
can::filter::ExtendedFilter::accept_all_into_fifo1(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut can = can.into_internal_loopback_mode();
|
let mut can = can.into_internal_loopback_mode();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user