Skip to content

Commit 5267f64

Browse files
author
Cor Peters
committed
Initial FDCAN support
1 parent 9806346 commit 5267f64

23 files changed

+5605
-3
lines changed

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ cortex-m = "0.7.1"
1616
nb = "0.1.1"
1717
stm32g4 = "0.13.0"
1818
paste = "1.0"
19+
bitflags = "1.2"
20+
vcell = "0.1"
21+
static_assertions = "1.1"
1922

2023
[dependencies.cast]
2124
version = "0.2.7"
@@ -40,6 +43,10 @@ version = "1.0.2"
4043
default-features = false
4144
version = "1.1"
4245

46+
[dependencies.defmt]
47+
version = "0.2.3"
48+
optional = true
49+
4350
[dev-dependencies]
4451
cortex-m-rt = "0.6.10"
4552
cortex-m-rtfm = "0.5.1"
@@ -55,6 +62,7 @@ rtt-target = { version = "0.3.0", features = ["cortex-m"] }
5562
panic-rtt-target = { version = "0.1.1", features = ["cortex-m"] }
5663
mpu6050 = "0.1.4"
5764

65+
#TODO: Separate feature sets
5866
[features]
5967
default = ["rt"]
6068
rt = ["stm32g4/rt"]
@@ -70,6 +78,7 @@ stm32g4a1 = ["stm32g4/stm32g4a1"]
7078
log-itm = ["cortex-m-log/itm"]
7179
log-rtt = []
7280
log-semihost = ["cortex-m-log/semihosting"]
81+
unstable-defmt = ["defmt"]
7382

7483
[profile.dev]
7584
codegen-units = 1

examples/can-echo.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use crate::hal::{
5+
fdcan::{
6+
config::NominalBitTiming,
7+
filter::{StandardFilter, StandardFilterSlot},
8+
frame::{FrameFormat, TxFrameHeader},
9+
id::StandardId,
10+
FdCan,
11+
},
12+
gpio::{GpioExt as _, Speed},
13+
nb::block,
14+
rcc::{Config, RccExt, SysClockSrc},
15+
stm32::Peripherals,
16+
time::U32Ext,
17+
};
18+
use stm32g4xx_hal as hal;
19+
20+
use core::num::{NonZeroU16, NonZeroU8};
21+
22+
use cortex_m_rt::entry;
23+
24+
use log::info;
25+
26+
#[macro_use]
27+
mod utils;
28+
29+
#[entry]
30+
fn main() -> ! {
31+
utils::logger::init();
32+
33+
info!("Start");
34+
35+
// APB1 (HSE): 24MHz, Bit rate: 125kBit/s, Sample Point 87.5%
36+
// Value was calculated with http://www.bittiming.can-wiki.info/
37+
// TODO: use the can_bit_timings crate
38+
let btr = NominalBitTiming {
39+
prescaler: NonZeroU16::new(12).unwrap(),
40+
seg1: NonZeroU8::new(13).unwrap(),
41+
seg2: NonZeroU8::new(2).unwrap(),
42+
sync_jump_width: NonZeroU8::new(1).unwrap(),
43+
};
44+
45+
info!("Init Clocks");
46+
47+
let dp = Peripherals::take().unwrap();
48+
let _cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");
49+
let rcc = dp.RCC.constrain();
50+
let mut rcc = rcc.freeze(Config::new(SysClockSrc::HSE(24.mhz())));
51+
52+
info!("Split GPIO");
53+
54+
let gpiob = dp.GPIOB.split(&mut rcc);
55+
56+
let can1 = {
57+
info!("Init CAN 1");
58+
let rx = gpiob.pb8.into_alternate().set_speed(Speed::VeryHigh);
59+
let tx = gpiob.pb9.into_alternate().set_speed(Speed::VeryHigh);
60+
61+
info!("-- Create CAN 1 instance");
62+
let can = FdCan::new(dp.FDCAN1, tx, rx, &rcc);
63+
64+
info!("-- Set CAN 1 in Config Mode");
65+
let mut can = can.into_config_mode();
66+
can.set_protocol_exception_handling(false);
67+
68+
info!("-- Configure nominal timing");
69+
can.set_nominal_bit_timing(btr);
70+
71+
info!("-- Configure Filters");
72+
can.set_standard_filter(
73+
StandardFilterSlot::_0,
74+
StandardFilter::accept_all_into_fifo0(),
75+
);
76+
77+
info!("-- Current Config: {:#?}", can.get_config());
78+
79+
info!("-- Set CAN1 in to normal mode");
80+
// can.into_external_loopback()
81+
can.into_normal()
82+
};
83+
84+
let can2 = {
85+
info!("Init CAN 2");
86+
let rx = gpiob.pb5.into_alternate().set_speed(Speed::VeryHigh);
87+
let tx = gpiob.pb13.into_alternate().set_speed(Speed::VeryHigh);
88+
89+
info!("-- Create CAN 2 instance");
90+
let can = FdCan::new(dp.FDCAN2, tx, rx, &rcc);
91+
92+
info!("-- Set CAN in Config Mode");
93+
let mut can = can.into_config_mode();
94+
95+
info!("-- Configure nominal timing");
96+
can.set_nominal_bit_timing(btr);
97+
98+
info!("-- Configure Filters");
99+
can.set_standard_filter(
100+
StandardFilterSlot::_0,
101+
StandardFilter::accept_all_into_fifo0(),
102+
);
103+
104+
info!("-- Set CAN2 in to normal mode");
105+
// can.into_external_loopback()
106+
can.into_normal()
107+
};
108+
109+
let mut can = can2;
110+
111+
info!("Create Message Data");
112+
let mut buffer = [0xAAAAAAAA, 0xFFFFFFFF, 0x0, 0x0, 0x0, 0x0];
113+
info!("Create Message Header");
114+
let header = TxFrameHeader {
115+
len: 2 * 4,
116+
id: StandardId::new(0x1).unwrap().into(),
117+
frame_format: FrameFormat::Standard,
118+
bit_rate_switching: false,
119+
marker: None,
120+
};
121+
info!("Initial Header: {:#X?}", &header);
122+
123+
info!("Transmit initial message");
124+
block!(can.transmit(header, &mut |b| {
125+
let len = b.len();
126+
for i in 0..len {
127+
b[i] = buffer[i];
128+
}
129+
},))
130+
.unwrap();
131+
132+
loop {
133+
if let Ok(rxheader) = block!(can.receive0(&mut |h, b| {
134+
info!("Received Header: {:#X?}", &h);
135+
info!("received data: {:X?}", &b);
136+
137+
for (i, d) in b.iter().enumerate() {
138+
buffer[i] = *d;
139+
}
140+
h
141+
})) {
142+
block!(
143+
can.transmit(rxheader.unwrap().to_tx_header(None), &mut |b| {
144+
let len = b.len();
145+
for i in 0..len {
146+
b[i] = buffer[i];
147+
}
148+
info!("Transmit: {:X?}", b);
149+
})
150+
)
151+
.unwrap();
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)