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
|
#![no_std]
#![no_main]
// required-features: fdcan
#[path = "../common.rs"]
mod common;
use common::*;
use embassy_executor::Spawner;
use embassy_stm32::peripherals::*;
use embassy_stm32::{Config, bind_interrupts, can};
use embassy_time::Duration;
use {defmt_rtt as _, panic_probe as _};
#[path = "../can_common.rs"]
mod can_common;
use can_common::*;
bind_interrupts!(struct Irqs2 {
FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;
});
bind_interrupts!(struct Irqs1 {
FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
});
#[cfg(feature = "stm32h563zi")]
fn options() -> (Config, TestOptions) {
info!("H563 config");
(
config(),
TestOptions {
max_latency: Duration::from_micros(1200),
max_buffered: 3,
},
)
}
#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))]
fn options() -> (Config, TestOptions) {
use embassy_stm32::rcc;
info!("H75 config");
let mut c = config();
c.rcc.hse = Some(rcc::Hse {
freq: embassy_stm32::time::Hertz(25_000_000),
mode: rcc::HseMode::Oscillator,
});
c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
(
c,
TestOptions {
max_latency: Duration::from_micros(1200),
max_buffered: 3,
},
)
}
#[cfg(any(feature = "stm32h7a3zi"))]
fn options() -> (Config, TestOptions) {
use embassy_stm32::rcc;
info!("H7a config");
let mut c = config();
c.rcc.hse = Some(rcc::Hse {
freq: embassy_stm32::time::Hertz(25_000_000),
mode: rcc::HseMode::Oscillator,
});
c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
(
c,
TestOptions {
max_latency: Duration::from_micros(1200),
max_buffered: 3,
},
)
}
#[cfg(any(feature = "stm32h7s3l8"))]
fn options() -> (Config, TestOptions) {
use embassy_stm32::rcc;
let mut c = config();
c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
(
c,
TestOptions {
max_latency: Duration::from_micros(1200),
max_buffered: 3,
},
)
}
#[cfg(any(feature = "stm32g491re"))]
fn options() -> (Config, TestOptions) {
info!("G4 config");
(
config(),
TestOptions {
max_latency: Duration::from_micros(500),
max_buffered: 6,
},
)
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
//let peripherals = init();
let (config, options) = options();
let peripherals = init_with_config(config);
let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1);
let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2);
// 250k bps
can.set_bitrate(250_000);
can2.set_bitrate(250_000);
can.properties().set_extended_filter(
can::filter::ExtendedFilterSlot::_0,
can::filter::ExtendedFilter::accept_all_into_fifo1(),
);
can2.properties().set_extended_filter(
can::filter::ExtendedFilterSlot::_0,
can::filter::ExtendedFilter::accept_all_into_fifo1(),
);
let mut can = can.into_internal_loopback_mode();
let mut can2 = can2.into_internal_loopback_mode();
run_can_tests(&mut can, &options).await;
run_can_tests(&mut can2, &options).await;
info!("CAN Configured");
// Test again with a split
let (mut tx, mut rx, _props) = can.split();
let (mut tx2, mut rx2, _props) = can2.split();
run_split_can_tests(&mut tx, &mut rx, &options).await;
run_split_can_tests(&mut tx2, &mut rx2, &options).await;
info!("Test OK");
cortex_m::asm::bkpt();
}
|