aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGustav Toft <[email protected]>2024-04-04 15:52:44 +0200
committerGustav Toft <[email protected]>2024-04-04 15:52:44 +0200
commita373633d0dbc352de1b488bf15e383f8ef1d4a8c (patch)
treea4590f26bd3252445e2adfa6d271a6f1cf74d54b /tests
parent0427c442ea531673e18da304c7402927589b8d0b (diff)
parent067e422863674762c0ee20178f3671ce16a5986c (diff)
Merge branch 'main' of https://github.com/GustavToft/embassy
Diffstat (limited to 'tests')
-rw-r--r--tests/rp/src/bin/gpio_multicore.rs12
-rw-r--r--tests/rp/src/bin/i2c.rs12
-rw-r--r--tests/rp/src/bin/multicore.rs12
-rw-r--r--tests/rp/src/bin/pwm.rs14
-rw-r--r--tests/stm32/src/bin/can.rs67
-rw-r--r--tests/stm32/src/bin/can_common.rs112
-rw-r--r--tests/stm32/src/bin/fdcan.rs199
-rw-r--r--tests/stm32/src/common.rs7
8 files changed, 204 insertions, 231 deletions
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs
index 8aed9b80c..e9c6f3122 100644
--- a/tests/rp/src/bin/gpio_multicore.rs
+++ b/tests/rp/src/bin/gpio_multicore.rs
@@ -21,10 +21,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, (), 1> = Channel::new();
21#[cortex_m_rt::entry] 21#[cortex_m_rt::entry]
22fn main() -> ! { 22fn main() -> ! {
23 let p = embassy_rp::init(Default::default()); 23 let p = embassy_rp::init(Default::default());
24 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 24 spawn_core1(
25 let executor1 = EXECUTOR1.init(Executor::new()); 25 p.CORE1,
26 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); 26 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
27 }); 27 move || {
28 let executor1 = EXECUTOR1.init(Executor::new());
29 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1))));
30 },
31 );
28 let executor0 = EXECUTOR0.init(Executor::new()); 32 let executor0 = EXECUTOR0.init(Executor::new());
29 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); 33 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0))));
30} 34}
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
index 153b37999..9615007bd 100644
--- a/tests/rp/src/bin/i2c.rs
+++ b/tests/rp/src/bin/i2c.rs
@@ -210,10 +210,14 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
210 config.addr = DEV_ADDR as u16; 210 config.addr = DEV_ADDR as u16;
211 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); 211 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
212 212
213 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 213 spawn_core1(
214 let executor1 = EXECUTOR1.init(Executor::new()); 214 p.CORE1,
215 executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); 215 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
216 }); 216 move || {
217 let executor1 = EXECUTOR1.init(Executor::new());
218 executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device))));
219 },
220 );
217 221
218 let c_sda = p.PIN_21; 222 let c_sda = p.PIN_21;
219 let c_scl = p.PIN_20; 223 let c_scl = p.PIN_20;
diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs
index 60d9f85ec..783ea0f27 100644
--- a/tests/rp/src/bin/multicore.rs
+++ b/tests/rp/src/bin/multicore.rs
@@ -19,10 +19,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, bool, 1> = Channel::new();
19#[cortex_m_rt::entry] 19#[cortex_m_rt::entry]
20fn main() -> ! { 20fn main() -> ! {
21 let p = embassy_rp::init(Default::default()); 21 let p = embassy_rp::init(Default::default());
22 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 22 spawn_core1(
23 let executor1 = EXECUTOR1.init(Executor::new()); 23 p.CORE1,
24 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); 24 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
25 }); 25 move || {
26 let executor1 = EXECUTOR1.init(Executor::new());
27 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task())));
28 },
29 );
26 let executor0 = EXECUTOR0.init(Executor::new()); 30 let executor0 = EXECUTOR0.init(Executor::new());
27 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 31 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));
28} 32}
diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs
index e71d9e610..4b02e5bab 100644
--- a/tests/rp/src/bin/pwm.rs
+++ b/tests/rp/src/bin/pwm.rs
@@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) {
28 28
29 // Test free-running clock 29 // Test free-running clock
30 { 30 {
31 let pwm = Pwm::new_free(&mut p.PWM_CH3, cfg.clone()); 31 let pwm = Pwm::new_free(&mut p.PWM_SLICE3, cfg.clone());
32 cortex_m::asm::delay(125); 32 cortex_m::asm::delay(125);
33 let ctr = pwm.counter(); 33 let ctr = pwm.counter();
34 assert!(ctr > 0); 34 assert!(ctr > 0);
@@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
46 // Test output from A 46 // Test output from A
47 { 47 {
48 let pin1 = Input::new(&mut p9, Pull::None); 48 let pin1 = Input::new(&mut p9, Pull::None);
49 let _pwm = Pwm::new_output_a(&mut p.PWM_CH3, &mut p6, cfg.clone()); 49 let _pwm = Pwm::new_output_a(&mut p.PWM_SLICE3, &mut p6, cfg.clone());
50 Timer::after_millis(1).await; 50 Timer::after_millis(1).await;
51 assert_eq!(pin1.is_low(), invert_a); 51 assert_eq!(pin1.is_low(), invert_a);
52 Timer::after_millis(5).await; 52 Timer::after_millis(5).await;
@@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) {
60 // Test output from B 60 // Test output from B
61 { 61 {
62 let pin2 = Input::new(&mut p11, Pull::None); 62 let pin2 = Input::new(&mut p11, Pull::None);
63 let _pwm = Pwm::new_output_b(&mut p.PWM_CH3, &mut p7, cfg.clone()); 63 let _pwm = Pwm::new_output_b(&mut p.PWM_SLICE3, &mut p7, cfg.clone());
64 Timer::after_millis(1).await; 64 Timer::after_millis(1).await;
65 assert_ne!(pin2.is_low(), invert_a); 65 assert_ne!(pin2.is_low(), invert_a);
66 Timer::after_millis(5).await; 66 Timer::after_millis(5).await;
@@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) {
75 { 75 {
76 let pin1 = Input::new(&mut p9, Pull::None); 76 let pin1 = Input::new(&mut p9, Pull::None);
77 let pin2 = Input::new(&mut p11, Pull::None); 77 let pin2 = Input::new(&mut p11, Pull::None);
78 let _pwm = Pwm::new_output_ab(&mut p.PWM_CH3, &mut p6, &mut p7, cfg.clone()); 78 let _pwm = Pwm::new_output_ab(&mut p.PWM_SLICE3, &mut p6, &mut p7, cfg.clone());
79 Timer::after_millis(1).await; 79 Timer::after_millis(1).await;
80 assert_eq!(pin1.is_low(), invert_a); 80 assert_eq!(pin1.is_low(), invert_a);
81 assert_ne!(pin2.is_low(), invert_a); 81 assert_ne!(pin2.is_low(), invert_a);
@@ -94,7 +94,7 @@ async fn main(_spawner: Spawner) {
94 // Test level-gated 94 // Test level-gated
95 { 95 {
96 let mut pin2 = Output::new(&mut p11, Level::Low); 96 let mut pin2 = Output::new(&mut p11, Level::Low);
97 let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::Level, cfg.clone()); 97 let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::Level, cfg.clone());
98 assert_eq!(pwm.counter(), 0); 98 assert_eq!(pwm.counter(), 0);
99 Timer::after_millis(5).await; 99 Timer::after_millis(5).await;
100 assert_eq!(pwm.counter(), 0); 100 assert_eq!(pwm.counter(), 0);
@@ -110,7 +110,7 @@ async fn main(_spawner: Spawner) {
110 // Test rising-gated 110 // Test rising-gated
111 { 111 {
112 let mut pin2 = Output::new(&mut p11, Level::Low); 112 let mut pin2 = Output::new(&mut p11, Level::Low);
113 let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::RisingEdge, cfg.clone()); 113 let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::RisingEdge, cfg.clone());
114 assert_eq!(pwm.counter(), 0); 114 assert_eq!(pwm.counter(), 0);
115 Timer::after_millis(5).await; 115 Timer::after_millis(5).await;
116 assert_eq!(pwm.counter(), 0); 116 assert_eq!(pwm.counter(), 0);
@@ -125,7 +125,7 @@ async fn main(_spawner: Spawner) {
125 // Test falling-gated 125 // Test falling-gated
126 { 126 {
127 let mut pin2 = Output::new(&mut p11, Level::High); 127 let mut pin2 = Output::new(&mut p11, Level::High);
128 let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::FallingEdge, cfg.clone()); 128 let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::FallingEdge, cfg.clone());
129 assert_eq!(pwm.counter(), 0); 129 assert_eq!(pwm.counter(), 0);
130 Timer::after_millis(5).await; 130 Timer::after_millis(5).await;
131 assert_eq!(pwm.counter(), 0); 131 assert_eq!(pwm.counter(), 0);
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index c08c69a3b..551764458 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -6,17 +6,20 @@
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::filter::Mask32;
13use embassy_stm32::can::bx::{Fifo, Frame, StandardId}; 12use embassy_stm32::can::{
14use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; 13 Can, Fifo, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler,
14};
15use embassy_stm32::gpio::{Input, Pull}; 15use embassy_stm32::gpio::{Input, Pull};
16use embassy_stm32::peripherals::CAN1; 16use embassy_stm32::peripherals::CAN1;
17use embassy_time::{Duration, Instant}; 17use embassy_time::Duration;
18use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
19 19
20mod can_common;
21use can_common::*;
22
20bind_interrupts!(struct Irqs { 23bind_interrupts!(struct Irqs {
21 CAN1_RX0 => Rx0InterruptHandler<CAN1>; 24 CAN1_RX0 => Rx0InterruptHandler<CAN1>;
22 CAN1_RX1 => Rx1InterruptHandler<CAN1>; 25 CAN1_RX1 => Rx1InterruptHandler<CAN1>;
@@ -29,6 +32,11 @@ async fn main(_spawner: Spawner) {
29 let p = embassy_stm32::init(config()); 32 let p = embassy_stm32::init(config());
30 info!("Hello World!"); 33 info!("Hello World!");
31 34
35 let options = TestOptions {
36 max_latency: Duration::from_micros(1200),
37 max_buffered: 2,
38 };
39
32 let can = peri!(p, CAN); 40 let can = peri!(p, CAN);
33 let tx = peri!(p, CAN_TX); 41 let tx = peri!(p, CAN_TX);
34 let mut rx = peri!(p, CAN_RX); 42 let mut rx = peri!(p, CAN_RX);
@@ -44,54 +52,25 @@ async fn main(_spawner: Spawner) {
44 52
45 info!("Configuring can..."); 53 info!("Configuring can...");
46 54
47 can.as_mut() 55 can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
48 .modify_filters()
49 .enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
50 56
51 can.set_bitrate(1_000_000); 57 can.modify_config()
52 can.as_mut()
53 .modify_config()
54 .set_loopback(true) // Receive own frames 58 .set_loopback(true) // Receive own frames
55 .set_silent(true) 59 .set_silent(true)
56 // .set_bit_timing(0x001c0003) 60 // .set_bit_timing(0x001c0003)
57 .enable(); 61 .set_bitrate(1_000_000);
58
59 info!("Can configured");
60
61 let mut i: u8 = 0;
62 loop {
63 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap();
64 62
65 info!("Transmitting frame..."); 63 can.enable().await;
66 let tx_ts = Instant::now();
67 can.write(&tx_frame).await;
68 64
69 let envelope = can.read().await.unwrap(); 65 info!("Can configured");
70 info!("Frame received!");
71
72 info!("loopback time {}", envelope.ts);
73 info!("loopback frame {=u8}", envelope.frame.data()[0]);
74
75 let latency = envelope.ts.saturating_duration_since(tx_ts);
76 info!("loopback latency {} us", latency.as_micros());
77 66
78 // Theoretical minimum latency is 55us, actual is usually ~80us 67 run_can_tests(&mut can, &options).await;
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 68
89 i += 1; 69 // Test again with a split
90 if i > 10 { 70 let (mut tx, mut rx) = can.split();
91 break; 71 run_split_can_tests(&mut tx, &mut rx, &options).await;
92 }
93 }
94 72
95 info!("Test OK"); 73 info!("Test OK");
74
96 cortex_m::asm::bkpt(); 75 cortex_m::asm::bkpt();
97} 76}
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 c7373e294..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,32 +53,36 @@ 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::FdcanConfigurator::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::FdcanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); 85 let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2);
84 86
85 // 250k bps 87 // 250k bps
86 can.set_bitrate(250_000); 88 can.set_bitrate(250_000);
@@ -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::ClassicFrame::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();
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::ClassicFrame::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();
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::ClassicFrame::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::ClassicFrame::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();
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::ClassicFrame::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::ClassicFrame::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();
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();
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index c379863a8..0e555efc8 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -251,13 +251,6 @@ define_peris!(
251); 251);
252 252
253pub fn config() -> Config { 253pub fn config() -> Config {
254 // Setting this bit is mandatory to use PG[15:2].
255 #[cfg(feature = "stm32u5a5zj")]
256 embassy_stm32::pac::PWR.svmcr().modify(|w| {
257 w.set_io2sv(true);
258 w.set_io2vmen(true);
259 });
260
261 #[allow(unused_mut)] 254 #[allow(unused_mut)]
262 let mut config = Config::default(); 255 let mut config = Config::default();
263 256