1
+ //! # Controller area network controller
2
+
3
+ use nb;
4
+
5
+ pub use crate :: hal_can:: { Id , Frame as FrameTrait , Can as CanTrait } ;
6
+ use crate :: pac:: { can0, CAN0 , CAN1 } ;
7
+ use crate :: gpio:: gpioa:: { PA11 , PA12 } ;
8
+ use crate :: gpio:: gpiob:: { PB5 , PB6 , PB8 , PB9 , PB12 , PB13 } ;
9
+ use crate :: gpio:: gpiod:: { PD0 , PD1 } ;
10
+ use crate :: gpio:: { Alternate , Floating , Input , PushPull } ;
11
+ use crate :: rcu:: { Rcu , Enable , Reset , BaseFrequency } ;
12
+ use crate :: time:: Hertz ;
13
+ use crate :: afio:: { Afio , Remap } ;
14
+ use core:: { convert:: TryInto , ops:: Deref } ;
15
+
16
+ pub struct Frame {
17
+ }
18
+
19
+ impl FrameTrait for Frame {
20
+ /// Creates a new frame.
21
+ /// Returns an error when the data slice is too long.
22
+ fn new ( id : impl Into < Id > , data : & [ u8 ] ) -> Result < Self , ( ) > {
23
+ unimplemented ! ( )
24
+ }
25
+
26
+ /// Creates a new remote frame (RTR bit set).
27
+ /// Returns an error when the data length code (DLC) is not valid.
28
+ fn new_remote ( id : impl Into < Id > , dlc : usize ) -> Result < Self , ( ) > {
29
+ unimplemented ! ( )
30
+ }
31
+
32
+ /// Returns true if this frame is a extended frame.
33
+ fn is_extended ( & self ) -> bool {
34
+ unimplemented ! ( )
35
+ }
36
+
37
+
38
+ /// Returns true if this frame is a remote frame.
39
+ fn is_remote_frame ( & self ) -> bool {
40
+ unimplemented ! ( )
41
+ }
42
+
43
+ /// Returns the frame identifier.
44
+ fn id ( & self ) -> Id {
45
+ unimplemented ! ( )
46
+ }
47
+
48
+ /// Returns the data length code (DLC) which is in the range 0..8.
49
+ ///
50
+ /// For data frames the DLC value always matches the length of the data.
51
+ /// Remote frames do not carry any data, yet the DLC can be greater than 0.
52
+ fn dlc ( & self ) -> usize {
53
+ unimplemented ! ( )
54
+ }
55
+
56
+ /// Returns the frame data (0..8 bytes in length).
57
+ fn data ( & self ) -> & [ u8 ] {
58
+ unimplemented ! ( )
59
+ }
60
+ }
61
+
62
+ /// Can error
63
+ #[ derive( Debug ) ]
64
+ pub enum Error {
65
+ /// Overrun occurred
66
+ Overrun ,
67
+ /// Mode fault occurred
68
+ ModeFault ,
69
+ /// CRC error
70
+ Crc ,
71
+ #[ doc( hidden) ]
72
+ _Extensible,
73
+ }
74
+
75
+ pub enum CanMode {
76
+ Normal = 0b00 ,
77
+ Silent = 0b10 ,
78
+ Loopback = 0b01 ,
79
+ SilentLoopback = 0b11
80
+ }
81
+
82
+ #[ derive( Clone ) ]
83
+ pub struct TimeQuantaConfiguration {
84
+ pub sync : u8 ,
85
+ pub propagandation : u8 ,
86
+ pub before_sample : u8 ,
87
+ pub after_sample : u8
88
+ }
89
+
90
+ impl TimeQuantaConfiguration {
91
+ fn sum ( & self ) -> u32 {
92
+ ( self . sync + self . propagandation + self . before_sample + self . after_sample ) as u32
93
+ }
94
+ fn bs1 ( & self ) -> u8 {
95
+ self . propagandation + self . before_sample
96
+ }
97
+ fn bs2 ( & self ) -> u8 {
98
+ self . after_sample
99
+ }
100
+ }
101
+
102
+ #[ doc( hidden) ]
103
+ pub trait CanX : Deref < Target = can0:: RegisterBlock > { }
104
+ impl CanX for CAN0 { }
105
+ impl CanX for CAN1 { }
106
+
107
+ pub trait Pins < CAN > {
108
+ type Variant ;
109
+ const REMAP : Self :: Variant ;
110
+ }
111
+
112
+ impl Pins < CAN0 >
113
+ for (
114
+ PA11 < Input < Floating > > ,
115
+ PA12 < Alternate < PushPull > > ,
116
+ )
117
+ {
118
+ type Variant = u8 ;
119
+ const REMAP : u8 = 0b00 ;
120
+ }
121
+ impl Pins < CAN0 >
122
+ for (
123
+ PB8 < Input < Floating > > ,
124
+ PB9 < Alternate < PushPull > > ,
125
+ )
126
+ {
127
+ type Variant = u8 ;
128
+ const REMAP : u8 = 0b10 ;
129
+ }
130
+ impl Pins < CAN0 >
131
+ for (
132
+ PD0 < Input < Floating > > ,
133
+ PD1 < Alternate < PushPull > > ,
134
+ )
135
+ {
136
+ type Variant = u8 ;
137
+ const REMAP : u8 = 0b11 ;
138
+ }
139
+
140
+ impl Pins < CAN1 >
141
+ for (
142
+ PB12 < Input < Floating > > ,
143
+ PB13 < Alternate < PushPull > > ,
144
+ )
145
+ {
146
+ type Variant = bool ;
147
+ const REMAP : bool = false ;
148
+ }
149
+ impl Pins < CAN1 >
150
+ for (
151
+ PB5 < Input < Floating > > ,
152
+ PB6 < Alternate < PushPull > > ,
153
+ )
154
+ {
155
+ type Variant = bool ;
156
+ const REMAP : bool = true ;
157
+ }
158
+
159
+ pub struct Can < CAN , PINS > {
160
+ can : CAN ,
161
+ pins : PINS ,
162
+ }
163
+
164
+ impl < PINS : Pins < CAN0 , Variant =u8 > > Can < CAN0 , PINS > {
165
+ pub fn can0 (
166
+ can : CAN0 ,
167
+ pins : PINS ,
168
+ afio : & mut Afio ,
169
+ tqc : TimeQuantaConfiguration ,
170
+ mode : CanMode ,
171
+ freq : impl Into < Hertz > ,
172
+ rcu : & mut Rcu
173
+ ) -> Self
174
+ {
175
+ CAN0 :: remap ( afio, PINS :: REMAP ) ;
176
+ Can :: new ( can, pins, tqc, mode, freq, rcu)
177
+ }
178
+ }
179
+
180
+ impl < PINS : Pins < CAN1 , Variant =bool > > Can < CAN1 , PINS > {
181
+ pub fn can1 (
182
+ can : CAN1 ,
183
+ pins : PINS ,
184
+ afio : & mut Afio ,
185
+ tqc : TimeQuantaConfiguration ,
186
+ mode : CanMode ,
187
+ freq : impl Into < Hertz > ,
188
+ rcu : & mut Rcu
189
+ ) -> Self
190
+ {
191
+ CAN1 :: remap ( afio, PINS :: REMAP ) ;
192
+ Can :: new ( can, pins, tqc, mode, freq, rcu)
193
+ }
194
+ }
195
+
196
+
197
+ impl < CAN , PINS > Can < CAN , PINS > where CAN : CanX
198
+ {
199
+ const MAX_PSC : u16 = 0b111111111 ;
200
+ fn new (
201
+ can : CAN ,
202
+ pins : PINS ,
203
+ tqc : TimeQuantaConfiguration ,
204
+ mode : CanMode ,
205
+ freq : impl Into < Hertz > ,
206
+ rcu : & mut Rcu
207
+ ) -> Self where CAN : Enable + Reset + BaseFrequency {
208
+
209
+ let baudpsc: u16 = (
210
+ CAN :: base_frequency ( rcu) . 0 / ( freq. into ( ) . 0 * tqc. sum ( ) )
211
+ ) . try_into ( ) . unwrap_or ( Self :: MAX_PSC ) ;
212
+ let baudpsc: u16 = if baudpsc > Self :: MAX_PSC {
213
+ Self :: MAX_PSC
214
+ } else if baudpsc == 0 {
215
+ unreachable ! ( ) ;
216
+ } else {
217
+ baudpsc
218
+ } ;
219
+
220
+ CAN :: enable ( rcu) ;
221
+ CAN :: reset ( rcu) ;
222
+ can. bt . write ( |w| unsafe { w
223
+ . baudpsc ( ) . bits ( baudpsc)
224
+ . scmod ( ) . bit ( match mode {
225
+ CanMode :: Silent | CanMode :: SilentLoopback => { true } ,
226
+ _ => { false } ,
227
+ } )
228
+ . lcmod ( ) . bit ( match mode {
229
+ CanMode :: Loopback | CanMode :: SilentLoopback => { true } ,
230
+ _ => { false } ,
231
+ } )
232
+ . sjw ( ) . bits ( tqc. sync )
233
+ . bs1 ( ) . bits ( tqc. bs1 ( ) )
234
+ . bs2 ( ) . bits ( tqc. bs2 ( ) )
235
+ } ) ;
236
+ Can { can, pins}
237
+ }
238
+ }
239
+
240
+
241
+ /// A CAN interface that is able to transmit and receive frames.
242
+ impl < CAN , PINS > CanTrait for Can < CAN , PINS > {
243
+ /// Associated frame type.
244
+ type Frame = Frame ;
245
+
246
+ /// Associated error type.
247
+ type Error = Error ;
248
+
249
+ /// Puts a frame in the transmit buffer to be sent on the bus.
250
+ ///
251
+ /// If the transmit buffer is full, this function will try to replace a pending
252
+ /// lower priority frame and return the frame that was replaced.
253
+ /// Returns `Err(WouldBlock)` if the transmit buffer is full and no frame can be
254
+ /// replaced.
255
+ ///
256
+ /// # Notes for implementers
257
+ ///
258
+ /// * Frames of equal identifier shall be transmited in FIFO fashion when more
259
+ /// than one transmit buffer is available.
260
+ /// * When replacing pending frames make sure the frame is not in the process of
261
+ /// being send to the bus.
262
+ fn try_transmit ( & mut self , frame : & Self :: Frame )
263
+ -> nb:: Result < Option < Self :: Frame > , Self :: Error > {
264
+ unimplemented ! ( )
265
+ }
266
+
267
+ /// Returns a received frame if available.
268
+ fn try_receive ( & mut self ) -> nb:: Result < Self :: Frame , Self :: Error > {
269
+ unimplemented ! ( )
270
+ }
271
+ }
0 commit comments