aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Krull <[email protected]>2024-09-23 19:02:59 +0200
committerGitHub <[email protected]>2024-09-23 19:02:59 +0200
commita2c473306f4a7c8e99add2546450ab3a7a97436e (patch)
tree5522a708e492db7d4632dc0a56fe5057244f03f0 /tests
parente02a987bafd4f0fcf9d80e7c4f6e1504b8b02cec (diff)
parent2935290a6222536d6341103f91bfd732165d3862 (diff)
Merge branch 'embassy-rs:main' into multi-signal
Diffstat (limited to 'tests')
-rw-r--r--tests/nrf/.cargo/config.toml (renamed from tests/nrf52840/.cargo/config.toml)2
-rw-r--r--tests/nrf/Cargo.toml109
-rw-r--r--tests/nrf/build.rs37
-rw-r--r--tests/nrf/gen_test.py44
-rw-r--r--tests/nrf/memory-nrf51422.x5
-rw-r--r--tests/nrf/memory-nrf52832.x5
-rw-r--r--tests/nrf/memory-nrf52833.x5
-rw-r--r--tests/nrf/memory-nrf52840.x (renamed from tests/nrf52840/memory.x)0
-rw-r--r--tests/nrf/memory-nrf5340.x5
-rw-r--r--tests/nrf/memory-nrf9160.x5
-rw-r--r--tests/nrf/src/bin/buffered_uart.rs82
-rw-r--r--tests/nrf/src/bin/buffered_uart_full.rs (renamed from tests/nrf52840/src/bin/buffered_uart_full.rs)33
-rw-r--r--tests/nrf/src/bin/buffered_uart_halves.rs86
-rw-r--r--tests/nrf/src/bin/buffered_uart_spam.rs (renamed from tests/nrf52840/src/bin/buffered_uart_spam.rs)31
-rw-r--r--tests/nrf/src/bin/ethernet_enc28j60_perf.rs (renamed from tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs)17
-rw-r--r--tests/nrf/src/bin/gpio.rs (renamed from tests/nrf51422/src/bin/gpio.rs)9
-rw-r--r--tests/nrf/src/bin/gpiote.rs (renamed from tests/nrf51422/src/bin/gpiote.rs)11
-rw-r--r--tests/nrf/src/bin/timer.rs (renamed from tests/nrf51422/src/bin/timer.rs)4
-rw-r--r--tests/nrf/src/bin/uart_halves.rs41
-rw-r--r--tests/nrf/src/bin/uart_split.rs49
-rw-r--r--tests/nrf/src/bin/wifi_esp_hosted_perf.rs (renamed from tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs)16
-rw-r--r--tests/nrf/src/common.rs102
-rw-r--r--tests/nrf51422/.cargo/config.toml9
-rw-r--r--tests/nrf51422/Cargo.toml23
-rw-r--r--tests/nrf51422/build.rs17
-rw-r--r--tests/nrf51422/memory.x5
-rw-r--r--tests/nrf52840/Cargo.toml29
-rw-r--r--tests/nrf52840/build.rs17
-rw-r--r--tests/nrf52840/src/bin/buffered_uart.rs78
-rw-r--r--tests/perf-client/Cargo.toml4
-rw-r--r--tests/perf-client/src/lib.rs9
-rw-r--r--tests/riscv32/Cargo.toml10
-rw-r--r--tests/riscv32/link.x214
-rw-r--r--tests/rp/Cargo.toml10
-rw-r--r--tests/rp/src/bin/adc.rs13
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs25
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs18
-rw-r--r--tests/rp/src/bin/gpio_multicore.rs12
-rw-r--r--tests/rp/src/bin/i2c.rs94
-rw-r--r--tests/rp/src/bin/multicore.rs12
-rw-r--r--tests/rp/src/bin/pwm.rs54
-rw-r--r--tests/rp/src/bin/timer.rs (renamed from tests/nrf52840/src/bin/timer.rs)7
-rw-r--r--tests/stm32/.cargo/config.toml6
-rw-r--r--tests/stm32/Cargo.toml64
-rw-r--r--tests/stm32/build.rs12
-rw-r--r--tests/stm32/gen_test.py2
-rw-r--r--tests/stm32/src/bin/can.rs69
-rw-r--r--tests/stm32/src/bin/can_common.rs109
-rw-r--r--tests/stm32/src/bin/cordic.rs140
-rw-r--r--tests/stm32/src/bin/cryp.rs79
-rw-r--r--tests/stm32/src/bin/dac.rs10
-rw-r--r--tests/stm32/src/bin/dac_l1.rs4
-rw-r--r--tests/stm32/src/bin/eth.rs18
-rw-r--r--tests/stm32/src/bin/fdcan.rs259
-rw-r--r--tests/stm32/src/bin/gpio.rs13
-rw-r--r--tests/stm32/src/bin/hash.rs32
-rw-r--r--tests/stm32/src/bin/rng.rs9
-rw-r--r--tests/stm32/src/bin/rtc.rs2
-rw-r--r--tests/stm32/src/bin/sdmmc.rs2
-rw-r--r--tests/stm32/src/bin/spi.rs107
-rw-r--r--tests/stm32/src/bin/spi_dma.rs133
-rw-r--r--tests/stm32/src/bin/stop.rs9
-rw-r--r--tests/stm32/src/bin/timer.rs2
-rw-r--r--tests/stm32/src/bin/ucpd.rs120
-rw-r--r--tests/stm32/src/bin/usart.rs10
-rw-r--r--tests/stm32/src/bin/usart_dma.rs2
-rw-r--r--tests/stm32/src/bin/usart_rx_ringbuffered.rs7
-rw-r--r--tests/stm32/src/bin/wpan_ble.rs2
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs2
-rw-r--r--tests/stm32/src/common.rs251
-rw-r--r--tests/utils/Cargo.toml2
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 @@
3runner = "teleprobe client run" 3runner = "teleprobe client run"
4 4
5[build] 5[build]
6#target = "thumbv6m-none-eabi"
6target = "thumbv7em-none-eabi" 7target = "thumbv7em-none-eabi"
8#target = "thumbv8m.main-none-eabihf"
7 9
8[env] 10[env]
9DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" 11DEFMT_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]
2edition = "2021"
3name = "embassy-nrf-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8teleprobe-meta = "1"
9
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
11embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] }
12embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] }
13embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.2.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] }
15embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
16embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
17embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
18embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] }
19embedded-hal-async = { version = "1.0" }
20embedded-hal-bus = { version = "0.1", features = ["async"] }
21static_cell = "2"
22perf-client = { path = "../perf-client" }
23
24defmt = "0.3"
25defmt-rtt = "0.4"
26
27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
28cortex-m-rt = "0.7.0"
29panic-probe = { version = "0.3", features = ["print-defmt"] }
30portable-atomic = { version = "1.6.0" }
31
32[features]
33nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"]
34nrf52832 = ["embassy-nrf/nrf52832", "easydma"]
35nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"]
36nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"]
37nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"]
38nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"]
39
40easydma = []
41two-uarts = []
42
43[profile.release]
44codegen-units = 1
45debug = 2
46debug-assertions = false
47incremental = false
48lto = "fat"
49opt-level = 's'
50overflow-checks = false
51
52# BEGIN TESTS
53# Generated by gen_test.py. DO NOT EDIT.
54[[bin]]
55name = "buffered_uart"
56path = "src/bin/buffered_uart.rs"
57required-features = [ "easydma",]
58
59[[bin]]
60name = "buffered_uart_full"
61path = "src/bin/buffered_uart_full.rs"
62required-features = [ "easydma",]
63
64[[bin]]
65name = "buffered_uart_halves"
66path = "src/bin/buffered_uart_halves.rs"
67required-features = [ "two-uarts",]
68
69[[bin]]
70name = "buffered_uart_spam"
71path = "src/bin/buffered_uart_spam.rs"
72required-features = [ "two-uarts",]
73
74[[bin]]
75name = "ethernet_enc28j60_perf"
76path = "src/bin/ethernet_enc28j60_perf.rs"
77required-features = [ "nrf52840",]
78
79[[bin]]
80name = "gpio"
81path = "src/bin/gpio.rs"
82required-features = []
83
84[[bin]]
85name = "gpiote"
86path = "src/bin/gpiote.rs"
87required-features = []
88
89[[bin]]
90name = "timer"
91path = "src/bin/timer.rs"
92required-features = []
93
94[[bin]]
95name = "uart_halves"
96path = "src/bin/uart_halves.rs"
97required-features = [ "two-uarts",]
98
99[[bin]]
100name = "uart_split"
101path = "src/bin/uart_split.rs"
102required-features = [ "easydma",]
103
104[[bin]]
105name = "wifi_esp_hosted_perf"
106path = "src/bin/wifi_esp_hosted_perf.rs"
107required-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 @@
1use std::error::Error;
2use std::path::PathBuf;
3use std::{env, fs};
4
5fn 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 @@
1import os
2import toml
3from glob import glob
4
5abspath = os.path.abspath(__file__)
6dname = os.path.dirname(abspath)
7os.chdir(dname)
8
9# ======= load test list
10tests = {}
11for 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
23things = {
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
34SEPARATOR_START = '# BEGIN TESTS\n'
35SEPARATOR_END = '# END TESTS\n'
36HELP = '# Generated by gen_test.py. DO NOT EDIT.\n'
37with open('Cargo.toml', 'r') as f:
38 data = f.read()
39before, data = data.split(SEPARATOR_START, maxsplit=1)
40_, after = data.split(SEPARATOR_END, maxsplit=1)
41data = before + SEPARATOR_START + HELP + \
42 toml.dumps(things) + SEPARATOR_END + after
43with 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 @@
1MEMORY
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 @@
1MEMORY
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 @@
1MEMORY
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 @@
1MEMORY
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 @@
1MEMORY
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"]
6mod common;
7
8use defmt::{panic, *};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_nrf::buffered_uarte::{self, BufferedUarte};
12use embassy_nrf::{peripherals, uarte};
13use {defmt_rtt as _, panic_probe as _};
14
15#[embassy_executor::main]
16async 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]
3teleprobe_meta::target!(b"nrf52840-dk"); 4
5#[path = "../common.rs"]
6mod common;
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_nrf::buffered_uarte::{self, BufferedUarte}; 10use embassy_nrf::buffered_uarte::{self, BufferedUarte};
8use embassy_nrf::{bind_interrupts, peripherals, uarte}; 11use embassy_nrf::{peripherals, uarte};
9use embedded_io_async::{Read, Write}; 12use embedded_io_async::{Read, Write};
10use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
11 14
12bind_interrupts!(struct Irqs {
13 UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
14});
15
16#[embassy_executor::main] 15#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 16async 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"]
6mod common;
7
8use defmt::{assert_eq, *};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx};
12use embassy_nrf::{peripherals, uarte};
13use {defmt_rtt as _, panic_probe as _};
14
15#[embassy_executor::main]
16async 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]
3teleprobe_meta::target!(b"nrf52840-dk"); 4
5#[path = "../common.rs"]
6mod common;
4 7
5use core::mem; 8use core::mem;
6use core::ptr::NonNull; 9use core::ptr::NonNull;
7 10
8use defmt::{assert_eq, *}; 11use defmt::{assert_eq, *};
9use embassy_executor::Spawner; 12use embassy_executor::Spawner;
10use embassy_nrf::buffered_uarte::{self, BufferedUarte}; 13use embassy_nrf::buffered_uarte::{self, BufferedUarteRx};
11use embassy_nrf::gpio::{Level, Output, OutputDrive}; 14use embassy_nrf::gpio::{Level, Output, OutputDrive};
12use embassy_nrf::ppi::{Event, Ppi, Task}; 15use embassy_nrf::ppi::{Event, Ppi, Task};
13use embassy_nrf::uarte::Uarte; 16use embassy_nrf::uarte::UarteTx;
14use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; 17use embassy_nrf::{pac, peripherals, uarte};
15use embassy_time::Timer; 18use embassy_time::Timer;
16use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
17 20
18bind_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]
24async fn main(_spawner: Spawner) { 22async 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]
3teleprobe_meta::target!(b"ak-gwe-r7"); 4teleprobe_meta::target!(b"ak-gwe-r7");
@@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120);
5 6
6use defmt::{info, unwrap}; 7use defmt::{info, unwrap};
7use embassy_executor::Spawner; 8use embassy_executor::Spawner;
8use embassy_net::{Stack, StackResources}; 9use embassy_net::StackResources;
9use embassy_net_enc28j60::Enc28j60; 10use embassy_net_enc28j60::Enc28j60;
10use embassy_nrf::gpio::{Level, Output, OutputDrive}; 11use embassy_nrf::gpio::{Level, Output, OutputDrive};
11use embassy_nrf::rng::Rng; 12use embassy_nrf::rng::Rng;
@@ -24,8 +25,8 @@ bind_interrupts!(struct Irqs {
24type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; 25type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>;
25 26
26#[embassy_executor::task] 27#[embassy_executor::task]
27async fn net_task(stack: &'static Stack<MyDriver>) -> ! { 28async 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]
3teleprobe_meta::target!(b"nrf51-dk"); 3
4#[path = "../common.rs"]
5mod common;
4 6
5use defmt::{assert, info}; 7use defmt::{assert, info};
6use embassy_executor::Spawner; 8use embassy_executor::Spawner;
7use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
8use embassy_time::Timer; 10use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10 11
11#[embassy_executor::main] 12#[embassy_executor::main]
12async fn main(_spawner: Spawner) { 13async 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]
3teleprobe_meta::target!(b"nrf51-dk"); 3
4#[path = "../common.rs"]
5mod common;
4 6
5use defmt::{assert, info}; 7use defmt::{assert, info};
6use embassy_executor::Spawner; 8use embassy_executor::Spawner;
7use embassy_futures::join::join; 9use embassy_futures::join::join;
8use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 10use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
9use embassy_time::{Duration, Instant, Timer}; 11use embassy_time::{Duration, Instant, Timer};
10use {defmt_rtt as _, panic_probe as _};
11 12
12#[embassy_executor::main] 13#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 14async 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]
3teleprobe_meta::target!(b"nrf51-dk"); 3
4#[path = "../common.rs"]
5mod common;
4 6
5use defmt::{assert, info}; 7use defmt::{assert, info};
6use embassy_executor::Spawner; 8use 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"]
6mod common;
7
8use defmt::{assert_eq, *};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_nrf::uarte::{UarteRx, UarteTx};
12use embassy_nrf::{peripherals, uarte};
13use {defmt_rtt as _, panic_probe as _};
14
15#[embassy_executor::main]
16async 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"]
6mod common;
7
8use defmt::{assert_eq, *};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_nrf::uarte::Uarte;
12use embassy_nrf::{peripherals, uarte};
13use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _};
15
16#[embassy_executor::main]
17async 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]
3teleprobe_meta::target!(b"nrf52840-dk"); 4teleprobe_meta::target!(b"nrf52840-dk");
@@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120);
5 6
6use defmt::{info, unwrap}; 7use defmt::{info, unwrap};
7use embassy_executor::Spawner; 8use embassy_executor::Spawner;
8use embassy_net::{Config, Stack, StackResources}; 9use embassy_net::{Config, StackResources};
9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 10use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
10use embassy_nrf::rng::Rng; 11use embassy_nrf::rng::Rng;
11use embassy_nrf::spim::{self, Spim}; 12use embassy_nrf::spim::{self, Spim};
@@ -39,8 +40,8 @@ async fn wifi_task(
39type MyDriver = hosted::NetDriver<'static>; 40type MyDriver = hosted::NetDriver<'static>;
40 41
41#[embassy_executor::task] 42#[embassy_executor::task]
42async fn net_task(stack: &'static Stack<MyDriver>) -> ! { 43async 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
3use {defmt_rtt as _, panic_probe as _};
4
5#[cfg(feature = "nrf52832")]
6teleprobe_meta::target!(b"nrf52832-dk");
7#[cfg(feature = "nrf52840")]
8teleprobe_meta::target!(b"nrf52840-dk");
9#[cfg(feature = "nrf52833")]
10teleprobe_meta::target!(b"nrf52833-dk");
11#[cfg(feature = "nrf5340")]
12teleprobe_meta::target!(b"nrf5340-dk");
13#[cfg(feature = "nrf9160")]
14teleprobe_meta::target!(b"nrf9160-dk");
15#[cfg(feature = "nrf51422")]
16teleprobe_meta::target!(b"nrf51-dk");
17
18macro_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")]
50define_peris!(PIN_A = P0_13, PIN_B = P0_14,);
51
52#[cfg(feature = "nrf52832")]
53define_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")]
61define_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")]
72define_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")]
83define_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")]
94define_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"
3runner = "teleprobe client run"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_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]
2edition = "2021"
3name = "embassy-nrf51-tests"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8teleprobe-meta = "1"
9
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] }
12embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-128", "integrated-timers"] }
13embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "gpiote"] }
15embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
16embedded-hal-async = { version = "1.0" }
17
18defmt = "0.3"
19defmt-rtt = "0.4"
20
21cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
22cortex-m-rt = "0.7.0"
23panic-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 @@
1use std::error::Error;
2use std::path::PathBuf;
3use std::{env, fs};
4
5fn 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 @@
1MEMORY
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]
2edition = "2021"
3name = "embassy-nrf-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8teleprobe-meta = "1"
9
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] }
12embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] }
13embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
15embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
16embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
17embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
18embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] }
19embedded-hal-async = { version = "1.0" }
20embedded-hal-bus = { version = "0.1", features = ["async"] }
21static_cell = "2"
22perf-client = { path = "../perf-client" }
23
24defmt = "0.3"
25defmt-rtt = "0.4"
26
27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
28cortex-m-rt = "0.7.0"
29panic-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 @@
1use std::error::Error;
2use std::path::PathBuf;
3use std::{env, fs};
4
5fn 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]
3teleprobe_meta::target!(b"nrf52840-dk");
4
5use defmt::{assert_eq, *};
6use embassy_executor::Spawner;
7use embassy_futures::join::join;
8use embassy_nrf::buffered_uarte::{self, BufferedUarte};
9use embassy_nrf::{bind_interrupts, peripherals, uarte};
10use {defmt_rtt as _, panic_probe as _};
11
12bind_interrupts!(struct Irqs {
13 UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
14});
15
16#[embassy_executor::main]
17async 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"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "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]
9embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } 7embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
10embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } 8embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", ] }
11embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 9embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
12defmt = "0.3.0" 10defmt = "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
3use defmt::{assert, *}; 3use defmt::{assert, *};
4use embassy_futures::join::join; 4use embassy_futures::join::join;
5use embassy_net::driver::Driver;
6use embassy_net::tcp::TcpSocket; 5use embassy_net::tcp::TcpSocket;
7use embassy_net::{Ipv4Address, Stack}; 6use embassy_net::{Ipv4Address, Stack};
8use embassy_time::{with_timeout, Duration, Timer}; 7use 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
16pub async fn run<D: Driver>(stack: &Stack<D>, expected: Expected) { 15pub 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;
38const UPLOAD_PORT: u16 = 4322; 37const UPLOAD_PORT: u16 = 4322;
39const UPLOAD_DOWNLOAD_PORT: u16 = 4323; 38const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
40 39
41async fn test_download<D: Driver>(stack: &Stack<D>) -> usize { 40async 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
81async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize { 80async 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
121async fn test_upload_download<D: Driver>(stack: &Stack<D>) -> usize { 120async 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]
8critical-section = { version = "1.1.1", features = ["restore-state-bool"] } 8critical-section = { version = "1.1.1", features = ["restore-state-bool"] }
9embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } 9embassy-sync = { version = "0.6.0", path = "../../embassy-sync" }
10embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } 10embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] }
11embassy-time = { version = "0.3.0", path = "../../embassy-time" } 11embassy-time = { version = "0.3.2", path = "../../embassy-time" }
12embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 12embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
13 13
14riscv-rt = "0.11" 14riscv-rt = "0.12.2"
15riscv = { version = "0.10", features = ["critical-section-single-hart"] } 15riscv = { 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
29PROVIDE(_stext = ORIGIN(REGION_TEXT));
30PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
31PROVIDE(_max_hart_id = 0);
32PROVIDE(_hart_stack_size = 2K);
33PROVIDE(_heap_size = 0);
34
35PROVIDE(InstructionMisaligned = ExceptionHandler);
36PROVIDE(InstructionFault = ExceptionHandler);
37PROVIDE(IllegalInstruction = ExceptionHandler);
38PROVIDE(Breakpoint = ExceptionHandler);
39PROVIDE(LoadMisaligned = ExceptionHandler);
40PROVIDE(LoadFault = ExceptionHandler);
41PROVIDE(StoreMisaligned = ExceptionHandler);
42PROVIDE(StoreFault = ExceptionHandler);;
43PROVIDE(UserEnvCall = ExceptionHandler);
44PROVIDE(SupervisorEnvCall = ExceptionHandler);
45PROVIDE(MachineEnvCall = ExceptionHandler);
46PROVIDE(InstructionPageFault = ExceptionHandler);
47PROVIDE(LoadPageFault = ExceptionHandler);
48PROVIDE(StorePageFault = ExceptionHandler);
49
50PROVIDE(SupervisorSoft = DefaultHandler);
51PROVIDE(MachineSoft = DefaultHandler);
52PROVIDE(SupervisorTimer = DefaultHandler);
53PROVIDE(MachineTimer = DefaultHandler);
54PROVIDE(SupervisorExternal = DefaultHandler);
55PROVIDE(MachineExternal = DefaultHandler);
56
57PROVIDE(DefaultHandler = DefaultInterruptHandler);
58PROVIDE(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. */
63PROVIDE(__pre_init = default_pre_init);
64
65/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
66PROVIDE(_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*/
75PROVIDE(_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*/
81PROVIDE(_start_trap = default_start_trap);
82
83SECTIONS
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 | */
166ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
167ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
168
169ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
170ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
171
172ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
173ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
174
175ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
176ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
177
178ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
179ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
180
181ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
182ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
183
184ASSERT(_stext % 4 == 0, "
185ERROR(riscv-rt): `_stext` must be 4-byte aligned");
186
187ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
188BUG(riscv-rt): .data is not 4-byte aligned");
189
190ASSERT(_sidata % 4 == 0, "
191BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
192
193ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
194BUG(riscv-rt): .bss is not 4-byte aligned");
195
196ASSERT(_sheap % 4 == 0, "
197BUG(riscv-rt): start of .heap is not 4-byte aligned");
198
199ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
200ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
201Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
202
203ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
204ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
205Consider changing `_max_hart_id` or `_hart_stack_size`.");
206
207ASSERT(SIZEOF(.got) == 0, "
208.got section detected in the input files. Dynamic relocations are not
209supported. If you are linking to C code compiled using the `gcc` crate
210then modify your build script to compile the C code _without_ the
211-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
212details.");
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]
8teleprobe-meta = "1.1" 8teleprobe-meta = "1.1"
9 9
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } 12embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", ] }
13embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } 13embassy-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"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 15embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
17embassy-embedded-hal = { version = "0.2.0", path = "../../embassy-embedded-hal/"}
17cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } 18cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
18cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } 19cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] }
19perf-client = { path = "../perf-client" } 20perf-client = { path = "../perf-client" }
@@ -28,7 +29,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
28embedded-hal-async = { version = "1.0" } 29embedded-hal-async = { version = "1.0" }
29embedded-hal-bus = { version = "0.1", features = ["async"] } 30embedded-hal-bus = { version = "0.1", features = ["async"] }
30panic-probe = { version = "0.3.0", features = ["print-defmt"] } 31panic-probe = { version = "0.3.0", features = ["print-defmt"] }
31futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
32embedded-io-async = { version = "0.6.1" } 32embedded-io-async = { version = "0.6.1" }
33embedded-storage = { version = "0.3" } 33embedded-storage = { version = "0.3" }
34static_cell = "2" 34static_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]
3teleprobe_meta::target!(b"rpi-pico"); 3teleprobe_meta::target!(b"rpi-pico");
4 4
5use cyw43::JoinOptions;
5use cyw43_pio::PioSpi; 6use cyw43_pio::PioSpi;
6use defmt::{panic, *}; 7use defmt::{panic, *};
7use embassy_executor::Spawner; 8use embassy_executor::Spawner;
8use embassy_net::{Config, Stack, StackResources}; 9use embassy_net::{Config, StackResources};
9use embassy_rp::gpio::{Level, Output}; 10use embassy_rp::gpio::{Level, Output};
10use embassy_rp::peripherals::{DMA_CH0, PIO0}; 11use embassy_rp::peripherals::{DMA_CH0, PIO0};
11use embassy_rp::pio::{InterruptHandler, Pio}; 12use 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]
32async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! { 33async 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
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_net::{Stack, StackResources}; 8use embassy_net::StackResources;
9use embassy_net_wiznet::chip::W5100S; 9use embassy_net_wiznet::chip::W5100S;
10use embassy_net_wiznet::*; 10use embassy_net_wiznet::*;
11use embassy_rp::clocks::RoscRng; 11use embassy_rp::clocks::RoscRng;
@@ -32,8 +32,8 @@ async fn ethernet_task(
32} 32}
33 33
34#[embassy_executor::task] 34#[embassy_executor::task]
35async fn net_task(stack: &'static Stack<Device<'static>>) -> ! { 35async 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]
22fn main() -> ! { 22fn main() -> ! {
23 let p = embassy_rp::init(Default::default()); 23 let p = embassy_rp::init(Default::default());
24 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 24 spawn_core1(
25 let executor1 = EXECUTOR1.init(Executor::new()); 25 p.CORE1,
26 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); 26 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
27 }); 27 move || {
28 let executor1 = EXECUTOR1.init(Executor::new());
29 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1))));
30 },
31 );
28 let executor0 = EXECUTOR0.init(Executor::new()); 32 let executor0 = EXECUTOR0.init(Executor::new());
29 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); 33 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0))));
30} 34}
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
index a0aed1a42..9615007bd 100644
--- a/tests/rp/src/bin/i2c.rs
+++ b/tests/rp/src/bin/i2c.rs
@@ -3,7 +3,10 @@
3teleprobe_meta::target!(b"rpi-pico"); 3teleprobe_meta::target!(b"rpi-pico");
4 4
5use defmt::{assert_eq, info, panic, unwrap}; 5use defmt::{assert_eq, info, panic, unwrap};
6use embassy_executor::Executor; 6use embassy_embedded_hal::SetConfig;
7use embassy_executor::{Executor, Spawner};
8use embassy_rp::clocks::{PllConfig, XoscConfig};
9use embassy_rp::config::Config as rpConfig;
7use embassy_rp::multicore::{spawn_core1, Stack}; 10use embassy_rp::multicore::{spawn_core1, Stack};
8use embassy_rp::peripherals::{I2C0, I2C1}; 11use embassy_rp::peripherals::{I2C0, I2C1};
9use embassy_rp::{bind_interrupts, i2c, i2c_slave}; 12use embassy_rp::{bind_interrupts, i2c, i2c_slave};
@@ -13,7 +16,6 @@ use static_cell::StaticCell;
13use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _};
14 17
15static mut CORE1_STACK: Stack<1024> = Stack::new(); 18static mut CORE1_STACK: Stack<1024> = Stack::new();
16static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
17static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); 19static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
18 20
19use crate::i2c::AbortReason; 21use 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] 108async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
108async 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.
187fn 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]
20fn main() -> ! { 20fn main() -> ! {
21 let p = embassy_rp::init(Default::default()); 21 let p = embassy_rp::init(Default::default());
22 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 22 spawn_core1(
23 let executor1 = EXECUTOR1.init(Executor::new()); 23 p.CORE1,
24 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); 24 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
25 }); 25 move || {
26 let executor1 = EXECUTOR1.init(Executor::new());
27 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task())));
28 },
29 );
26 let executor0 = EXECUTOR0.init(Executor::new()); 30 let executor0 = EXECUTOR0.init(Executor::new());
27 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 31 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));
28} 32}
diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs
index e71d9e610..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]
3teleprobe_meta::target!(b"nrf52840-dk"); 3teleprobe_meta::target!(b"rpi-pico");
4 4
5use defmt::{assert, info}; 5use defmt::{assert, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_time::{Instant, Timer}; 7use embassy_time::{Instant, Timer};
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
10#[embassy_executor::main] 10#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 11async 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"))']
6runner = "teleprobe client run" 6runner = "teleprobe client run"
7#runner = "teleprobe local run --chip STM32F103C8 --elf" 7#runner = "teleprobe local run --chip STM32H7S3L8Hx --elf"
8 8
9rustflags = [ 9rustflags = [
10 # Code-size optimizations. 10 # Code-size optimizations.
@@ -14,9 +14,9 @@ rustflags = [
14] 14]
15 15
16[build] 16[build]
17target = "thumbv6m-none-eabi" 17#target = "thumbv6m-none-eabi"
18#target = "thumbv7m-none-eabi" 18#target = "thumbv7m-none-eabi"
19#target = "thumbv7em-none-eabi" 19target = "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]
9stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] 9stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
10stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] 10stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma"]
11stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] 11stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"]
12stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] 12stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"]
13stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] 13stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"]
14stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] 14stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"]
15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] 15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"]
16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"] 16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"]
17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"] 17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"]
18stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"] 18stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"]
19stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash"] 19stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"]
20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash"] 20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"]
21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"] 21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"]
22stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] 22stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"]
23stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] 23stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma"]
24stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] 24stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"]
25stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] 25stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"]
26stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] 26stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"]
27stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] 27stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"]
28stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng", "hash"] 28stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"]
29stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] 29stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash
30stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] 30stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"]
31stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] 31stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"]
32stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] 32stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"]
33 33stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
34stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"]
35stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs.
36stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"]
37
38spi-v1 = []
39spi-v345 = []
40cryp = []
34hash = [] 41hash = []
35eth = ["embassy-executor/task-arena-size-16384"] 42eth = ["embassy-executor/task-arena-size-16384"]
36rng = [] 43rng = []
@@ -44,15 +51,17 @@ mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"]
44embassy-stm32-wpan = [] 51embassy-stm32-wpan = []
45not-gpdma = [] 52not-gpdma = []
46dac = [] 53dac = []
54ucpd = []
55cordic = ["dep:num-traits"]
47 56
48cm0 = ["portable-atomic/unsafe-assume-single-core"] 57cm0 = ["portable-atomic/unsafe-assume-single-core"]
49 58
50[dependencies] 59[dependencies]
51teleprobe-meta = "1" 60teleprobe-meta = "1"
52 61
53embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 62embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] }
54embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 63embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
55embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } 64embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] }
56embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } 65embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] }
57embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 66embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
58embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } 67embassy-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"
67embedded-hal = "0.2.6" 76embedded-hal = "0.2.6"
68embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 77embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
69embedded-hal-async = { version = "1.0" } 78embedded-hal-async = { version = "1.0" }
79embedded-can = { version = "0.4" }
70micromath = "2.0.0" 80micromath = "2.0.0"
71panic-probe = { version = "0.3.0", features = ["print-defmt"] } 81panic-probe = { version = "0.3.0", features = ["print-defmt"] }
72rand_core = { version = "0.6", default-features = false } 82rand_core = { version = "0.6", default-features = false }
@@ -76,6 +86,9 @@ portable-atomic = { version = "1.5", features = [] }
76 86
77chrono = { version = "^0.4", default-features = false, optional = true} 87chrono = { version = "^0.4", default-features = false, optional = true}
78sha2 = { version = "0.10.8", default-features = false } 88sha2 = { version = "0.10.8", default-features = false }
89hmac = "0.12.1"
90aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] }
91num-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"
85required-features = [ "can",] 98required-features = [ "can",]
86 99
87[[bin]] 100[[bin]]
101name = "cordic"
102path = "src/bin/cordic.rs"
103required-features = [ "rng", "cordic",]
104
105[[bin]]
106name = "cryp"
107path = "src/bin/cryp.rs"
108required-features = [ "cryp",]
109
110[[bin]]
88name = "dac" 111name = "dac"
89path = "src/bin/dac.rs" 112path = "src/bin/dac.rs"
90required-features = [ "dac",] 113required-features = [ "dac",]
@@ -150,6 +173,11 @@ path = "src/bin/timer.rs"
150required-features = [] 173required-features = []
151 174
152[[bin]] 175[[bin]]
176name = "ucpd"
177path = "src/bin/ucpd.rs"
178required-features = [ "ucpd",]
179
180[[bin]]
153name = "usart" 181name = "usart"
154path = "src/bin/usart.rs" 182path = "src/bin/usart.rs"
155required-features = [] 183required-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"]
7mod common; 7mod common;
8use common::*; 8use common::*;
9use defmt::assert;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::bind_interrupts; 10use embassy_stm32::bind_interrupts;
12use embassy_stm32::can::bxcan::filter::Mask32; 11use embassy_stm32::can::filter::Mask32;
13use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; 12use embassy_stm32::can::{Fifo, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler};
14use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler};
15use embassy_stm32::gpio::{Input, Pull}; 13use embassy_stm32::gpio::{Input, Pull};
16use embassy_stm32::peripherals::CAN1; 14use embassy_stm32::peripherals::CAN1;
17use embassy_time::{Duration, Instant}; 15use embassy_time::Duration;
18use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
19 17
18mod can_common;
19use can_common::*;
20
20bind_interrupts!(struct Irqs { 21bind_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]
28async fn main(_spawner: Spawner) { 29async 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 @@
1use defmt::{assert, *};
2use embassy_stm32::can;
3use embassy_time::{Duration, Instant};
4
5#[derive(Clone, Copy, Debug)]
6pub struct TestOptions {
7 pub max_latency: Duration,
8 pub max_buffered: u8,
9}
10
11pub async fn run_can_tests<'d>(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
83pub 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"]
9mod common;
10use common::*;
11use embassy_executor::Spawner;
12use embassy_stm32::cordic::utils;
13use embassy_stm32::{bind_interrupts, cordic, peripherals, rng};
14use num_traits::Float;
15use {defmt_rtt as _, panic_probe as _};
16
17bind_interrupts!(struct Irqs {
18 RNG => rng::InterruptHandler<peripherals::RNG>;
19});
20
21/* input value control, can be changed */
22
23const INPUT_U32_COUNT: usize = 9;
24const 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.
28const OUTPUT_LENGTH: usize = (INPUT_U32_COUNT - 1) * 2;
29
30#[embassy_executor::main]
31async 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"]
6mod common;
7
8use aes_gcm::aead::heapless::Vec;
9use aes_gcm::aead::{AeadInPlace, KeyInit};
10use aes_gcm::Aes128Gcm;
11use common::*;
12use embassy_executor::Spawner;
13use embassy_stm32::cryp::{self, *};
14use embassy_stm32::{bind_interrupts, peripherals};
15use {defmt_rtt as _, panic_probe as _};
16
17bind_interrupts!(struct Irqs {
18 CRYP => cryp::InterruptHandler<peripherals::CRYP>;
19});
20
21#[embassy_executor::main]
22async 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;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::Adc;
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma; 15use embassy_stm32::dma::NoDma;
16use embassy_time::{Delay, Timer}; 16use embassy_time::Timer;
17use micromath::F32Ext; 17use micromath::F32Ext;
18use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
19 19
20#[embassy_executor::main] 20#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 21async 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;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21bind_interrupts!(struct Irqs { 21bind_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]
26async fn main(_spawner: Spawner) { 26async 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 @@
6mod common; 6mod common;
7use common::*; 7use common::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_net::{Stack, StackResources}; 9use embassy_net::StackResources;
10use embassy_stm32::eth::generic_smi::GenericSMI; 10use embassy_stm32::eth::generic_smi::GenericSMI;
11use embassy_stm32::eth::{Ethernet, PacketQueue}; 11use embassy_stm32::eth::{Ethernet, PacketQueue};
12use embassy_stm32::peripherals::ETH; 12use embassy_stm32::peripherals::ETH;
@@ -32,13 +32,13 @@ bind_interrupts!(struct Irqs {
32type Device = Ethernet<'static, ETH, GenericSMI>; 32type Device = Ethernet<'static, ETH, GenericSMI>;
33 33
34#[embassy_executor::task] 34#[embassy_executor::task]
35async fn net_task(stack: &'static Stack<Device>) -> ! { 35async 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]
40async fn main(spawner: Spawner) { 40async 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"]
7mod common; 7mod common;
8use common::*; 8use common::*;
9use defmt::assert;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::peripherals::*; 10use embassy_stm32::peripherals::*;
12use embassy_stm32::{bind_interrupts, can, Config}; 11use embassy_stm32::{bind_interrupts, can, Config};
13use embassy_time::{Duration, Instant}; 12use embassy_time::Duration;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16bind_interrupts!(struct Irqs { 15mod can_common;
16use can_common::*;
17
18bind_interrupts!(struct Irqs2 {
19 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
20 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;
21});
22bind_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
21struct TestOptions { 27#[cfg(feature = "stm32h563zi")]
22 config: Config, 28fn 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"))]
28fn options() -> TestOptions { 40fn 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"))]
45fn options() -> TestOptions { 59fn 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"))]
78fn 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"))]
62fn options() -> TestOptions { 92fn 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]
72async fn main(_spawner: Spawner) { 104async 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]
12async fn main(_spawner: Spawner) { 12async 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
218fn delay() { 218fn 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;
9use embassy_stm32::dma::NoDma; 9use embassy_stm32::dma::NoDma;
10use embassy_stm32::hash::*; 10use embassy_stm32::hash::*;
11use embassy_stm32::{bind_interrupts, hash, peripherals}; 11use embassy_stm32::{bind_interrupts, hash, peripherals};
12use hmac::{Hmac, Mac};
12use sha2::{Digest, Sha224, Sha256}; 13use sha2::{Digest, Sha224, Sha256};
13use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
14 15
16type HmacSha256 = Hmac<Sha256>;
17
15#[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32h753zi"))] 18#[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32h753zi"))]
16bind_interrupts!(struct Irqs { 19bind_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))]
27bind_interrupts!(struct Irqs { 32bind_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]
32async fn main(_spawner: Spawner) { 37async 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 {
23bind_interrupts!(struct Irqs { 23bind_interrupts!(struct Irqs {
24 RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>; 24 RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>;
25}); 25});
26#[cfg(any(feature = "stm32u083rc"))]
27bind_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)))]
33bind_interrupts!(struct Irqs { 38bind_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]
38async fn main(_spawner: Spawner) { 43async 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 {
20async fn main(_spawner: Spawner) { 20async 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;
6use common::*; 6use common::*;
7use defmt::assert_eq; 7use defmt::assert_eq;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::dma::NoDma; 9use embassy_stm32::gpio::{Level, Output, Speed};
10use embassy_stm32::spi::{self, Spi}; 10use embassy_stm32::mode::Blocking;
11use embassy_stm32::spi::{self, Spi, Word};
11use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
12 13
13#[embassy_executor::main] 14#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 15async 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
68fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>)
69where
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"); 112fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>, mosi_out: &mut Output<'_>)
63 cortex_m::asm::bkpt(); 113where
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
128fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>)
129where
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;
6use common::*; 6use common::*;
7use defmt::assert_eq; 7use defmt::assert_eq;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::spi::{self, Spi}; 9use embassy_stm32::gpio::{Level, Output, Speed};
10use embassy_stm32::mode::Async;
11use embassy_stm32::spi::{self, Spi, Word};
10use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
11 13
12#[embassy_executor::main] 14#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 15async 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
75async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>)
76where
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"); 139async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>, mosi_out: &mut Output<'_>)
80 cortex_m::asm::bkpt(); 140where
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
165async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>)
166where
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]
12async fn main(_spawner: Spawner) { 12async 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"]
5mod common;
6
7use common::*;
8use defmt::{assert, assert_eq};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd};
12use embassy_stm32::{bind_interrupts, peripherals};
13use embassy_time::Timer;
14
15bind_interrupts!(struct Irqs {
16 UCPD1_2 => ucpd::InterruptHandler<peripherals::UCPD1>, ucpd::InterruptHandler<peripherals::UCPD2>;
17});
18
19static SRC_TO_SNK: [u8; 6] = [0, 1, 2, 3, 4, 5];
20static SNK_TO_SRC: [u8; 4] = [9, 8, 7, 6];
21
22async 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
29async 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
66async 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]
104async 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;
6use common::*; 6use common::*;
7use defmt::{assert, assert_eq, unreachable}; 7use defmt::{assert, assert_eq, unreachable};
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::dma::NoDma;
10use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; 9use embassy_stm32::usart::{Config, ConfigError, Error, Uart};
11use embassy_time::{block_for, Duration, Instant}; 10use embassy_time::{block_for, Duration, Instant};
12 11
13#[embassy_executor::main] 12#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 13async 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]
13async fn main(_spawner: Spawner) { 13async 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;
8use common::*; 8use common::*;
9use defmt::{assert_eq, panic}; 9use defmt::{assert_eq, panic};
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_stm32::mode::Async;
11use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; 12use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx};
12use embassy_time::Timer; 13use embassy_time::Timer;
13use rand_chacha::ChaCha8Rng; 14use rand_chacha::ChaCha8Rng;
@@ -17,7 +18,7 @@ const DMA_BUF_SIZE: usize = 256;
17 18
18#[embassy_executor::main] 19#[embassy_executor::main]
19async fn main(spawner: Spawner) { 20async 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]
54async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { 55async 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]
77async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UART_RX_DMA>) { 78async 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
3pub use defmt::*; 3pub use defmt::*;
4#[allow(unused)] 4#[allow(unused)]
5use embassy_stm32::rcc::*;
6#[allow(unused)]
5use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
6use embassy_stm32::Config; 8use embassy_stm32::Config;
7use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -54,6 +56,14 @@ teleprobe_meta::target!(b"nucleo-stm32l496zg");
54teleprobe_meta::target!(b"nucleo-stm32wl55jc"); 56teleprobe_meta::target!(b"nucleo-stm32wl55jc");
55#[cfg(feature = "stm32wba52cg")] 57#[cfg(feature = "stm32wba52cg")]
56teleprobe_meta::target!(b"nucleo-stm32wba52cg"); 58teleprobe_meta::target!(b"nucleo-stm32wba52cg");
59#[cfg(feature = "stm32f091rc")]
60teleprobe_meta::target!(b"nucleo-stm32f091rc");
61#[cfg(feature = "stm32h503rb")]
62teleprobe_meta::target!(b"nucleo-stm32h503rb");
63#[cfg(feature = "stm32h7s3l8")]
64teleprobe_meta::target!(b"nucleo-stm32h7s3l8");
65#[cfg(feature = "stm32u083rc")]
66teleprobe_meta::target!(b"nucleo-stm32u083rc");
57 67
58macro_rules! define_peris { 68macro_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")]
99define_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")]
89define_peris!( 105define_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!(
108define_peris!( 124define_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!(
116define_peris!( 132define_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"))]
130define_peris!( 146define_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")]
178define_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")]
161define_peris!( 184define_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!(
191define_peris!( 214define_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")]
257define_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")]
264define_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
234pub fn config() -> Config { 270pub 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)]
704pub fn init() -> embassy_stm32::Peripherals {
705 init_with_config(config())
706}
707
708#[allow(unused)]
709pub 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"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "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]
9rand = "0.8" 7rand = "0.8"
10serial = "0.4" 8serial = "0.4"