@@ -24,6 +24,36 @@ use core::sync::atomic::{AtomicU8, Ordering};
2424const EXID_MASK : u32 = 0b1_1111_1111_1100_0000_0000_0000_0000 ;
2525const MAX_EXTENDED_ID : u32 = 0x1FFF_FFFF ;
2626
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+
2757/// A CAN identifier, which can be either 11 or 27 (extended) bits.
2858/// u16 and u32 respectively are used here despite the fact that the upper bits are unused.
2959#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
@@ -252,42 +282,27 @@ impl CanFilterData {
252282}
253283
254284impl Can {
255- /// Initialize the CAN Peripheral
256- pub fn new (
285+ pub fn new_with_opts (
257286 can : stm32:: CAN ,
258287 rx : gpioa:: PA11 < AF9 > ,
259288 tx : gpioa:: PA12 < AF9 > ,
260289 apb1 : & mut APB1 ,
261- ) -> Self {
290+ opts : CanOpts ,
291+ ) -> Can {
262292 apb1. enr ( ) . modify ( |_, w| w. canen ( ) . enabled ( ) ) ;
263293 can. mcr . modify ( |_, w| w. sleep ( ) . clear_bit ( ) ) ;
264294 can. mcr . modify ( |_, w| w. inrq ( ) . set_bit ( ) ) ;
265295
266296 // Wait for INAK to confirm we have entered initialization mode
267297 while !can. msr . read ( ) . inak ( ) . bit_is_set ( ) { }
268298
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;
291306 can. btr . modify ( |_, w| unsafe {
292307 w. brp ( )
293308 . bits ( brp)
@@ -297,8 +312,8 @@ impl Can {
297312 . bits ( ts1)
298313 . ts2 ( )
299314 . bits ( ts2)
300- // .lbkm()
301- //.set_bit( )
315+ . lbkm ( )
316+ . bit ( lbkm )
302317 } ) ;
303318
304319 // Leave initialization mode by clearing INRQ and switch to normal mode
@@ -312,6 +327,15 @@ impl Can {
312327 _tx : tx,
313328 }
314329 }
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+ }
315339
316340 /// Enable CAN event interrupts for `Event`
317341 pub fn listen ( & mut self , event : Event ) {
@@ -407,7 +431,7 @@ impl embedded_hal_can::Transmitter for CanTransmitter {
407431
408432 // NOTE(unsafe): full 8bit write is unsafe via the svd2rust api
409433 tx. tdtr
410- . modify ( |_, w| unsafe { w. dlc ( ) . bits ( data . len ( ) as u8 ) } ) ;
434+ . modify ( |_, w| unsafe { w. dlc ( ) . bits ( frame . dlc as u8 ) } ) ;
411435
412436 tx. tir . modify ( |_, w| w. rtr ( ) . clear_bit ( ) ) ;
413437 } else {
@@ -579,4 +603,8 @@ impl CanFrame {
579603 data : [ 0 ; 8 ] ,
580604 }
581605 }
606+
607+ pub fn len ( & self ) -> usize {
608+ self . dlc
609+ }
582610}
0 commit comments