forked from stm32-rs/stm32h7xx-hal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
can-echo.rs
144 lines (119 loc) · 4.12 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! Basic Controller Area Network (CAN bus) example
//!
//! The example is configured to use loopback mode. In this mode each packet
//! that is sent appears on the devices pins, but is also received by the
//! peripheral. To receive packets from external devices, uncomment the
//! `can.into_normal()` method.
//!
//! Tested on a STM32H735G-DK
#![no_main]
#![no_std]
use crate::hal::{
gpio::{GpioExt as _, Speed},
nb::block,
pac,
prelude::*,
rcc,
rcc::rec,
};
use fdcan::{
config::NominalBitTiming,
filter::{StandardFilter, StandardFilterSlot},
frame::{FrameFormat, TxFrameHeader},
id::StandardId,
};
use stm32h7xx_hal as hal;
use core::num::{NonZeroU16, NonZeroU8};
use cortex_m_rt::entry;
use log::info;
#[macro_use]
mod utilities;
#[entry]
fn main() -> ! {
utilities::logger::init();
// Kernel Clock 24MHz, Bit rate: 125kBit/s, Sample Point 87.5%
// Value was calculated with http://www.bittiming.can-wiki.info/
// TODO: use the can_bit_timings crate
let btr = NominalBitTiming {
prescaler: NonZeroU16::new(12).unwrap(),
seg1: NonZeroU8::new(13).unwrap(),
seg2: NonZeroU8::new(2).unwrap(),
sync_jump_width: NonZeroU8::new(1).unwrap(),
};
let dp = pac::Peripherals::take().unwrap();
let cp =
cortex_m::Peripherals::take().expect("cannot take core peripherals");
// Constrain and Freeze power
info!("Setup PWR... ");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
// Constrain and Freeze clock
info!("Setup RCC... ");
let rcc = dp.RCC.constrain();
let ccdr = rcc
.sys_ck(192.MHz())
.pll1_strategy(rcc::PllConfigStrategy::Iterative)
.pll1_q_ck(24.MHz())
.freeze(pwrcfg, &dp.SYSCFG);
// Setup fdcan_tq_ck = 24MHz
assert_eq!(ccdr.clocks.pll1_q_ck().unwrap().raw(), 24_000_000);
let fdcan_prec = ccdr
.peripheral
.FDCAN
.kernel_clk_mux(rec::FdcanClkSel::Pll1Q);
let mut delay = cp.SYST.delay(ccdr.clocks);
let can1 = {
info!("Init CAN 1");
let gpioh = dp.GPIOH.split(ccdr.peripheral.GPIOH);
let rx = gpioh.ph14.into_alternate().speed(Speed::VeryHigh);
let tx = gpioh.ph13.into_alternate().speed(Speed::VeryHigh);
info!("-- Create CAN 1 instance");
dp.FDCAN1.fdcan(tx, rx, fdcan_prec)
};
// let can2 = {
// info!("Init CAN 2");
// let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
// let rx = gpiob.pb5.into_alternate().speed(Speed::VeryHigh);
// let tx = gpiob.pb6.into_alternate().speed(Speed::VeryHigh);
// info!("-- Create CAN 2 instance");
// dp.FDCAN2.fdcan(tx, rx, fdcan_prec)
// };
let mut can = can1;
can.set_protocol_exception_handling(false);
info!("-- Configure nominal timing");
can.set_nominal_bit_timing(btr);
info!("-- Configure Filters");
can.set_standard_filter(
StandardFilterSlot::_0,
StandardFilter::accept_all_into_fifo0(),
);
info!("-- Set CAN into normal mode");
let mut can = can.into_external_loopback();
//let mut can = can.into_normal();
info!("Create Message Data");
let mut buffer = [
0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
];
info!("Create Message Header");
let header = TxFrameHeader {
len: 2 * 4,
id: StandardId::new(0x1).unwrap().into(),
frame_format: FrameFormat::Standard,
bit_rate_switching: false,
marker: None,
};
info!("Initial Header: {:#X?}", &header);
info!("Transmit initial message");
block!(can.transmit(header, &buffer)).unwrap();
loop {
if let Ok(rxheader) = block!(can.receive0(&mut buffer)) {
info!("Received Header: {:#X?}", rxheader);
info!("received data: {:X?}", &buffer);
delay.delay_ms(1_u16);
block!(can.transmit(rxheader.unwrap().to_tx_header(None), &buffer))
.unwrap();
info!("Transmit: {:X?}", buffer);
}
}
}