stm32l4xx_hal/
can.rs

1//! # Controller Area Network (CAN) Interface
2//!
3//! Based on STM32F4xx HAL.
4
5use crate::pac::CAN1;
6use crate::rcc::{Enable, RccBus, Reset};
7
8mod sealed {
9    pub trait Sealed {}
10}
11
12/// A pair of (TX, RX) pins configured for CAN communication
13pub trait Pins: sealed::Sealed {
14    /// The CAN peripheral that uses these pins
15    type Instance;
16}
17
18/// Implements sealed::Sealed and Pins for a (TX, RX) pair of pins associated with a CAN peripheral
19/// The alternate function number can be specified after each pin name.
20macro_rules! pins {
21    ($($PER:ident => ($tx:ident<$txaf:literal>, $rx:ident<$rxaf:literal>),)+) => {
22        $(
23            impl crate::can::sealed::Sealed for ($tx<crate::gpio::Alternate<PushPull, $txaf, >>, $rx<crate::gpio::Alternate<PushPull, $rxaf>>) {}
24            impl crate::can::Pins for ($tx<crate::gpio::Alternate<PushPull, $txaf, >>, $rx<crate::gpio::Alternate<PushPull, $rxaf>>) {
25                type Instance = $PER;
26            }
27        )+
28    }
29}
30
31mod common_pins {
32    use crate::gpio::{
33        gpioa::{PA11, PA12},
34        gpiob::{PB8, PB9},
35        gpiod::{PD0, PD1},
36        PushPull,
37    };
38    use crate::pac::CAN1;
39
40    // All STM32L4 models with CAN support these pins
41    pins! {
42        CAN1 => (PA12<9>, PA11<9>),
43        CAN1 => (PD1<9>, PD0<9>),
44        CAN1 => (PB9<9>, PB8<9>),
45    }
46}
47
48// L4x1
49#[cfg(any(feature = "stm32l431", feature = "stm32l451", feature = "stm32l471"))]
50mod pb13_pb12_af10 {
51    use crate::gpio::{
52        gpiob::{PB12, PB13},
53        PushPull,
54    };
55    use crate::pac::CAN1;
56    pins! { CAN1 => (PB13<10>, PB12<10>), }
57}
58
59impl crate::can::sealed::Sealed for crate::pac::CAN1 {}
60
61/// Interface to the CAN peripheral.
62pub struct Can<CAN, Pins> {
63    can: CAN,
64    pins: Pins,
65}
66
67impl<CAN, P> Can<CAN, P>
68where
69    CAN: Enable + Reset,
70    P: Pins<Instance = CAN>,
71{
72    /// Creates a CAN interface.
73    pub fn new(apb: &mut <CAN as RccBus>::Bus, can: CAN, pins: P) -> Can<CAN, P> {
74        CAN::enable(apb);
75        CAN::reset(apb);
76        Can { can, pins }
77    }
78
79    // Split the peripheral back into its components.
80    pub fn split(self) -> (CAN, P) {
81        (self.can, self.pins)
82    }
83}
84
85unsafe impl<Pins> bxcan::Instance for Can<CAN1, Pins> {
86    const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
87}
88
89unsafe impl<Pins> bxcan::FilterOwner for Can<CAN1, Pins> {
90    const NUM_FILTER_BANKS: u8 = 14;
91}
92
93unsafe impl<Pins> bxcan::MasterInstance for Can<CAN1, Pins> {}