-
Notifications
You must be signed in to change notification settings - Fork 182
/
Copy pathcan-echo.rs
85 lines (68 loc) · 2.61 KB
/
can-echo.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! Simple CAN example.
//! Requires a transceiver connected to PA11, PA12 (CAN1) or PB5 PB6 (CAN2).
#![no_main]
#![no_std]
use bxcan::Fifo;
use panic_halt as _;
use bxcan::filter::Mask32;
use cortex_m_rt::entry;
use nb::block;
use stm32f1xx_hal::{pac, prelude::*};
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
// To meet CAN clock accuracy requirements an external crystal or ceramic
// resonator must be used. The blue pill has a 8MHz external crystal.
// Other boards might have a crystal with another frequency or none at all.
rcc.cfgr.use_hse(8.MHz()).freeze(&mut flash.acr);
let mut can1 = {
let gpioa = dp.GPIOA.split();
let rx = gpioa.pa11;
let tx = gpioa.pa12;
let can = dp.CAN1.can(
#[cfg(not(feature = "connectivity"))]
dp.USB,
(tx, rx),
);
// APB1 (PCLK1): 8MHz, Bit rate: 125kBit/s, Sample Point 87.5%
// Value was calculated with http://www.bittiming.can-wiki.info/
bxcan::Can::builder(can)
.set_bit_timing(0x001c_0003)
.leave_disabled()
};
// Configure filters so that can frames can be received.
let mut filters = can1.modify_filters();
filters.enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
#[cfg(feature = "connectivity")]
let _can2 = {
let gpiob = dp.GPIOB.split();
let can = dp.CAN2.can((gpiob.pb6, gpiob.pb5));
// APB1 (PCLK1): 8MHz, Bit rate: 125kBit/s, Sample Point 87.5%
// Value was calculated with http://www.bittiming.can-wiki.info/
let can2 = bxcan::Can::builder(can)
.set_bit_timing(0x001c_0003)
.leave_disabled();
// A total of 28 filters are shared between the two CAN instances.
// Split them equally between CAN1 and CAN2.
let mut slave_filters = filters.set_split(14).slave_filters();
slave_filters.enable_bank(14, Fifo::Fifo0, Mask32::accept_all());
can2
};
// Drop filters to leave filter configuraiton mode.
drop(filters);
// Select the interface.
let mut can = can1;
//let mut can = _can2;
// Split the peripheral into transmitter and receiver parts.
block!(can.enable_non_blocking()).unwrap();
// Echo back received packages in sequence.
// See the `can-rtfm` example for an echo implementation that adheres to
// correct frame ordering based on the transfer id.
loop {
if let Ok(frame) = block!(can.receive()) {
block!(can.transmit(&frame)).unwrap();
}
}
}