diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-23 01:45:10 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-23 01:45:10 +0100 |
| commit | a6a5d9913cda2ecfe89b63fa0bcf7afaebc2dac0 (patch) | |
| tree | 14124a6f34d351a979cb110a0ce566b588f5d272 /tests | |
| parent | 5b7e2d88265b5633fa53047961598fbc38bffed0 (diff) | |
| parent | 2855bb69680a42a721fe88168657ea1e634e8766 (diff) | |
Merge branch 'main' into stm32l0-reset-rtc
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/nrf52840/src/bin/buffered_uart.rs | 87 | ||||
| -rw-r--r-- | tests/nrf52840/src/bin/buffered_uart_full.rs | 2 | ||||
| -rw-r--r-- | tests/nrf52840/src/bin/buffered_uart_halves.rs | 82 | ||||
| -rw-r--r-- | tests/rp/Cargo.toml | 1 | ||||
| -rw-r--r-- | tests/rp/src/bin/i2c.rs | 94 | ||||
| -rw-r--r-- | tests/stm32/Cargo.toml | 3 | ||||
| -rw-r--r-- | tests/stm32/build.rs | 1 | ||||
| -rw-r--r-- | tests/stm32/src/bin/fdcan.rs | 111 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 13 |
9 files changed, 231 insertions, 163 deletions
diff --git a/tests/nrf52840/src/bin/buffered_uart.rs b/tests/nrf52840/src/bin/buffered_uart.rs index 354d787b4..a01d66d85 100644 --- a/tests/nrf52840/src/bin/buffered_uart.rs +++ b/tests/nrf52840/src/bin/buffered_uart.rs | |||
| @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs { | |||
| 15 | 15 | ||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_nrf::init(Default::default()); | 18 | let mut p = embassy_nrf::init(Default::default()); |
| 19 | let mut config = uarte::Config::default(); | 19 | let mut config = uarte::Config::default(); |
| 20 | config.parity = uarte::Parity::EXCLUDED; | 20 | config.parity = uarte::Parity::EXCLUDED; |
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | 21 | config.baudrate = uarte::Baudrate::BAUD1M; |
| @@ -23,55 +23,58 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | 23 | let mut tx_buffer = [0u8; 1024]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 24 | let mut rx_buffer = [0u8; 1024]; |
| 25 | 25 | ||
| 26 | let mut u = BufferedUarte::new( | 26 | // test teardown + recreate of the buffereduarte works fine. |
| 27 | p.UARTE0, | 27 | for _ in 0..2 { |
| 28 | p.TIMER0, | 28 | let u = BufferedUarte::new( |
| 29 | p.PPI_CH0, | 29 | &mut p.UARTE0, |
| 30 | p.PPI_CH1, | 30 | &mut p.TIMER0, |
| 31 | p.PPI_GROUP0, | 31 | &mut p.PPI_CH0, |
| 32 | Irqs, | 32 | &mut p.PPI_CH1, |
| 33 | p.P1_03, | 33 | &mut p.PPI_GROUP0, |
| 34 | p.P1_02, | 34 | Irqs, |
| 35 | config.clone(), | 35 | &mut p.P1_03, |
| 36 | &mut rx_buffer, | 36 | &mut p.P1_02, |
| 37 | &mut tx_buffer, | 37 | config.clone(), |
| 38 | ); | 38 | &mut rx_buffer, |
| 39 | &mut tx_buffer, | ||
| 40 | ); | ||
| 39 | 41 | ||
| 40 | info!("uarte initialized!"); | 42 | info!("uarte initialized!"); |
| 41 | 43 | ||
| 42 | let (mut rx, mut tx) = u.split(); | 44 | let (mut rx, mut tx) = u.split(); |
| 43 | 45 | ||
| 44 | const COUNT: usize = 40_000; | 46 | const COUNT: usize = 40_000; |
| 45 | 47 | ||
| 46 | let tx_fut = async { | 48 | let tx_fut = async { |
| 47 | let mut tx_buf = [0; 215]; | 49 | let mut tx_buf = [0; 215]; |
| 48 | let mut i = 0; | 50 | let mut i = 0; |
| 49 | while i < COUNT { | 51 | while i < COUNT { |
| 50 | let n = tx_buf.len().min(COUNT - i); | 52 | let n = tx_buf.len().min(COUNT - i); |
| 51 | let tx_buf = &mut tx_buf[..n]; | 53 | let tx_buf = &mut tx_buf[..n]; |
| 52 | for (j, b) in tx_buf.iter_mut().enumerate() { | 54 | for (j, b) in tx_buf.iter_mut().enumerate() { |
| 53 | *b = (i + j) as u8; | 55 | *b = (i + j) as u8; |
| 56 | } | ||
| 57 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 58 | i += n; | ||
| 54 | } | 59 | } |
| 55 | let n = unwrap!(tx.write(tx_buf).await); | 60 | }; |
| 56 | i += n; | 61 | let rx_fut = async { |
| 57 | } | 62 | let mut i = 0; |
| 58 | }; | 63 | while i < COUNT { |
| 59 | let rx_fut = async { | 64 | let buf = unwrap!(rx.fill_buf().await); |
| 60 | let mut i = 0; | ||
| 61 | while i < COUNT { | ||
| 62 | let buf = unwrap!(rx.fill_buf().await); | ||
| 63 | 65 | ||
| 64 | for &b in buf { | 66 | for &b in buf { |
| 65 | assert_eq!(b, i as u8); | 67 | assert_eq!(b, i as u8); |
| 66 | i = i + 1; | 68 | i = i + 1; |
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | let n = buf.len(); | 71 | let n = buf.len(); |
| 70 | rx.consume(n); | 72 | rx.consume(n); |
| 71 | } | 73 | } |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | join(rx_fut, tx_fut).await; | 76 | join(rx_fut, tx_fut).await; |
| 77 | } | ||
| 75 | 78 | ||
| 76 | info!("Test OK"); | 79 | info!("Test OK"); |
| 77 | cortex_m::asm::bkpt(); | 80 | cortex_m::asm::bkpt(); |
diff --git a/tests/nrf52840/src/bin/buffered_uart_full.rs b/tests/nrf52840/src/bin/buffered_uart_full.rs index e59c75ba9..62edaed25 100644 --- a/tests/nrf52840/src/bin/buffered_uart_full.rs +++ b/tests/nrf52840/src/bin/buffered_uart_full.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | 23 | let mut tx_buffer = [0u8; 1024]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 24 | let mut rx_buffer = [0u8; 1024]; |
| 25 | 25 | ||
| 26 | let mut u = BufferedUarte::new( | 26 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 27 | p.UARTE0, |
| 28 | p.TIMER0, | 28 | p.TIMER0, |
| 29 | p.PPI_CH0, | 29 | p.PPI_CH0, |
diff --git a/tests/nrf52840/src/bin/buffered_uart_halves.rs b/tests/nrf52840/src/bin/buffered_uart_halves.rs new file mode 100644 index 000000000..54a9fef5b --- /dev/null +++ b/tests/nrf52840/src/bin/buffered_uart_halves.rs | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert_eq, *}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | ||
| 18 | async fn main(_spawner: Spawner) { | ||
| 19 | let mut p = embassy_nrf::init(Default::default()); | ||
| 20 | let mut config = uarte::Config::default(); | ||
| 21 | config.parity = uarte::Parity::EXCLUDED; | ||
| 22 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 23 | |||
| 24 | let mut tx_buffer = [0u8; 1024]; | ||
| 25 | let mut rx_buffer = [0u8; 1024]; | ||
| 26 | |||
| 27 | // test teardown + recreate of the buffereduarte works fine. | ||
| 28 | for _ in 0..2 { | ||
| 29 | const COUNT: usize = 40_000; | ||
| 30 | |||
| 31 | let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer); | ||
| 32 | |||
| 33 | let mut rx = BufferedUarteRx::new( | ||
| 34 | &mut p.UARTE0, | ||
| 35 | &mut p.TIMER0, | ||
| 36 | &mut p.PPI_CH0, | ||
| 37 | &mut p.PPI_CH1, | ||
| 38 | &mut p.PPI_GROUP0, | ||
| 39 | Irqs, | ||
| 40 | &mut p.P1_03, | ||
| 41 | config.clone(), | ||
| 42 | &mut rx_buffer, | ||
| 43 | ); | ||
| 44 | |||
| 45 | let tx_fut = async { | ||
| 46 | info!("tx initialized!"); | ||
| 47 | |||
| 48 | let mut tx_buf = [0; 215]; | ||
| 49 | let mut i = 0; | ||
| 50 | while i < COUNT { | ||
| 51 | let n = tx_buf.len().min(COUNT - i); | ||
| 52 | let tx_buf = &mut tx_buf[..n]; | ||
| 53 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 54 | *b = (i + j) as u8; | ||
| 55 | } | ||
| 56 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 57 | i += n; | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | let rx_fut = async { | ||
| 61 | info!("rx initialized!"); | ||
| 62 | |||
| 63 | let mut i = 0; | ||
| 64 | while i < COUNT { | ||
| 65 | let buf = unwrap!(rx.fill_buf().await); | ||
| 66 | |||
| 67 | for &b in buf { | ||
| 68 | assert_eq!(b, i as u8); | ||
| 69 | i = i + 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | let n = buf.len(); | ||
| 73 | rx.consume(n); | ||
| 74 | } | ||
| 75 | }; | ||
| 76 | |||
| 77 | join(rx_fut, tx_fut).await; | ||
| 78 | } | ||
| 79 | |||
| 80 | info!("Test OK"); | ||
| 81 | cortex_m::asm::bkpt(); | ||
| 82 | } | ||
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 46e1e9a5f..e67f2117d 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -14,6 +14,7 @@ embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt | |||
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } | 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } |
| 17 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal/"} | ||
| 17 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } | 18 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } |
| 18 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } | 19 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } |
| 19 | perf-client = { path = "../perf-client" } | 20 | perf-client = { path = "../perf-client" } |
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs index a0aed1a42..153b37999 100644 --- a/tests/rp/src/bin/i2c.rs +++ b/tests/rp/src/bin/i2c.rs | |||
| @@ -3,7 +3,10 @@ | |||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use defmt::{assert_eq, info, panic, unwrap}; | 5 | use defmt::{assert_eq, info, panic, unwrap}; |
| 6 | use embassy_executor::Executor; | 6 | use embassy_embedded_hal::SetConfig; |
| 7 | use embassy_executor::{Executor, Spawner}; | ||
| 8 | use embassy_rp::clocks::{PllConfig, XoscConfig}; | ||
| 9 | use embassy_rp::config::Config as rpConfig; | ||
| 7 | use embassy_rp::multicore::{spawn_core1, Stack}; | 10 | use embassy_rp::multicore::{spawn_core1, Stack}; |
| 8 | use embassy_rp::peripherals::{I2C0, I2C1}; | 11 | use embassy_rp::peripherals::{I2C0, I2C1}; |
| 9 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; | 12 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; |
| @@ -13,7 +16,6 @@ use static_cell::StaticCell; | |||
| 13 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; | 16 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; |
| 14 | 17 | ||
| 15 | static mut CORE1_STACK: Stack<1024> = Stack::new(); | 18 | static mut CORE1_STACK: Stack<1024> = Stack::new(); |
| 16 | static EXECUTOR0: StaticCell<Executor> = StaticCell::new(); | ||
| 17 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); | 19 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); |
| 18 | 20 | ||
| 19 | use crate::i2c::AbortReason; | 21 | use crate::i2c::AbortReason; |
| @@ -44,10 +46,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 44 | Ok(x) => match x { | 46 | Ok(x) => match x { |
| 45 | i2c_slave::ReadStatus::Done => break, | 47 | i2c_slave::ReadStatus::Done => break, |
| 46 | i2c_slave::ReadStatus::NeedMoreBytes => count += 1, | 48 | i2c_slave::ReadStatus::NeedMoreBytes => count += 1, |
| 47 | i2c_slave::ReadStatus::LeftoverBytes(x) => { | 49 | i2c_slave::ReadStatus::LeftoverBytes(x) => panic!("tried to write {} extra bytes", x), |
| 48 | info!("tried to write {} extra bytes", x); | ||
| 49 | break; | ||
| 50 | } | ||
| 51 | }, | 50 | }, |
| 52 | Err(e) => match e { | 51 | Err(e) => match e { |
| 53 | embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), | 52 | embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), |
| @@ -92,6 +91,8 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 92 | resp_buff[i] = i as u8; | 91 | resp_buff[i] = i as u8; |
| 93 | } | 92 | } |
| 94 | dev.respond_to_read(&resp_buff).await.unwrap(); | 93 | dev.respond_to_read(&resp_buff).await.unwrap(); |
| 94 | // reset count for next round of tests | ||
| 95 | count = 0xD0; | ||
| 95 | } | 96 | } |
| 96 | x => panic!("Invalid Write Read {:x}", x), | 97 | x => panic!("Invalid Write Read {:x}", x), |
| 97 | } | 98 | } |
| @@ -104,8 +105,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 104 | } | 105 | } |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | #[embassy_executor::task] | 108 | async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { |
| 108 | async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { | ||
| 109 | info!("Device start"); | 109 | info!("Device start"); |
| 110 | 110 | ||
| 111 | { | 111 | { |
| @@ -179,33 +179,55 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { | |||
| 179 | info!("large write_read - OK") | 179 | info!("large write_read - OK") |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | info!("Test OK"); | 182 | #[embassy_executor::main] |
| 183 | cortex_m::asm::bkpt(); | 183 | async fn main(_core0_spawner: Spawner) { |
| 184 | } | 184 | let mut config = rpConfig::default(); |
| 185 | 185 | // Configure clk_sys to 48MHz to support 1kHz scl. | |
| 186 | #[cortex_m_rt::entry] | 186 | // In theory it can go lower, but we won't bother to test below 1kHz. |
| 187 | fn main() -> ! { | 187 | config.clocks.xosc = Some(XoscConfig { |
| 188 | let p = embassy_rp::init(Default::default()); | 188 | hz: 12_000_000, |
| 189 | info!("Hello World!"); | 189 | delay_multiplier: 128, |
| 190 | 190 | sys_pll: Some(PllConfig { | |
| 191 | let d_sda = p.PIN_19; | 191 | refdiv: 1, |
| 192 | let d_scl = p.PIN_18; | 192 | fbdiv: 120, |
| 193 | let mut config = i2c_slave::Config::default(); | 193 | post_div1: 6, |
| 194 | config.addr = DEV_ADDR as u16; | 194 | post_div2: 5, |
| 195 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | 195 | }), |
| 196 | 196 | usb_pll: Some(PllConfig { | |
| 197 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 197 | refdiv: 1, |
| 198 | let executor1 = EXECUTOR1.init(Executor::new()); | 198 | fbdiv: 120, |
| 199 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | 199 | post_div1: 6, |
| 200 | }); | 200 | post_div2: 5, |
| 201 | 201 | }), | |
| 202 | let executor0 = EXECUTOR0.init(Executor::new()); | 202 | }); |
| 203 | 203 | ||
| 204 | let c_sda = p.PIN_21; | 204 | let p = embassy_rp::init(config); |
| 205 | let c_scl = p.PIN_20; | 205 | info!("Hello World!"); |
| 206 | let mut config = i2c::Config::default(); | 206 | |
| 207 | config.frequency = 5_000; | 207 | let d_sda = p.PIN_19; |
| 208 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | 208 | let d_scl = p.PIN_18; |
| 209 | let mut config = i2c_slave::Config::default(); | ||
| 210 | config.addr = DEV_ADDR as u16; | ||
| 211 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | ||
| 212 | |||
| 213 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | ||
| 214 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 215 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | ||
| 216 | }); | ||
| 217 | |||
| 218 | let c_sda = p.PIN_21; | ||
| 219 | let c_scl = p.PIN_20; | ||
| 220 | let mut controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, Default::default()); | ||
| 221 | |||
| 222 | for freq in [1000, 100_000, 400_000, 1_000_000] { | ||
| 223 | info!("testing at {}hz", freq); | ||
| 224 | let mut config = i2c::Config::default(); | ||
| 225 | config.frequency = freq; | ||
| 226 | controller.set_config(&config).unwrap(); | ||
| 227 | controller_task(&mut controller).await; | ||
| 228 | } | ||
| 209 | 229 | ||
| 210 | executor0.run(|spawner| unwrap!(spawner.spawn(controller_task(controller)))); | 230 | info!("Test OK"); |
| 231 | cortex_m::asm::bkpt(); | ||
| 232 | } | ||
| 211 | } | 233 | } |
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 8554682a4..828a28e2c 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -26,7 +26,7 @@ stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash" | |||
| 26 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] | 26 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] |
| 27 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] | 27 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] |
| 28 | stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng", "hash"] | 28 | stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng", "hash"] |
| 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] | 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng", "hash"] |
| 30 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] | 30 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] |
| 31 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] | 31 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] |
| 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] | 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] |
| @@ -69,6 +69,7 @@ cortex-m-rt = "0.7.0" | |||
| 69 | embedded-hal = "0.2.6" | 69 | embedded-hal = "0.2.6" |
| 70 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 70 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 71 | embedded-hal-async = { version = "1.0" } | 71 | embedded-hal-async = { version = "1.0" } |
| 72 | embedded-can = { version = "0.4" } | ||
| 72 | micromath = "2.0.0" | 73 | micromath = "2.0.0" |
| 73 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 74 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 74 | rand_core = { version = "0.6", default-features = false } | 75 | rand_core = { version = "0.6", default-features = false } |
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index bc5589164..176adff62 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs | |||
| @@ -16,6 +16,7 @@ fn main() -> Result<(), Box<dyn Error>> { | |||
| 16 | feature = "stm32l073rz", | 16 | feature = "stm32l073rz", |
| 17 | // wrong ram size in stm32-data | 17 | // wrong ram size in stm32-data |
| 18 | feature = "stm32wl55jc", | 18 | feature = "stm32wl55jc", |
| 19 | feature = "stm32u5a5zj", | ||
| 19 | // no VTOR, so interrupts can't work when running from RAM | 20 | // no VTOR, so interrupts can't work when running from RAM |
| 20 | feature = "stm32f091rc", | 21 | feature = "stm32f091rc", |
| 21 | )) { | 22 | )) { |
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs index 7363eaa16..398e31ffc 100644 --- a/tests/stm32/src/bin/fdcan.rs +++ b/tests/stm32/src/bin/fdcan.rs | |||
| @@ -36,7 +36,7 @@ fn options() -> TestOptions { | |||
| 36 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; | 36 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; |
| 37 | TestOptions { | 37 | TestOptions { |
| 38 | config: c, | 38 | config: c, |
| 39 | max_latency: Duration::from_micros(3800), | 39 | max_latency: Duration::from_micros(1200), |
| 40 | second_fifo_working: false, | 40 | second_fifo_working: false, |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| @@ -53,12 +53,12 @@ fn options() -> TestOptions { | |||
| 53 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; | 53 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; |
| 54 | TestOptions { | 54 | TestOptions { |
| 55 | config: c, | 55 | config: c, |
| 56 | max_latency: Duration::from_micros(5500), | 56 | max_latency: Duration::from_micros(1200), |
| 57 | second_fifo_working: false, | 57 | second_fifo_working: false, |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | #[cfg(any(feature = "stm32g491re"))] | 61 | #[cfg(any(feature = "stm32g491re", feature = "stm32g431cb"))] |
| 62 | fn options() -> TestOptions { | 62 | fn options() -> TestOptions { |
| 63 | info!("G4 config"); | 63 | info!("G4 config"); |
| 64 | TestOptions { | 64 | TestOptions { |
| @@ -75,14 +75,14 @@ async fn main(_spawner: Spawner) { | |||
| 75 | let options = options(); | 75 | let options = options(); |
| 76 | let peripherals = embassy_stm32::init(options.config); | 76 | let peripherals = embassy_stm32::init(options.config); |
| 77 | 77 | ||
| 78 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); | 78 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); |
| 79 | 79 | ||
| 80 | // 250k bps | 80 | // 250k bps |
| 81 | can.set_bitrate(250_000); | 81 | can.set_bitrate(250_000); |
| 82 | 82 | ||
| 83 | can.can.set_extended_filter( | 83 | can.set_extended_filter( |
| 84 | can::filter::ExtendedFilterSlot::_0, | 84 | can::fd::filter::ExtendedFilterSlot::_0, |
| 85 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | 85 | can::fd::filter::ExtendedFilter::accept_all_into_fifo1(), |
| 86 | ); | 86 | ); |
| 87 | 87 | ||
| 88 | let mut can = can.into_internal_loopback_mode(); | 88 | let mut can = can.into_internal_loopback_mode(); |
| @@ -91,31 +91,21 @@ async fn main(_spawner: Spawner) { | |||
| 91 | 91 | ||
| 92 | let mut i: u8 = 0; | 92 | let mut i: u8 = 0; |
| 93 | loop { | 93 | loop { |
| 94 | let tx_frame = can::TxFrame::new( | 94 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); |
| 95 | can::TxFrameHeader { | ||
| 96 | len: 1, | ||
| 97 | frame_format: can::FrameFormat::Standard, | ||
| 98 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 99 | bit_rate_switching: false, | ||
| 100 | marker: None, | ||
| 101 | }, | ||
| 102 | &[i], | ||
| 103 | ) | ||
| 104 | .unwrap(); | ||
| 105 | 95 | ||
| 106 | info!("Transmitting frame..."); | 96 | info!("Transmitting frame..."); |
| 107 | let tx_ts = Instant::now(); | 97 | let tx_ts = Instant::now(); |
| 108 | can.write(&tx_frame).await; | 98 | can.write(&tx_frame).await; |
| 109 | 99 | ||
| 110 | let envelope = can.read().await.unwrap(); | 100 | let (frame, timestamp) = can.read().await.unwrap(); |
| 111 | info!("Frame received!"); | 101 | info!("Frame received!"); |
| 112 | 102 | ||
| 113 | // Check data. | 103 | // Check data. |
| 114 | assert!(i == envelope.data()[0], "{} == {}", i, envelope.data()[0]); | 104 | assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]); |
| 115 | 105 | ||
| 116 | info!("loopback time {}", envelope.header.time_stamp); | 106 | info!("loopback time {}", timestamp); |
| 117 | info!("loopback frame {=u8}", envelope.data()[0]); | 107 | info!("loopback frame {=u8}", frame.data()[0]); |
| 118 | let latency = envelope.timestamp.saturating_duration_since(tx_ts); | 108 | let latency = timestamp.saturating_duration_since(tx_ts); |
| 119 | info!("loopback latency {} us", latency.as_micros()); | 109 | info!("loopback latency {} us", latency.as_micros()); |
| 120 | 110 | ||
| 121 | // Theoretical minimum latency is 55us, actual is usually ~80us | 111 | // Theoretical minimum latency is 55us, actual is usually ~80us |
| @@ -143,47 +133,26 @@ async fn main(_spawner: Spawner) { | |||
| 143 | // in each FIFO so make sure we write enough to fill them both up before reading. | 133 | // in each FIFO so make sure we write enough to fill them both up before reading. |
| 144 | for i in 0..3 { | 134 | for i in 0..3 { |
| 145 | // Try filling up the RX FIFO0 buffers with standard packets | 135 | // Try filling up the RX FIFO0 buffers with standard packets |
| 146 | let tx_frame = can::TxFrame::new( | 136 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); |
| 147 | can::TxFrameHeader { | ||
| 148 | len: 1, | ||
| 149 | frame_format: can::FrameFormat::Standard, | ||
| 150 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 151 | bit_rate_switching: false, | ||
| 152 | marker: None, | ||
| 153 | }, | ||
| 154 | &[i], | ||
| 155 | ) | ||
| 156 | .unwrap(); | ||
| 157 | info!("Transmitting frame {}", i); | 137 | info!("Transmitting frame {}", i); |
| 158 | can.write(&tx_frame).await; | 138 | can.write(&tx_frame).await; |
| 159 | } | 139 | } |
| 160 | for i in 3..max_buffered { | 140 | for i in 3..max_buffered { |
| 161 | // Try filling up the RX FIFO0 buffers with extended packets | 141 | // Try filling up the RX FIFO0 buffers with extended packets |
| 162 | let tx_frame = can::TxFrame::new( | 142 | let tx_frame = can::frame::ClassicFrame::new_extended(0x1232344, &[i; 1]).unwrap(); |
| 163 | can::TxFrameHeader { | ||
| 164 | len: 1, | ||
| 165 | frame_format: can::FrameFormat::Standard, | ||
| 166 | id: can::ExtendedId::new(0x1232344).unwrap().into(), | ||
| 167 | bit_rate_switching: false, | ||
| 168 | marker: None, | ||
| 169 | }, | ||
| 170 | &[i], | ||
| 171 | ) | ||
| 172 | .unwrap(); | ||
| 173 | |||
| 174 | info!("Transmitting frame {}", i); | 143 | info!("Transmitting frame {}", i); |
| 175 | can.write(&tx_frame).await; | 144 | can.write(&tx_frame).await; |
| 176 | } | 145 | } |
| 177 | 146 | ||
| 178 | // Try and receive all 6 packets | 147 | // Try and receive all 6 packets |
| 179 | for i in 0..max_buffered { | 148 | for i in 0..max_buffered { |
| 180 | let envelope = can.read().await.unwrap(); | 149 | let (frame, _ts) = can.read().await.unwrap(); |
| 181 | match envelope.header.id { | 150 | match frame.id() { |
| 182 | can::Id::Extended(id) => { | 151 | embedded_can::Id::Extended(id) => { |
| 183 | info!("Extended received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | 152 | info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i); |
| 184 | } | 153 | } |
| 185 | can::Id::Standard(id) => { | 154 | embedded_can::Id::Standard(id) => { |
| 186 | info!("Standard received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | 155 | info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i); |
| 187 | } | 156 | } |
| 188 | } | 157 | } |
| 189 | } | 158 | } |
| @@ -192,48 +161,26 @@ async fn main(_spawner: Spawner) { | |||
| 192 | let (mut tx, mut rx) = can.split(); | 161 | let (mut tx, mut rx) = can.split(); |
| 193 | for i in 0..3 { | 162 | for i in 0..3 { |
| 194 | // Try filling up the RX FIFO0 buffers with standard packets | 163 | // Try filling up the RX FIFO0 buffers with standard packets |
| 195 | let tx_frame = can::TxFrame::new( | 164 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); |
| 196 | can::TxFrameHeader { | ||
| 197 | len: 1, | ||
| 198 | frame_format: can::FrameFormat::Standard, | ||
| 199 | id: can::StandardId::new(0x123).unwrap().into(), | ||
| 200 | bit_rate_switching: false, | ||
| 201 | marker: None, | ||
| 202 | }, | ||
| 203 | &[i], | ||
| 204 | ) | ||
| 205 | .unwrap(); | ||
| 206 | |||
| 207 | info!("Transmitting frame {}", i); | 165 | info!("Transmitting frame {}", i); |
| 208 | tx.write(&tx_frame).await; | 166 | tx.write(&tx_frame).await; |
| 209 | } | 167 | } |
| 210 | for i in 3..max_buffered { | 168 | for i in 3..max_buffered { |
| 211 | // Try filling up the RX FIFO0 buffers with extended packets | 169 | // Try filling up the RX FIFO0 buffers with extended packets |
| 212 | let tx_frame = can::TxFrame::new( | 170 | let tx_frame = can::frame::ClassicFrame::new_extended(0x1232344, &[i; 1]).unwrap(); |
| 213 | can::TxFrameHeader { | ||
| 214 | len: 1, | ||
| 215 | frame_format: can::FrameFormat::Standard, | ||
| 216 | id: can::ExtendedId::new(0x1232344).unwrap().into(), | ||
| 217 | bit_rate_switching: false, | ||
| 218 | marker: None, | ||
| 219 | }, | ||
| 220 | &[i], | ||
| 221 | ) | ||
| 222 | .unwrap(); | ||
| 223 | |||
| 224 | info!("Transmitting frame {}", i); | 171 | info!("Transmitting frame {}", i); |
| 225 | tx.write(&tx_frame).await; | 172 | tx.write(&tx_frame).await; |
| 226 | } | 173 | } |
| 227 | 174 | ||
| 228 | // Try and receive all 6 packets | 175 | // Try and receive all 6 packets |
| 229 | for i in 0..max_buffered { | 176 | for i in 0..max_buffered { |
| 230 | let envelope = rx.read().await.unwrap(); | 177 | let (frame, _ts) = rx.read().await.unwrap(); |
| 231 | match envelope.header.id { | 178 | match frame.id() { |
| 232 | can::Id::Extended(id) => { | 179 | embedded_can::Id::Extended(id) => { |
| 233 | info!("Extended received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | 180 | info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i); |
| 234 | } | 181 | } |
| 235 | can::Id::Standard(id) => { | 182 | embedded_can::Id::Standard(id) => { |
| 236 | info!("Standard received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | 183 | info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i); |
| 237 | } | 184 | } |
| 238 | } | 185 | } |
| 239 | } | 186 | } |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 50a7f9bae..1e6b1cce9 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -577,7 +577,18 @@ pub fn config() -> Config { | |||
| 577 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] | 577 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] |
| 578 | { | 578 | { |
| 579 | use embassy_stm32::rcc::*; | 579 | use embassy_stm32::rcc::*; |
| 580 | config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); | 580 | config.rcc.hsi = true; |
| 581 | config.rcc.pll1 = Some(Pll { | ||
| 582 | source: PllSource::HSI, // 16 MHz | ||
| 583 | prediv: PllPreDiv::DIV1, | ||
| 584 | mul: PllMul::MUL10, | ||
| 585 | divp: None, | ||
| 586 | divq: None, | ||
| 587 | divr: Some(PllDiv::DIV1), // 160 MHz | ||
| 588 | }); | ||
| 589 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 590 | config.rcc.voltage_range = VoltageScale::RANGE1; | ||
| 591 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 581 | } | 592 | } |
| 582 | 593 | ||
| 583 | #[cfg(feature = "stm32wba52cg")] | 594 | #[cfg(feature = "stm32wba52cg")] |
