@@ -24,6 +24,36 @@ use core::sync::atomic::{AtomicU8, Ordering};
24
24
const EXID_MASK : u32 = 0b1_1111_1111_1100_0000_0000_0000_0000 ;
25
25
const MAX_EXTENDED_ID : u32 = 0x1FFF_FFFF ;
26
26
27
+ /// Options the CAN bus. This is primarily used to set bus timings, but also controls options like enabling loopback or silent mode for debugging.
28
+ /// See http://www.bittiming.can-wiki.info/#bxCAN for generating the timing parameters for different baud rates and clocks.
29
+ ///
30
+ /// Use `CanBitRateOpts::default()` to get 250kbps at 32mhz system clock
31
+ pub struct CanOpts {
32
+ pub brp : u16 ,
33
+ pub sjw : u8 ,
34
+ pub ts1 : u8 ,
35
+ pub ts2 : u8 ,
36
+ pub lbkm : bool ,
37
+ }
38
+
39
+ impl CanOpts {
40
+ pub fn new ( brp : u16 , sjw : u8 , ts1 : u8 , ts2 : u8 , lbkm : bool ) -> CanOpts {
41
+ CanOpts {
42
+ brp,
43
+ sjw,
44
+ ts1,
45
+ ts2,
46
+ lbkm,
47
+ }
48
+ }
49
+ }
50
+
51
+ impl Default for CanOpts {
52
+ fn default ( ) -> Self {
53
+ CanOpts :: new ( 4 , 0 , 10 , 3 , false )
54
+ }
55
+ }
56
+
27
57
/// A CAN identifier, which can be either 11 or 27 (extended) bits.
28
58
/// u16 and u32 respectively are used here despite the fact that the upper bits are unused.
29
59
#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
@@ -252,42 +282,27 @@ impl CanFilterData {
252
282
}
253
283
254
284
impl Can {
255
- /// Initialize the CAN Peripheral
256
- pub fn new (
285
+ pub fn new_with_opts (
257
286
can : stm32:: CAN ,
258
287
rx : gpioa:: PA11 < AF9 > ,
259
288
tx : gpioa:: PA12 < AF9 > ,
260
289
apb1 : & mut APB1 ,
261
- ) -> Self {
290
+ opts : CanOpts ,
291
+ ) -> Can {
262
292
apb1. enr ( ) . modify ( |_, w| w. canen ( ) . enabled ( ) ) ;
263
293
can. mcr . modify ( |_, w| w. sleep ( ) . clear_bit ( ) ) ;
264
294
can. mcr . modify ( |_, w| w. inrq ( ) . set_bit ( ) ) ;
265
295
266
296
// Wait for INAK to confirm we have entered initialization mode
267
297
while !can. msr . read ( ) . inak ( ) . bit_is_set ( ) { }
268
298
269
- // TODO: actually calculate baud params
270
-
271
- // Our baud rate calc here is aiming for roughly 4000uS total bit time or about 250kbps
272
- // Though we actually allow closer to 5500uS total given the sjw setting
273
- // Calculations for timing value from http://www.bittiming.can-wiki.info/#bxCAN
274
-
275
- // Baud rate prescaler defines time quanta
276
- // tq = (BRP[9:0]+1) x tPCLK
277
- let brp: u16 = 4 ;
278
-
279
- // Resynchronization jump width: number of quanta segments may be expanded to resync
280
- // tRJW = tq x (SJW[1:0] + 1)
281
- let sjw = 0 ;
282
-
283
- // Time seg 2
284
- // tBS2 = tq x (TS2[2:0] + 1)
285
- let ts2 = 3 ;
286
-
287
- // Time seg 1
288
- // tBS1 = tq x (TS1[3:0] + 1)
289
- let ts1 = 10 ;
290
-
299
+ let CanOpts {
300
+ brp,
301
+ sjw,
302
+ ts1,
303
+ ts2,
304
+ lbkm,
305
+ } = opts;
291
306
can. btr . modify ( |_, w| unsafe {
292
307
w. brp ( )
293
308
. bits ( brp)
@@ -297,8 +312,8 @@ impl Can {
297
312
. bits ( ts1)
298
313
. ts2 ( )
299
314
. bits ( ts2)
300
- // .lbkm()
301
- //.set_bit( )
315
+ . lbkm ( )
316
+ . bit ( lbkm )
302
317
} ) ;
303
318
304
319
// Leave initialization mode by clearing INRQ and switch to normal mode
@@ -312,6 +327,15 @@ impl Can {
312
327
_tx : tx,
313
328
}
314
329
}
330
+ /// Initialize the CAN Peripheral
331
+ pub fn new (
332
+ can : stm32:: CAN ,
333
+ rx : gpioa:: PA11 < AF9 > ,
334
+ tx : gpioa:: PA12 < AF9 > ,
335
+ apb1 : & mut APB1 ,
336
+ ) -> Self {
337
+ Can :: new_with_opts ( can, rx, tx, apb1, CanOpts :: default ( ) )
338
+ }
315
339
316
340
/// Enable CAN event interrupts for `Event`
317
341
pub fn listen ( & mut self , event : Event ) {
@@ -407,7 +431,7 @@ impl embedded_hal_can::Transmitter for CanTransmitter {
407
431
408
432
// NOTE(unsafe): full 8bit write is unsafe via the svd2rust api
409
433
tx. tdtr
410
- . modify ( |_, w| unsafe { w. dlc ( ) . bits ( data . len ( ) as u8 ) } ) ;
434
+ . modify ( |_, w| unsafe { w. dlc ( ) . bits ( frame . dlc as u8 ) } ) ;
411
435
412
436
tx. tir . modify ( |_, w| w. rtr ( ) . clear_bit ( ) ) ;
413
437
} else {
@@ -579,4 +603,8 @@ impl CanFrame {
579
603
data : [ 0 ; 8 ] ,
580
604
}
581
605
}
606
+
607
+ pub fn len ( & self ) -> usize {
608
+ self . dlc
609
+ }
582
610
}
0 commit comments