stm32f1xx_hal/
can.rs

1//! # Controller Area Network (CAN) Interface
2//!
3//! ## Alternate function remapping
4//!
5//! ### CAN1
6//!
7//! | Function \ Remap | 0 (default) | 1    |
8//! |------------------|-------------|------|
9//! | TX (A-PP)        | PA12        | PB9  |
10//! | RX (I-F/PU)      | PA11        | PB8  |
11//!
12//! ### CAN2
13//!
14//! | Function \ Remap | 0 (default) | 1    |
15//! |------------------|-------------|------|
16//! | TX (A-PP)        | PB6         | PB13 |
17//! | RX (I-F/PU)      | PB5         | PB12 |
18
19use crate::afio::{self, RInto, Rmp};
20use crate::gpio::{Floating, UpMode};
21use crate::pac::{self, RCC};
22
23pub trait CanExt: Sized + Instance {
24    fn can<PULL: UpMode>(
25        self,
26        #[cfg(not(feature = "connectivity"))] usb: pac::USB,
27        pins: (impl RInto<Self::Tx, 0>, impl RInto<Self::Rx<PULL>, 0>),
28        rcc: &mut RCC,
29    ) -> Can<Self, PULL>;
30    fn can_loopback(
31        self,
32        #[cfg(not(feature = "connectivity"))] usb: pac::USB,
33        rcc: &mut RCC,
34    ) -> Can<Self, Floating>;
35}
36
37impl<CAN: Instance> CanExt for CAN {
38    fn can<PULL: UpMode>(
39        self,
40        #[cfg(not(feature = "connectivity"))] usb: pac::USB,
41        pins: (impl RInto<Self::Tx, 0>, impl RInto<Self::Rx<PULL>, 0>),
42        rcc: &mut RCC,
43    ) -> Can<Self, PULL> {
44        Can::new(
45            self,
46            #[cfg(not(feature = "connectivity"))]
47            usb,
48            pins,
49            rcc,
50        )
51    }
52    fn can_loopback(
53        self,
54        #[cfg(not(feature = "connectivity"))] usb: pac::USB,
55        rcc: &mut RCC,
56    ) -> Can<Self, Floating> {
57        Can::new_loopback(
58            self,
59            #[cfg(not(feature = "connectivity"))]
60            usb,
61            rcc,
62        )
63    }
64}
65
66pub trait Instance: crate::rcc::Enable + afio::CanCommon {}
67#[cfg(not(feature = "connectivity"))]
68use pac::CAN as CAN1;
69#[cfg(feature = "connectivity")]
70use pac::CAN1;
71
72impl Instance for CAN1 {}
73#[cfg(feature = "connectivity")]
74impl Instance for pac::CAN2 {}
75
76/// Interface to the CAN peripheral.
77#[allow(unused)]
78pub struct Can<CAN: Instance, PULL = Floating> {
79    can: CAN,
80    pins: (Option<CAN::Tx>, Option<CAN::Rx<PULL>>),
81}
82
83impl<CAN: Instance, const R: u8> Rmp<CAN, R> {
84    pub fn can<PULL: UpMode>(
85        self,
86        #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
87        pins: (impl RInto<CAN::Tx, R>, impl RInto<CAN::Rx<PULL>, R>),
88        rcc: &mut RCC,
89    ) -> Can<CAN, PULL> {
90        CAN::enable(rcc);
91
92        let pins = (Some(pins.0.rinto()), Some(pins.1.rinto()));
93        Can { can: self.0, pins }
94    }
95    pub fn can_loopback(
96        self,
97        #[cfg(not(feature = "connectivity"))] usb: pac::USB,
98        rcc: &mut RCC,
99    ) -> Can<CAN, Floating> {
100        Can::new_loopback(
101            self.0,
102            #[cfg(not(feature = "connectivity"))]
103            usb,
104            rcc,
105        )
106    }
107}
108
109impl<CAN: Instance, PULL: UpMode> Can<CAN, PULL> {
110    /// Creates a CAN interface.
111    ///
112    /// CAN shares SRAM with the USB peripheral. Take ownership of USB to
113    /// prevent accidental shared usage.
114    pub fn new<const R: u8>(
115        can: impl Into<Rmp<CAN, R>>,
116        #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
117        pins: (impl RInto<CAN::Tx, R>, impl RInto<CAN::Rx<PULL>, R>),
118        rcc: &mut RCC,
119    ) -> Can<CAN, PULL> {
120        can.into().can(
121            #[cfg(not(feature = "connectivity"))]
122            _usb,
123            pins,
124            rcc,
125        )
126    }
127
128    /// Creates a CAN interface in loopback mode
129    pub fn new_loopback(
130        can: CAN,
131        #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
132        rcc: &mut RCC,
133    ) -> Can<CAN, PULL> {
134        CAN::enable(rcc);
135
136        Can {
137            can,
138            pins: (None, None),
139        }
140    }
141}
142
143unsafe impl<PULL> bxcan::Instance for Can<CAN1, PULL> {
144    const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
145}
146
147#[cfg(feature = "connectivity")]
148unsafe impl<PULL> bxcan::Instance for Can<pac::CAN2, PULL> {
149    const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN2::ptr() as *mut _;
150}
151
152unsafe impl<PULL> bxcan::FilterOwner for Can<CAN1, PULL> {
153    const NUM_FILTER_BANKS: u8 = 28;
154}
155
156#[cfg(feature = "connectivity")]
157unsafe impl<PULL> bxcan::MasterInstance for Can<CAN1, PULL> {}