|
1 | 1 | //! # Controller Area Network (CAN) Interface
|
2 | 2 | //!
|
3 | 3 |
|
4 |
| -use crate::gpio::{Const, NoPin, PinA, PushPull, SetAlternate}; |
| 4 | +use crate::gpio::{self, NoPin}; |
5 | 5 | use crate::pac::{CAN1, CAN2};
|
6 | 6 | use crate::rcc;
|
7 | 7 |
|
8 |
| -pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset {} |
| 8 | +pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset { |
| 9 | + type Tx; |
| 10 | + type Rx; |
| 11 | +} |
| 12 | + |
| 13 | +macro_rules! can { |
| 14 | + ($CAN:ty: $Can:ident, $can:ident) => { |
| 15 | + pub type $Can = Can<$CAN>; |
| 16 | + |
| 17 | + impl Instance for $CAN { |
| 18 | + type Tx = gpio::alt::$can::Tx; |
| 19 | + type Rx = gpio::alt::$can::Rx; |
| 20 | + } |
| 21 | + }; |
| 22 | +} |
9 | 23 |
|
10 | 24 | // Implemented by all SPI instances
|
11 |
| -impl Instance for CAN1 {} |
12 |
| -pub type Can1<PINS> = Can<CAN1, PINS>; |
13 |
| -impl Instance for CAN2 {} |
14 |
| -pub type Can2<PINS> = Can<CAN2, PINS>; |
| 25 | +can! { CAN1: Can1, can1 } |
| 26 | +can! { CAN2: Can2, can2 } |
15 | 27 | #[cfg(feature = "can3")]
|
16 |
| -pub type Can3<PINS> = Can<crate::pac::CAN3, PINS>; |
| 28 | +can! { crate::pac::CAN3: Can3, can3 } |
17 | 29 |
|
18 | 30 | pub struct Tx;
|
19 | 31 | impl crate::Sealed for Tx {}
|
20 | 32 | pub struct Rx;
|
21 | 33 | impl crate::Sealed for Rx {}
|
22 | 34 |
|
23 |
| -pub trait Pins<CAN> { |
24 |
| - fn set_alt_mode(&mut self); |
25 |
| - fn restore_mode(&mut self); |
26 |
| -} |
27 |
| - |
28 |
| -impl<CAN, TX, RX, const TXA: u8, const RXA: u8> Pins<CAN> for (TX, RX) |
29 |
| -where |
30 |
| - TX: PinA<Tx, CAN, A = Const<TXA>> + SetAlternate<TXA, PushPull>, |
31 |
| - RX: PinA<Rx, CAN, A = Const<RXA>> + SetAlternate<RXA, PushPull>, |
32 |
| -{ |
33 |
| - fn set_alt_mode(&mut self) { |
34 |
| - self.0.set_alt_mode(); |
35 |
| - self.1.set_alt_mode(); |
36 |
| - } |
37 |
| - fn restore_mode(&mut self) { |
38 |
| - self.0.restore_mode(); |
39 |
| - self.1.restore_mode(); |
40 |
| - } |
41 |
| -} |
42 |
| - |
43 | 35 | /// Pins and definitions for models with a third CAN peripheral
|
44 | 36 | #[cfg(feature = "can3")]
|
45 | 37 | mod can3 {
|
46 | 38 | use super::*;
|
47 | 39 | use crate::pac::CAN3;
|
48 | 40 |
|
49 |
| - impl Instance for CAN3 {} |
50 |
| - |
51 |
| - unsafe impl<PINS> bxcan::Instance for Can<CAN3, PINS> { |
| 41 | + unsafe impl bxcan::Instance for Can<CAN3> { |
52 | 42 | const REGISTERS: *mut bxcan::RegisterBlock = CAN3::ptr() as *mut _;
|
53 | 43 | }
|
54 | 44 |
|
55 |
| - unsafe impl<PINS> bxcan::FilterOwner for Can<CAN3, PINS> { |
| 45 | + unsafe impl bxcan::FilterOwner for Can<CAN3> { |
56 | 46 | const NUM_FILTER_BANKS: u8 = 14;
|
57 | 47 | }
|
58 | 48 | }
|
59 | 49 |
|
60 | 50 | pub trait CanExt: Sized + Instance {
|
61 |
| - fn can<TX, RX>(self, pins: (TX, RX)) -> Can<Self, (TX, RX)> |
62 |
| - where |
63 |
| - (TX, RX): Pins<Self>; |
64 |
| - fn tx<TX>(self, tx_pin: TX) -> Can<Self, (TX, NoPin)> |
| 51 | + fn can(self, pins: (impl Into<Self::Tx>, impl Into<Self::Rx>)) -> Can<Self>; |
| 52 | + |
| 53 | + fn tx(self, tx_pin: impl Into<Self::Tx>) -> Can<Self> |
65 | 54 | where
|
66 |
| - (TX, NoPin): Pins<Self>; |
67 |
| - fn rx<RX>(self, rx_pin: RX) -> Can<Self, (NoPin, RX)> |
| 55 | + NoPin: Into<Self::Rx>; |
| 56 | + |
| 57 | + fn rx(self, rx_pin: impl Into<Self::Rx>) -> Can<Self> |
68 | 58 | where
|
69 |
| - (NoPin, RX): Pins<Self>; |
| 59 | + NoPin: Into<Self::Tx>; |
70 | 60 | }
|
71 | 61 |
|
72 | 62 | impl<CAN: Instance> CanExt for CAN {
|
73 |
| - fn can<TX, RX>(self, pins: (TX, RX)) -> Can<Self, (TX, RX)> |
74 |
| - where |
75 |
| - (TX, RX): Pins<Self>, |
76 |
| - { |
| 63 | + fn can(self, pins: (impl Into<Self::Tx>, impl Into<Self::Rx>)) -> Can<Self> { |
77 | 64 | Can::new(self, pins)
|
78 | 65 | }
|
79 |
| - fn tx<TX>(self, tx_pin: TX) -> Can<Self, (TX, NoPin)> |
| 66 | + |
| 67 | + fn tx(self, tx_pin: impl Into<Self::Tx>) -> Can<Self> |
80 | 68 | where
|
81 |
| - (TX, NoPin): Pins<Self>, |
| 69 | + NoPin: Into<Self::Rx>, |
82 | 70 | {
|
83 | 71 | Can::tx(self, tx_pin)
|
84 | 72 | }
|
85 |
| - fn rx<RX>(self, rx_pin: RX) -> Can<Self, (NoPin, RX)> |
| 73 | + |
| 74 | + fn rx(self, rx_pin: impl Into<Self::Rx>) -> Can<Self> |
86 | 75 | where
|
87 |
| - (NoPin, RX): Pins<Self>, |
| 76 | + NoPin: Into<Self::Tx>, |
88 | 77 | {
|
89 | 78 | Can::rx(self, rx_pin)
|
90 | 79 | }
|
91 | 80 | }
|
92 | 81 |
|
93 | 82 | /// Interface to the CAN peripheral.
|
94 |
| -pub struct Can<CAN, PINS> { |
| 83 | +pub struct Can<CAN: Instance> { |
95 | 84 | can: CAN,
|
96 |
| - pins: PINS, |
| 85 | + pins: (CAN::Tx, CAN::Rx), |
97 | 86 | }
|
98 | 87 |
|
99 |
| -impl<CAN, TX, RX> Can<CAN, (TX, RX)> |
100 |
| -where |
101 |
| - CAN: Instance, |
102 |
| - (TX, RX): Pins<CAN>, |
103 |
| -{ |
| 88 | +impl<CAN: Instance> Can<CAN> { |
104 | 89 | /// Creates a CAN interface.
|
105 |
| - pub fn new(can: CAN, mut pins: (TX, RX)) -> Self { |
| 90 | + pub fn new(can: CAN, pins: (impl Into<CAN::Tx>, impl Into<CAN::Rx>)) -> Self { |
106 | 91 | unsafe {
|
107 | 92 | // NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
|
108 | 93 | let rcc = &(*crate::pac::RCC::ptr());
|
109 | 94 | CAN::enable(rcc);
|
110 | 95 | CAN::reset(rcc);
|
111 | 96 | }
|
112 | 97 |
|
113 |
| - pins.set_alt_mode(); |
| 98 | + let pins = (pins.0.into(), pins.1.into()); |
114 | 99 |
|
115 | 100 | Can { can, pins }
|
116 | 101 | }
|
117 | 102 |
|
118 |
| - pub fn release(mut self) -> (CAN, (TX, RX)) { |
119 |
| - self.pins.restore_mode(); |
120 |
| - |
121 |
| - (self.can, (self.pins.0, self.pins.1)) |
| 103 | + pub fn release<TX, RX, E>(self) -> Result<(CAN, (TX, RX)), E> |
| 104 | + where |
| 105 | + TX: TryFrom<CAN::Tx, Error = E>, |
| 106 | + RX: TryFrom<CAN::Rx, Error = E>, |
| 107 | + { |
| 108 | + Ok((self.can, (self.pins.0.try_into()?, self.pins.1.try_into()?))) |
122 | 109 | }
|
123 | 110 | }
|
124 | 111 |
|
125 |
| -impl<CAN, TX> Can<CAN, (TX, NoPin)> |
126 |
| -where |
127 |
| - CAN: Instance, |
128 |
| - (TX, NoPin): Pins<CAN>, |
129 |
| -{ |
130 |
| - pub fn tx(usart: CAN, tx_pin: TX) -> Self { |
| 112 | +impl<CAN: Instance> Can<CAN> { |
| 113 | + pub fn tx(usart: CAN, tx_pin: impl Into<CAN::Tx>) -> Self |
| 114 | + where |
| 115 | + NoPin: Into<CAN::Rx>, |
| 116 | + { |
131 | 117 | Self::new(usart, (tx_pin, NoPin))
|
132 | 118 | }
|
133 | 119 | }
|
134 | 120 |
|
135 |
| -impl<CAN, RX> Can<CAN, (NoPin, RX)> |
136 |
| -where |
137 |
| - CAN: Instance, |
138 |
| - (NoPin, RX): Pins<CAN>, |
139 |
| -{ |
140 |
| - pub fn rx(usart: CAN, rx_pin: RX) -> Self { |
| 121 | +impl<CAN: Instance> Can<CAN> { |
| 122 | + pub fn rx(usart: CAN, rx_pin: impl Into<CAN::Rx>) -> Self |
| 123 | + where |
| 124 | + NoPin: Into<CAN::Tx>, |
| 125 | + { |
141 | 126 | Self::new(usart, (NoPin, rx_pin))
|
142 | 127 | }
|
143 | 128 | }
|
144 | 129 |
|
145 |
| -unsafe impl<PINS> bxcan::Instance for Can<CAN1, PINS> { |
| 130 | +unsafe impl bxcan::Instance for Can<CAN1> { |
146 | 131 | const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
|
147 | 132 | }
|
148 | 133 |
|
149 |
| -unsafe impl<PINS> bxcan::Instance for Can<CAN2, PINS> { |
| 134 | +unsafe impl bxcan::Instance for Can<CAN2> { |
150 | 135 | const REGISTERS: *mut bxcan::RegisterBlock = CAN2::ptr() as *mut _;
|
151 | 136 | }
|
152 | 137 |
|
153 |
| -unsafe impl<PINS> bxcan::FilterOwner for Can<CAN1, PINS> { |
| 138 | +unsafe impl bxcan::FilterOwner for Can<CAN1> { |
154 | 139 | const NUM_FILTER_BANKS: u8 = 28;
|
155 | 140 | }
|
156 | 141 |
|
157 |
| -unsafe impl<PINS> bxcan::MasterInstance for Can<CAN1, PINS> {} |
| 142 | +unsafe impl bxcan::MasterInstance for Can<CAN1> {} |
0 commit comments