aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/stm32/src/bin/can.rs50
-rw-r--r--tests/stm32/src/bin/can_common.rs112
-rw-r--r--tests/stm32/src/bin/fdcan.rs195
3 files changed, 163 insertions, 194 deletions
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index c08c69a3b..74d84c42f 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -6,17 +6,19 @@
6#[path = "../common.rs"] 6#[path = "../common.rs"]
7mod common; 7mod common;
8use common::*; 8use common::*;
9use defmt::assert;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::bind_interrupts; 10use embassy_stm32::bind_interrupts;
12use embassy_stm32::can::bx::filter::Mask32; 11use embassy_stm32::can::bx::filter::Mask32;
13use embassy_stm32::can::bx::{Fifo, Frame, StandardId}; 12use embassy_stm32::can::bx::Fifo;
14use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; 13use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler};
15use embassy_stm32::gpio::{Input, Pull}; 14use embassy_stm32::gpio::{Input, Pull};
16use embassy_stm32::peripherals::CAN1; 15use embassy_stm32::peripherals::CAN1;
17use embassy_time::{Duration, Instant}; 16use embassy_time::Duration;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
19mod can_common;
20use can_common::*;
21
20bind_interrupts!(struct Irqs { 22bind_interrupts!(struct Irqs {
21 CAN1_RX0 => Rx0InterruptHandler<CAN1>; 23 CAN1_RX0 => Rx0InterruptHandler<CAN1>;
22 CAN1_RX1 => Rx1InterruptHandler<CAN1>; 24 CAN1_RX1 => Rx1InterruptHandler<CAN1>;
@@ -29,6 +31,11 @@ async fn main(_spawner: Spawner) {
29 let p = embassy_stm32::init(config()); 31 let p = embassy_stm32::init(config());
30 info!("Hello World!"); 32 info!("Hello World!");
31 33
34 let options = TestOptions {
35 max_latency: Duration::from_micros(1200),
36 max_buffered: 2,
37 };
38
32 let can = peri!(p, CAN); 39 let can = peri!(p, CAN);
33 let tx = peri!(p, CAN_TX); 40 let tx = peri!(p, CAN_TX);
34 let mut rx = peri!(p, CAN_RX); 41 let mut rx = peri!(p, CAN_RX);
@@ -58,40 +65,13 @@ async fn main(_spawner: Spawner) {
58 65
59 info!("Can configured"); 66 info!("Can configured");
60 67
61 let mut i: u8 = 0; 68 run_can_tests(&mut can, &options).await;
62 loop {
63 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap();
64
65 info!("Transmitting frame...");
66 let tx_ts = Instant::now();
67 can.write(&tx_frame).await;
68
69 let envelope = can.read().await.unwrap();
70 info!("Frame received!");
71 69
72 info!("loopback time {}", envelope.ts); 70 // Test again with a split
73 info!("loopback frame {=u8}", envelope.frame.data()[0]); 71 let (mut tx, mut rx) = can.split();
74 72 run_split_can_tests(&mut tx, &mut rx, &options).await;
75 let latency = envelope.ts.saturating_duration_since(tx_ts);
76 info!("loopback latency {} us", latency.as_micros());
77
78 // Theoretical minimum latency is 55us, actual is usually ~80us
79 const MIN_LATENCY: Duration = Duration::from_micros(50);
80 const MAX_LATENCY: Duration = Duration::from_micros(150);
81 assert!(
82 MIN_LATENCY <= latency && latency <= MAX_LATENCY,
83 "{} <= {} <= {}",
84 MIN_LATENCY,
85 latency,
86 MAX_LATENCY
87 );
88
89 i += 1;
90 if i > 10 {
91 break;
92 }
93 }
94 73
95 info!("Test OK"); 74 info!("Test OK");
75
96 cortex_m::asm::bkpt(); 76 cortex_m::asm::bkpt();
97} 77}
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/bin/can_common.rs
new file mode 100644
index 000000000..4b39269cc
--- /dev/null
+++ b/tests/stm32/src/bin/can_common.rs
@@ -0,0 +1,112 @@
1use defmt::{assert, *};
2use embassy_stm32::can;
3use embassy_time::{Duration, Instant};
4
5#[derive(Clone, Copy, Debug)]
6pub struct TestOptions {
7 pub max_latency: Duration,
8 pub max_buffered: u8,
9}
10
11pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) {
12 let mut i: u8 = 0;
13 loop {
14 //let tx_frame = can::frame::Frame::new_standard(0x123, &[i, 0x12 as u8, 0x34 as u8, 0x56 as u8, 0x78 as u8, 0x9A as u8, 0xBC as u8 ]).unwrap();
15 let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap();
16
17 //info!("Transmitting frame...");
18 let tx_ts = Instant::now();
19 can.write(&tx_frame).await;
20
21 let (frame, timestamp) = can.read().await.unwrap().parts();
22 //info!("Frame received!");
23
24 // Check data.
25 assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]);
26
27 //info!("loopback time {}", timestamp);
28 //info!("loopback frame {=u8}", frame.data()[0]);
29 let latency = timestamp.saturating_duration_since(tx_ts);
30 info!("loopback latency {} us", latency.as_micros());
31
32 // Theoretical minimum latency is 55us, actual is usually ~80us
33 const MIN_LATENCY: Duration = Duration::from_micros(50);
34 // Was failing at 150 but we are not getting a real time stamp. I'm not
35 // sure if there are other delays
36 assert!(
37 MIN_LATENCY <= latency && latency <= options.max_latency,
38 "{} <= {} <= {}",
39 MIN_LATENCY,
40 latency,
41 options.max_latency
42 );
43
44 i += 1;
45 if i > 5 {
46 break;
47 }
48 }
49
50 // Below here, check that we can receive from both FIFO0 and FIFO1
51 // Above we configured FIFO1 for extended ID packets. There are only 3 slots
52 // in each FIFO so make sure we write enough to fill them both up before reading.
53 for i in 0..options.max_buffered {
54 // Try filling up the RX FIFO0 buffers
55 //let tx_frame = if 0 != (i & 0x01) {
56 let tx_frame = if i < options.max_buffered / 2 {
57 info!("Transmitting standard frame {}", i);
58 can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap()
59 } else {
60 info!("Transmitting extended frame {}", i);
61 can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap()
62 };
63 can.write(&tx_frame).await;
64 }
65
66 // Try and receive all 6 packets
67 for _i in 0..options.max_buffered {
68 let (frame, _ts) = can.read().await.unwrap().parts();
69 match frame.id() {
70 embedded_can::Id::Extended(_id) => {
71 info!("Extended received! {}", frame.data()[0]);
72 //info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
73 }
74 embedded_can::Id::Standard(_id) => {
75 info!("Standard received! {}", frame.data()[0]);
76 //info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
77 }
78 }
79 }
80}
81
82pub async fn run_split_can_tests<'d, T: can::Instance>(
83 tx: &mut can::CanTx<'d, T>,
84 rx: &mut can::CanRx<'d, T>,
85 options: &TestOptions,
86) {
87 for i in 0..options.max_buffered {
88 // Try filling up the RX FIFO0 buffers
89 //let tx_frame = if 0 != (i & 0x01) {
90 let tx_frame = if i < options.max_buffered / 2 {
91 info!("Transmitting standard frame {}", i);
92 can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap()
93 } else {
94 info!("Transmitting extended frame {}", i);
95 can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap()
96 };
97 tx.write(&tx_frame).await;
98 }
99
100 // Try and receive all 6 packets
101 for _i in 0..options.max_buffered {
102 let (frame, _ts) = rx.read().await.unwrap().parts();
103 match frame.id() {
104 embedded_can::Id::Extended(_id) => {
105 info!("Extended received! {}", frame.data()[0]);
106 }
107 embedded_can::Id::Standard(_id) => {
108 info!("Standard received! {}", frame.data()[0]);
109 }
110 }
111 }
112}
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index bddfa7684..27bdd038a 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -6,13 +6,15 @@
6#[path = "../common.rs"] 6#[path = "../common.rs"]
7mod common; 7mod common;
8use common::*; 8use common::*;
9use defmt::assert;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::peripherals::*; 10use embassy_stm32::peripherals::*;
12use embassy_stm32::{bind_interrupts, can, Config}; 11use embassy_stm32::{bind_interrupts, can, Config};
13use embassy_time::{Duration, Instant}; 12use embassy_time::Duration;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
15mod can_common;
16use can_common::*;
17
16bind_interrupts!(struct Irqs2 { 18bind_interrupts!(struct Irqs2 {
17 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; 19 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
18 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; 20 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;
@@ -22,14 +24,8 @@ bind_interrupts!(struct Irqs1 {
22 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; 24 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
23}); 25});
24 26
25struct TestOptions {
26 config: Config,
27 max_latency: Duration,
28 second_fifo_working: bool,
29}
30
31#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h563zi"))] 27#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h563zi"))]
32fn options() -> TestOptions { 28fn options() -> (Config, TestOptions) {
33 use embassy_stm32::rcc; 29 use embassy_stm32::rcc;
34 info!("H75 config"); 30 info!("H75 config");
35 let mut c = config(); 31 let mut c = config();
@@ -38,15 +34,17 @@ fn options() -> TestOptions {
38 mode: rcc::HseMode::Oscillator, 34 mode: rcc::HseMode::Oscillator,
39 }); 35 });
40 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; 36 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
41 TestOptions { 37 (
42 config: c, 38 c,
43 max_latency: Duration::from_micros(1200), 39 TestOptions {
44 second_fifo_working: false, 40 max_latency: Duration::from_micros(1200),
45 } 41 max_buffered: 3,
42 },
43 )
46} 44}
47 45
48#[cfg(any(feature = "stm32h7a3zi"))] 46#[cfg(any(feature = "stm32h7a3zi"))]
49fn options() -> TestOptions { 47fn options() -> (Config, TestOptions) {
50 use embassy_stm32::rcc; 48 use embassy_stm32::rcc;
51 info!("H7a config"); 49 info!("H7a config");
52 let mut c = config(); 50 let mut c = config();
@@ -55,29 +53,33 @@ fn options() -> TestOptions {
55 mode: rcc::HseMode::Oscillator, 53 mode: rcc::HseMode::Oscillator,
56 }); 54 });
57 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; 55 c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
58 TestOptions { 56 (
59 config: c, 57 c,
60 max_latency: Duration::from_micros(1200), 58 TestOptions {
61 second_fifo_working: false, 59 max_latency: Duration::from_micros(1200),
62 } 60 max_buffered: 3,
61 },
62 )
63} 63}
64 64
65#[cfg(any(feature = "stm32g491re", feature = "stm32g431cb"))] 65#[cfg(any(feature = "stm32g491re", feature = "stm32g431cb"))]
66fn options() -> TestOptions { 66fn options() -> (Config, TestOptions) {
67 info!("G4 config"); 67 info!("G4 config");
68 TestOptions { 68 (
69 config: config(), 69 config(),
70 max_latency: Duration::from_micros(500), 70 TestOptions {
71 second_fifo_working: true, 71 max_latency: Duration::from_micros(500),
72 } 72 max_buffered: 6,
73 },
74 )
73} 75}
74 76
75#[embassy_executor::main] 77#[embassy_executor::main]
76async fn main(_spawner: Spawner) { 78async fn main(_spawner: Spawner) {
77 //let peripherals = embassy_stm32::init(config()); 79 //let peripherals = embassy_stm32::init(config());
78 80
79 let options = options(); 81 let (config, options) = options();
80 let peripherals = embassy_stm32::init(options.config); 82 let peripherals = embassy_stm32::init(config);
81 83
82 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); 84 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1);
83 let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); 85 let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2);
@@ -98,141 +100,16 @@ async fn main(_spawner: Spawner) {
98 let mut can = can.into_internal_loopback_mode(); 100 let mut can = can.into_internal_loopback_mode();
99 let mut can2 = can2.into_internal_loopback_mode(); 101 let mut can2 = can2.into_internal_loopback_mode();
100 102
101 info!("CAN Configured"); 103 run_can_tests(&mut can, &options).await;
104 run_can_tests(&mut can2, &options).await;
102 105
103 let mut i: u8 = 0; 106 info!("CAN Configured");
104 loop {
105 let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap();
106
107 info!("Transmitting frame...");
108 let tx_ts = Instant::now();
109 can.write(&tx_frame).await;
110
111 let (frame, timestamp) = can.read().await.unwrap().parts();
112 info!("Frame received!");
113
114 // Check data.
115 assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]);
116
117 info!("loopback time {}", timestamp);
118 info!("loopback frame {=u8}", frame.data()[0]);
119 let latency = timestamp.saturating_duration_since(tx_ts);
120 info!("loopback latency {} us", latency.as_micros());
121
122 // Theoretical minimum latency is 55us, actual is usually ~80us
123 const MIN_LATENCY: Duration = Duration::from_micros(50);
124 // Was failing at 150 but we are not getting a real time stamp. I'm not
125 // sure if there are other delays
126 assert!(
127 MIN_LATENCY <= latency && latency <= options.max_latency,
128 "{} <= {} <= {}",
129 MIN_LATENCY,
130 latency,
131 options.max_latency
132 );
133
134 i += 1;
135 if i > 10 {
136 break;
137 }
138 }
139
140 let mut i: u8 = 0;
141 loop {
142 let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap();
143
144 info!("Transmitting frame...");
145 let tx_ts = Instant::now();
146 can2.write(&tx_frame).await;
147
148 let (frame, timestamp) = can2.read().await.unwrap().parts();
149 info!("Frame received!");
150
151 //print_regs().await;
152 // Check data.
153 assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]);
154
155 info!("loopback time {}", timestamp);
156 info!("loopback frame {=u8}", frame.data()[0]);
157 let latency = timestamp.saturating_duration_since(tx_ts);
158 info!("loopback latency {} us", latency.as_micros());
159
160 // Theoretical minimum latency is 55us, actual is usually ~80us
161 const MIN_LATENCY: Duration = Duration::from_micros(50);
162 // Was failing at 150 but we are not getting a real time stamp. I'm not
163 // sure if there are other delays
164 assert!(
165 MIN_LATENCY <= latency && latency <= options.max_latency,
166 "{} <= {} <= {}",
167 MIN_LATENCY,
168 latency,
169 options.max_latency
170 );
171
172 i += 1;
173 if i > 10 {
174 break;
175 }
176 }
177
178 let max_buffered = if options.second_fifo_working { 6 } else { 3 };
179
180 // Below here, check that we can receive from both FIFO0 and FIFO0
181 // Above we configured FIFO1 for extended ID packets. There are only 3 slots
182 // in each FIFO so make sure we write enough to fill them both up before reading.
183 for i in 0..3 {
184 // Try filling up the RX FIFO0 buffers with standard packets
185 let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap();
186 info!("Transmitting frame {}", i);
187 can.write(&tx_frame).await;
188 }
189 for i in 3..max_buffered {
190 // Try filling up the RX FIFO0 buffers with extended packets
191 let tx_frame = can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap();
192 info!("Transmitting frame {}", i);
193 can.write(&tx_frame).await;
194 }
195
196 // Try and receive all 6 packets
197 for i in 0..max_buffered {
198 let (frame, _ts) = can.read().await.unwrap().parts();
199 match frame.id() {
200 embedded_can::Id::Extended(id) => {
201 info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
202 }
203 embedded_can::Id::Standard(id) => {
204 info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
205 }
206 }
207 }
208 107
209 // Test again with a split 108 // Test again with a split
210 let (mut tx, mut rx) = can.split(); 109 let (mut tx, mut rx) = can.split();
211 for i in 0..3 { 110 let (mut tx2, mut rx2) = can2.split();
212 // Try filling up the RX FIFO0 buffers with standard packets 111 run_split_can_tests(&mut tx, &mut rx, &options).await;
213 let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap(); 112 run_split_can_tests(&mut tx2, &mut rx2, &options).await;
214 info!("Transmitting frame {}", i);
215 tx.write(&tx_frame).await;
216 }
217 for i in 3..max_buffered {
218 // Try filling up the RX FIFO0 buffers with extended packets
219 let tx_frame = can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap();
220 info!("Transmitting frame {}", i);
221 tx.write(&tx_frame).await;
222 }
223
224 // Try and receive all 6 packets
225 for i in 0..max_buffered {
226 let (frame, _ts) = rx.read().await.unwrap().parts();
227 match frame.id() {
228 embedded_can::Id::Extended(id) => {
229 info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
230 }
231 embedded_can::Id::Standard(id) => {
232 info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i);
233 }
234 }
235 }
236 113
237 info!("Test OK"); 114 info!("Test OK");
238 cortex_m::asm::bkpt(); 115 cortex_m::asm::bkpt();