Skip to content

Commit ad3bf09

Browse files
zklapowSh3Rm4n
authored andcommitted
support more CAN config; fix length for tx
1 parent 1053b01 commit ad3bf09

File tree

1 file changed

+56
-28
lines changed

1 file changed

+56
-28
lines changed

src/can.rs

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,36 @@ use core::sync::atomic::{AtomicU8, Ordering};
2424
const EXID_MASK: u32 = 0b1_1111_1111_1100_0000_0000_0000_0000;
2525
const 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

254284
impl 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

Comments
 (0)