diff options
| author | Peter Krull <[email protected]> | 2024-09-23 19:02:59 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-23 19:02:59 +0200 |
| commit | a2c473306f4a7c8e99add2546450ab3a7a97436e (patch) | |
| tree | 5522a708e492db7d4632dc0a56fe5057244f03f0 /tests | |
| parent | e02a987bafd4f0fcf9d80e7c4f6e1504b8b02cec (diff) | |
| parent | 2935290a6222536d6341103f91bfd732165d3862 (diff) | |
Merge branch 'embassy-rs:main' into multi-signal
Diffstat (limited to 'tests')
71 files changed, 2132 insertions, 703 deletions
diff --git a/tests/nrf52840/.cargo/config.toml b/tests/nrf/.cargo/config.toml index 9d6b0313a..8f9bccbc0 100644 --- a/tests/nrf52840/.cargo/config.toml +++ b/tests/nrf/.cargo/config.toml | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | runner = "teleprobe client run" | 3 | runner = "teleprobe client run" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | #target = "thumbv6m-none-eabi" | ||
| 6 | target = "thumbv7em-none-eabi" | 7 | target = "thumbv7em-none-eabi" |
| 8 | #target = "thumbv8m.main-none-eabihf" | ||
| 7 | 9 | ||
| 8 | [env] | 10 | [env] |
| 9 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" | 11 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml new file mode 100644 index 000000000..f666634d5 --- /dev/null +++ b/tests/nrf/Cargo.toml | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.2.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | ||
| 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | ||
| 18 | embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } | ||
| 19 | embedded-hal-async = { version = "1.0" } | ||
| 20 | embedded-hal-bus = { version = "0.1", features = ["async"] } | ||
| 21 | static_cell = "2" | ||
| 22 | perf-client = { path = "../perf-client" } | ||
| 23 | |||
| 24 | defmt = "0.3" | ||
| 25 | defmt-rtt = "0.4" | ||
| 26 | |||
| 27 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 28 | cortex-m-rt = "0.7.0" | ||
| 29 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 30 | portable-atomic = { version = "1.6.0" } | ||
| 31 | |||
| 32 | [features] | ||
| 33 | nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] | ||
| 34 | nrf52832 = ["embassy-nrf/nrf52832", "easydma"] | ||
| 35 | nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"] | ||
| 36 | nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"] | ||
| 37 | nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"] | ||
| 38 | nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"] | ||
| 39 | |||
| 40 | easydma = [] | ||
| 41 | two-uarts = [] | ||
| 42 | |||
| 43 | [profile.release] | ||
| 44 | codegen-units = 1 | ||
| 45 | debug = 2 | ||
| 46 | debug-assertions = false | ||
| 47 | incremental = false | ||
| 48 | lto = "fat" | ||
| 49 | opt-level = 's' | ||
| 50 | overflow-checks = false | ||
| 51 | |||
| 52 | # BEGIN TESTS | ||
| 53 | # Generated by gen_test.py. DO NOT EDIT. | ||
| 54 | [[bin]] | ||
| 55 | name = "buffered_uart" | ||
| 56 | path = "src/bin/buffered_uart.rs" | ||
| 57 | required-features = [ "easydma",] | ||
| 58 | |||
| 59 | [[bin]] | ||
| 60 | name = "buffered_uart_full" | ||
| 61 | path = "src/bin/buffered_uart_full.rs" | ||
| 62 | required-features = [ "easydma",] | ||
| 63 | |||
| 64 | [[bin]] | ||
| 65 | name = "buffered_uart_halves" | ||
| 66 | path = "src/bin/buffered_uart_halves.rs" | ||
| 67 | required-features = [ "two-uarts",] | ||
| 68 | |||
| 69 | [[bin]] | ||
| 70 | name = "buffered_uart_spam" | ||
| 71 | path = "src/bin/buffered_uart_spam.rs" | ||
| 72 | required-features = [ "two-uarts",] | ||
| 73 | |||
| 74 | [[bin]] | ||
| 75 | name = "ethernet_enc28j60_perf" | ||
| 76 | path = "src/bin/ethernet_enc28j60_perf.rs" | ||
| 77 | required-features = [ "nrf52840",] | ||
| 78 | |||
| 79 | [[bin]] | ||
| 80 | name = "gpio" | ||
| 81 | path = "src/bin/gpio.rs" | ||
| 82 | required-features = [] | ||
| 83 | |||
| 84 | [[bin]] | ||
| 85 | name = "gpiote" | ||
| 86 | path = "src/bin/gpiote.rs" | ||
| 87 | required-features = [] | ||
| 88 | |||
| 89 | [[bin]] | ||
| 90 | name = "timer" | ||
| 91 | path = "src/bin/timer.rs" | ||
| 92 | required-features = [] | ||
| 93 | |||
| 94 | [[bin]] | ||
| 95 | name = "uart_halves" | ||
| 96 | path = "src/bin/uart_halves.rs" | ||
| 97 | required-features = [ "two-uarts",] | ||
| 98 | |||
| 99 | [[bin]] | ||
| 100 | name = "uart_split" | ||
| 101 | path = "src/bin/uart_split.rs" | ||
| 102 | required-features = [ "easydma",] | ||
| 103 | |||
| 104 | [[bin]] | ||
| 105 | name = "wifi_esp_hosted_perf" | ||
| 106 | path = "src/bin/wifi_esp_hosted_perf.rs" | ||
| 107 | required-features = [ "nrf52840",] | ||
| 108 | |||
| 109 | # END TESTS | ||
diff --git a/tests/nrf/build.rs b/tests/nrf/build.rs new file mode 100644 index 000000000..3c15cf10f --- /dev/null +++ b/tests/nrf/build.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | |||
| 8 | // copy the right memory.x | ||
| 9 | #[cfg(feature = "nrf51422")] | ||
| 10 | let memory_x = include_bytes!("memory-nrf51422.x"); | ||
| 11 | #[cfg(feature = "nrf52832")] | ||
| 12 | let memory_x = include_bytes!("memory-nrf52832.x"); | ||
| 13 | #[cfg(feature = "nrf52833")] | ||
| 14 | let memory_x = include_bytes!("memory-nrf52833.x"); | ||
| 15 | #[cfg(feature = "nrf52840")] | ||
| 16 | let memory_x = include_bytes!("memory-nrf52840.x"); | ||
| 17 | #[cfg(feature = "nrf5340")] | ||
| 18 | let memory_x = include_bytes!("memory-nrf5340.x"); | ||
| 19 | #[cfg(feature = "nrf9160")] | ||
| 20 | let memory_x = include_bytes!("memory-nrf9160.x"); | ||
| 21 | fs::write(out.join("memory.x"), memory_x).unwrap(); | ||
| 22 | |||
| 23 | // copy main linker script. | ||
| 24 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); | ||
| 25 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 26 | println!("cargo:rerun-if-changed=link_ram.x"); | ||
| 27 | |||
| 28 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 29 | #[cfg(feature = "nrf51422")] | ||
| 30 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 31 | #[cfg(not(feature = "nrf51422"))] | ||
| 32 | println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); | ||
| 33 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 34 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 35 | |||
| 36 | Ok(()) | ||
| 37 | } | ||
diff --git a/tests/nrf/gen_test.py b/tests/nrf/gen_test.py new file mode 100644 index 000000000..daf714376 --- /dev/null +++ b/tests/nrf/gen_test.py | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | import os | ||
| 2 | import toml | ||
| 3 | from glob import glob | ||
| 4 | |||
| 5 | abspath = os.path.abspath(__file__) | ||
| 6 | dname = os.path.dirname(abspath) | ||
| 7 | os.chdir(dname) | ||
| 8 | |||
| 9 | # ======= load test list | ||
| 10 | tests = {} | ||
| 11 | for f in sorted(glob('./src/bin/*.rs')): | ||
| 12 | name = os.path.splitext(os.path.basename(f))[0] | ||
| 13 | features = [] | ||
| 14 | with open(f, 'r') as f: | ||
| 15 | for line in f: | ||
| 16 | if line.startswith('// required-features:'): | ||
| 17 | features = [feature.strip() for feature in line.split(':', 2)[1].strip().split(',')] | ||
| 18 | |||
| 19 | tests[name] = features | ||
| 20 | |||
| 21 | # ========= Update Cargo.toml | ||
| 22 | |||
| 23 | things = { | ||
| 24 | 'bin': [ | ||
| 25 | { | ||
| 26 | 'name': f'{name}', | ||
| 27 | 'path': f'src/bin/{name}.rs', | ||
| 28 | 'required-features': features, | ||
| 29 | } | ||
| 30 | for name, features in tests.items() | ||
| 31 | ] | ||
| 32 | } | ||
| 33 | |||
| 34 | SEPARATOR_START = '# BEGIN TESTS\n' | ||
| 35 | SEPARATOR_END = '# END TESTS\n' | ||
| 36 | HELP = '# Generated by gen_test.py. DO NOT EDIT.\n' | ||
| 37 | with open('Cargo.toml', 'r') as f: | ||
| 38 | data = f.read() | ||
| 39 | before, data = data.split(SEPARATOR_START, maxsplit=1) | ||
| 40 | _, after = data.split(SEPARATOR_END, maxsplit=1) | ||
| 41 | data = before + SEPARATOR_START + HELP + \ | ||
| 42 | toml.dumps(things) + SEPARATOR_END + after | ||
| 43 | with open('Cargo.toml', 'w') as f: | ||
| 44 | f.write(data) | ||
diff --git a/tests/nrf/memory-nrf51422.x b/tests/nrf/memory-nrf51422.x new file mode 100644 index 000000000..c140005ce --- /dev/null +++ b/tests/nrf/memory-nrf51422.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 256K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 32K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf52832.x b/tests/nrf/memory-nrf52832.x new file mode 100644 index 000000000..c140005ce --- /dev/null +++ b/tests/nrf/memory-nrf52832.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 256K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 32K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf52833.x b/tests/nrf/memory-nrf52833.x new file mode 100644 index 000000000..a4baa2dc4 --- /dev/null +++ b/tests/nrf/memory-nrf52833.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 512K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 64K | ||
| 5 | } | ||
diff --git a/tests/nrf52840/memory.x b/tests/nrf/memory-nrf52840.x index 58900a7bd..58900a7bd 100644 --- a/tests/nrf52840/memory.x +++ b/tests/nrf/memory-nrf52840.x | |||
diff --git a/tests/nrf/memory-nrf5340.x b/tests/nrf/memory-nrf5340.x new file mode 100644 index 000000000..58900a7bd --- /dev/null +++ b/tests/nrf/memory-nrf5340.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 1024K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf9160.x b/tests/nrf/memory-nrf9160.x new file mode 100644 index 000000000..58900a7bd --- /dev/null +++ b/tests/nrf/memory-nrf9160.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 1024K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 5 | } | ||
diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs new file mode 100644 index 000000000..04f32832f --- /dev/null +++ b/tests/nrf/src/bin/buffered_uart.rs | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{panic, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 21 | |||
| 22 | let mut tx_buffer = [0u8; 1024]; | ||
| 23 | let mut rx_buffer = [0u8; 1024]; | ||
| 24 | |||
| 25 | // test teardown + recreate of the buffereduarte works fine. | ||
| 26 | for _ in 0..2 { | ||
| 27 | let u = BufferedUarte::new( | ||
| 28 | &mut peri!(p, UART0), | ||
| 29 | &mut p.TIMER0, | ||
| 30 | &mut p.PPI_CH0, | ||
| 31 | &mut p.PPI_CH1, | ||
| 32 | &mut p.PPI_GROUP0, | ||
| 33 | irqs!(UART0_BUFFERED), | ||
| 34 | &mut peri!(p, PIN_A), | ||
| 35 | &mut peri!(p, PIN_B), | ||
| 36 | config.clone(), | ||
| 37 | &mut rx_buffer, | ||
| 38 | &mut tx_buffer, | ||
| 39 | ); | ||
| 40 | |||
| 41 | info!("uarte initialized!"); | ||
| 42 | |||
| 43 | let (mut rx, mut tx) = u.split(); | ||
| 44 | |||
| 45 | const COUNT: usize = 40_000; | ||
| 46 | |||
| 47 | let tx_fut = async { | ||
| 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 | let mut i = 0; | ||
| 62 | while i < COUNT { | ||
| 63 | let buf = unwrap!(rx.fill_buf().await); | ||
| 64 | |||
| 65 | for &b in buf { | ||
| 66 | if b != i as u8 { | ||
| 67 | panic!("mismatch {} vs {}, index {}", b, i as u8, i); | ||
| 68 | } | ||
| 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/nrf52840/src/bin/buffered_uart_full.rs b/tests/nrf/src/bin/buffered_uart_full.rs index e59c75ba9..09353bbe8 100644 --- a/tests/nrf52840/src/bin/buffered_uart_full.rs +++ b/tests/nrf/src/bin/buffered_uart_full.rs | |||
| @@ -1,18 +1,17 @@ | |||
| 1 | // required-features: easydma | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 10 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; |
| 8 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 11 | use embassy_nrf::{peripherals, uarte}; |
| 9 | use embedded_io_async::{Read, Write}; | 12 | use embedded_io_async::{Read, Write}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_nrf::init(Default::default()); | 17 | let p = embassy_nrf::init(Default::default()); |
| @@ -20,18 +19,18 @@ async fn main(_spawner: Spawner) { | |||
| 20 | config.parity = uarte::Parity::EXCLUDED; | 19 | config.parity = uarte::Parity::EXCLUDED; |
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | 20 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 22 | 21 | ||
| 23 | let mut tx_buffer = [0u8; 1024]; | 22 | let mut tx_buffer = [0u8; 500]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 23 | let mut rx_buffer = [0u8; 500]; |
| 25 | 24 | ||
| 26 | let mut u = BufferedUarte::new( | 25 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 26 | peri!(p, UART0), |
| 28 | p.TIMER0, | 27 | p.TIMER0, |
| 29 | p.PPI_CH0, | 28 | p.PPI_CH0, |
| 30 | p.PPI_CH1, | 29 | p.PPI_CH1, |
| 31 | p.PPI_GROUP0, | 30 | p.PPI_GROUP0, |
| 32 | Irqs, | 31 | irqs!(UART0_BUFFERED), |
| 33 | p.P1_03, | 32 | peri!(p, PIN_A), |
| 34 | p.P1_02, | 33 | peri!(p, PIN_B), |
| 35 | config.clone(), | 34 | config.clone(), |
| 36 | &mut rx_buffer, | 35 | &mut rx_buffer, |
| 37 | &mut tx_buffer, | 36 | &mut tx_buffer, |
| @@ -41,22 +40,22 @@ async fn main(_spawner: Spawner) { | |||
| 41 | 40 | ||
| 42 | let (mut rx, mut tx) = u.split(); | 41 | let (mut rx, mut tx) = u.split(); |
| 43 | 42 | ||
| 44 | let mut buf = [0; 1024]; | 43 | let mut buf = [0; 500]; |
| 45 | for (j, b) in buf.iter_mut().enumerate() { | 44 | for (j, b) in buf.iter_mut().enumerate() { |
| 46 | *b = j as u8; | 45 | *b = j as u8; |
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | // Write 1024b. This causes the rx buffer to get exactly full. | 48 | // Write 500b. This causes the rx buffer to get exactly full. |
| 50 | unwrap!(tx.write_all(&buf).await); | 49 | unwrap!(tx.write_all(&buf).await); |
| 51 | unwrap!(tx.flush().await); | 50 | unwrap!(tx.flush().await); |
| 52 | 51 | ||
| 53 | // Read those 1024b. | 52 | // Read those 500b. |
| 54 | unwrap!(rx.read_exact(&mut buf).await); | 53 | unwrap!(rx.read_exact(&mut buf).await); |
| 55 | for (j, b) in buf.iter().enumerate() { | 54 | for (j, b) in buf.iter().enumerate() { |
| 56 | assert_eq!(*b, j as u8); | 55 | assert_eq!(*b, j as u8); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | // The buffer should now be unclogged. Write 1024b again. | 58 | // The buffer should now be unclogged. Write 500b again. |
| 60 | unwrap!(tx.write_all(&buf).await); | 59 | unwrap!(tx.write_all(&buf).await); |
| 61 | unwrap!(tx.flush().await); | 60 | unwrap!(tx.flush().await); |
| 62 | 61 | ||
diff --git a/tests/nrf/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs new file mode 100644 index 000000000..bdf5ad726 --- /dev/null +++ b/tests/nrf/src/bin/buffered_uart_halves.rs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | // required-features: two-uarts | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 21 | |||
| 22 | let mut tx_buffer = [0u8; 1024]; | ||
| 23 | let mut rx_buffer = [0u8; 1024]; | ||
| 24 | |||
| 25 | // test teardown + recreate of the buffereduarte works fine. | ||
| 26 | for _ in 0..2 { | ||
| 27 | const COUNT: usize = 40_000; | ||
| 28 | |||
| 29 | let mut tx = BufferedUarteTx::new( | ||
| 30 | &mut peri!(p, UART1), | ||
| 31 | irqs!(UART1_BUFFERED), | ||
| 32 | &mut peri!(p, PIN_A), | ||
| 33 | config.clone(), | ||
| 34 | &mut tx_buffer, | ||
| 35 | ); | ||
| 36 | |||
| 37 | let mut rx = BufferedUarteRx::new( | ||
| 38 | &mut peri!(p, UART0), | ||
| 39 | &mut p.TIMER0, | ||
| 40 | &mut p.PPI_CH0, | ||
| 41 | &mut p.PPI_CH1, | ||
| 42 | &mut p.PPI_GROUP0, | ||
| 43 | irqs!(UART0_BUFFERED), | ||
| 44 | &mut peri!(p, PIN_B), | ||
| 45 | config.clone(), | ||
| 46 | &mut rx_buffer, | ||
| 47 | ); | ||
| 48 | |||
| 49 | let tx_fut = async { | ||
| 50 | info!("tx initialized!"); | ||
| 51 | |||
| 52 | let mut tx_buf = [0; 215]; | ||
| 53 | let mut i = 0; | ||
| 54 | while i < COUNT { | ||
| 55 | let n = tx_buf.len().min(COUNT - i); | ||
| 56 | let tx_buf = &mut tx_buf[..n]; | ||
| 57 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 58 | *b = (i + j) as u8; | ||
| 59 | } | ||
| 60 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 61 | i += n; | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | let rx_fut = async { | ||
| 65 | info!("rx initialized!"); | ||
| 66 | |||
| 67 | let mut i = 0; | ||
| 68 | while i < COUNT { | ||
| 69 | let buf = unwrap!(rx.fill_buf().await); | ||
| 70 | |||
| 71 | for &b in buf { | ||
| 72 | assert_eq!(b, i as u8); | ||
| 73 | i = i + 1; | ||
| 74 | } | ||
| 75 | |||
| 76 | let n = buf.len(); | ||
| 77 | rx.consume(n); | ||
| 78 | } | ||
| 79 | }; | ||
| 80 | |||
| 81 | join(rx_fut, tx_fut).await; | ||
| 82 | } | ||
| 83 | |||
| 84 | info!("Test OK"); | ||
| 85 | cortex_m::asm::bkpt(); | ||
| 86 | } | ||
diff --git a/tests/nrf52840/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 400c0df99..e8fca452e 100644 --- a/tests/nrf52840/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -1,25 +1,23 @@ | |||
| 1 | // required-features: two-uarts | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 4 | 7 | ||
| 5 | use core::mem; | 8 | use core::mem; |
| 6 | use core::ptr::NonNull; | 9 | use core::ptr::NonNull; |
| 7 | 10 | ||
| 8 | use defmt::{assert_eq, *}; | 11 | use defmt::{assert_eq, *}; |
| 9 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 10 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 13 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx}; |
| 11 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 14 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 12 | use embassy_nrf::ppi::{Event, Ppi, Task}; | 15 | use embassy_nrf::ppi::{Event, Ppi, Task}; |
| 13 | use embassy_nrf::uarte::Uarte; | 16 | use embassy_nrf::uarte::UarteTx; |
| 14 | use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; | 17 | use embassy_nrf::{pac, peripherals, uarte}; |
| 15 | use embassy_time::Timer; | 18 | use embassy_time::Timer; |
| 16 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 17 | 20 | ||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 20 | UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 24 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 25 | let mut p = embassy_nrf::init(Default::default()); | 23 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -27,23 +25,20 @@ async fn main(_spawner: Spawner) { | |||
| 27 | config.parity = uarte::Parity::EXCLUDED; | 25 | config.parity = uarte::Parity::EXCLUDED; |
| 28 | config.baudrate = uarte::Baudrate::BAUD1M; | 26 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 29 | 27 | ||
| 30 | let mut tx_buffer = [0u8; 1024]; | ||
| 31 | let mut rx_buffer = [0u8; 1024]; | 28 | let mut rx_buffer = [0u8; 1024]; |
| 32 | 29 | ||
| 33 | mem::forget(Output::new(&mut p.P1_02, Level::High, OutputDrive::Standard)); | 30 | mem::forget(Output::new(&mut peri!(p, PIN_A), Level::High, OutputDrive::Standard)); |
| 34 | 31 | ||
| 35 | let mut u = BufferedUarte::new( | 32 | let mut u = BufferedUarteRx::new( |
| 36 | p.UARTE0, | 33 | peri!(p, UART0), |
| 37 | p.TIMER0, | 34 | p.TIMER0, |
| 38 | p.PPI_CH0, | 35 | p.PPI_CH0, |
| 39 | p.PPI_CH1, | 36 | p.PPI_CH1, |
| 40 | p.PPI_GROUP0, | 37 | p.PPI_GROUP0, |
| 41 | Irqs, | 38 | irqs!(UART0_BUFFERED), |
| 42 | p.P1_03, | 39 | peri!(p, PIN_B), |
| 43 | p.P1_04, | ||
| 44 | config.clone(), | 40 | config.clone(), |
| 45 | &mut rx_buffer, | 41 | &mut rx_buffer, |
| 46 | &mut tx_buffer, | ||
| 47 | ); | 42 | ); |
| 48 | 43 | ||
| 49 | info!("uarte initialized!"); | 44 | info!("uarte initialized!"); |
| @@ -54,7 +49,7 @@ async fn main(_spawner: Spawner) { | |||
| 54 | // Tx spam in a loop. | 49 | // Tx spam in a loop. |
| 55 | const NSPAM: usize = 17; | 50 | const NSPAM: usize = 17; |
| 56 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 51 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 57 | let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone()); | 52 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 58 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; | 53 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; |
| 59 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; | 54 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; |
| 60 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; | 55 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; |
diff --git a/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs index 33c2f4235..ed58627f1 100644 --- a/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs +++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // required-features: nrf52840 | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"ak-gwe-r7"); | 4 | teleprobe_meta::target!(b"ak-gwe-r7"); |
| @@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 6 | ||
| 6 | use defmt::{info, unwrap}; | 7 | use defmt::{info, unwrap}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Stack, StackResources}; | 9 | use embassy_net::StackResources; |
| 9 | use embassy_net_enc28j60::Enc28j60; | 10 | use embassy_net_enc28j60::Enc28j60; |
| 10 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 11 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 11 | use embassy_nrf::rng::Rng; | 12 | use embassy_nrf::rng::Rng; |
| @@ -24,8 +25,8 @@ bind_interrupts!(struct Irqs { | |||
| 24 | type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; | 25 | type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; |
| 25 | 26 | ||
| 26 | #[embassy_executor::task] | 27 | #[embassy_executor::task] |
| 27 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { | 28 | async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! { |
| 28 | stack.run().await | 29 | runner.run().await |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | #[embassy_executor::main] | 32 | #[embassy_executor::main] |
| @@ -64,16 +65,10 @@ async fn main(spawner: Spawner) { | |||
| 64 | let seed = u64::from_le_bytes(seed); | 65 | let seed = u64::from_le_bytes(seed); |
| 65 | 66 | ||
| 66 | // Init network stack | 67 | // Init network stack |
| 67 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||
| 68 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 68 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 69 | let stack = &*STACK.init(Stack::new( | 69 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 70 | device, | ||
| 71 | config, | ||
| 72 | RESOURCES.init(StackResources::<2>::new()), | ||
| 73 | seed, | ||
| 74 | )); | ||
| 75 | 70 | ||
| 76 | unwrap!(spawner.spawn(net_task(stack))); | 71 | unwrap!(spawner.spawn(net_task(runner))); |
| 77 | 72 | ||
| 78 | perf_client::run( | 73 | perf_client::run( |
| 79 | stack, | 74 | stack, |
diff --git a/tests/nrf51422/src/bin/gpio.rs b/tests/nrf/src/bin/gpio.rs index 6d5a87d0a..9e809a694 100644 --- a/tests/nrf51422/src/bin/gpio.rs +++ b/tests/nrf/src/bin/gpio.rs | |||
| @@ -1,19 +1,20 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 8 | use embassy_time::Timer; | 10 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | 11 | ||
| 11 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 13 | let p = embassy_nrf::init(Default::default()); | 14 | let p = embassy_nrf::init(Default::default()); |
| 14 | 15 | ||
| 15 | let input = Input::new(p.P0_13, Pull::Up); | 16 | let input = Input::new(peri!(p, PIN_A), Pull::Up); |
| 16 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | 17 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); |
| 17 | 18 | ||
| 18 | output.set_low(); | 19 | output.set_low(); |
| 19 | Timer::after_millis(10).await; | 20 | Timer::after_millis(10).await; |
diff --git a/tests/nrf51422/src/bin/gpiote.rs b/tests/nrf/src/bin/gpiote.rs index 330fe993e..0700016d1 100644 --- a/tests/nrf51422/src/bin/gpiote.rs +++ b/tests/nrf/src/bin/gpiote.rs | |||
| @@ -1,20 +1,21 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | 9 | use embassy_futures::join::join; |
| 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 10 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 9 | use embassy_time::{Duration, Instant, Timer}; | 11 | use embassy_time::{Duration, Instant, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | 12 | ||
| 12 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_nrf::init(Default::default()); | 15 | let p = embassy_nrf::init(Default::default()); |
| 15 | 16 | ||
| 16 | let mut input = Input::new(p.P0_13, Pull::Up); | 17 | let mut input = Input::new(peri!(p, PIN_A), Pull::Up); |
| 17 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | 18 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); |
| 18 | 19 | ||
| 19 | let fut1 = async { | 20 | let fut1 = async { |
| 20 | Timer::after_millis(100).await; | 21 | Timer::after_millis(100).await; |
| @@ -24,6 +25,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let start = Instant::now(); | 25 | let start = Instant::now(); |
| 25 | input.wait_for_high().await; | 26 | input.wait_for_high().await; |
| 26 | let dur = Instant::now() - start; | 27 | let dur = Instant::now() - start; |
| 28 | info!("took {} ms", dur.as_millis()); | ||
| 27 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | 29 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); |
| 28 | }; | 30 | }; |
| 29 | 31 | ||
| @@ -37,6 +39,7 @@ async fn main(_spawner: Spawner) { | |||
| 37 | let start = Instant::now(); | 39 | let start = Instant::now(); |
| 38 | input.wait_for_low().await; | 40 | input.wait_for_low().await; |
| 39 | let dur = Instant::now() - start; | 41 | let dur = Instant::now() - start; |
| 42 | info!("took {} ms", dur.as_millis()); | ||
| 40 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | 43 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
diff --git a/tests/nrf51422/src/bin/timer.rs b/tests/nrf/src/bin/timer.rs index cf9ea41a8..1ae9dd647 100644 --- a/tests/nrf51422/src/bin/timer.rs +++ b/tests/nrf/src/bin/timer.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
diff --git a/tests/nrf/src/bin/uart_halves.rs b/tests/nrf/src/bin/uart_halves.rs new file mode 100644 index 000000000..f48ea43a1 --- /dev/null +++ b/tests/nrf/src/bin/uart_halves.rs | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | // required-features: two-uarts | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::{UarteRx, UarteTx}; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 21 | |||
| 22 | let mut tx = UarteTx::new(&mut peri!(p, UART0), irqs!(UART0), &mut peri!(p, PIN_A), config.clone()); | ||
| 23 | let mut rx = UarteRx::new(&mut peri!(p, UART1), irqs!(UART1), &mut peri!(p, PIN_B), config.clone()); | ||
| 24 | |||
| 25 | let data = [ | ||
| 26 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 27 | ]; | ||
| 28 | |||
| 29 | let tx_fut = async { | ||
| 30 | tx.write(&data).await.unwrap(); | ||
| 31 | }; | ||
| 32 | let rx_fut = async { | ||
| 33 | let mut buf = [0u8; 16]; | ||
| 34 | rx.read(&mut buf).await.unwrap(); | ||
| 35 | assert_eq!(data, buf); | ||
| 36 | }; | ||
| 37 | join(rx_fut, tx_fut).await; | ||
| 38 | |||
| 39 | info!("Test OK"); | ||
| 40 | cortex_m::asm::bkpt(); | ||
| 41 | } | ||
diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs new file mode 100644 index 000000000..70d8b2e33 --- /dev/null +++ b/tests/nrf/src/bin/uart_split.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::Uarte; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD9600; | ||
| 22 | |||
| 23 | let uarte = Uarte::new( | ||
| 24 | &mut peri!(p, UART0), | ||
| 25 | irqs!(UART0), | ||
| 26 | &mut peri!(p, PIN_A), | ||
| 27 | &mut peri!(p, PIN_B), | ||
| 28 | config.clone(), | ||
| 29 | ); | ||
| 30 | let (mut tx, mut rx) = uarte.split(); | ||
| 31 | |||
| 32 | let data = [ | ||
| 33 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 34 | ]; | ||
| 35 | |||
| 36 | let tx_fut = async { | ||
| 37 | Timer::after_millis(10).await; | ||
| 38 | tx.write(&data).await.unwrap(); | ||
| 39 | }; | ||
| 40 | let rx_fut = async { | ||
| 41 | let mut buf = [0u8; 16]; | ||
| 42 | rx.read(&mut buf).await.unwrap(); | ||
| 43 | assert_eq!(data, buf); | ||
| 44 | }; | ||
| 45 | join(rx_fut, tx_fut).await; | ||
| 46 | |||
| 47 | info!("Test OK"); | ||
| 48 | cortex_m::asm::bkpt(); | ||
| 49 | } | ||
diff --git a/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs index b83edddc4..34fb8103b 100644 --- a/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs +++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // required-features: nrf52840 | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | teleprobe_meta::target!(b"nrf52840-dk"); |
| @@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 6 | ||
| 6 | use defmt::{info, unwrap}; | 7 | use defmt::{info, unwrap}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Config, Stack, StackResources}; | 9 | use embassy_net::{Config, StackResources}; |
| 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 10 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 10 | use embassy_nrf::rng::Rng; | 11 | use embassy_nrf::rng::Rng; |
| 11 | use embassy_nrf::spim::{self, Spim}; | 12 | use embassy_nrf::spim::{self, Spim}; |
| @@ -39,8 +40,8 @@ async fn wifi_task( | |||
| 39 | type MyDriver = hosted::NetDriver<'static>; | 40 | type MyDriver = hosted::NetDriver<'static>; |
| 40 | 41 | ||
| 41 | #[embassy_executor::task] | 42 | #[embassy_executor::task] |
| 42 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { | 43 | async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! { |
| 43 | stack.run().await | 44 | runner.run().await |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | #[embassy_executor::main] | 47 | #[embassy_executor::main] |
| @@ -85,16 +86,15 @@ async fn main(spawner: Spawner) { | |||
| 85 | let seed = u64::from_le_bytes(seed); | 86 | let seed = u64::from_le_bytes(seed); |
| 86 | 87 | ||
| 87 | // Init network stack | 88 | // Init network stack |
| 88 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||
| 89 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 89 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 90 | let stack = &*STACK.init(Stack::new( | 90 | let (stack, runner) = embassy_net::new( |
| 91 | device, | 91 | device, |
| 92 | Config::dhcpv4(Default::default()), | 92 | Config::dhcpv4(Default::default()), |
| 93 | RESOURCES.init(StackResources::<2>::new()), | 93 | RESOURCES.init(StackResources::new()), |
| 94 | seed, | 94 | seed, |
| 95 | )); | 95 | ); |
| 96 | 96 | ||
| 97 | unwrap!(spawner.spawn(net_task(stack))); | 97 | unwrap!(spawner.spawn(net_task(runner))); |
| 98 | 98 | ||
| 99 | perf_client::run( | 99 | perf_client::run( |
| 100 | stack, | 100 | stack, |
diff --git a/tests/nrf/src/common.rs b/tests/nrf/src/common.rs new file mode 100644 index 000000000..ff5299b0f --- /dev/null +++ b/tests/nrf/src/common.rs | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use {defmt_rtt as _, panic_probe as _}; | ||
| 4 | |||
| 5 | #[cfg(feature = "nrf52832")] | ||
| 6 | teleprobe_meta::target!(b"nrf52832-dk"); | ||
| 7 | #[cfg(feature = "nrf52840")] | ||
| 8 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 9 | #[cfg(feature = "nrf52833")] | ||
| 10 | teleprobe_meta::target!(b"nrf52833-dk"); | ||
| 11 | #[cfg(feature = "nrf5340")] | ||
| 12 | teleprobe_meta::target!(b"nrf5340-dk"); | ||
| 13 | #[cfg(feature = "nrf9160")] | ||
| 14 | teleprobe_meta::target!(b"nrf9160-dk"); | ||
| 15 | #[cfg(feature = "nrf51422")] | ||
| 16 | teleprobe_meta::target!(b"nrf51-dk"); | ||
| 17 | |||
| 18 | macro_rules! define_peris { | ||
| 19 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { | ||
| 20 | #[allow(unused_macros)] | ||
| 21 | macro_rules! peri { | ||
| 22 | $( | ||
| 23 | ($p:expr, $name) => { | ||
| 24 | $p.$peri | ||
| 25 | }; | ||
| 26 | )* | ||
| 27 | } | ||
| 28 | #[allow(unused_macros)] | ||
| 29 | macro_rules! irqs { | ||
| 30 | $( | ||
| 31 | ($irq_name) => {{ | ||
| 32 | embassy_nrf::bind_interrupts!(struct Irqs $irq_code); | ||
| 33 | Irqs | ||
| 34 | }}; | ||
| 35 | )* | ||
| 36 | ( @ dummy ) => {}; | ||
| 37 | } | ||
| 38 | |||
| 39 | #[allow(unused)] | ||
| 40 | #[allow(non_camel_case_types)] | ||
| 41 | pub mod peris { | ||
| 42 | $( | ||
| 43 | pub type $name = embassy_nrf::peripherals::$peri; | ||
| 44 | )* | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | } | ||
| 48 | |||
| 49 | #[cfg(feature = "nrf51422")] | ||
| 50 | define_peris!(PIN_A = P0_13, PIN_B = P0_14,); | ||
| 51 | |||
| 52 | #[cfg(feature = "nrf52832")] | ||
| 53 | define_peris!( | ||
| 54 | PIN_A = P0_11, PIN_B = P0_12, | ||
| 55 | UART0 = UARTE0, | ||
| 56 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 57 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 58 | ); | ||
| 59 | |||
| 60 | #[cfg(feature = "nrf52833")] | ||
| 61 | define_peris!( | ||
| 62 | PIN_A = P1_01, PIN_B = P1_02, | ||
| 63 | UART0 = UARTE0, | ||
| 64 | UART1 = UARTE1, | ||
| 65 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 66 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 67 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 68 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 69 | ); | ||
| 70 | |||
| 71 | #[cfg(feature = "nrf52840")] | ||
| 72 | define_peris!( | ||
| 73 | PIN_A = P1_02, PIN_B = P1_03, | ||
| 74 | UART0 = UARTE0, | ||
| 75 | UART1 = UARTE1, | ||
| 76 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 77 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 78 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 79 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 80 | ); | ||
| 81 | |||
| 82 | #[cfg(feature = "nrf5340")] | ||
| 83 | define_peris!( | ||
| 84 | PIN_A = P1_08, PIN_B = P1_09, | ||
| 85 | UART0 = SERIAL0, | ||
| 86 | UART1 = SERIAL1, | ||
| 87 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 88 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 89 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 90 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 91 | ); | ||
| 92 | |||
| 93 | #[cfg(feature = "nrf9160")] | ||
| 94 | define_peris!( | ||
| 95 | PIN_A = P0_00, PIN_B = P0_01, | ||
| 96 | UART0 = SERIAL0, | ||
| 97 | UART1 = SERIAL1, | ||
| 98 | @irq UART0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 99 | @irq UART1 = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 100 | @irq UART0_BUFFERED = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 101 | @irq UART1_BUFFERED = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 102 | ); | ||
diff --git a/tests/nrf51422/.cargo/config.toml b/tests/nrf51422/.cargo/config.toml deleted file mode 100644 index 634805633..000000000 --- a/tests/nrf51422/.cargo/config.toml +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | #runner = "teleprobe local run --chip nRF51422_xxAA --elf" | ||
| 3 | runner = "teleprobe client run" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv6m-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace,embassy_hal_internal=debug" | ||
diff --git a/tests/nrf51422/Cargo.toml b/tests/nrf51422/Cargo.toml deleted file mode 100644 index 07236987b..000000000 --- a/tests/nrf51422/Cargo.toml +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf51-tests" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-128", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "gpiote"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embedded-hal-async = { version = "1.0" } | ||
| 17 | |||
| 18 | defmt = "0.3" | ||
| 19 | defmt-rtt = "0.4" | ||
| 20 | |||
| 21 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 22 | cortex-m-rt = "0.7.0" | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
diff --git a/tests/nrf51422/build.rs b/tests/nrf51422/build.rs deleted file mode 100644 index 13ebbe4ee..000000000 --- a/tests/nrf51422/build.rs +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | fs::write(out.join("memory.x"), include_bytes!("memory.x")).unwrap(); | ||
| 8 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 9 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 10 | |||
| 11 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 12 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 13 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 14 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 15 | |||
| 16 | Ok(()) | ||
| 17 | } | ||
diff --git a/tests/nrf51422/memory.x b/tests/nrf51422/memory.x deleted file mode 100644 index a5881e66f..000000000 --- a/tests/nrf51422/memory.x +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 16K | ||
| 5 | } | ||
diff --git a/tests/nrf52840/Cargo.toml b/tests/nrf52840/Cargo.toml deleted file mode 100644 index 84ca99f1f..000000000 --- a/tests/nrf52840/Cargo.toml +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | ||
| 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | ||
| 18 | embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } | ||
| 19 | embedded-hal-async = { version = "1.0" } | ||
| 20 | embedded-hal-bus = { version = "0.1", features = ["async"] } | ||
| 21 | static_cell = "2" | ||
| 22 | perf-client = { path = "../perf-client" } | ||
| 23 | |||
| 24 | defmt = "0.3" | ||
| 25 | defmt-rtt = "0.4" | ||
| 26 | |||
| 27 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 28 | cortex-m-rt = "0.7.0" | ||
| 29 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
diff --git a/tests/nrf52840/build.rs b/tests/nrf52840/build.rs deleted file mode 100644 index 71c82a70f..000000000 --- a/tests/nrf52840/build.rs +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); | ||
| 8 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 9 | println!("cargo:rerun-if-changed=link_ram.x"); | ||
| 10 | |||
| 11 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 12 | println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); | ||
| 13 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 14 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 15 | |||
| 16 | Ok(()) | ||
| 17 | } | ||
diff --git a/tests/nrf52840/src/bin/buffered_uart.rs b/tests/nrf52840/src/bin/buffered_uart.rs deleted file mode 100644 index 354d787b4..000000000 --- a/tests/nrf52840/src/bin/buffered_uart.rs +++ /dev/null | |||
| @@ -1,78 +0,0 @@ | |||
| 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, BufferedUarte}; | ||
| 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 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 22 | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | ||
| 24 | let mut rx_buffer = [0u8; 1024]; | ||
| 25 | |||
| 26 | let mut u = BufferedUarte::new( | ||
| 27 | p.UARTE0, | ||
| 28 | p.TIMER0, | ||
| 29 | p.PPI_CH0, | ||
| 30 | p.PPI_CH1, | ||
| 31 | p.PPI_GROUP0, | ||
| 32 | Irqs, | ||
| 33 | p.P1_03, | ||
| 34 | p.P1_02, | ||
| 35 | config.clone(), | ||
| 36 | &mut rx_buffer, | ||
| 37 | &mut tx_buffer, | ||
| 38 | ); | ||
| 39 | |||
| 40 | info!("uarte initialized!"); | ||
| 41 | |||
| 42 | let (mut rx, mut tx) = u.split(); | ||
| 43 | |||
| 44 | const COUNT: usize = 40_000; | ||
| 45 | |||
| 46 | let tx_fut = async { | ||
| 47 | let mut tx_buf = [0; 215]; | ||
| 48 | let mut i = 0; | ||
| 49 | while i < COUNT { | ||
| 50 | let n = tx_buf.len().min(COUNT - i); | ||
| 51 | let tx_buf = &mut tx_buf[..n]; | ||
| 52 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 53 | *b = (i + j) as u8; | ||
| 54 | } | ||
| 55 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 56 | i += n; | ||
| 57 | } | ||
| 58 | }; | ||
| 59 | let rx_fut = async { | ||
| 60 | let mut i = 0; | ||
| 61 | while i < COUNT { | ||
| 62 | let buf = unwrap!(rx.fill_buf().await); | ||
| 63 | |||
| 64 | for &b in buf { | ||
| 65 | assert_eq!(b, i as u8); | ||
| 66 | i = i + 1; | ||
| 67 | } | ||
| 68 | |||
| 69 | let n = buf.len(); | ||
| 70 | rx.consume(n); | ||
| 71 | } | ||
| 72 | }; | ||
| 73 | |||
| 74 | join(rx_fut, tx_fut).await; | ||
| 75 | |||
| 76 | info!("Test OK"); | ||
| 77 | cortex_m::asm::bkpt(); | ||
| 78 | } | ||
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 4390a6da1..eb2a33a30 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml | |||
| @@ -3,10 +3,8 @@ name = "perf-client" | |||
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2021" |
| 5 | 5 | ||
| 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| 7 | |||
| 8 | [dependencies] | 6 | [dependencies] |
| 9 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } | 7 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } | 8 | embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", ] } |
| 11 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 9 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 12 | defmt = "0.3.0" | 10 | defmt = "0.3.0" |
diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs index 54762379a..4bd9e5674 100644 --- a/tests/perf-client/src/lib.rs +++ b/tests/perf-client/src/lib.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | use defmt::{assert, *}; | 3 | use defmt::{assert, *}; |
| 4 | use embassy_futures::join::join; | 4 | use embassy_futures::join::join; |
| 5 | use embassy_net::driver::Driver; | ||
| 6 | use embassy_net::tcp::TcpSocket; | 5 | use embassy_net::tcp::TcpSocket; |
| 7 | use embassy_net::{Ipv4Address, Stack}; | 6 | use embassy_net::{Ipv4Address, Stack}; |
| 8 | use embassy_time::{with_timeout, Duration, Timer}; | 7 | use embassy_time::{with_timeout, Duration, Timer}; |
| @@ -13,7 +12,7 @@ pub struct Expected { | |||
| 13 | pub updown_kbps: usize, | 12 | pub updown_kbps: usize, |
| 14 | } | 13 | } |
| 15 | 14 | ||
| 16 | pub async fn run<D: Driver>(stack: &Stack<D>, expected: Expected) { | 15 | pub async fn run(stack: Stack<'_>, expected: Expected) { |
| 17 | info!("Waiting for DHCP up..."); | 16 | info!("Waiting for DHCP up..."); |
| 18 | while stack.config_v4().is_none() { | 17 | while stack.config_v4().is_none() { |
| 19 | Timer::after_millis(100).await; | 18 | Timer::after_millis(100).await; |
| @@ -38,7 +37,7 @@ const DOWNLOAD_PORT: u16 = 4321; | |||
| 38 | const UPLOAD_PORT: u16 = 4322; | 37 | const UPLOAD_PORT: u16 = 4322; |
| 39 | const UPLOAD_DOWNLOAD_PORT: u16 = 4323; | 38 | const UPLOAD_DOWNLOAD_PORT: u16 = 4323; |
| 40 | 39 | ||
| 41 | async fn test_download<D: Driver>(stack: &Stack<D>) -> usize { | 40 | async fn test_download(stack: Stack<'_>) -> usize { |
| 42 | info!("Testing download..."); | 41 | info!("Testing download..."); |
| 43 | 42 | ||
| 44 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 43 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
| @@ -78,7 +77,7 @@ async fn test_download<D: Driver>(stack: &Stack<D>) -> usize { | |||
| 78 | kbps | 77 | kbps |
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize { | 80 | async fn test_upload(stack: Stack<'_>) -> usize { |
| 82 | info!("Testing upload..."); | 81 | info!("Testing upload..."); |
| 83 | 82 | ||
| 84 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 83 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
| @@ -118,7 +117,7 @@ async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize { | |||
| 118 | kbps | 117 | kbps |
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | async fn test_upload_download<D: Driver>(stack: &Stack<D>) -> usize { | 120 | async fn test_upload_download(stack: Stack<'_>) -> usize { |
| 122 | info!("Testing upload+download..."); | 121 | info!("Testing upload+download..."); |
| 123 | 122 | ||
| 124 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 123 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 38fb2deec..ae2b0e180 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml | |||
| @@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } | 8 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } |
| 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } | 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } |
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } | 10 | embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } |
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time" } | 11 | embassy-time = { version = "0.3.2", path = "../../embassy-time" } |
| 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 13 | 13 | ||
| 14 | riscv-rt = "0.11" | 14 | riscv-rt = "0.12.2" |
| 15 | riscv = { version = "0.10", features = ["critical-section-single-hart"] } | 15 | riscv = { version = "0.11.1", features = ["critical-section-single-hart"] } |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | [profile.dev] | 18 | [profile.dev] |
diff --git a/tests/riscv32/link.x b/tests/riscv32/link.x new file mode 100644 index 000000000..4076b0c68 --- /dev/null +++ b/tests/riscv32/link.x | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | /* # EMBASSY notes | ||
| 2 | This file is a workaround for https://github.com/rust-embedded/riscv/issues/196 | ||
| 3 | Remove when fixed upstream. | ||
| 4 | */ | ||
| 5 | /* # Developer notes | ||
| 6 | |||
| 7 | - Symbols that start with a double underscore (__) are considered "private" | ||
| 8 | |||
| 9 | - Symbols that start with a single underscore (_) are considered "semi-public"; they can be | ||
| 10 | overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { | ||
| 11 | static mut _heap_size }`). | ||
| 12 | |||
| 13 | - `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a | ||
| 14 | symbol if not dropped if it appears in or near the front of the linker arguments and "it's not | ||
| 15 | needed" by any of the preceding objects (linker arguments) | ||
| 16 | |||
| 17 | - `PROVIDE` is used to provide default values that can be overridden by a user linker script | ||
| 18 | |||
| 19 | - In this linker script, you may find symbols that look like `${...}` (e.g., `4`). | ||
| 20 | These are wildcards used by the `build.rs` script to adapt to different target particularities. | ||
| 21 | Check `build.rs` for more details about these symbols. | ||
| 22 | |||
| 23 | - On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* | ||
| 24 | the LMA of .data are all `4`-byte aligned. These alignments are assumed by the RAM | ||
| 25 | initialization routine. There's also a second benefit: `4`-byte aligned boundaries | ||
| 26 | means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`. | ||
| 27 | */ | ||
| 28 | |||
| 29 | PROVIDE(_stext = ORIGIN(REGION_TEXT)); | ||
| 30 | PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)); | ||
| 31 | PROVIDE(_max_hart_id = 0); | ||
| 32 | PROVIDE(_hart_stack_size = 2K); | ||
| 33 | PROVIDE(_heap_size = 0); | ||
| 34 | |||
| 35 | PROVIDE(InstructionMisaligned = ExceptionHandler); | ||
| 36 | PROVIDE(InstructionFault = ExceptionHandler); | ||
| 37 | PROVIDE(IllegalInstruction = ExceptionHandler); | ||
| 38 | PROVIDE(Breakpoint = ExceptionHandler); | ||
| 39 | PROVIDE(LoadMisaligned = ExceptionHandler); | ||
| 40 | PROVIDE(LoadFault = ExceptionHandler); | ||
| 41 | PROVIDE(StoreMisaligned = ExceptionHandler); | ||
| 42 | PROVIDE(StoreFault = ExceptionHandler);; | ||
| 43 | PROVIDE(UserEnvCall = ExceptionHandler); | ||
| 44 | PROVIDE(SupervisorEnvCall = ExceptionHandler); | ||
| 45 | PROVIDE(MachineEnvCall = ExceptionHandler); | ||
| 46 | PROVIDE(InstructionPageFault = ExceptionHandler); | ||
| 47 | PROVIDE(LoadPageFault = ExceptionHandler); | ||
| 48 | PROVIDE(StorePageFault = ExceptionHandler); | ||
| 49 | |||
| 50 | PROVIDE(SupervisorSoft = DefaultHandler); | ||
| 51 | PROVIDE(MachineSoft = DefaultHandler); | ||
| 52 | PROVIDE(SupervisorTimer = DefaultHandler); | ||
| 53 | PROVIDE(MachineTimer = DefaultHandler); | ||
| 54 | PROVIDE(SupervisorExternal = DefaultHandler); | ||
| 55 | PROVIDE(MachineExternal = DefaultHandler); | ||
| 56 | |||
| 57 | PROVIDE(DefaultHandler = DefaultInterruptHandler); | ||
| 58 | PROVIDE(ExceptionHandler = DefaultExceptionHandler); | ||
| 59 | |||
| 60 | /* # Pre-initialization function */ | ||
| 61 | /* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function, | ||
| 62 | then the function this points to will be called before the RAM is initialized. */ | ||
| 63 | PROVIDE(__pre_init = default_pre_init); | ||
| 64 | |||
| 65 | /* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ | ||
| 66 | PROVIDE(_setup_interrupts = default_setup_interrupts); | ||
| 67 | |||
| 68 | /* # Multi-processing hook function | ||
| 69 | fn _mp_hook() -> bool; | ||
| 70 | |||
| 71 | This function is called from all the harts and must return true only for one hart, | ||
| 72 | which will perform memory initialization. For other harts it must return false | ||
| 73 | and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). | ||
| 74 | */ | ||
| 75 | PROVIDE(_mp_hook = default_mp_hook); | ||
| 76 | |||
| 77 | /* # Start trap function override | ||
| 78 | By default uses the riscv crates default trap handler | ||
| 79 | but by providing the `_start_trap` symbol external crates can override. | ||
| 80 | */ | ||
| 81 | PROVIDE(_start_trap = default_start_trap); | ||
| 82 | |||
| 83 | SECTIONS | ||
| 84 | { | ||
| 85 | .text.dummy (NOLOAD) : | ||
| 86 | { | ||
| 87 | /* This section is intended to make _stext address work */ | ||
| 88 | . = ABSOLUTE(_stext); | ||
| 89 | } > REGION_TEXT | ||
| 90 | |||
| 91 | .text _stext : | ||
| 92 | { | ||
| 93 | /* Put reset handler first in .text section so it ends up as the entry */ | ||
| 94 | /* point of the program. */ | ||
| 95 | KEEP(*(.init)); | ||
| 96 | KEEP(*(.init.rust)); | ||
| 97 | . = ALIGN(4); | ||
| 98 | *(.trap); | ||
| 99 | *(.trap.rust); | ||
| 100 | *(.text.abort); | ||
| 101 | *(.text .text.*); | ||
| 102 | } > REGION_TEXT | ||
| 103 | |||
| 104 | .eh_frame : { KEEP(*(.eh_frame)) } > REGION_TEXT | ||
| 105 | .eh_frame_hdr : { *(.eh_frame_hdr) } > REGION_TEXT | ||
| 106 | |||
| 107 | .rodata : ALIGN(4) | ||
| 108 | { | ||
| 109 | *(.srodata .srodata.*); | ||
| 110 | *(.rodata .rodata.*); | ||
| 111 | |||
| 112 | /* 4-byte align the end (VMA) of this section. | ||
| 113 | This is required by LLD to ensure the LMA of the following .data | ||
| 114 | section will have the correct alignment. */ | ||
| 115 | . = ALIGN(4); | ||
| 116 | } > REGION_RODATA | ||
| 117 | |||
| 118 | .data : ALIGN(4) | ||
| 119 | { | ||
| 120 | _sidata = LOADADDR(.data); | ||
| 121 | _sdata = .; | ||
| 122 | /* Must be called __global_pointer$ for linker relaxations to work. */ | ||
| 123 | PROVIDE(__global_pointer$ = . + 0x800); | ||
| 124 | *(.sdata .sdata.* .sdata2 .sdata2.*); | ||
| 125 | *(.data .data.*); | ||
| 126 | . = ALIGN(4); | ||
| 127 | _edata = .; | ||
| 128 | } > REGION_DATA AT > REGION_RODATA | ||
| 129 | |||
| 130 | .bss (NOLOAD) : ALIGN(4) | ||
| 131 | { | ||
| 132 | _sbss = .; | ||
| 133 | *(.sbss .sbss.* .bss .bss.*); | ||
| 134 | . = ALIGN(4); | ||
| 135 | _ebss = .; | ||
| 136 | } > REGION_BSS | ||
| 137 | |||
| 138 | /* fictitious region that represents the memory available for the heap */ | ||
| 139 | .heap (NOLOAD) : | ||
| 140 | { | ||
| 141 | _sheap = .; | ||
| 142 | . += _heap_size; | ||
| 143 | . = ALIGN(4); | ||
| 144 | _eheap = .; | ||
| 145 | } > REGION_HEAP | ||
| 146 | |||
| 147 | /* fictitious region that represents the memory available for the stack */ | ||
| 148 | .stack (NOLOAD) : | ||
| 149 | { | ||
| 150 | _estack = .; | ||
| 151 | . = ABSOLUTE(_stack_start); | ||
| 152 | _sstack = .; | ||
| 153 | } > REGION_STACK | ||
| 154 | |||
| 155 | /* fake output .got section */ | ||
| 156 | /* Dynamic relocations are unsupported. This section is only used to detect | ||
| 157 | relocatable code in the input files and raise an error if relocatable code | ||
| 158 | is found */ | ||
| 159 | .got (INFO) : | ||
| 160 | { | ||
| 161 | KEEP(*(.got .got.*)); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | /* Do not exceed this mark in the error messages above | */ | ||
| 166 | ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " | ||
| 167 | ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); | ||
| 168 | |||
| 169 | ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, " | ||
| 170 | ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned"); | ||
| 171 | |||
| 172 | ASSERT(ORIGIN(REGION_DATA) % 4 == 0, " | ||
| 173 | ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned"); | ||
| 174 | |||
| 175 | ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, " | ||
| 176 | ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned"); | ||
| 177 | |||
| 178 | ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " | ||
| 179 | ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); | ||
| 180 | |||
| 181 | ASSERT(ORIGIN(REGION_STACK) % 4 == 0, " | ||
| 182 | ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned"); | ||
| 183 | |||
| 184 | ASSERT(_stext % 4 == 0, " | ||
| 185 | ERROR(riscv-rt): `_stext` must be 4-byte aligned"); | ||
| 186 | |||
| 187 | ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, " | ||
| 188 | BUG(riscv-rt): .data is not 4-byte aligned"); | ||
| 189 | |||
| 190 | ASSERT(_sidata % 4 == 0, " | ||
| 191 | BUG(riscv-rt): the LMA of .data is not 4-byte aligned"); | ||
| 192 | |||
| 193 | ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, " | ||
| 194 | BUG(riscv-rt): .bss is not 4-byte aligned"); | ||
| 195 | |||
| 196 | ASSERT(_sheap % 4 == 0, " | ||
| 197 | BUG(riscv-rt): start of .heap is not 4-byte aligned"); | ||
| 198 | |||
| 199 | ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), " | ||
| 200 | ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region. | ||
| 201 | Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'"); | ||
| 202 | |||
| 203 | ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, " | ||
| 204 | ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts. | ||
| 205 | Consider changing `_max_hart_id` or `_hart_stack_size`."); | ||
| 206 | |||
| 207 | ASSERT(SIZEOF(.got) == 0, " | ||
| 208 | .got section detected in the input files. Dynamic relocations are not | ||
| 209 | supported. If you are linking to C code compiled using the `gcc` crate | ||
| 210 | then modify your build script to compile the C code _without_ the | ||
| 211 | -fPIC flag. See the documentation of the `gcc::Config.fpic` method for | ||
| 212 | details."); | ||
| 213 | |||
| 214 | /* Do not exceed this mark in the error messages above | */ | ||
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 46e1e9a5f..12f1ec3ce 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -7,13 +7,14 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | teleprobe-meta = "1.1" | 8 | teleprobe-meta = "1.1" |
| 9 | 9 | ||
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } | 12 | embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", ] } |
| 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } | 13 | embassy-rp = { version = "0.2.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram", "rp2040"] } |
| 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.2.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" } |
| @@ -28,7 +29,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 28 | embedded-hal-async = { version = "1.0" } | 29 | embedded-hal-async = { version = "1.0" } |
| 29 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 30 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 30 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 31 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 31 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 32 | embedded-io-async = { version = "0.6.1" } | 32 | embedded-io-async = { version = "0.6.1" } |
| 33 | embedded-storage = { version = "0.3" } | 33 | embedded-storage = { version = "0.3" } |
| 34 | static_cell = "2" | 34 | static_cell = "2" |
diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 29eda95bf..65c246472 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs | |||
| @@ -130,6 +130,19 @@ async fn main(_spawner: Spawner) { | |||
| 130 | defmt::assert!(temp.iter().all(|t| *t > 0.0)); | 130 | defmt::assert!(temp.iter().all(|t| *t > 0.0)); |
| 131 | defmt::assert!(temp.iter().all(|t| *t < 60.0)); | 131 | defmt::assert!(temp.iter().all(|t| *t < 60.0)); |
| 132 | } | 132 | } |
| 133 | { | ||
| 134 | let mut multi = [0u16; 2]; | ||
| 135 | let mut channels = [ | ||
| 136 | Channel::new_pin(&mut p.PIN_26, Pull::Up), | ||
| 137 | Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), | ||
| 138 | ]; | ||
| 139 | adc.read_many_multichannel(&mut channels, &mut multi, 1, &mut p.DMA_CH0) | ||
| 140 | .await | ||
| 141 | .unwrap(); | ||
| 142 | defmt::assert!(multi[0] > 3_000); | ||
| 143 | let temp = convert_to_celsius(multi[1]); | ||
| 144 | defmt::assert!(temp > 0.0 && temp < 60.0); | ||
| 145 | } | ||
| 133 | 146 | ||
| 134 | info!("Test OK"); | 147 | info!("Test OK"); |
| 135 | cortex_m::asm::bkpt(); | 148 | cortex_m::asm::bkpt(); |
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index b46ae670a..30e4afb07 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs | |||
| @@ -2,10 +2,11 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use cyw43::JoinOptions; | ||
| 5 | use cyw43_pio::PioSpi; | 6 | use cyw43_pio::PioSpi; |
| 6 | use defmt::{panic, *}; | 7 | use defmt::{panic, *}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Config, Stack, StackResources}; | 9 | use embassy_net::{Config, StackResources}; |
| 9 | use embassy_rp::gpio::{Level, Output}; | 10 | use embassy_rp::gpio::{Level, Output}; |
| 10 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; | 11 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 11 | use embassy_rp::pio::{InterruptHandler, Pio}; | 12 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| @@ -29,8 +30,8 @@ async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stati | |||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | #[embassy_executor::task] | 32 | #[embassy_executor::task] |
| 32 | async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! { | 33 | async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! { |
| 33 | stack.run().await | 34 | runner.run().await |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | #[embassy_executor::main] | 37 | #[embassy_executor::main] |
| @@ -45,8 +46,8 @@ async fn main(spawner: Spawner) { | |||
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | // cyw43 firmware needs to be flashed manually: | 48 | // cyw43 firmware needs to be flashed manually: |
| 48 | // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x101b0000 | 49 | // probe-rs download 43439A0.bin --binary-format bin --chip RP2040 --base-address 0x101b0000 |
| 49 | // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101f8000 | 50 | // probe-rs download 43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x101f8000 |
| 50 | let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 230321) }; | 51 | let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 230321) }; |
| 51 | let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; | 52 | let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; |
| 52 | 53 | ||
| @@ -69,19 +70,21 @@ async fn main(spawner: Spawner) { | |||
| 69 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | 70 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |
| 70 | 71 | ||
| 71 | // Init network stack | 72 | // Init network stack |
| 72 | static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); | ||
| 73 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 73 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 74 | let stack = &*STACK.init(Stack::new( | 74 | let (stack, runner) = embassy_net::new( |
| 75 | net_device, | 75 | net_device, |
| 76 | Config::dhcpv4(Default::default()), | 76 | Config::dhcpv4(Default::default()), |
| 77 | RESOURCES.init(StackResources::<2>::new()), | 77 | RESOURCES.init(StackResources::new()), |
| 78 | seed, | 78 | seed, |
| 79 | )); | 79 | ); |
| 80 | 80 | ||
| 81 | unwrap!(spawner.spawn(net_task(stack))); | 81 | unwrap!(spawner.spawn(net_task(runner))); |
| 82 | 82 | ||
| 83 | loop { | 83 | loop { |
| 84 | match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { | 84 | match control |
| 85 | .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) | ||
| 86 | .await | ||
| 87 | { | ||
| 85 | Ok(_) => break, | 88 | Ok(_) => break, |
| 86 | Err(err) => { | 89 | Err(err) => { |
| 87 | panic!("join failed with status={}", err.status); | 90 | panic!("join failed with status={}", err.status); |
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs index 5d5547773..ae2adfa55 100644 --- a/tests/rp/src/bin/ethernet_w5100s_perf.rs +++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs | |||
| @@ -5,7 +5,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Stack, StackResources}; | 8 | use embassy_net::StackResources; |
| 9 | use embassy_net_wiznet::chip::W5100S; | 9 | use embassy_net_wiznet::chip::W5100S; |
| 10 | use embassy_net_wiznet::*; | 10 | use embassy_net_wiznet::*; |
| 11 | use embassy_rp::clocks::RoscRng; | 11 | use embassy_rp::clocks::RoscRng; |
| @@ -32,8 +32,8 @@ async fn ethernet_task( | |||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | #[embassy_executor::task] | 34 | #[embassy_executor::task] |
| 35 | async fn net_task(stack: &'static Stack<Device<'static>>) -> ! { | 35 | async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! { |
| 36 | stack.run().await | 36 | runner.run().await |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | #[embassy_executor::main] | 39 | #[embassy_executor::main] |
| @@ -59,24 +59,24 @@ async fn main(spawner: Spawner) { | |||
| 59 | w5500_int, | 59 | w5500_int, |
| 60 | w5500_reset, | 60 | w5500_reset, |
| 61 | ) | 61 | ) |
| 62 | .await; | 62 | .await |
| 63 | .unwrap(); | ||
| 63 | unwrap!(spawner.spawn(ethernet_task(runner))); | 64 | unwrap!(spawner.spawn(ethernet_task(runner))); |
| 64 | 65 | ||
| 65 | // Generate random seed | 66 | // Generate random seed |
| 66 | let seed = rng.next_u64(); | 67 | let seed = rng.next_u64(); |
| 67 | 68 | ||
| 68 | // Init network stack | 69 | // Init network stack |
| 69 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||
| 70 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 70 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 71 | let stack = &*STACK.init(Stack::new( | 71 | let (stack, runner) = embassy_net::new( |
| 72 | device, | 72 | device, |
| 73 | embassy_net::Config::dhcpv4(Default::default()), | 73 | embassy_net::Config::dhcpv4(Default::default()), |
| 74 | RESOURCES.init(StackResources::<2>::new()), | 74 | RESOURCES.init(StackResources::new()), |
| 75 | seed, | 75 | seed, |
| 76 | )); | 76 | ); |
| 77 | 77 | ||
| 78 | // Launch network task | 78 | // Launch network task |
| 79 | unwrap!(spawner.spawn(net_task(&stack))); | 79 | unwrap!(spawner.spawn(net_task(runner))); |
| 80 | 80 | ||
| 81 | perf_client::run( | 81 | perf_client::run( |
| 82 | stack, | 82 | stack, |
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] |
| 22 | fn main() -> ! { | 22 | fn 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 a0aed1a42..9615007bd 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,59 @@ 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 | }), | ||
| 202 | }); | ||
| 203 | |||
| 204 | let p = embassy_rp::init(config); | ||
| 205 | info!("Hello World!"); | ||
| 206 | |||
| 207 | let d_sda = p.PIN_19; | ||
| 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( | ||
| 214 | p.CORE1, | ||
| 215 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | ||
| 216 | move || { | ||
| 217 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 218 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | ||
| 219 | }, | ||
| 220 | ); | ||
| 201 | 221 | ||
| 202 | let executor0 = EXECUTOR0.init(Executor::new()); | 222 | let c_sda = p.PIN_21; |
| 223 | let c_scl = p.PIN_20; | ||
| 224 | let mut controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, Default::default()); | ||
| 203 | 225 | ||
| 204 | let c_sda = p.PIN_21; | 226 | for freq in [1000, 100_000, 400_000, 1_000_000] { |
| 205 | let c_scl = p.PIN_20; | 227 | info!("testing at {}hz", freq); |
| 206 | let mut config = i2c::Config::default(); | 228 | let mut config = i2c::Config::default(); |
| 207 | config.frequency = 5_000; | 229 | config.frequency = freq; |
| 208 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | 230 | controller.set_config(&config).unwrap(); |
| 231 | controller_task(&mut controller).await; | ||
| 232 | } | ||
| 209 | 233 | ||
| 210 | executor0.run(|spawner| unwrap!(spawner.spawn(controller_task(controller)))); | 234 | info!("Test OK"); |
| 235 | cortex_m::asm::bkpt(); | ||
| 236 | } | ||
| 211 | } | 237 | } |
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] |
| 20 | fn main() -> ! { | 20 | fn 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..c05197000 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, Pull::None, 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,13 @@ 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( |
| 114 | &mut p.PWM_SLICE3, | ||
| 115 | &mut p7, | ||
| 116 | Pull::None, | ||
| 117 | InputMode::RisingEdge, | ||
| 118 | cfg.clone(), | ||
| 119 | ); | ||
| 114 | assert_eq!(pwm.counter(), 0); | 120 | assert_eq!(pwm.counter(), 0); |
| 115 | Timer::after_millis(5).await; | 121 | Timer::after_millis(5).await; |
| 116 | assert_eq!(pwm.counter(), 0); | 122 | assert_eq!(pwm.counter(), 0); |
| @@ -125,7 +131,13 @@ async fn main(_spawner: Spawner) { | |||
| 125 | // Test falling-gated | 131 | // Test falling-gated |
| 126 | { | 132 | { |
| 127 | let mut pin2 = Output::new(&mut p11, Level::High); | 133 | 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()); | 134 | let pwm = Pwm::new_input( |
| 135 | &mut p.PWM_SLICE3, | ||
| 136 | &mut p7, | ||
| 137 | Pull::None, | ||
| 138 | InputMode::FallingEdge, | ||
| 139 | cfg.clone(), | ||
| 140 | ); | ||
| 129 | assert_eq!(pwm.counter(), 0); | 141 | assert_eq!(pwm.counter(), 0); |
| 130 | Timer::after_millis(5).await; | 142 | Timer::after_millis(5).await; |
| 131 | assert_eq!(pwm.counter(), 0); | 143 | assert_eq!(pwm.counter(), 0); |
| @@ -137,6 +149,34 @@ async fn main(_spawner: Spawner) { | |||
| 137 | assert_eq!(pwm.counter(), 1); | 149 | assert_eq!(pwm.counter(), 1); |
| 138 | } | 150 | } |
| 139 | 151 | ||
| 152 | // pull-down | ||
| 153 | { | ||
| 154 | let pin2 = Input::new(&mut p11, Pull::None); | ||
| 155 | Pwm::new_input( | ||
| 156 | &mut p.PWM_SLICE3, | ||
| 157 | &mut p7, | ||
| 158 | Pull::Down, | ||
| 159 | InputMode::FallingEdge, | ||
| 160 | cfg.clone(), | ||
| 161 | ); | ||
| 162 | Timer::after_millis(1).await; | ||
| 163 | assert!(pin2.is_low()); | ||
| 164 | } | ||
| 165 | |||
| 166 | // pull-up | ||
| 167 | { | ||
| 168 | let pin2 = Input::new(&mut p11, Pull::None); | ||
| 169 | Pwm::new_input( | ||
| 170 | &mut p.PWM_SLICE3, | ||
| 171 | &mut p7, | ||
| 172 | Pull::Up, | ||
| 173 | InputMode::FallingEdge, | ||
| 174 | cfg.clone(), | ||
| 175 | ); | ||
| 176 | Timer::after_millis(1).await; | ||
| 177 | assert!(pin2.is_high()); | ||
| 178 | } | ||
| 179 | |||
| 140 | info!("Test OK"); | 180 | info!("Test OK"); |
| 141 | cortex_m::asm::bkpt(); | 181 | cortex_m::asm::bkpt(); |
| 142 | } | 182 | } |
diff --git a/tests/nrf52840/src/bin/timer.rs b/tests/rp/src/bin/timer.rs index 117947a94..be9242144 100644 --- a/tests/nrf52840/src/bin/timer.rs +++ b/tests/rp/src/bin/timer.rs | |||
| @@ -1,15 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use defmt::{assert, info}; | 5 | use defmt::{assert, *}; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_time::{Instant, Timer}; | 7 | use embassy_time::{Instant, Timer}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 11 | async fn main(_spawner: Spawner) { | 11 | async fn main(_spawner: Spawner) { |
| 12 | let _p = embassy_nrf::init(Default::default()); | 12 | let _p = embassy_rp::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let start = Instant::now(); | 15 | let start = Instant::now(); |
| @@ -18,6 +18,7 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let ms = (end - start).as_millis(); | 18 | let ms = (end - start).as_millis(); |
| 19 | info!("slept for {} ms", ms); | 19 | info!("slept for {} ms", ms); |
| 20 | assert!(ms >= 99); | 20 | assert!(ms >= 99); |
| 21 | assert!(ms < 110); | ||
| 21 | 22 | ||
| 22 | info!("Test OK"); | 23 | info!("Test OK"); |
| 23 | cortex_m::asm::bkpt(); | 24 | cortex_m::asm::bkpt(); |
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml index 8e32b4cee..8752da59b 100644 --- a/tests/stm32/.cargo/config.toml +++ b/tests/stm32/.cargo/config.toml | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 6 | runner = "teleprobe client run" | 6 | runner = "teleprobe client run" |
| 7 | #runner = "teleprobe local run --chip STM32F103C8 --elf" | 7 | #runner = "teleprobe local run --chip STM32H7S3L8Hx --elf" |
| 8 | 8 | ||
| 9 | rustflags = [ | 9 | rustflags = [ |
| 10 | # Code-size optimizations. | 10 | # Code-size optimizations. |
| @@ -14,9 +14,9 @@ rustflags = [ | |||
| 14 | ] | 14 | ] |
| 15 | 15 | ||
| 16 | [build] | 16 | [build] |
| 17 | target = "thumbv6m-none-eabi" | 17 | #target = "thumbv6m-none-eabi" |
| 18 | #target = "thumbv7m-none-eabi" | 18 | #target = "thumbv7m-none-eabi" |
| 19 | #target = "thumbv7em-none-eabi" | 19 | target = "thumbv7em-none-eabi" |
| 20 | #target = "thumbv8m.main-none-eabihf" | 20 | #target = "thumbv8m.main-none-eabihf" |
| 21 | 21 | ||
| 22 | [env] | 22 | [env] |
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index fc4420687..2eac636e5 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -7,30 +7,37 @@ autobins = false | |||
| 7 | 7 | ||
| 8 | [features] | 8 | [features] |
| 9 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] | 9 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] |
| 10 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] | 10 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma"] |
| 11 | stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] | 11 | stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"] |
| 12 | stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] | 12 | stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] |
| 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] | 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] |
| 14 | stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] | 14 | stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] |
| 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] | 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] |
| 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"] | 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] |
| 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"] | 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] |
| 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"] | 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"] |
| 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash"] | 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] |
| 20 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash"] | 20 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] |
| 21 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"] | 21 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] |
| 22 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] | 22 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] |
| 23 | stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] | 23 | stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma"] |
| 24 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] | 24 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] |
| 25 | stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] | 25 | 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", "spi-v345", "chrono", "rng", "hash", "cordic"] |
| 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] | 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash |
| 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", "spi-v345", "chrono", "rng", "hash"] |
| 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] | 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] |
| 33 | 33 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] | |
| 34 | stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] | ||
| 35 | stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs. | ||
| 36 | stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] | ||
| 37 | |||
| 38 | spi-v1 = [] | ||
| 39 | spi-v345 = [] | ||
| 40 | cryp = [] | ||
| 34 | hash = [] | 41 | hash = [] |
| 35 | eth = ["embassy-executor/task-arena-size-16384"] | 42 | eth = ["embassy-executor/task-arena-size-16384"] |
| 36 | rng = [] | 43 | rng = [] |
| @@ -44,15 +51,17 @@ mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | |||
| 44 | embassy-stm32-wpan = [] | 51 | embassy-stm32-wpan = [] |
| 45 | not-gpdma = [] | 52 | not-gpdma = [] |
| 46 | dac = [] | 53 | dac = [] |
| 54 | ucpd = [] | ||
| 55 | cordic = ["dep:num-traits"] | ||
| 47 | 56 | ||
| 48 | cm0 = ["portable-atomic/unsafe-assume-single-core"] | 57 | cm0 = ["portable-atomic/unsafe-assume-single-core"] |
| 49 | 58 | ||
| 50 | [dependencies] | 59 | [dependencies] |
| 51 | teleprobe-meta = "1" | 60 | teleprobe-meta = "1" |
| 52 | 61 | ||
| 53 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 62 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 54 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 63 | embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 55 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } | 64 | embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } |
| 56 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } | 65 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } |
| 57 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 66 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 58 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } | 67 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } |
| @@ -67,6 +76,7 @@ cortex-m-rt = "0.7.0" | |||
| 67 | embedded-hal = "0.2.6" | 76 | embedded-hal = "0.2.6" |
| 68 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 77 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 69 | embedded-hal-async = { version = "1.0" } | 78 | embedded-hal-async = { version = "1.0" } |
| 79 | embedded-can = { version = "0.4" } | ||
| 70 | micromath = "2.0.0" | 80 | micromath = "2.0.0" |
| 71 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 81 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 72 | rand_core = { version = "0.6", default-features = false } | 82 | rand_core = { version = "0.6", default-features = false } |
| @@ -76,6 +86,9 @@ portable-atomic = { version = "1.5", features = [] } | |||
| 76 | 86 | ||
| 77 | chrono = { version = "^0.4", default-features = false, optional = true} | 87 | chrono = { version = "^0.4", default-features = false, optional = true} |
| 78 | sha2 = { version = "0.10.8", default-features = false } | 88 | sha2 = { version = "0.10.8", default-features = false } |
| 89 | hmac = "0.12.1" | ||
| 90 | aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] } | ||
| 91 | num-traits = {version="0.2", default-features = false,features = ["libm"], optional = true} | ||
| 79 | 92 | ||
| 80 | # BEGIN TESTS | 93 | # BEGIN TESTS |
| 81 | # Generated by gen_test.py. DO NOT EDIT. | 94 | # Generated by gen_test.py. DO NOT EDIT. |
| @@ -85,6 +98,16 @@ path = "src/bin/can.rs" | |||
| 85 | required-features = [ "can",] | 98 | required-features = [ "can",] |
| 86 | 99 | ||
| 87 | [[bin]] | 100 | [[bin]] |
| 101 | name = "cordic" | ||
| 102 | path = "src/bin/cordic.rs" | ||
| 103 | required-features = [ "rng", "cordic",] | ||
| 104 | |||
| 105 | [[bin]] | ||
| 106 | name = "cryp" | ||
| 107 | path = "src/bin/cryp.rs" | ||
| 108 | required-features = [ "cryp",] | ||
| 109 | |||
| 110 | [[bin]] | ||
| 88 | name = "dac" | 111 | name = "dac" |
| 89 | path = "src/bin/dac.rs" | 112 | path = "src/bin/dac.rs" |
| 90 | required-features = [ "dac",] | 113 | required-features = [ "dac",] |
| @@ -150,6 +173,11 @@ path = "src/bin/timer.rs" | |||
| 150 | required-features = [] | 173 | required-features = [] |
| 151 | 174 | ||
| 152 | [[bin]] | 175 | [[bin]] |
| 176 | name = "ucpd" | ||
| 177 | path = "src/bin/ucpd.rs" | ||
| 178 | required-features = [ "ucpd",] | ||
| 179 | |||
| 180 | [[bin]] | ||
| 153 | name = "usart" | 181 | name = "usart" |
| 154 | path = "src/bin/usart.rs" | 182 | path = "src/bin/usart.rs" |
| 155 | required-features = [] | 183 | required-features = [] |
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index f32a7b2f8..722671bf1 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs | |||
| @@ -10,12 +10,12 @@ fn main() -> Result<(), Box<dyn Error>> { | |||
| 10 | 10 | ||
| 11 | if cfg!(any( | 11 | if cfg!(any( |
| 12 | // too little RAM to run from RAM. | 12 | // too little RAM to run from RAM. |
| 13 | feature = "stm32f103c8", | 13 | feature = "stm32f103c8", // 20 kb |
| 14 | feature = "stm32c031c6", | 14 | feature = "stm32c031c6", // 6 kb |
| 15 | feature = "stm32wb55rg", | 15 | feature = "stm32l073rz", // 20 kb |
| 16 | feature = "stm32l073rz", | 16 | feature = "stm32h503rb", // 32 kb |
| 17 | // wrong ram size in stm32-data | 17 | // no VTOR, so interrupts can't work when running from RAM |
| 18 | feature = "stm32wl55jc", | 18 | feature = "stm32f091rc", |
| 19 | )) { | 19 | )) { |
| 20 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | 20 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); |
| 21 | println!("cargo:rerun-if-changed=link.x"); | 21 | println!("cargo:rerun-if-changed=link.x"); |
diff --git a/tests/stm32/gen_test.py b/tests/stm32/gen_test.py index 8ff156c0e..daf714376 100644 --- a/tests/stm32/gen_test.py +++ b/tests/stm32/gen_test.py | |||
| @@ -14,7 +14,7 @@ for f in sorted(glob('./src/bin/*.rs')): | |||
| 14 | with open(f, 'r') as f: | 14 | with open(f, 'r') as f: |
| 15 | for line in f: | 15 | for line in f: |
| 16 | if line.startswith('// required-features:'): | 16 | if line.startswith('// required-features:'): |
| 17 | features = line.split(':', 2)[1].strip().split(',') | 17 | features = [feature.strip() for feature in line.split(':', 2)[1].strip().split(',')] |
| 18 | 18 | ||
| 19 | tests[name] = features | 19 | tests[name] = features |
| 20 | 20 | ||
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs index f4effa244..85a5f8d83 100644 --- a/tests/stm32/src/bin/can.rs +++ b/tests/stm32/src/bin/can.rs | |||
| @@ -6,17 +6,18 @@ | |||
| 6 | #[path = "../common.rs"] | 6 | #[path = "../common.rs"] |
| 7 | mod common; | 7 | mod common; |
| 8 | use common::*; | 8 | use common::*; |
| 9 | use defmt::assert; | ||
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::bind_interrupts; | 10 | use embassy_stm32::bind_interrupts; |
| 12 | use embassy_stm32::can::bxcan::filter::Mask32; | 11 | use embassy_stm32::can::filter::Mask32; |
| 13 | use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; | 12 | use embassy_stm32::can::{Fifo, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; |
| 14 | use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; | ||
| 15 | use embassy_stm32::gpio::{Input, Pull}; | 13 | use embassy_stm32::gpio::{Input, Pull}; |
| 16 | use embassy_stm32::peripherals::CAN1; | 14 | use embassy_stm32::peripherals::CAN1; |
| 17 | use embassy_time::{Duration, Instant}; | 15 | use embassy_time::Duration; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 16 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 17 | ||
| 18 | mod can_common; | ||
| 19 | use can_common::*; | ||
| 20 | |||
| 20 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| 21 | CAN1_RX0 => Rx0InterruptHandler<CAN1>; | 22 | CAN1_RX0 => Rx0InterruptHandler<CAN1>; |
| 22 | CAN1_RX1 => Rx1InterruptHandler<CAN1>; | 23 | CAN1_RX1 => Rx1InterruptHandler<CAN1>; |
| @@ -26,9 +27,14 @@ bind_interrupts!(struct Irqs { | |||
| 26 | 27 | ||
| 27 | #[embassy_executor::main] | 28 | #[embassy_executor::main] |
| 28 | async fn main(_spawner: Spawner) { | 29 | async fn main(_spawner: Spawner) { |
| 29 | let p = embassy_stm32::init(config()); | 30 | let p = init(); |
| 30 | info!("Hello World!"); | 31 | info!("Hello World!"); |
| 31 | 32 | ||
| 33 | let options = TestOptions { | ||
| 34 | max_latency: Duration::from_micros(1200), | ||
| 35 | max_buffered: 2, | ||
| 36 | }; | ||
| 37 | |||
| 32 | let can = peri!(p, CAN); | 38 | let can = peri!(p, CAN); |
| 33 | let tx = peri!(p, CAN_TX); | 39 | let tx = peri!(p, CAN_TX); |
| 34 | let mut rx = peri!(p, CAN_RX); | 40 | let mut rx = peri!(p, CAN_RX); |
| @@ -40,58 +46,29 @@ async fn main(_spawner: Spawner) { | |||
| 40 | let rx_pin = Input::new(&mut rx, Pull::Up); | 46 | let rx_pin = Input::new(&mut rx, Pull::Up); |
| 41 | core::mem::forget(rx_pin); | 47 | core::mem::forget(rx_pin); |
| 42 | 48 | ||
| 43 | let mut can = Can::new(can, rx, tx, Irqs); | 49 | let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); |
| 44 | 50 | ||
| 45 | info!("Configuring can..."); | 51 | info!("Configuring can..."); |
| 46 | 52 | ||
| 47 | can.as_mut() | 53 | can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); |
| 48 | .modify_filters() | ||
| 49 | .enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); | ||
| 50 | 54 | ||
| 51 | can.set_bitrate(1_000_000); | 55 | can.modify_config() |
| 52 | can.as_mut() | ||
| 53 | .modify_config() | ||
| 54 | .set_loopback(true) // Receive own frames | 56 | .set_loopback(true) // Receive own frames |
| 55 | .set_silent(true) | 57 | .set_silent(true) |
| 56 | // .set_bit_timing(0x001c0003) | 58 | // .set_bit_timing(0x001c0003) |
| 57 | .enable(); | 59 | .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]); | ||
| 64 | 60 | ||
| 65 | info!("Transmitting frame..."); | 61 | can.enable().await; |
| 66 | let tx_ts = Instant::now(); | ||
| 67 | can.write(&tx_frame).await; | ||
| 68 | 62 | ||
| 69 | let envelope = can.read().await.unwrap(); | 63 | info!("Can configured"); |
| 70 | info!("Frame received!"); | ||
| 71 | |||
| 72 | info!("loopback time {}", envelope.ts); | ||
| 73 | info!("loopback frame {=u8}", envelope.frame.data().unwrap()[0]); | ||
| 74 | |||
| 75 | let latency = envelope.ts.saturating_duration_since(tx_ts); | ||
| 76 | info!("loopback latency {} us", latency.as_micros()); | ||
| 77 | 64 | ||
| 78 | // Theoretical minimum latency is 55us, actual is usually ~80us | 65 | 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 | 66 | ||
| 89 | i += 1; | 67 | // Test again with a split |
| 90 | if i > 10 { | 68 | let (mut tx, mut rx) = can.split(); |
| 91 | break; | 69 | run_split_can_tests(&mut tx, &mut rx, &options).await; |
| 92 | } | ||
| 93 | } | ||
| 94 | 70 | ||
| 95 | info!("Test OK"); | 71 | info!("Test OK"); |
| 72 | |||
| 96 | cortex_m::asm::bkpt(); | 73 | cortex_m::asm::bkpt(); |
| 97 | } | 74 | } |
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/bin/can_common.rs new file mode 100644 index 000000000..4e1740ad5 --- /dev/null +++ b/tests/stm32/src/bin/can_common.rs | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | use defmt::{assert, *}; | ||
| 2 | use embassy_stm32::can; | ||
| 3 | use embassy_time::{Duration, Instant}; | ||
| 4 | |||
| 5 | #[derive(Clone, Copy, Debug)] | ||
| 6 | pub struct TestOptions { | ||
| 7 | pub max_latency: Duration, | ||
| 8 | pub max_buffered: u8, | ||
| 9 | } | ||
| 10 | |||
| 11 | pub async fn run_can_tests<'d>(can: &mut can::Can<'d>, options: &TestOptions) { | ||
| 12 | //pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) { | ||
| 13 | let mut i: u8 = 0; | ||
| 14 | loop { | ||
| 15 | //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(); | ||
| 16 | let tx_frame = can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap(); | ||
| 17 | |||
| 18 | //info!("Transmitting frame..."); | ||
| 19 | let tx_ts = Instant::now(); | ||
| 20 | can.write(&tx_frame).await; | ||
| 21 | |||
| 22 | let (frame, timestamp) = can.read().await.unwrap().parts(); | ||
| 23 | //info!("Frame received!"); | ||
| 24 | |||
| 25 | // Check data. | ||
| 26 | assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]); | ||
| 27 | |||
| 28 | //info!("loopback time {}", timestamp); | ||
| 29 | //info!("loopback frame {=u8}", frame.data()[0]); | ||
| 30 | let latency = timestamp.saturating_duration_since(tx_ts); | ||
| 31 | info!("loopback latency {} us", latency.as_micros()); | ||
| 32 | |||
| 33 | // Theoretical minimum latency is 55us, actual is usually ~80us | ||
| 34 | const MIN_LATENCY: Duration = Duration::from_micros(50); | ||
| 35 | // Was failing at 150 but we are not getting a real time stamp. I'm not | ||
| 36 | // sure if there are other delays | ||
| 37 | assert!( | ||
| 38 | MIN_LATENCY <= latency && latency <= options.max_latency, | ||
| 39 | "{} <= {} <= {}", | ||
| 40 | MIN_LATENCY, | ||
| 41 | latency, | ||
| 42 | options.max_latency | ||
| 43 | ); | ||
| 44 | |||
| 45 | i += 1; | ||
| 46 | if i > 5 { | ||
| 47 | break; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | // Below here, check that we can receive from both FIFO0 and FIFO1 | ||
| 52 | // Above we configured FIFO1 for extended ID packets. There are only 3 slots | ||
| 53 | // in each FIFO so make sure we write enough to fill them both up before reading. | ||
| 54 | for i in 0..options.max_buffered { | ||
| 55 | // Try filling up the RX FIFO0 buffers | ||
| 56 | //let tx_frame = if 0 != (i & 0x01) { | ||
| 57 | let tx_frame = if i < options.max_buffered / 2 { | ||
| 58 | info!("Transmitting standard frame {}", i); | ||
| 59 | can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap() | ||
| 60 | } else { | ||
| 61 | info!("Transmitting extended frame {}", i); | ||
| 62 | can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap() | ||
| 63 | }; | ||
| 64 | can.write(&tx_frame).await; | ||
| 65 | } | ||
| 66 | |||
| 67 | // Try and receive all 6 packets | ||
| 68 | for _i in 0..options.max_buffered { | ||
| 69 | let (frame, _ts) = can.read().await.unwrap().parts(); | ||
| 70 | match frame.id() { | ||
| 71 | embedded_can::Id::Extended(_id) => { | ||
| 72 | info!("Extended received! {}", frame.data()[0]); | ||
| 73 | //info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 74 | } | ||
| 75 | embedded_can::Id::Standard(_id) => { | ||
| 76 | info!("Standard received! {}", frame.data()[0]); | ||
| 77 | //info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | pub async fn run_split_can_tests<'d>(tx: &mut can::CanTx<'d>, rx: &mut can::CanRx<'d>, options: &TestOptions) { | ||
| 84 | for i in 0..options.max_buffered { | ||
| 85 | // Try filling up the RX FIFO0 buffers | ||
| 86 | //let tx_frame = if 0 != (i & 0x01) { | ||
| 87 | let tx_frame = if i < options.max_buffered / 2 { | ||
| 88 | info!("Transmitting standard frame {}", i); | ||
| 89 | can::frame::Frame::new_standard(0x123, &[i; 1]).unwrap() | ||
| 90 | } else { | ||
| 91 | info!("Transmitting extended frame {}", i); | ||
| 92 | can::frame::Frame::new_extended(0x1232344, &[i; 1]).unwrap() | ||
| 93 | }; | ||
| 94 | tx.write(&tx_frame).await; | ||
| 95 | } | ||
| 96 | |||
| 97 | // Try and receive all 6 packets | ||
| 98 | for _i in 0..options.max_buffered { | ||
| 99 | let (frame, _ts) = rx.read().await.unwrap().parts(); | ||
| 100 | match frame.id() { | ||
| 101 | embedded_can::Id::Extended(_id) => { | ||
| 102 | info!("Extended received! {}", frame.data()[0]); | ||
| 103 | } | ||
| 104 | embedded_can::Id::Standard(_id) => { | ||
| 105 | info!("Standard received! {}", frame.data()[0]); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs new file mode 100644 index 000000000..879ad56b6 --- /dev/null +++ b/tests/stm32/src/bin/cordic.rs | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | // required-features: rng, cordic | ||
| 2 | |||
| 3 | // Test Cordic driver, with Q1.31 format, Sin function, at 24 iterations (aka PRECISION = 6), using DMA transfer | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | #[path = "../common.rs"] | ||
| 9 | mod common; | ||
| 10 | use common::*; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::cordic::utils; | ||
| 13 | use embassy_stm32::{bind_interrupts, cordic, peripherals, rng}; | ||
| 14 | use num_traits::Float; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 19 | }); | ||
| 20 | |||
| 21 | /* input value control, can be changed */ | ||
| 22 | |||
| 23 | const INPUT_U32_COUNT: usize = 9; | ||
| 24 | const INPUT_U8_COUNT: usize = 4 * INPUT_U32_COUNT; | ||
| 25 | |||
| 26 | // Assume first calculation needs 2 arguments, the reset needs 1 argument. | ||
| 27 | // And all calculation generate 2 results. | ||
| 28 | const OUTPUT_LENGTH: usize = (INPUT_U32_COUNT - 1) * 2; | ||
| 29 | |||
| 30 | #[embassy_executor::main] | ||
| 31 | async fn main(_spawner: Spawner) { | ||
| 32 | let dp = init(); | ||
| 33 | |||
| 34 | // | ||
| 35 | // use RNG generate random Q1.31 value | ||
| 36 | // | ||
| 37 | // we don't generate floating-point value, since not all binary value are valid floating-point value, | ||
| 38 | // and Q1.31 only accept a fixed range of value. | ||
| 39 | |||
| 40 | let mut rng = rng::Rng::new(dp.RNG, Irqs); | ||
| 41 | |||
| 42 | let mut input_buf_u8 = [0u8; INPUT_U8_COUNT]; | ||
| 43 | defmt::unwrap!(rng.async_fill_bytes(&mut input_buf_u8).await); | ||
| 44 | |||
| 45 | // convert every [u8; 4] to a u32, for a Q1.31 value | ||
| 46 | let mut input_q1_31 = unsafe { core::mem::transmute::<[u8; INPUT_U8_COUNT], [u32; INPUT_U32_COUNT]>(input_buf_u8) }; | ||
| 47 | |||
| 48 | // ARG2 for Sin function should be inside [0, 1], set MSB to 0 of a Q1.31 value, will make sure it's no less than 0. | ||
| 49 | input_q1_31[1] &= !(1u32 << 31); | ||
| 50 | |||
| 51 | // | ||
| 52 | // CORDIC calculation | ||
| 53 | // | ||
| 54 | |||
| 55 | let mut output_q1_31 = [0u32; OUTPUT_LENGTH]; | ||
| 56 | |||
| 57 | // setup Cordic driver | ||
| 58 | let mut cordic = cordic::Cordic::new( | ||
| 59 | dp.CORDIC, | ||
| 60 | defmt::unwrap!(cordic::Config::new( | ||
| 61 | cordic::Function::Sin, | ||
| 62 | Default::default(), | ||
| 63 | Default::default(), | ||
| 64 | )), | ||
| 65 | ); | ||
| 66 | |||
| 67 | #[cfg(feature = "stm32g491re")] | ||
| 68 | let (mut write_dma, mut read_dma) = (dp.DMA1_CH4, dp.DMA1_CH5); | ||
| 69 | |||
| 70 | #[cfg(any( | ||
| 71 | feature = "stm32h563zi", | ||
| 72 | feature = "stm32u585ai", | ||
| 73 | feature = "stm32u5a5zj", | ||
| 74 | feature = "stm32h7s3l8" | ||
| 75 | ))] | ||
| 76 | let (mut write_dma, mut read_dma) = (dp.GPDMA1_CH0, dp.GPDMA1_CH1); | ||
| 77 | |||
| 78 | // calculate first result using blocking mode | ||
| 79 | let cnt0 = defmt::unwrap!(cordic.blocking_calc_32bit(&input_q1_31[..2], &mut output_q1_31, false, false)); | ||
| 80 | |||
| 81 | // calculate rest results using async mode | ||
| 82 | let cnt1 = defmt::unwrap!( | ||
| 83 | cordic | ||
| 84 | .async_calc_32bit( | ||
| 85 | &mut write_dma, | ||
| 86 | &mut read_dma, | ||
| 87 | &input_q1_31[2..], | ||
| 88 | &mut output_q1_31[cnt0..], | ||
| 89 | true, | ||
| 90 | false, | ||
| 91 | ) | ||
| 92 | .await | ||
| 93 | ); | ||
| 94 | |||
| 95 | // all output value length should be the same as our output buffer size | ||
| 96 | defmt::assert_eq!(cnt0 + cnt1, output_q1_31.len()); | ||
| 97 | |||
| 98 | let mut cordic_result_f64 = [0.0f64; OUTPUT_LENGTH]; | ||
| 99 | |||
| 100 | for (f64_val, u32_val) in cordic_result_f64.iter_mut().zip(output_q1_31) { | ||
| 101 | *f64_val = utils::q1_31_to_f64(u32_val); | ||
| 102 | } | ||
| 103 | |||
| 104 | // | ||
| 105 | // software calculation | ||
| 106 | // | ||
| 107 | |||
| 108 | let mut software_result_f64 = [0.0f64; OUTPUT_LENGTH]; | ||
| 109 | |||
| 110 | let arg2 = utils::q1_31_to_f64(input_q1_31[1]); | ||
| 111 | |||
| 112 | for (&arg1, res) in input_q1_31 | ||
| 113 | .iter() | ||
| 114 | .enumerate() | ||
| 115 | .filter_map(|(idx, val)| if idx != 1 { Some(val) } else { None }) | ||
| 116 | .zip(software_result_f64.chunks_mut(2)) | ||
| 117 | { | ||
| 118 | let arg1 = utils::q1_31_to_f64(arg1); | ||
| 119 | |||
| 120 | let (raw_res1, raw_res2) = (arg1 * core::f64::consts::PI).sin_cos(); | ||
| 121 | (res[0], res[1]) = (raw_res1 * arg2, raw_res2 * arg2); | ||
| 122 | } | ||
| 123 | |||
| 124 | // | ||
| 125 | // check result are the same | ||
| 126 | // | ||
| 127 | |||
| 128 | for (cordic_res, software_res) in cordic_result_f64[..cnt0 + cnt1] | ||
| 129 | .chunks(2) | ||
| 130 | .zip(software_result_f64.chunks(2)) | ||
| 131 | { | ||
| 132 | for (cord_res, soft_res) in cordic_res.iter().zip(software_res.iter()) { | ||
| 133 | // 2.0.powi(-19) is the max residual error for Sin function, in q1.31 format, with 24 iterations (aka PRECISION = 6) | ||
| 134 | defmt::assert!((cord_res - soft_res).abs() <= 2.0.powi(-19)); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | info!("Test OK"); | ||
| 139 | cortex_m::asm::bkpt(); | ||
| 140 | } | ||
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs new file mode 100644 index 000000000..028775ac8 --- /dev/null +++ b/tests/stm32/src/bin/cryp.rs | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | // required-features: cryp | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use aes_gcm::aead::heapless::Vec; | ||
| 9 | use aes_gcm::aead::{AeadInPlace, KeyInit}; | ||
| 10 | use aes_gcm::Aes128Gcm; | ||
| 11 | use common::*; | ||
| 12 | use embassy_executor::Spawner; | ||
| 13 | use embassy_stm32::cryp::{self, *}; | ||
| 14 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | CRYP => cryp::InterruptHandler<peripherals::CRYP>; | ||
| 19 | }); | ||
| 20 | |||
| 21 | #[embassy_executor::main] | ||
| 22 | async fn main(_spawner: Spawner) { | ||
| 23 | let p: embassy_stm32::Peripherals = init(); | ||
| 24 | |||
| 25 | const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567"; | ||
| 26 | const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh"; | ||
| 27 | const AAD1: &[u8] = b"additional data 1 stdargadrhaethaethjatjatjaetjartjstrjsfkk;'jopofyuisrteytweTASTUIKFUKIXTRDTEREharhaeryhaterjartjarthaethjrtjarthaetrhartjatejatrjsrtjartjyt1"; | ||
| 28 | const AAD2: &[u8] = b"additional data 2 stdhthsthsthsrthsrthsrtjdykjdukdyuldadfhsdghsdghsdghsadghjk'hioethjrtjarthaetrhartjatecfgjhzdfhgzdfhzdfghzdfhzdfhzfhjatrjsrtjartjytjfytjfyg"; | ||
| 29 | |||
| 30 | let in_dma = peri!(p, CRYP_IN_DMA); | ||
| 31 | let out_dma = peri!(p, CRYP_OUT_DMA); | ||
| 32 | |||
| 33 | let mut hw_cryp = Cryp::new(p.CRYP, in_dma, out_dma, Irqs); | ||
| 34 | let key: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | ||
| 35 | let mut ciphertext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; | ||
| 36 | let mut plaintext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; | ||
| 37 | let iv: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; | ||
| 38 | |||
| 39 | // Encrypt in hardware using AES-GCM 128-bit in blocking mode. | ||
| 40 | let aes_gcm = AesGcm::new(&key, &iv); | ||
| 41 | let mut gcm_encrypt = hw_cryp.start_blocking(&aes_gcm, Direction::Encrypt); | ||
| 42 | hw_cryp.aad_blocking(&mut gcm_encrypt, AAD1, false); | ||
| 43 | hw_cryp.aad_blocking(&mut gcm_encrypt, AAD2, true); | ||
| 44 | hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD1, &mut ciphertext[..PAYLOAD1.len()], false); | ||
| 45 | hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD2, &mut ciphertext[PAYLOAD1.len()..], true); | ||
| 46 | let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt); | ||
| 47 | |||
| 48 | // Decrypt in hardware using AES-GCM 128-bit in async (DMA) mode. | ||
| 49 | let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt).await; | ||
| 50 | hw_cryp.aad(&mut gcm_decrypt, AAD1, false).await; | ||
| 51 | hw_cryp.aad(&mut gcm_decrypt, AAD2, true).await; | ||
| 52 | hw_cryp | ||
| 53 | .payload(&mut gcm_decrypt, &ciphertext, &mut plaintext, true) | ||
| 54 | .await; | ||
| 55 | let decrypt_tag = hw_cryp.finish(gcm_decrypt).await; | ||
| 56 | |||
| 57 | info!("AES-GCM Ciphertext: {:?}", ciphertext); | ||
| 58 | info!("AES-GCM Plaintext: {:?}", plaintext); | ||
| 59 | defmt::assert!(PAYLOAD1 == &plaintext[..PAYLOAD1.len()]); | ||
| 60 | defmt::assert!(PAYLOAD2 == &plaintext[PAYLOAD1.len()..]); | ||
| 61 | defmt::assert!(encrypt_tag == decrypt_tag); | ||
| 62 | |||
| 63 | // Encrypt in software using AES-GCM 128-bit | ||
| 64 | let mut payload_vec: Vec<u8, { PAYLOAD1.len() + PAYLOAD2.len() + 16 }> = Vec::from_slice(&PAYLOAD1).unwrap(); | ||
| 65 | payload_vec.extend_from_slice(&PAYLOAD2).unwrap(); | ||
| 66 | let cipher = Aes128Gcm::new(&key.into()); | ||
| 67 | let mut aad: Vec<u8, { AAD1.len() + AAD2.len() }> = Vec::from_slice(&AAD1).unwrap(); | ||
| 68 | aad.extend_from_slice(&AAD2).unwrap(); | ||
| 69 | let _ = cipher.encrypt_in_place(&iv.into(), &aad, &mut payload_vec); | ||
| 70 | |||
| 71 | defmt::assert!(ciphertext == payload_vec[0..ciphertext.len()]); | ||
| 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); | ||
| 73 | |||
| 74 | // Decrypt in software using AES-GCM 128-bit | ||
| 75 | let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec); | ||
| 76 | |||
| 77 | info!("Test OK"); | ||
| 78 | cortex_m::asm::bkpt(); | ||
| 79 | } | ||
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 9d64742df..88e661525 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs | |||
| @@ -13,14 +13,14 @@ use embassy_executor::Spawner; | |||
| 13 | use embassy_stm32::adc::Adc; | 13 | use embassy_stm32::adc::Adc; |
| 14 | use embassy_stm32::dac::{DacCh1, Value}; | 14 | use embassy_stm32::dac::{DacCh1, Value}; |
| 15 | use embassy_stm32::dma::NoDma; | 15 | use embassy_stm32::dma::NoDma; |
| 16 | use embassy_time::{Delay, Timer}; | 16 | use embassy_time::Timer; |
| 17 | use micromath::F32Ext; | 17 | use micromath::F32Ext; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 19 | ||
| 20 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 21 | async fn main(_spawner: Spawner) { |
| 22 | // Initialize the board and obtain a Peripherals instance | 22 | // Initialize the board and obtain a Peripherals instance |
| 23 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 23 | let p: embassy_stm32::Peripherals = init(); |
| 24 | 24 | ||
| 25 | let adc = peri!(p, ADC); | 25 | let adc = peri!(p, ADC); |
| 26 | let dac = peri!(p, DAC); | 26 | let dac = peri!(p, DAC); |
| @@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) { | |||
| 28 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; | 28 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; |
| 29 | 29 | ||
| 30 | let mut dac = DacCh1::new(dac, NoDma, dac_pin); | 30 | let mut dac = DacCh1::new(dac, NoDma, dac_pin); |
| 31 | let mut adc = Adc::new(adc, &mut Delay); | 31 | let mut adc = Adc::new(adc); |
| 32 | 32 | ||
| 33 | #[cfg(feature = "stm32h755zi")] | 33 | #[cfg(feature = "stm32h755zi")] |
| 34 | let normalization_factor = 256; | 34 | let normalization_factor = 256; |
| @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { | |||
| 38 | dac.set(Value::Bit8(0)); | 38 | dac.set(Value::Bit8(0)); |
| 39 | // Now wait a little to obtain a stable value | 39 | // Now wait a little to obtain a stable value |
| 40 | Timer::after_millis(30).await; | 40 | Timer::after_millis(30).await; |
| 41 | let offset = adc.read(&mut adc_pin); | 41 | let offset = adc.blocking_read(&mut adc_pin); |
| 42 | 42 | ||
| 43 | for v in 0..=255 { | 43 | for v in 0..=255 { |
| 44 | // First set the DAC output value | 44 | // First set the DAC output value |
| @@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) { | |||
| 49 | Timer::after_millis(30).await; | 49 | Timer::after_millis(30).await; |
| 50 | 50 | ||
| 51 | // Need to steal the peripherals here because PA4 is obviously in use already | 51 | // Need to steal the peripherals here because PA4 is obviously in use already |
| 52 | let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); | 52 | let measured = adc.blocking_read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); |
| 53 | // Calibrate and normalize the measurement to get close to the dac_output_val | 53 | // Calibrate and normalize the measurement to get close to the dac_output_val |
| 54 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; | 54 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; |
| 55 | 55 | ||
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs index f8b00aaef..925db617d 100644 --- a/tests/stm32/src/bin/dac_l1.rs +++ b/tests/stm32/src/bin/dac_l1.rs | |||
| @@ -19,13 +19,13 @@ use micromath::F32Ext; | |||
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | 20 | ||
| 21 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| 22 | ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC>; | 22 | ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC1>; |
| 23 | }); | 23 | }); |
| 24 | 24 | ||
| 25 | #[embassy_executor::main] | 25 | #[embassy_executor::main] |
| 26 | async fn main(_spawner: Spawner) { | 26 | async fn main(_spawner: Spawner) { |
| 27 | // Initialize the board and obtain a Peripherals instance | 27 | // Initialize the board and obtain a Peripherals instance |
| 28 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 28 | let p: embassy_stm32::Peripherals = init(); |
| 29 | 29 | ||
| 30 | let adc = peri!(p, ADC); | 30 | let adc = peri!(p, ADC); |
| 31 | let dac = peri!(p, DAC); | 31 | let dac = peri!(p, DAC); |
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 7c02f0354..bf1922dde 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | mod common; | 6 | mod common; |
| 7 | use common::*; | 7 | use common::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_net::{Stack, StackResources}; | 9 | use embassy_net::StackResources; |
| 10 | use embassy_stm32::eth::generic_smi::GenericSMI; | 10 | use embassy_stm32::eth::generic_smi::GenericSMI; |
| 11 | use embassy_stm32::eth::{Ethernet, PacketQueue}; | 11 | use embassy_stm32::eth::{Ethernet, PacketQueue}; |
| 12 | use embassy_stm32::peripherals::ETH; | 12 | use embassy_stm32::peripherals::ETH; |
| @@ -32,13 +32,13 @@ bind_interrupts!(struct Irqs { | |||
| 32 | type Device = Ethernet<'static, ETH, GenericSMI>; | 32 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| 33 | 33 | ||
| 34 | #[embassy_executor::task] | 34 | #[embassy_executor::task] |
| 35 | async fn net_task(stack: &'static Stack<Device>) -> ! { | 35 | async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! { |
| 36 | stack.run().await | 36 | runner.run().await |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | #[embassy_executor::main] | 39 | #[embassy_executor::main] |
| 40 | async fn main(spawner: Spawner) { | 40 | async fn main(spawner: Spawner) { |
| 41 | let p = embassy_stm32::init(config()); | 41 | let p = init(); |
| 42 | info!("Hello World!"); | 42 | info!("Hello World!"); |
| 43 | 43 | ||
| 44 | // Generate random seed. | 44 | // Generate random seed. |
| @@ -99,17 +99,11 @@ async fn main(spawner: Spawner) { | |||
| 99 | //}); | 99 | //}); |
| 100 | 100 | ||
| 101 | // Init network stack | 101 | // Init network stack |
| 102 | static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||
| 103 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 102 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 104 | let stack = &*STACK.init(Stack::new( | 103 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 105 | device, | ||
| 106 | config, | ||
| 107 | RESOURCES.init(StackResources::<2>::new()), | ||
| 108 | seed, | ||
| 109 | )); | ||
| 110 | 104 | ||
| 111 | // Launch network task | 105 | // Launch network task |
| 112 | unwrap!(spawner.spawn(net_task(&stack))); | 106 | unwrap!(spawner.spawn(net_task(runner))); |
| 113 | 107 | ||
| 114 | perf_client::run( | 108 | perf_client::run( |
| 115 | stack, | 109 | stack, |
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs index 7363eaa16..83d7eca85 100644 --- a/tests/stm32/src/bin/fdcan.rs +++ b/tests/stm32/src/bin/fdcan.rs | |||
| @@ -6,26 +6,38 @@ | |||
| 6 | #[path = "../common.rs"] | 6 | #[path = "../common.rs"] |
| 7 | mod common; | 7 | mod common; |
| 8 | use common::*; | 8 | use common::*; |
| 9 | use defmt::assert; | ||
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::peripherals::*; | 10 | use embassy_stm32::peripherals::*; |
| 12 | use embassy_stm32::{bind_interrupts, can, Config}; | 11 | use embassy_stm32::{bind_interrupts, can, Config}; |
| 13 | use embassy_time::{Duration, Instant}; | 12 | use embassy_time::Duration; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 15 | 14 | ||
| 16 | bind_interrupts!(struct Irqs { | 15 | mod can_common; |
| 16 | use can_common::*; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs2 { | ||
| 19 | FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; | ||
| 20 | FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; | ||
| 21 | }); | ||
| 22 | bind_interrupts!(struct Irqs1 { | ||
| 17 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | 23 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; |
| 18 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | 24 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; |
| 19 | }); | 25 | }); |
| 20 | 26 | ||
| 21 | struct TestOptions { | 27 | #[cfg(feature = "stm32h563zi")] |
| 22 | config: Config, | 28 | fn options() -> (Config, TestOptions) { |
| 23 | max_latency: Duration, | 29 | info!("H563 config"); |
| 24 | second_fifo_working: bool, | 30 | ( |
| 31 | config(), | ||
| 32 | TestOptions { | ||
| 33 | max_latency: Duration::from_micros(1200), | ||
| 34 | max_buffered: 3, | ||
| 35 | }, | ||
| 36 | ) | ||
| 25 | } | 37 | } |
| 26 | 38 | ||
| 27 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h563zi"))] | 39 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 28 | fn options() -> TestOptions { | 40 | fn options() -> (Config, TestOptions) { |
| 29 | use embassy_stm32::rcc; | 41 | use embassy_stm32::rcc; |
| 30 | info!("H75 config"); | 42 | info!("H75 config"); |
| 31 | let mut c = config(); | 43 | let mut c = config(); |
| @@ -33,16 +45,18 @@ fn options() -> TestOptions { | |||
| 33 | freq: embassy_stm32::time::Hertz(25_000_000), | 45 | freq: embassy_stm32::time::Hertz(25_000_000), |
| 34 | mode: rcc::HseMode::Oscillator, | 46 | mode: rcc::HseMode::Oscillator, |
| 35 | }); | 47 | }); |
| 36 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; | 48 | c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; |
| 37 | TestOptions { | 49 | ( |
| 38 | config: c, | 50 | c, |
| 39 | max_latency: Duration::from_micros(3800), | 51 | TestOptions { |
| 40 | second_fifo_working: false, | 52 | max_latency: Duration::from_micros(1200), |
| 41 | } | 53 | max_buffered: 3, |
| 54 | }, | ||
| 55 | ) | ||
| 42 | } | 56 | } |
| 43 | 57 | ||
| 44 | #[cfg(any(feature = "stm32h7a3zi"))] | 58 | #[cfg(any(feature = "stm32h7a3zi"))] |
| 45 | fn options() -> TestOptions { | 59 | fn options() -> (Config, TestOptions) { |
| 46 | use embassy_stm32::rcc; | 60 | use embassy_stm32::rcc; |
| 47 | info!("H7a config"); | 61 | info!("H7a config"); |
| 48 | let mut c = config(); | 62 | let mut c = config(); |
| @@ -50,193 +64,78 @@ fn options() -> TestOptions { | |||
| 50 | freq: embassy_stm32::time::Hertz(25_000_000), | 64 | freq: embassy_stm32::time::Hertz(25_000_000), |
| 51 | mode: rcc::HseMode::Oscillator, | 65 | mode: rcc::HseMode::Oscillator, |
| 52 | }); | 66 | }); |
| 53 | c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE; | 67 | c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; |
| 54 | TestOptions { | 68 | ( |
| 55 | config: c, | 69 | c, |
| 56 | max_latency: Duration::from_micros(5500), | 70 | TestOptions { |
| 57 | second_fifo_working: false, | 71 | max_latency: Duration::from_micros(1200), |
| 58 | } | 72 | max_buffered: 3, |
| 73 | }, | ||
| 74 | ) | ||
| 75 | } | ||
| 76 | |||
| 77 | #[cfg(any(feature = "stm32h7s3l8"))] | ||
| 78 | fn options() -> (Config, TestOptions) { | ||
| 79 | use embassy_stm32::rcc; | ||
| 80 | let mut c = config(); | ||
| 81 | c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; | ||
| 82 | ( | ||
| 83 | c, | ||
| 84 | TestOptions { | ||
| 85 | max_latency: Duration::from_micros(1200), | ||
| 86 | max_buffered: 3, | ||
| 87 | }, | ||
| 88 | ) | ||
| 59 | } | 89 | } |
| 60 | 90 | ||
| 61 | #[cfg(any(feature = "stm32g491re"))] | 91 | #[cfg(any(feature = "stm32g491re"))] |
| 62 | fn options() -> TestOptions { | 92 | fn options() -> (Config, TestOptions) { |
| 63 | info!("G4 config"); | 93 | info!("G4 config"); |
| 64 | TestOptions { | 94 | ( |
| 65 | config: config(), | 95 | config(), |
| 66 | max_latency: Duration::from_micros(500), | 96 | TestOptions { |
| 67 | second_fifo_working: true, | 97 | max_latency: Duration::from_micros(500), |
| 68 | } | 98 | max_buffered: 6, |
| 99 | }, | ||
| 100 | ) | ||
| 69 | } | 101 | } |
| 70 | 102 | ||
| 71 | #[embassy_executor::main] | 103 | #[embassy_executor::main] |
| 72 | async fn main(_spawner: Spawner) { | 104 | async fn main(_spawner: Spawner) { |
| 73 | //let peripherals = embassy_stm32::init(config()); | 105 | //let peripherals = init(); |
| 74 | 106 | ||
| 75 | let options = options(); | 107 | let (config, options) = options(); |
| 76 | let peripherals = embassy_stm32::init(options.config); | 108 | let peripherals = init_with_config(config); |
| 77 | 109 | ||
| 78 | let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs); | 110 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); |
| 111 | let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); | ||
| 79 | 112 | ||
| 80 | // 250k bps | 113 | // 250k bps |
| 81 | can.set_bitrate(250_000); | 114 | can.set_bitrate(250_000); |
| 115 | can2.set_bitrate(250_000); | ||
| 82 | 116 | ||
| 83 | can.can.set_extended_filter( | 117 | can.properties().set_extended_filter( |
| 118 | can::filter::ExtendedFilterSlot::_0, | ||
| 119 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | ||
| 120 | ); | ||
| 121 | can2.properties().set_extended_filter( | ||
| 84 | can::filter::ExtendedFilterSlot::_0, | 122 | can::filter::ExtendedFilterSlot::_0, |
| 85 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | 123 | can::filter::ExtendedFilter::accept_all_into_fifo1(), |
| 86 | ); | 124 | ); |
| 87 | 125 | ||
| 88 | let mut can = can.into_internal_loopback_mode(); | 126 | let mut can = can.into_internal_loopback_mode(); |
| 127 | let mut can2 = can2.into_internal_loopback_mode(); | ||
| 89 | 128 | ||
| 90 | info!("CAN Configured"); | 129 | run_can_tests(&mut can, &options).await; |
| 130 | run_can_tests(&mut can2, &options).await; | ||
| 91 | 131 | ||
| 92 | let mut i: u8 = 0; | 132 | info!("CAN Configured"); |
| 93 | loop { | ||
| 94 | let tx_frame = can::TxFrame::new( | ||
| 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 | |||
| 106 | info!("Transmitting frame..."); | ||
| 107 | let tx_ts = Instant::now(); | ||
| 108 | can.write(&tx_frame).await; | ||
| 109 | |||
| 110 | let envelope = can.read().await.unwrap(); | ||
| 111 | info!("Frame received!"); | ||
| 112 | |||
| 113 | // Check data. | ||
| 114 | assert!(i == envelope.data()[0], "{} == {}", i, envelope.data()[0]); | ||
| 115 | |||
| 116 | info!("loopback time {}", envelope.header.time_stamp); | ||
| 117 | info!("loopback frame {=u8}", envelope.data()[0]); | ||
| 118 | let latency = envelope.timestamp.saturating_duration_since(tx_ts); | ||
| 119 | info!("loopback latency {} us", latency.as_micros()); | ||
| 120 | |||
| 121 | // Theoretical minimum latency is 55us, actual is usually ~80us | ||
| 122 | const MIN_LATENCY: Duration = Duration::from_micros(50); | ||
| 123 | // Was failing at 150 but we are not getting a real time stamp. I'm not | ||
| 124 | // sure if there are other delays | ||
| 125 | assert!( | ||
| 126 | MIN_LATENCY <= latency && latency <= options.max_latency, | ||
| 127 | "{} <= {} <= {}", | ||
| 128 | MIN_LATENCY, | ||
| 129 | latency, | ||
| 130 | options.max_latency | ||
| 131 | ); | ||
| 132 | |||
| 133 | i += 1; | ||
| 134 | if i > 10 { | ||
| 135 | break; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | let max_buffered = if options.second_fifo_working { 6 } else { 3 }; | ||
| 140 | |||
| 141 | // Below here, check that we can receive from both FIFO0 and FIFO0 | ||
| 142 | // Above we configured FIFO1 for extended ID packets. There are only 3 slots | ||
| 143 | // in each FIFO so make sure we write enough to fill them both up before reading. | ||
| 144 | for i in 0..3 { | ||
| 145 | // Try filling up the RX FIFO0 buffers with standard packets | ||
| 146 | let tx_frame = can::TxFrame::new( | ||
| 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); | ||
| 158 | can.write(&tx_frame).await; | ||
| 159 | } | ||
| 160 | for i in 3..max_buffered { | ||
| 161 | // Try filling up the RX FIFO0 buffers with extended packets | ||
| 162 | let tx_frame = can::TxFrame::new( | ||
| 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); | ||
| 175 | can.write(&tx_frame).await; | ||
| 176 | } | ||
| 177 | |||
| 178 | // Try and receive all 6 packets | ||
| 179 | for i in 0..max_buffered { | ||
| 180 | let envelope = can.read().await.unwrap(); | ||
| 181 | match envelope.header.id { | ||
| 182 | can::Id::Extended(id) => { | ||
| 183 | info!("Extended received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | ||
| 184 | } | ||
| 185 | can::Id::Standard(id) => { | ||
| 186 | info!("Standard received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 | 133 | ||
| 191 | // Test again with a split | 134 | // Test again with a split |
| 192 | let (mut tx, mut rx) = can.split(); | 135 | let (mut tx, mut rx, _props) = can.split(); |
| 193 | for i in 0..3 { | 136 | let (mut tx2, mut rx2, _props) = can2.split(); |
| 194 | // Try filling up the RX FIFO0 buffers with standard packets | 137 | run_split_can_tests(&mut tx, &mut rx, &options).await; |
| 195 | let tx_frame = can::TxFrame::new( | 138 | run_split_can_tests(&mut tx2, &mut rx2, &options).await; |
| 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); | ||
| 208 | tx.write(&tx_frame).await; | ||
| 209 | } | ||
| 210 | for i in 3..max_buffered { | ||
| 211 | // Try filling up the RX FIFO0 buffers with extended packets | ||
| 212 | let tx_frame = can::TxFrame::new( | ||
| 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); | ||
| 225 | tx.write(&tx_frame).await; | ||
| 226 | } | ||
| 227 | |||
| 228 | // Try and receive all 6 packets | ||
| 229 | for i in 0..max_buffered { | ||
| 230 | let envelope = rx.read().await.unwrap(); | ||
| 231 | match envelope.header.id { | ||
| 232 | can::Id::Extended(id) => { | ||
| 233 | info!("Extended received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | ||
| 234 | } | ||
| 235 | can::Id::Standard(id) => { | ||
| 236 | info!("Standard received! {:x} {} {}", id.as_raw(), envelope.data()[0], i); | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | 139 | ||
| 241 | info!("Test OK"); | 140 | info!("Test OK"); |
| 242 | cortex_m::asm::bkpt(); | 141 | cortex_m::asm::bkpt(); |
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index c4e2fe161..4a2584b4e 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs | |||
| @@ -10,7 +10,7 @@ use embassy_stm32::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull, Spe | |||
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 13 | let p = embassy_stm32::init(config()); | 13 | let p = init(); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | // Arduino pins D0 and D1 | 16 | // Arduino pins D0 and D1 |
| @@ -112,7 +112,7 @@ async fn main(_spawner: Spawner) { | |||
| 112 | let b = Input::new(&mut b, Pull::Down); | 112 | let b = Input::new(&mut b, Pull::Down); |
| 113 | // no pull, the status is undefined | 113 | // no pull, the status is undefined |
| 114 | 114 | ||
| 115 | let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low, Pull::None); | 115 | let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low); |
| 116 | delay(); | 116 | delay(); |
| 117 | assert!(b.is_low()); | 117 | assert!(b.is_low()); |
| 118 | a.set_high(); // High-Z output | 118 | a.set_high(); // High-Z output |
| @@ -203,7 +203,7 @@ async fn main(_spawner: Spawner) { | |||
| 203 | 203 | ||
| 204 | let mut a = Flex::new(&mut a); | 204 | let mut a = Flex::new(&mut a); |
| 205 | a.set_low(); | 205 | a.set_low(); |
| 206 | a.set_as_input_output(Speed::Low, Pull::None); | 206 | a.set_as_input_output(Speed::Low); |
| 207 | delay(); | 207 | delay(); |
| 208 | assert!(b.is_low()); | 208 | assert!(b.is_low()); |
| 209 | a.set_high(); // High-Z output | 209 | a.set_high(); // High-Z output |
| @@ -216,7 +216,12 @@ async fn main(_spawner: Spawner) { | |||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | fn delay() { | 218 | fn delay() { |
| 219 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h7a3zi"))] | 219 | #[cfg(any( |
| 220 | feature = "stm32h755zi", | ||
| 221 | feature = "stm32h753zi", | ||
| 222 | feature = "stm32h7a3zi", | ||
| 223 | feature = "stm32h7s3l8" | ||
| 224 | ))] | ||
| 220 | cortex_m::asm::delay(9000); | 225 | cortex_m::asm::delay(9000); |
| 221 | cortex_m::asm::delay(1000); | 226 | cortex_m::asm::delay(1000); |
| 222 | } | 227 | } |
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs index cfcf3d976..bdb3c9a69 100644 --- a/tests/stm32/src/bin/hash.rs +++ b/tests/stm32/src/bin/hash.rs | |||
| @@ -9,9 +9,12 @@ use embassy_executor::Spawner; | |||
| 9 | use embassy_stm32::dma::NoDma; | 9 | use embassy_stm32::dma::NoDma; |
| 10 | use embassy_stm32::hash::*; | 10 | use embassy_stm32::hash::*; |
| 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; | 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; |
| 12 | use hmac::{Hmac, Mac}; | ||
| 12 | use sha2::{Digest, Sha224, Sha256}; | 13 | use sha2::{Digest, Sha224, Sha256}; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 15 | ||
| 16 | type HmacSha256 = Hmac<Sha256>; | ||
| 17 | |||
| 15 | #[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32h753zi"))] | 18 | #[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 16 | bind_interrupts!(struct Irqs { | 19 | bind_interrupts!(struct Irqs { |
| 17 | HASH_RNG => hash::InterruptHandler<peripherals::HASH>; | 20 | HASH_RNG => hash::InterruptHandler<peripherals::HASH>; |
| @@ -21,8 +24,10 @@ bind_interrupts!(struct Irqs { | |||
| 21 | feature = "stm32wba52cg", | 24 | feature = "stm32wba52cg", |
| 22 | feature = "stm32l552ze", | 25 | feature = "stm32l552ze", |
| 23 | feature = "stm32h563zi", | 26 | feature = "stm32h563zi", |
| 27 | feature = "stm32h503rb", | ||
| 24 | feature = "stm32u5a5zj", | 28 | feature = "stm32u5a5zj", |
| 25 | feature = "stm32u585ai" | 29 | feature = "stm32u585ai", |
| 30 | feature = "stm32h7s3l8" | ||
| 26 | ))] | 31 | ))] |
| 27 | bind_interrupts!(struct Irqs { | 32 | bind_interrupts!(struct Irqs { |
| 28 | HASH => hash::InterruptHandler<peripherals::HASH>; | 33 | HASH => hash::InterruptHandler<peripherals::HASH>; |
| @@ -30,7 +35,7 @@ bind_interrupts!(struct Irqs { | |||
| 30 | 35 | ||
| 31 | #[embassy_executor::main] | 36 | #[embassy_executor::main] |
| 32 | async fn main(_spawner: Spawner) { | 37 | async fn main(_spawner: Spawner) { |
| 33 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 38 | let p: embassy_stm32::Peripherals = init(); |
| 34 | let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); | 39 | let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); |
| 35 | 40 | ||
| 36 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; | 41 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; |
| @@ -38,11 +43,11 @@ async fn main(_spawner: Spawner) { | |||
| 38 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; | 43 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; |
| 39 | 44 | ||
| 40 | // Start an SHA-256 digest. | 45 | // Start an SHA-256 digest. |
| 41 | let mut sha256context = hw_hasher.start(Algorithm::SHA256, DataType::Width8); | 46 | let mut sha256context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, None); |
| 42 | hw_hasher.update_blocking(&mut sha256context, test_1); | 47 | hw_hasher.update_blocking(&mut sha256context, test_1); |
| 43 | 48 | ||
| 44 | // Interrupt the SHA-256 digest to compute an SHA-224 digest. | 49 | // Interrupt the SHA-256 digest to compute an SHA-224 digest. |
| 45 | let mut sha224context = hw_hasher.start(Algorithm::SHA224, DataType::Width8); | 50 | let mut sha224context = hw_hasher.start(Algorithm::SHA224, DataType::Width8, None); |
| 46 | hw_hasher.update_blocking(&mut sha224context, test_3); | 51 | hw_hasher.update_blocking(&mut sha224context, test_3); |
| 47 | let mut sha224_digest_buffer: [u8; 28] = [0; 28]; | 52 | let mut sha224_digest_buffer: [u8; 28] = [0; 28]; |
| 48 | let _ = hw_hasher.finish_blocking(sha224context, &mut sha224_digest_buffer); | 53 | let _ = hw_hasher.finish_blocking(sha224context, &mut sha224_digest_buffer); |
| @@ -73,6 +78,25 @@ async fn main(_spawner: Spawner) { | |||
| 73 | info!("Software SHA-256 Digest: {:?}", sw_sha224_digest[..]); | 78 | info!("Software SHA-256 Digest: {:?}", sw_sha224_digest[..]); |
| 74 | defmt::assert!(sha224_digest_buffer == sw_sha224_digest[..]); | 79 | defmt::assert!(sha224_digest_buffer == sw_sha224_digest[..]); |
| 75 | 80 | ||
| 81 | let hmac_key: [u8; 64] = [0x55; 64]; | ||
| 82 | |||
| 83 | // Compute HMAC in hardware. | ||
| 84 | let mut sha256hmac_context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, Some(&hmac_key)); | ||
| 85 | hw_hasher.update_blocking(&mut sha256hmac_context, test_1); | ||
| 86 | hw_hasher.update_blocking(&mut sha256hmac_context, test_2); | ||
| 87 | let mut hw_hmac: [u8; 32] = [0; 32]; | ||
| 88 | hw_hasher.finish_blocking(sha256hmac_context, &mut hw_hmac); | ||
| 89 | |||
| 90 | // Compute HMAC in software. | ||
| 91 | let mut sw_mac = HmacSha256::new_from_slice(&hmac_key).unwrap(); | ||
| 92 | sw_mac.update(test_1); | ||
| 93 | sw_mac.update(test_2); | ||
| 94 | let sw_hmac = sw_mac.finalize().into_bytes(); | ||
| 95 | |||
| 96 | info!("Hardware HMAC: {:?}", hw_hmac); | ||
| 97 | info!("Software HMAC: {:?}", sw_hmac[..]); | ||
| 98 | defmt::assert!(hw_hmac == sw_hmac[..]); | ||
| 99 | |||
| 76 | info!("Test OK"); | 100 | info!("Test OK"); |
| 77 | cortex_m::asm::bkpt(); | 101 | cortex_m::asm::bkpt(); |
| 78 | } | 102 | } |
diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs index 7f2023d4d..8438353a8 100644 --- a/tests/stm32/src/bin/rng.rs +++ b/tests/stm32/src/bin/rng.rs | |||
| @@ -23,12 +23,17 @@ bind_interrupts!(struct Irqs { | |||
| 23 | bind_interrupts!(struct Irqs { | 23 | bind_interrupts!(struct Irqs { |
| 24 | RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>; | 24 | RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>; |
| 25 | }); | 25 | }); |
| 26 | #[cfg(any(feature = "stm32u083rc"))] | ||
| 27 | bind_interrupts!(struct Irqs { | ||
| 28 | RNG_CRYP => rng::InterruptHandler<peripherals::RNG>; | ||
| 29 | }); | ||
| 26 | #[cfg(not(any( | 30 | #[cfg(not(any( |
| 27 | feature = "stm32l4a6zg", | 31 | feature = "stm32l4a6zg", |
| 28 | feature = "stm32l073rz", | 32 | feature = "stm32l073rz", |
| 29 | feature = "stm32h755zi", | 33 | feature = "stm32h755zi", |
| 30 | feature = "stm32h753zi", | 34 | feature = "stm32h753zi", |
| 31 | feature = "stm32f429zi" | 35 | feature = "stm32f429zi", |
| 36 | feature = "stm32u083rc" | ||
| 32 | )))] | 37 | )))] |
| 33 | bind_interrupts!(struct Irqs { | 38 | bind_interrupts!(struct Irqs { |
| 34 | RNG => rng::InterruptHandler<peripherals::RNG>; | 39 | RNG => rng::InterruptHandler<peripherals::RNG>; |
| @@ -36,7 +41,7 @@ bind_interrupts!(struct Irqs { | |||
| 36 | 41 | ||
| 37 | #[embassy_executor::main] | 42 | #[embassy_executor::main] |
| 38 | async fn main(_spawner: Spawner) { | 43 | async fn main(_spawner: Spawner) { |
| 39 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 44 | let p: embassy_stm32::Peripherals = init(); |
| 40 | 45 | ||
| 41 | let mut rng = Rng::new(p.RNG, Irqs); | 46 | let mut rng = Rng::new(p.RNG, Irqs); |
| 42 | 47 | ||
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index c04d616ac..5fe98d807 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs | |||
| @@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let mut config = config(); | 18 | let mut config = config(); |
| 19 | config.rcc.ls = LsConfig::default_lse(); | 19 | config.rcc.ls = LsConfig::default_lse(); |
| 20 | 20 | ||
| 21 | let p = embassy_stm32::init(config); | 21 | let p = init_with_config(config); |
| 22 | info!("Hello World!"); | 22 | info!("Hello World!"); |
| 23 | 23 | ||
| 24 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | 24 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) |
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs index 54f55d2d6..a6bc117c0 100644 --- a/tests/stm32/src/bin/sdmmc.rs +++ b/tests/stm32/src/bin/sdmmc.rs | |||
| @@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs { | |||
| 20 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
| 21 | info!("Hello World!"); | 21 | info!("Hello World!"); |
| 22 | 22 | ||
| 23 | let p = embassy_stm32::init(config()); | 23 | let p = init(); |
| 24 | 24 | ||
| 25 | let (mut sdmmc, mut dma, mut clk, mut cmd, mut d0, mut d1, mut d2, mut d3) = | 25 | let (mut sdmmc, mut dma, mut clk, mut cmd, mut d0, mut d1, mut d2, mut d3) = |
| 26 | (p.SDIO, p.DMA2_CH3, p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11); | 26 | (p.SDIO, p.DMA2_CH3, p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11); |
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index b0bdd477f..9712a8c5a 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs | |||
| @@ -6,35 +6,84 @@ mod common; | |||
| 6 | use common::*; | 6 | use common::*; |
| 7 | use defmt::assert_eq; | 7 | use defmt::assert_eq; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::dma::NoDma; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::spi::{self, Spi}; | 10 | use embassy_stm32::mode::Blocking; |
| 11 | use embassy_stm32::spi::{self, Spi, Word}; | ||
| 11 | use embassy_stm32::time::Hertz; | 12 | use embassy_stm32::time::Hertz; |
| 12 | 13 | ||
| 13 | #[embassy_executor::main] | 14 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 15 | async fn main(_spawner: Spawner) { |
| 15 | let p = embassy_stm32::init(config()); | 16 | let p = init(); |
| 16 | info!("Hello World!"); | 17 | info!("Hello World!"); |
| 17 | 18 | ||
| 18 | let spi = peri!(p, SPI); | 19 | let mut spi_peri = peri!(p, SPI); |
| 19 | let sck = peri!(p, SPI_SCK); | 20 | let mut sck = peri!(p, SPI_SCK); |
| 20 | let mosi = peri!(p, SPI_MOSI); | 21 | let mut mosi = peri!(p, SPI_MOSI); |
| 21 | let miso = peri!(p, SPI_MISO); | 22 | let mut miso = peri!(p, SPI_MISO); |
| 22 | 23 | ||
| 23 | let mut spi_config = spi::Config::default(); | 24 | let mut spi_config = spi::Config::default(); |
| 24 | spi_config.frequency = Hertz(1_000_000); | 25 | spi_config.frequency = Hertz(1_000_000); |
| 25 | 26 | ||
| 26 | let mut spi = Spi::new( | 27 | let mut spi = Spi::new_blocking( |
| 27 | spi, sck, // Arduino D13 | 28 | &mut spi_peri, |
| 28 | mosi, // Arduino D11 | 29 | &mut sck, // Arduino D13 |
| 29 | miso, // Arduino D12 | 30 | &mut mosi, // Arduino D11 |
| 30 | NoDma, NoDma, spi_config, | 31 | &mut miso, // Arduino D12 |
| 32 | spi_config, | ||
| 31 | ); | 33 | ); |
| 32 | 34 | ||
| 33 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 35 | test_txrx::<u8>(&mut spi); |
| 36 | test_txrx::<u16>(&mut spi); | ||
| 37 | |||
| 38 | // Assert the RCC bit gets disabled on drop. | ||
| 39 | #[cfg(feature = "stm32f429zi")] | ||
| 40 | defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | ||
| 41 | drop(spi); | ||
| 42 | #[cfg(feature = "stm32f429zi")] | ||
| 43 | defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | ||
| 44 | |||
| 45 | // test rx-only configuration | ||
| 46 | let mut spi = Spi::new_blocking_rxonly(&mut spi_peri, &mut sck, &mut miso, spi_config); | ||
| 47 | let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); | ||
| 48 | |||
| 49 | test_rx::<u8>(&mut spi, &mut mosi_out); | ||
| 50 | test_rx::<u16>(&mut spi, &mut mosi_out); | ||
| 51 | drop(spi); | ||
| 52 | drop(mosi_out); | ||
| 53 | |||
| 54 | let mut spi = Spi::new_blocking_txonly(&mut spi_peri, &mut sck, &mut mosi, spi_config); | ||
| 55 | test_tx::<u8>(&mut spi); | ||
| 56 | test_tx::<u16>(&mut spi); | ||
| 57 | drop(spi); | ||
| 58 | |||
| 59 | let mut spi = Spi::new_blocking_txonly_nosck(&mut spi_peri, &mut mosi, spi_config); | ||
| 60 | test_tx::<u8>(&mut spi); | ||
| 61 | test_tx::<u16>(&mut spi); | ||
| 62 | drop(spi); | ||
| 63 | |||
| 64 | info!("Test OK"); | ||
| 65 | cortex_m::asm::bkpt(); | ||
| 66 | } | ||
| 67 | |||
| 68 | fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) | ||
| 69 | where | ||
| 70 | W: core::ops::Not<Output = W>, | ||
| 71 | { | ||
| 72 | let data: [W; 9] = [ | ||
| 73 | 0x00u8.into(), | ||
| 74 | 0xFFu8.into(), | ||
| 75 | 0xAAu8.into(), | ||
| 76 | 0x55u8.into(), | ||
| 77 | 0xC0u8.into(), | ||
| 78 | 0xFFu8.into(), | ||
| 79 | 0xEEu8.into(), | ||
| 80 | 0xC0u8.into(), | ||
| 81 | 0xDEu8.into(), | ||
| 82 | ]; | ||
| 34 | 83 | ||
| 35 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. | 84 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. |
| 36 | // so we should get the data we sent back. | 85 | // so we should get the data we sent back. |
| 37 | let mut buf = [0; 9]; | 86 | let mut buf = [W::default(); 9]; |
| 38 | spi.blocking_transfer(&mut buf, &data).unwrap(); | 87 | spi.blocking_transfer(&mut buf, &data).unwrap(); |
| 39 | assert_eq!(buf, data); | 88 | assert_eq!(buf, data); |
| 40 | 89 | ||
| @@ -58,7 +107,33 @@ async fn main(_spawner: Spawner) { | |||
| 58 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); | 107 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); |
| 59 | spi.blocking_read::<u8>(&mut []).unwrap(); | 108 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 60 | spi.blocking_write::<u8>(&[]).unwrap(); | 109 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 110 | } | ||
| 61 | 111 | ||
| 62 | info!("Test OK"); | 112 | fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>, mosi_out: &mut Output<'_>) |
| 63 | cortex_m::asm::bkpt(); | 113 | where |
| 114 | W: core::ops::Not<Output = W>, | ||
| 115 | { | ||
| 116 | let mut buf = [W::default(); 9]; | ||
| 117 | |||
| 118 | mosi_out.set_high(); | ||
| 119 | spi.blocking_read(&mut buf).unwrap(); | ||
| 120 | assert_eq!(buf, [!W::default(); 9]); | ||
| 121 | mosi_out.set_low(); | ||
| 122 | spi.blocking_read(&mut buf).unwrap(); | ||
| 123 | assert_eq!(buf, [W::default(); 9]); | ||
| 124 | spi.blocking_read::<u8>(&mut []).unwrap(); | ||
| 125 | spi.blocking_read::<u8>(&mut []).unwrap(); | ||
| 126 | } | ||
| 127 | |||
| 128 | fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) | ||
| 129 | where | ||
| 130 | W: core::ops::Not<Output = W>, | ||
| 131 | { | ||
| 132 | let buf = [W::default(); 9]; | ||
| 133 | |||
| 134 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. | ||
| 135 | spi.blocking_write(&buf).unwrap(); | ||
| 136 | spi.blocking_write::<u8>(&[]).unwrap(); | ||
| 137 | spi.blocking_write(&buf).unwrap(); | ||
| 138 | spi.blocking_write::<u8>(&[]).unwrap(); | ||
| 64 | } | 139 | } |
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index 5d46726dd..307409a16 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs | |||
| @@ -6,36 +6,91 @@ mod common; | |||
| 6 | use common::*; | 6 | use common::*; |
| 7 | use defmt::assert_eq; | 7 | use defmt::assert_eq; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::spi::{self, Spi}; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::mode::Async; | ||
| 11 | use embassy_stm32::spi::{self, Spi, Word}; | ||
| 10 | use embassy_stm32::time::Hertz; | 12 | use embassy_stm32::time::Hertz; |
| 11 | 13 | ||
| 12 | #[embassy_executor::main] | 14 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 15 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_stm32::init(config()); | 16 | let p = init(); |
| 15 | info!("Hello World!"); | 17 | info!("Hello World!"); |
| 16 | 18 | ||
| 17 | let spi = peri!(p, SPI); | 19 | let mut spi_peri = peri!(p, SPI); |
| 18 | let sck = peri!(p, SPI_SCK); | 20 | let mut sck = peri!(p, SPI_SCK); |
| 19 | let mosi = peri!(p, SPI_MOSI); | 21 | let mut mosi = peri!(p, SPI_MOSI); |
| 20 | let miso = peri!(p, SPI_MISO); | 22 | let mut miso = peri!(p, SPI_MISO); |
| 21 | let tx_dma = peri!(p, SPI_TX_DMA); | 23 | let mut tx_dma = peri!(p, SPI_TX_DMA); |
| 22 | let rx_dma = peri!(p, SPI_RX_DMA); | 24 | let mut rx_dma = peri!(p, SPI_RX_DMA); |
| 23 | 25 | ||
| 24 | let mut spi_config = spi::Config::default(); | 26 | let mut spi_config = spi::Config::default(); |
| 25 | spi_config.frequency = Hertz(1_000_000); | 27 | spi_config.frequency = Hertz(1_000_000); |
| 26 | 28 | ||
| 27 | let mut spi = Spi::new( | 29 | let mut spi = Spi::new( |
| 28 | spi, sck, // Arduino D13 | 30 | &mut spi_peri, |
| 29 | mosi, // Arduino D11 | 31 | &mut sck, // Arduino D13 |
| 30 | miso, // Arduino D12 | 32 | &mut mosi, // Arduino D11 |
| 31 | tx_dma, rx_dma, spi_config, | 33 | &mut miso, // Arduino D12 |
| 34 | &mut tx_dma, | ||
| 35 | &mut rx_dma, | ||
| 36 | spi_config, | ||
| 32 | ); | 37 | ); |
| 33 | 38 | ||
| 34 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 39 | test_txrx::<u8>(&mut spi).await; |
| 40 | test_txrx::<u16>(&mut spi).await; | ||
| 41 | drop(spi); | ||
| 42 | |||
| 43 | // test rx-only configuration | ||
| 44 | let mut spi = Spi::new_rxonly( | ||
| 45 | &mut spi_peri, | ||
| 46 | &mut sck, | ||
| 47 | &mut miso, | ||
| 48 | // SPIv1/f1 requires txdma even if rxonly. | ||
| 49 | #[cfg(not(feature = "spi-v345"))] | ||
| 50 | &mut tx_dma, | ||
| 51 | &mut rx_dma, | ||
| 52 | spi_config, | ||
| 53 | ); | ||
| 54 | let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); | ||
| 55 | |||
| 56 | test_rx::<u8>(&mut spi, &mut mosi_out).await; | ||
| 57 | test_rx::<u16>(&mut spi, &mut mosi_out).await; | ||
| 58 | drop(spi); | ||
| 59 | drop(mosi_out); | ||
| 60 | |||
| 61 | let mut spi = Spi::new_txonly(&mut spi_peri, &mut sck, &mut mosi, &mut tx_dma, spi_config); | ||
| 62 | test_tx::<u8>(&mut spi).await; | ||
| 63 | test_tx::<u16>(&mut spi).await; | ||
| 64 | drop(spi); | ||
| 65 | |||
| 66 | let mut spi = Spi::new_txonly_nosck(&mut spi_peri, &mut mosi, &mut tx_dma, spi_config); | ||
| 67 | test_tx::<u8>(&mut spi).await; | ||
| 68 | test_tx::<u16>(&mut spi).await; | ||
| 69 | drop(spi); | ||
| 70 | |||
| 71 | info!("Test OK"); | ||
| 72 | cortex_m::asm::bkpt(); | ||
| 73 | } | ||
| 74 | |||
| 75 | async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) | ||
| 76 | where | ||
| 77 | W: core::ops::Not<Output = W>, | ||
| 78 | { | ||
| 79 | let data: [W; 9] = [ | ||
| 80 | 0x00u8.into(), | ||
| 81 | 0xFFu8.into(), | ||
| 82 | 0xAAu8.into(), | ||
| 83 | 0x55u8.into(), | ||
| 84 | 0xC0u8.into(), | ||
| 85 | 0xFFu8.into(), | ||
| 86 | 0xEEu8.into(), | ||
| 87 | 0xC0u8.into(), | ||
| 88 | 0xDEu8.into(), | ||
| 89 | ]; | ||
| 35 | 90 | ||
| 36 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. | 91 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. |
| 37 | // so we should get the data we sent back. | 92 | // so we should get the data we sent back. |
| 38 | let mut buf = [0; 9]; | 93 | let mut buf = [W::default(); 9]; |
| 39 | spi.transfer(&mut buf, &data).await.unwrap(); | 94 | spi.transfer(&mut buf, &data).await.unwrap(); |
| 40 | assert_eq!(buf, data); | 95 | assert_eq!(buf, data); |
| 41 | 96 | ||
| @@ -59,8 +114,12 @@ async fn main(_spawner: Spawner) { | |||
| 59 | spi.transfer_in_place::<u8>(&mut []).await.unwrap(); | 114 | spi.transfer_in_place::<u8>(&mut []).await.unwrap(); |
| 60 | spi.read::<u8>(&mut []).await.unwrap(); | 115 | spi.read::<u8>(&mut []).await.unwrap(); |
| 61 | spi.write::<u8>(&[]).await.unwrap(); | 116 | spi.write::<u8>(&[]).await.unwrap(); |
| 117 | spi.blocking_transfer::<u8>(&mut [], &[]).unwrap(); | ||
| 118 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); | ||
| 119 | spi.blocking_read::<u8>(&mut []).unwrap(); | ||
| 120 | spi.blocking_write::<u8>(&[]).unwrap(); | ||
| 62 | 121 | ||
| 63 | // === Check mixing blocking with async. | 122 | // Check mixing blocking with async. |
| 64 | spi.blocking_transfer(&mut buf, &data).unwrap(); | 123 | spi.blocking_transfer(&mut buf, &data).unwrap(); |
| 65 | assert_eq!(buf, data); | 124 | assert_eq!(buf, data); |
| 66 | spi.transfer(&mut buf, &data).await.unwrap(); | 125 | spi.transfer(&mut buf, &data).await.unwrap(); |
| @@ -75,7 +134,47 @@ async fn main(_spawner: Spawner) { | |||
| 75 | spi.blocking_write(&buf).unwrap(); | 134 | spi.blocking_write(&buf).unwrap(); |
| 76 | spi.blocking_read(&mut buf).unwrap(); | 135 | spi.blocking_read(&mut buf).unwrap(); |
| 77 | spi.write(&buf).await.unwrap(); | 136 | spi.write(&buf).await.unwrap(); |
| 137 | } | ||
| 78 | 138 | ||
| 79 | info!("Test OK"); | 139 | async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>, mosi_out: &mut Output<'_>) |
| 80 | cortex_m::asm::bkpt(); | 140 | where |
| 141 | W: core::ops::Not<Output = W>, | ||
| 142 | { | ||
| 143 | let mut buf = [W::default(); 9]; | ||
| 144 | |||
| 145 | mosi_out.set_high(); | ||
| 146 | spi.read(&mut buf).await.unwrap(); | ||
| 147 | assert_eq!(buf, [!W::default(); 9]); | ||
| 148 | spi.blocking_read(&mut buf).unwrap(); | ||
| 149 | assert_eq!(buf, [!W::default(); 9]); | ||
| 150 | spi.read(&mut buf).await.unwrap(); | ||
| 151 | assert_eq!(buf, [!W::default(); 9]); | ||
| 152 | spi.read(&mut buf).await.unwrap(); | ||
| 153 | assert_eq!(buf, [!W::default(); 9]); | ||
| 154 | spi.blocking_read(&mut buf).unwrap(); | ||
| 155 | assert_eq!(buf, [!W::default(); 9]); | ||
| 156 | spi.blocking_read(&mut buf).unwrap(); | ||
| 157 | assert_eq!(buf, [!W::default(); 9]); | ||
| 158 | mosi_out.set_low(); | ||
| 159 | spi.read(&mut buf).await.unwrap(); | ||
| 160 | assert_eq!(buf, [W::default(); 9]); | ||
| 161 | spi.read::<u8>(&mut []).await.unwrap(); | ||
| 162 | spi.blocking_read::<u8>(&mut []).unwrap(); | ||
| 163 | } | ||
| 164 | |||
| 165 | async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) | ||
| 166 | where | ||
| 167 | W: core::ops::Not<Output = W>, | ||
| 168 | { | ||
| 169 | let buf = [W::default(); 9]; | ||
| 170 | |||
| 171 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. | ||
| 172 | spi.blocking_write(&buf).unwrap(); | ||
| 173 | spi.write(&buf).await.unwrap(); | ||
| 174 | spi.blocking_write(&buf).unwrap(); | ||
| 175 | spi.blocking_write(&buf).unwrap(); | ||
| 176 | spi.write(&buf).await.unwrap(); | ||
| 177 | spi.write(&buf).await.unwrap(); | ||
| 178 | spi.write::<u8>(&[]).await.unwrap(); | ||
| 179 | spi.blocking_write::<u8>(&[]).unwrap(); | ||
| 81 | } | 180 | } |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 000296d46..772bc527c 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -51,7 +51,14 @@ async fn async_main(spawner: Spawner) { | |||
| 51 | let mut config = Config::default(); | 51 | let mut config = Config::default(); |
| 52 | config.rcc.ls = LsConfig::default_lse(); | 52 | config.rcc.ls = LsConfig::default_lse(); |
| 53 | 53 | ||
| 54 | let p = embassy_stm32::init(config); | 54 | // System Clock seems cannot be greater than 16 MHz |
| 55 | #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] | ||
| 56 | { | ||
| 57 | use embassy_stm32::rcc::HSIPrescaler; | ||
| 58 | config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4 | ||
| 59 | } | ||
| 60 | |||
| 61 | let p = init_with_config(config); | ||
| 55 | info!("Hello World!"); | 62 | info!("Hello World!"); |
| 56 | 63 | ||
| 57 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | 64 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) |
diff --git a/tests/stm32/src/bin/timer.rs b/tests/stm32/src/bin/timer.rs index d86f54ad2..8719e7670 100644 --- a/tests/stm32/src/bin/timer.rs +++ b/tests/stm32/src/bin/timer.rs | |||
| @@ -10,7 +10,7 @@ use embassy_time::{Instant, Timer}; | |||
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 13 | let _p = embassy_stm32::init(config()); | 13 | let _p = init(); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | let start = Instant::now(); | 16 | let start = Instant::now(); |
diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs new file mode 100644 index 000000000..bd7b35d6b --- /dev/null +++ b/tests/stm32/src/bin/ucpd.rs | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | // required-features: ucpd | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 6 | |||
| 7 | use common::*; | ||
| 8 | use defmt::{assert, assert_eq}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; | ||
| 12 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | UCPD1_2 => ucpd::InterruptHandler<peripherals::UCPD1>, ucpd::InterruptHandler<peripherals::UCPD2>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | static SRC_TO_SNK: [u8; 6] = [0, 1, 2, 3, 4, 5]; | ||
| 20 | static SNK_TO_SRC: [u8; 4] = [9, 8, 7, 6]; | ||
| 21 | |||
| 22 | async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: CcVState) { | ||
| 23 | let (mut cc1, mut _cc2) = cc_phy.vstate(); | ||
| 24 | while cc1 != vstate { | ||
| 25 | (cc1, _cc2) = cc_phy.wait_for_vstate_change().await; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | async fn source( | ||
| 30 | mut ucpd: Ucpd<'static, peripherals::UCPD1>, | ||
| 31 | rx_dma: peripherals::DMA1_CH1, | ||
| 32 | tx_dma: peripherals::DMA1_CH2, | ||
| 33 | ) { | ||
| 34 | debug!("source: setting default current pull-up"); | ||
| 35 | ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); | ||
| 36 | |||
| 37 | // Wait for default sink. | ||
| 38 | debug!("source: wait for sink"); | ||
| 39 | wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await; | ||
| 40 | |||
| 41 | // Advertise a higher current by changing the pull-up resistor. | ||
| 42 | debug!("source: sink detected, setting 3.0A current pull-up"); | ||
| 43 | ucpd.cc_phy().set_pull(CcPull::Source3_0A); | ||
| 44 | |||
| 45 | let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1); | ||
| 46 | |||
| 47 | // Listen for an incoming message | ||
| 48 | debug!("source: wait for message from sink"); | ||
| 49 | let mut snk_to_src_buf = [0_u8; 30]; | ||
| 50 | let n = unwrap!(pd_phy.receive(snk_to_src_buf.as_mut()).await); | ||
| 51 | assert_eq!(n, SNK_TO_SRC.len()); | ||
| 52 | assert_eq!(&snk_to_src_buf[..n], SNK_TO_SRC.as_slice()); | ||
| 53 | |||
| 54 | // Send message | ||
| 55 | debug!("source: message received, sending message"); | ||
| 56 | unwrap!(pd_phy.transmit(SRC_TO_SNK.as_slice()).await); | ||
| 57 | |||
| 58 | // Wait for hard-reset | ||
| 59 | debug!("source: message sent, waiting for hard-reset"); | ||
| 60 | assert!(matches!( | ||
| 61 | pd_phy.receive(snk_to_src_buf.as_mut()).await, | ||
| 62 | Err(RxError::HardReset) | ||
| 63 | )); | ||
| 64 | } | ||
| 65 | |||
| 66 | async fn sink( | ||
| 67 | mut ucpd: Ucpd<'static, peripherals::UCPD2>, | ||
| 68 | rx_dma: peripherals::DMA1_CH3, | ||
| 69 | tx_dma: peripherals::DMA1_CH4, | ||
| 70 | ) { | ||
| 71 | debug!("sink: setting pull down"); | ||
| 72 | ucpd.cc_phy().set_pull(CcPull::Sink); | ||
| 73 | |||
| 74 | // Wait for default source. | ||
| 75 | debug!("sink: waiting for default vstate"); | ||
| 76 | wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await; | ||
| 77 | |||
| 78 | // Wait higher current pull-up. | ||
| 79 | //debug!("sink: source default vstate detected, waiting for 3.0A vstate"); | ||
| 80 | //wait_for_vstate(ucpd.cc_phy(), CcVState::HIGHEST).await; | ||
| 81 | //debug!("sink: source 3.0A vstate detected"); | ||
| 82 | // TODO: not working yet, why? no idea, replace with timer for now | ||
| 83 | Timer::after_millis(100).await; | ||
| 84 | |||
| 85 | let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1); | ||
| 86 | |||
| 87 | // Send message | ||
| 88 | debug!("sink: sending message"); | ||
| 89 | unwrap!(pd_phy.transmit(SNK_TO_SRC.as_slice()).await); | ||
| 90 | |||
| 91 | // Listen for an incoming message | ||
| 92 | debug!("sink: message sent, waiting for message from source"); | ||
| 93 | let mut src_to_snk_buf = [0_u8; 30]; | ||
| 94 | let n = unwrap!(pd_phy.receive(src_to_snk_buf.as_mut()).await); | ||
| 95 | assert_eq!(n, SRC_TO_SNK.len()); | ||
| 96 | assert_eq!(&src_to_snk_buf[..n], SRC_TO_SNK.as_slice()); | ||
| 97 | |||
| 98 | // Send hard reset | ||
| 99 | debug!("sink: message received, sending hard-reset"); | ||
| 100 | unwrap!(pd_phy.transmit_hardreset().await); | ||
| 101 | } | ||
| 102 | |||
| 103 | #[embassy_executor::main] | ||
| 104 | async fn main(_spawner: Spawner) { | ||
| 105 | let p = init(); | ||
| 106 | info!("Hello World!"); | ||
| 107 | |||
| 108 | // Wire between PD0 and PA8 | ||
| 109 | let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15, Default::default()); | ||
| 110 | let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2, Default::default()); | ||
| 111 | |||
| 112 | join( | ||
| 113 | source(ucpd1, p.DMA1_CH1, p.DMA1_CH2), | ||
| 114 | sink(ucpd2, p.DMA1_CH3, p.DMA1_CH4), | ||
| 115 | ) | ||
| 116 | .await; | ||
| 117 | |||
| 118 | info!("Test OK"); | ||
| 119 | cortex_m::asm::bkpt(); | ||
| 120 | } | ||
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs index 9b20eb784..53da30fff 100644 --- a/tests/stm32/src/bin/usart.rs +++ b/tests/stm32/src/bin/usart.rs | |||
| @@ -6,13 +6,12 @@ mod common; | |||
| 6 | use common::*; | 6 | use common::*; |
| 7 | use defmt::{assert, assert_eq, unreachable}; | 7 | use defmt::{assert, assert_eq, unreachable}; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::dma::NoDma; | ||
| 10 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; | 9 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; |
| 11 | use embassy_time::{block_for, Duration, Instant}; | 10 | use embassy_time::{block_for, Duration, Instant}; |
| 12 | 11 | ||
| 13 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 15 | let p = embassy_stm32::init(config()); | 14 | let p = init(); |
| 16 | info!("Hello World!"); | 15 | info!("Hello World!"); |
| 17 | 16 | ||
| 18 | // Arduino pins D0 and D1 | 17 | // Arduino pins D0 and D1 |
| @@ -20,11 +19,10 @@ async fn main(_spawner: Spawner) { | |||
| 20 | let mut usart = peri!(p, UART); | 19 | let mut usart = peri!(p, UART); |
| 21 | let mut rx = peri!(p, UART_RX); | 20 | let mut rx = peri!(p, UART_RX); |
| 22 | let mut tx = peri!(p, UART_TX); | 21 | let mut tx = peri!(p, UART_TX); |
| 23 | let irq = irqs!(UART); | ||
| 24 | 22 | ||
| 25 | { | 23 | { |
| 26 | let config = Config::default(); | 24 | let config = Config::default(); |
| 27 | let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); | 25 | let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); |
| 28 | 26 | ||
| 29 | // We can't send too many bytes, they have to fit in the FIFO. | 27 | // We can't send too many bytes, they have to fit in the FIFO. |
| 30 | // This is because we aren't sending+receiving at the same time. | 28 | // This is because we aren't sending+receiving at the same time. |
| @@ -40,7 +38,7 @@ async fn main(_spawner: Spawner) { | |||
| 40 | // Test error handling with with an overflow error | 38 | // Test error handling with with an overflow error |
| 41 | { | 39 | { |
| 42 | let config = Config::default(); | 40 | let config = Config::default(); |
| 43 | let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); | 41 | let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); |
| 44 | 42 | ||
| 45 | // Send enough bytes to fill the RX FIFOs off all USART versions. | 43 | // Send enough bytes to fill the RX FIFOs off all USART versions. |
| 46 | let data = [0; 64]; | 44 | let data = [0; 64]; |
| @@ -70,7 +68,7 @@ async fn main(_spawner: Spawner) { | |||
| 70 | 68 | ||
| 71 | let mut config = Config::default(); | 69 | let mut config = Config::default(); |
| 72 | config.baudrate = baudrate; | 70 | config.baudrate = baudrate; |
| 73 | let mut usart = match Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config) { | 71 | let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { |
| 74 | Ok(x) => x, | 72 | Ok(x) => x, |
| 75 | Err(ConfigError::BaudrateTooHigh) => { | 73 | Err(ConfigError::BaudrateTooHigh) => { |
| 76 | info!("baudrate too high"); | 74 | info!("baudrate too high"); |
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs index 24e2b2896..266b81809 100644 --- a/tests/stm32/src/bin/usart_dma.rs +++ b/tests/stm32/src/bin/usart_dma.rs | |||
| @@ -11,7 +11,7 @@ use embassy_stm32::usart::{Config, Uart}; | |||
| 11 | 11 | ||
| 12 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_stm32::init(config()); | 14 | let p = init(); |
| 15 | info!("Hello World!"); | 15 | info!("Hello World!"); |
| 16 | 16 | ||
| 17 | // Arduino pins D0 and D1 | 17 | // Arduino pins D0 and D1 |
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index f5d618db4..98c7ef312 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs | |||
| @@ -8,6 +8,7 @@ mod common; | |||
| 8 | use common::*; | 8 | use common::*; |
| 9 | use defmt::{assert_eq, panic}; | 9 | use defmt::{assert_eq, panic}; |
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::mode::Async; | ||
| 11 | use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; | 12 | use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; |
| 12 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 13 | use rand_chacha::ChaCha8Rng; | 14 | use rand_chacha::ChaCha8Rng; |
| @@ -17,7 +18,7 @@ const DMA_BUF_SIZE: usize = 256; | |||
| 17 | 18 | ||
| 18 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 19 | async fn main(spawner: Spawner) { | 20 | async fn main(spawner: Spawner) { |
| 20 | let p = embassy_stm32::init(config()); | 21 | let p = init(); |
| 21 | info!("Hello World!"); | 22 | info!("Hello World!"); |
| 22 | 23 | ||
| 23 | // Arduino pins D0 and D1 | 24 | // Arduino pins D0 and D1 |
| @@ -51,7 +52,7 @@ async fn main(spawner: Spawner) { | |||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | #[embassy_executor::task] | 54 | #[embassy_executor::task] |
| 54 | async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { | 55 | async fn transmit_task(mut tx: UartTx<'static, Async>) { |
| 55 | // workaround https://github.com/embassy-rs/embassy/issues/1426 | 56 | // workaround https://github.com/embassy-rs/embassy/issues/1426 |
| 56 | Timer::after_millis(100).await; | 57 | Timer::after_millis(100).await; |
| 57 | 58 | ||
| @@ -74,7 +75,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) | |||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | #[embassy_executor::task] | 77 | #[embassy_executor::task] |
| 77 | async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UART_RX_DMA>) { | 78 | async fn receive_task(mut rx: RingBufferedUartRx<'static>) { |
| 78 | info!("Ready to receive..."); | 79 | info!("Ready to receive..."); |
| 79 | 80 | ||
| 80 | let mut rng = ChaCha8Rng::seed_from_u64(1337); | 81 | let mut rng = ChaCha8Rng::seed_from_u64(1337); |
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs index 82a540d45..fde1dfa9b 100644 --- a/tests/stm32/src/bin/wpan_ble.rs +++ b/tests/stm32/src/bin/wpan_ble.rs | |||
| @@ -41,7 +41,7 @@ async fn main(spawner: Spawner) { | |||
| 41 | let mut config = config(); | 41 | let mut config = config(); |
| 42 | config.rcc = WPAN_DEFAULT; | 42 | config.rcc = WPAN_DEFAULT; |
| 43 | 43 | ||
| 44 | let p = embassy_stm32::init(config); | 44 | let p = init_with_config(config); |
| 45 | info!("Hello World!"); | 45 | info!("Hello World!"); |
| 46 | 46 | ||
| 47 | let config = Config::default(); | 47 | let config = Config::default(); |
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index fe53b8786..b65ace40f 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs | |||
| @@ -34,7 +34,7 @@ async fn main(spawner: Spawner) { | |||
| 34 | let mut config = config(); | 34 | let mut config = config(); |
| 35 | config.rcc = WPAN_DEFAULT; | 35 | config.rcc = WPAN_DEFAULT; |
| 36 | 36 | ||
| 37 | let p = embassy_stm32::init(config); | 37 | let p = init_with_config(config); |
| 38 | info!("Hello World!"); | 38 | info!("Hello World!"); |
| 39 | 39 | ||
| 40 | let config = Config::default(); | 40 | let config = Config::default(); |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 36fe8a235..935a41ed2 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | pub use defmt::*; | 3 | pub use defmt::*; |
| 4 | #[allow(unused)] | 4 | #[allow(unused)] |
| 5 | use embassy_stm32::rcc::*; | ||
| 6 | #[allow(unused)] | ||
| 5 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 6 | use embassy_stm32::Config; | 8 | use embassy_stm32::Config; |
| 7 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -54,6 +56,14 @@ teleprobe_meta::target!(b"nucleo-stm32l496zg"); | |||
| 54 | teleprobe_meta::target!(b"nucleo-stm32wl55jc"); | 56 | teleprobe_meta::target!(b"nucleo-stm32wl55jc"); |
| 55 | #[cfg(feature = "stm32wba52cg")] | 57 | #[cfg(feature = "stm32wba52cg")] |
| 56 | teleprobe_meta::target!(b"nucleo-stm32wba52cg"); | 58 | teleprobe_meta::target!(b"nucleo-stm32wba52cg"); |
| 59 | #[cfg(feature = "stm32f091rc")] | ||
| 60 | teleprobe_meta::target!(b"nucleo-stm32f091rc"); | ||
| 61 | #[cfg(feature = "stm32h503rb")] | ||
| 62 | teleprobe_meta::target!(b"nucleo-stm32h503rb"); | ||
| 63 | #[cfg(feature = "stm32h7s3l8")] | ||
| 64 | teleprobe_meta::target!(b"nucleo-stm32h7s3l8"); | ||
| 65 | #[cfg(feature = "stm32u083rc")] | ||
| 66 | teleprobe_meta::target!(b"nucleo-stm32u083rc"); | ||
| 57 | 67 | ||
| 58 | macro_rules! define_peris { | 68 | macro_rules! define_peris { |
| 59 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { | 69 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { |
| @@ -85,6 +95,12 @@ macro_rules! define_peris { | |||
| 85 | }; | 95 | }; |
| 86 | } | 96 | } |
| 87 | 97 | ||
| 98 | #[cfg(feature = "stm32f091rc")] | ||
| 99 | define_peris!( | ||
| 100 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, | ||
| 101 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, | ||
| 102 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 103 | ); | ||
| 88 | #[cfg(feature = "stm32f103c8")] | 104 | #[cfg(feature = "stm32f103c8")] |
| 89 | define_peris!( | 105 | define_peris!( |
| 90 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, | 106 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, |
| @@ -108,7 +124,7 @@ define_peris!( | |||
| 108 | define_peris!( | 124 | define_peris!( |
| 109 | UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, | 125 | UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, |
| 110 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, | 126 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, |
| 111 | ADC = ADC1, DAC = DAC, DAC_PIN = PA4, | 127 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, |
| 112 | CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1, | 128 | CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1, |
| 113 | @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;}, | 129 | @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;}, |
| 114 | ); | 130 | ); |
| @@ -116,7 +132,7 @@ define_peris!( | |||
| 116 | define_peris!( | 132 | define_peris!( |
| 117 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5, | 133 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5, |
| 118 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, | 134 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, |
| 119 | ADC = ADC1, DAC = DAC, DAC_PIN = PA4, | 135 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, |
| 120 | CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12, | 136 | CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12, |
| 121 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | 137 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, |
| 122 | ); | 138 | ); |
| @@ -128,6 +144,7 @@ define_peris!( | |||
| 128 | ); | 144 | ); |
| 129 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] | 145 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 130 | define_peris!( | 146 | define_peris!( |
| 147 | CRYP_IN_DMA = DMA1_CH0, CRYP_OUT_DMA = DMA1_CH1, | ||
| 131 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, | 148 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, |
| 132 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, | 149 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, |
| 133 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, | 150 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, |
| @@ -157,6 +174,12 @@ define_peris!( | |||
| 157 | SPI = SPI4, SPI_SCK = PE12, SPI_MOSI = PE14, SPI_MISO = PE13, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | 174 | SPI = SPI4, SPI_SCK = PE12, SPI_MOSI = PE14, SPI_MISO = PE13, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, |
| 158 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, | 175 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, |
| 159 | ); | 176 | ); |
| 177 | #[cfg(feature = "stm32h503rb")] | ||
| 178 | define_peris!( | ||
| 179 | UART = USART1, UART_TX = PB14, UART_RX = PB15, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, | ||
| 180 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | ||
| 181 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 182 | ); | ||
| 160 | #[cfg(feature = "stm32c031c6")] | 183 | #[cfg(feature = "stm32c031c6")] |
| 161 | define_peris!( | 184 | define_peris!( |
| 162 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, | 185 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, |
| @@ -191,7 +214,7 @@ define_peris!( | |||
| 191 | define_peris!( | 214 | define_peris!( |
| 192 | UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, | 215 | UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, |
| 193 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, | 216 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, |
| 194 | ADC = ADC, DAC = DAC, DAC_PIN = PA4, | 217 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, |
| 195 | @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;}, | 218 | @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;}, |
| 196 | ); | 219 | ); |
| 197 | #[cfg(feature = "stm32l552ze")] | 220 | #[cfg(feature = "stm32l552ze")] |
| @@ -230,26 +253,86 @@ define_peris!( | |||
| 230 | SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | 253 | SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, |
| 231 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, | 254 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, |
| 232 | ); | 255 | ); |
| 256 | #[cfg(feature = "stm32h7s3l8")] | ||
| 257 | define_peris!( | ||
| 258 | CRYP_IN_DMA = GPDMA1_CH0, CRYP_OUT_DMA = GPDMA1_CH1, | ||
| 259 | UART = USART1, UART_TX = PB14, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, | ||
| 260 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | ||
| 261 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 262 | ); | ||
| 263 | #[cfg(feature = "stm32u083rc")] | ||
| 264 | define_peris!( | ||
| 265 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, | ||
| 266 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, | ||
| 267 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 268 | ); | ||
| 233 | 269 | ||
| 234 | pub fn config() -> Config { | 270 | pub fn config() -> Config { |
| 235 | // Setting this bit is mandatory to use PG[15:2]. | ||
| 236 | #[cfg(feature = "stm32u5a5zj")] | ||
| 237 | embassy_stm32::pac::PWR.svmcr().modify(|w| { | ||
| 238 | w.set_io2sv(true); | ||
| 239 | w.set_io2vmen(true); | ||
| 240 | }); | ||
| 241 | |||
| 242 | #[allow(unused_mut)] | 271 | #[allow(unused_mut)] |
| 243 | let mut config = Config::default(); | 272 | let mut config = Config::default(); |
| 244 | 273 | ||
| 274 | #[cfg(feature = "stm32c031c6")] | ||
| 275 | { | ||
| 276 | config.rcc.hsi = Some(Hsi { | ||
| 277 | sys_div: HsiSysDiv::DIV1, // 48Mhz | ||
| 278 | ker_div: HsiKerDiv::DIV3, // 16Mhz | ||
| 279 | }); | ||
| 280 | config.rcc.sys = Sysclk::HSISYS; | ||
| 281 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 282 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 283 | } | ||
| 284 | |||
| 285 | #[cfg(feature = "stm32g071rb")] | ||
| 286 | { | ||
| 287 | config.rcc.hsi = true; | ||
| 288 | config.rcc.pll = Some(Pll { | ||
| 289 | source: PllSource::HSI, | ||
| 290 | prediv: PllPreDiv::DIV1, | ||
| 291 | mul: PllMul::MUL16, | ||
| 292 | divp: None, | ||
| 293 | divq: None, | ||
| 294 | divr: Some(PllRDiv::DIV4), // 16 / 1 * 16 / 4 = 64 Mhz | ||
| 295 | }); | ||
| 296 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 297 | } | ||
| 245 | #[cfg(feature = "stm32wb55rg")] | 298 | #[cfg(feature = "stm32wb55rg")] |
| 246 | { | 299 | { |
| 247 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; | 300 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; |
| 248 | } | 301 | } |
| 249 | 302 | ||
| 303 | #[cfg(feature = "stm32f091rc")] | ||
| 304 | { | ||
| 305 | config.rcc.hse = Some(Hse { | ||
| 306 | freq: Hertz(8_000_000), | ||
| 307 | mode: HseMode::Bypass, | ||
| 308 | }); | ||
| 309 | config.rcc.pll = Some(Pll { | ||
| 310 | src: PllSource::HSE, | ||
| 311 | prediv: PllPreDiv::DIV1, | ||
| 312 | mul: PllMul::MUL6, | ||
| 313 | }); | ||
| 314 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 315 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 316 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 317 | } | ||
| 318 | #[cfg(feature = "stm32f103c8")] | ||
| 319 | { | ||
| 320 | config.rcc.hse = Some(Hse { | ||
| 321 | freq: Hertz(8_000_000), | ||
| 322 | mode: HseMode::Oscillator, | ||
| 323 | }); | ||
| 324 | config.rcc.pll = Some(Pll { | ||
| 325 | src: PllSource::HSE, | ||
| 326 | prediv: PllPreDiv::DIV1, | ||
| 327 | mul: PllMul::MUL9, | ||
| 328 | }); | ||
| 329 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 330 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 331 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 332 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 333 | } | ||
| 250 | #[cfg(feature = "stm32f207zg")] | 334 | #[cfg(feature = "stm32f207zg")] |
| 251 | { | 335 | { |
| 252 | use embassy_stm32::rcc::*; | ||
| 253 | // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) | 336 | // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) |
| 254 | config.rcc.hse = Some(Hse { | 337 | config.rcc.hse = Some(Hse { |
| 255 | freq: Hertz(8_000_000), | 338 | freq: Hertz(8_000_000), |
| @@ -278,7 +361,6 @@ pub fn config() -> Config { | |||
| 278 | 361 | ||
| 279 | #[cfg(feature = "stm32f303ze")] | 362 | #[cfg(feature = "stm32f303ze")] |
| 280 | { | 363 | { |
| 281 | use embassy_stm32::rcc::*; | ||
| 282 | config.rcc.hse = Some(Hse { | 364 | config.rcc.hse = Some(Hse { |
| 283 | freq: Hertz(8_000_000), | 365 | freq: Hertz(8_000_000), |
| 284 | mode: HseMode::Bypass, | 366 | mode: HseMode::Bypass, |
| @@ -296,7 +378,6 @@ pub fn config() -> Config { | |||
| 296 | 378 | ||
| 297 | #[cfg(feature = "stm32f429zi")] | 379 | #[cfg(feature = "stm32f429zi")] |
| 298 | { | 380 | { |
| 299 | use embassy_stm32::rcc::*; | ||
| 300 | config.rcc.hse = Some(Hse { | 381 | config.rcc.hse = Some(Hse { |
| 301 | freq: Hertz(8_000_000), | 382 | freq: Hertz(8_000_000), |
| 302 | mode: HseMode::Bypass, | 383 | mode: HseMode::Bypass, |
| @@ -317,7 +398,6 @@ pub fn config() -> Config { | |||
| 317 | 398 | ||
| 318 | #[cfg(feature = "stm32f446re")] | 399 | #[cfg(feature = "stm32f446re")] |
| 319 | { | 400 | { |
| 320 | use embassy_stm32::rcc::*; | ||
| 321 | config.rcc.hse = Some(Hse { | 401 | config.rcc.hse = Some(Hse { |
| 322 | freq: Hertz(8_000_000), | 402 | freq: Hertz(8_000_000), |
| 323 | mode: HseMode::Oscillator, | 403 | mode: HseMode::Oscillator, |
| @@ -338,7 +418,6 @@ pub fn config() -> Config { | |||
| 338 | 418 | ||
| 339 | #[cfg(feature = "stm32f767zi")] | 419 | #[cfg(feature = "stm32f767zi")] |
| 340 | { | 420 | { |
| 341 | use embassy_stm32::rcc::*; | ||
| 342 | config.rcc.hse = Some(Hse { | 421 | config.rcc.hse = Some(Hse { |
| 343 | freq: Hertz(8_000_000), | 422 | freq: Hertz(8_000_000), |
| 344 | mode: HseMode::Bypass, | 423 | mode: HseMode::Bypass, |
| @@ -359,7 +438,6 @@ pub fn config() -> Config { | |||
| 359 | 438 | ||
| 360 | #[cfg(feature = "stm32h563zi")] | 439 | #[cfg(feature = "stm32h563zi")] |
| 361 | { | 440 | { |
| 362 | use embassy_stm32::rcc::*; | ||
| 363 | config.rcc.hsi = None; | 441 | config.rcc.hsi = None; |
| 364 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 442 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| 365 | config.rcc.hse = Some(Hse { | 443 | config.rcc.hse = Some(Hse { |
| @@ -382,9 +460,50 @@ pub fn config() -> Config { | |||
| 382 | config.rcc.voltage_scale = VoltageScale::Scale0; | 460 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 383 | } | 461 | } |
| 384 | 462 | ||
| 463 | #[cfg(feature = "stm32h503rb")] | ||
| 464 | { | ||
| 465 | config.rcc.hsi = None; | ||
| 466 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | ||
| 467 | config.rcc.hse = Some(Hse { | ||
| 468 | freq: Hertz(24_000_000), | ||
| 469 | mode: HseMode::Oscillator, | ||
| 470 | }); | ||
| 471 | config.rcc.pll1 = Some(Pll { | ||
| 472 | source: PllSource::HSE, | ||
| 473 | prediv: PllPreDiv::DIV6, | ||
| 474 | mul: PllMul::MUL125, | ||
| 475 | divp: Some(PllDiv::DIV2), | ||
| 476 | divq: Some(PllDiv::DIV2), | ||
| 477 | divr: None, | ||
| 478 | }); | ||
| 479 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 480 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 481 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 482 | config.rcc.apb3_pre = APBPrescaler::DIV1; | ||
| 483 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 484 | config.rcc.voltage_scale = VoltageScale::Scale0; | ||
| 485 | } | ||
| 486 | |||
| 487 | #[cfg(feature = "stm32g491re")] | ||
| 488 | { | ||
| 489 | config.rcc.hse = Some(Hse { | ||
| 490 | freq: Hertz(24_000_000), | ||
| 491 | mode: HseMode::Oscillator, | ||
| 492 | }); | ||
| 493 | config.rcc.pll = Some(Pll { | ||
| 494 | source: PllSource::HSE, | ||
| 495 | prediv: PllPreDiv::DIV6, | ||
| 496 | mul: PllMul::MUL85, | ||
| 497 | divp: None, | ||
| 498 | divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan. | ||
| 499 | divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz | ||
| 500 | }); | ||
| 501 | config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q; | ||
| 502 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 503 | } | ||
| 504 | |||
| 385 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] | 505 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 386 | { | 506 | { |
| 387 | use embassy_stm32::rcc::*; | ||
| 388 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | 507 | config.rcc.hsi = Some(HSIPrescaler::DIV1); |
| 389 | config.rcc.csi = true; | 508 | config.rcc.csi = true; |
| 390 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 509 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| @@ -411,7 +530,7 @@ pub fn config() -> Config { | |||
| 411 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 530 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 412 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 531 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 413 | config.rcc.voltage_scale = VoltageScale::Scale1; | 532 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 414 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 533 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 415 | #[cfg(any(feature = "stm32h755zi"))] | 534 | #[cfg(any(feature = "stm32h755zi"))] |
| 416 | { | 535 | { |
| 417 | config.rcc.supply_config = SupplyConfig::DirectSMPS; | 536 | config.rcc.supply_config = SupplyConfig::DirectSMPS; |
| @@ -420,7 +539,6 @@ pub fn config() -> Config { | |||
| 420 | 539 | ||
| 421 | #[cfg(any(feature = "stm32h7a3zi"))] | 540 | #[cfg(any(feature = "stm32h7a3zi"))] |
| 422 | { | 541 | { |
| 423 | use embassy_stm32::rcc::*; | ||
| 424 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | 542 | config.rcc.hsi = Some(HSIPrescaler::DIV1); |
| 425 | config.rcc.csi = true; | 543 | config.rcc.csi = true; |
| 426 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 544 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| @@ -447,13 +565,12 @@ pub fn config() -> Config { | |||
| 447 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz | 565 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz |
| 448 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz | 566 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz |
| 449 | config.rcc.voltage_scale = VoltageScale::Scale0; | 567 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 450 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 568 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 451 | } | 569 | } |
| 452 | 570 | ||
| 453 | #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] | 571 | #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] |
| 454 | { | 572 | { |
| 455 | use embassy_stm32::rcc::*; | 573 | config.rcc.sys = Sysclk::PLL1_R; |
| 456 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 457 | config.rcc.hsi = true; | 574 | config.rcc.hsi = true; |
| 458 | config.rcc.pll = Some(Pll { | 575 | config.rcc.pll = Some(Pll { |
| 459 | source: PllSource::HSI, | 576 | source: PllSource::HSI, |
| @@ -467,13 +584,12 @@ pub fn config() -> Config { | |||
| 467 | 584 | ||
| 468 | #[cfg(feature = "stm32wl55jc")] | 585 | #[cfg(feature = "stm32wl55jc")] |
| 469 | { | 586 | { |
| 470 | use embassy_stm32::rcc::*; | ||
| 471 | config.rcc.hse = Some(Hse { | 587 | config.rcc.hse = Some(Hse { |
| 472 | freq: Hertz(32_000_000), | 588 | freq: Hertz(32_000_000), |
| 473 | mode: HseMode::Bypass, | 589 | mode: HseMode::Bypass, |
| 474 | prescaler: HsePrescaler::DIV1, | 590 | prescaler: HsePrescaler::DIV1, |
| 475 | }); | 591 | }); |
| 476 | config.rcc.mux = ClockSrc::PLL1_R; | 592 | config.rcc.sys = Sysclk::PLL1_R; |
| 477 | config.rcc.pll = Some(Pll { | 593 | config.rcc.pll = Some(Pll { |
| 478 | source: PllSource::HSE, | 594 | source: PllSource::HSE, |
| 479 | prediv: PllPreDiv::DIV2, | 595 | prediv: PllPreDiv::DIV2, |
| @@ -486,9 +602,8 @@ pub fn config() -> Config { | |||
| 486 | 602 | ||
| 487 | #[cfg(any(feature = "stm32l552ze"))] | 603 | #[cfg(any(feature = "stm32l552ze"))] |
| 488 | { | 604 | { |
| 489 | use embassy_stm32::rcc::*; | ||
| 490 | config.rcc.hsi = true; | 605 | config.rcc.hsi = true; |
| 491 | config.rcc.mux = ClockSrc::PLL1_R; | 606 | config.rcc.sys = Sysclk::PLL1_R; |
| 492 | config.rcc.pll = Some(Pll { | 607 | config.rcc.pll = Some(Pll { |
| 493 | // 110Mhz clock (16 / 4 * 55 / 2) | 608 | // 110Mhz clock (16 / 4 * 55 / 2) |
| 494 | source: PllSource::HSI, | 609 | source: PllSource::HSI, |
| @@ -502,43 +617,103 @@ pub fn config() -> Config { | |||
| 502 | 617 | ||
| 503 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] | 618 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] |
| 504 | { | 619 | { |
| 505 | use embassy_stm32::rcc::*; | 620 | config.rcc.hsi = true; |
| 506 | config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); | 621 | config.rcc.pll1 = Some(Pll { |
| 622 | source: PllSource::HSI, // 16 MHz | ||
| 623 | prediv: PllPreDiv::DIV1, | ||
| 624 | mul: PllMul::MUL10, | ||
| 625 | divp: None, | ||
| 626 | divq: None, | ||
| 627 | divr: Some(PllDiv::DIV1), // 160 MHz | ||
| 628 | }); | ||
| 629 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 630 | config.rcc.voltage_range = VoltageScale::RANGE1; | ||
| 631 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 507 | } | 632 | } |
| 508 | 633 | ||
| 509 | #[cfg(feature = "stm32wba52cg")] | 634 | #[cfg(feature = "stm32wba52cg")] |
| 510 | { | 635 | { |
| 511 | use embassy_stm32::rcc::*; | 636 | config.rcc.sys = Sysclk::HSI; |
| 512 | config.rcc.mux = ClockSrc::HSI; | 637 | config.rcc.mux.rngsel = mux::Rngsel::HSI; |
| 513 | |||
| 514 | embassy_stm32::pac::RCC.ccipr2().write(|w| { | ||
| 515 | w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI); | ||
| 516 | }); | ||
| 517 | } | 638 | } |
| 518 | 639 | ||
| 519 | #[cfg(feature = "stm32l073rz")] | 640 | #[cfg(feature = "stm32l073rz")] |
| 520 | { | 641 | { |
| 521 | use embassy_stm32::rcc::*; | ||
| 522 | config.rcc.hsi = true; | 642 | config.rcc.hsi = true; |
| 523 | config.rcc.pll = Some(Pll { | 643 | config.rcc.pll = Some(Pll { |
| 524 | source: PllSource::HSI, | 644 | source: PllSource::HSI, |
| 525 | mul: PllMul::MUL4, | 645 | mul: PllMul::MUL4, |
| 526 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) | 646 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) |
| 527 | }); | 647 | }); |
| 528 | config.rcc.mux = ClockSrc::PLL1_R; | 648 | config.rcc.sys = Sysclk::PLL1_R; |
| 529 | } | 649 | } |
| 530 | 650 | ||
| 531 | #[cfg(any(feature = "stm32l152re"))] | 651 | #[cfg(any(feature = "stm32l152re"))] |
| 532 | { | 652 | { |
| 533 | use embassy_stm32::rcc::*; | ||
| 534 | config.rcc.hsi = true; | 653 | config.rcc.hsi = true; |
| 535 | config.rcc.pll = Some(Pll { | 654 | config.rcc.pll = Some(Pll { |
| 536 | source: PllSource::HSI, | 655 | source: PllSource::HSI, |
| 537 | mul: PllMul::MUL4, | 656 | mul: PllMul::MUL4, |
| 538 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) | 657 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) |
| 539 | }); | 658 | }); |
| 540 | config.rcc.mux = ClockSrc::PLL1_R; | 659 | config.rcc.sys = Sysclk::PLL1_R; |
| 660 | } | ||
| 661 | #[cfg(any(feature = "stm32h7s3l8"))] | ||
| 662 | { | ||
| 663 | config.rcc.hse = Some(Hse { | ||
| 664 | freq: Hertz(24_000_000), | ||
| 665 | mode: HseMode::Oscillator, | ||
| 666 | }); | ||
| 667 | config.rcc.pll1 = Some(Pll { | ||
| 668 | source: PllSource::HSE, | ||
| 669 | prediv: PllPreDiv::DIV3, | ||
| 670 | mul: PllMul::MUL150, | ||
| 671 | divp: Some(PllDiv::DIV2), // 600Mhz | ||
| 672 | divq: Some(PllDiv::DIV25), // 48Mhz | ||
| 673 | divr: None, | ||
| 674 | }); | ||
| 675 | config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz | ||
| 676 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz | ||
| 677 | config.rcc.apb1_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 678 | config.rcc.apb2_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 679 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 680 | config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 681 | config.rcc.voltage_scale = VoltageScale::HIGH; | ||
| 682 | config.rcc.mux.spi1sel = mux::Spi123sel::PLL1_Q; | ||
| 683 | } | ||
| 684 | #[cfg(any(feature = "stm32u083rc"))] | ||
| 685 | { | ||
| 686 | config.rcc.hsi = true; | ||
| 687 | config.rcc.pll = Some(Pll { | ||
| 688 | source: PllSource::HSI, // 16 MHz | ||
| 689 | prediv: PllPreDiv::DIV1, | ||
| 690 | mul: PllMul::MUL7, | ||
| 691 | divp: None, | ||
| 692 | divq: None, | ||
| 693 | divr: Some(PllRDiv::DIV2), // 56 MHz | ||
| 694 | }); | ||
| 695 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 696 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 697 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; // USB uses ICLK | ||
| 541 | } | 698 | } |
| 542 | 699 | ||
| 543 | config | 700 | config |
| 544 | } | 701 | } |
| 702 | |||
| 703 | #[allow(unused)] | ||
| 704 | pub fn init() -> embassy_stm32::Peripherals { | ||
| 705 | init_with_config(config()) | ||
| 706 | } | ||
| 707 | |||
| 708 | #[allow(unused)] | ||
| 709 | pub fn init_with_config(config: Config) -> embassy_stm32::Peripherals { | ||
| 710 | #[cfg(any(feature = "stm32wl55jc", feature = "stm32h755zi"))] | ||
| 711 | { | ||
| 712 | // Not in shared memory, but we're not running the second core, so it's fine | ||
| 713 | static SHARED_DATA: core::mem::MaybeUninit<embassy_stm32::SharedData> = core::mem::MaybeUninit::uninit(); | ||
| 714 | embassy_stm32::init_primary(config, &SHARED_DATA) | ||
| 715 | } | ||
| 716 | |||
| 717 | #[cfg(not(any(feature = "stm32wl55jc", feature = "stm32h755zi")))] | ||
| 718 | embassy_stm32::init(config) | ||
| 719 | } | ||
diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml index 7d66fd586..7b54a4f52 100644 --- a/tests/utils/Cargo.toml +++ b/tests/utils/Cargo.toml | |||
| @@ -3,8 +3,6 @@ name = "test-utils" | |||
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2021" |
| 5 | 5 | ||
| 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| 7 | |||
| 8 | [dependencies] | 6 | [dependencies] |
| 9 | rand = "0.8" | 7 | rand = "0.8" |
| 10 | serial = "0.4" | 8 | serial = "0.4" |
