aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDion Dokter <[email protected]>2025-11-20 13:22:38 +0100
committerDion Dokter <[email protected]>2025-11-20 13:22:38 +0100
commit4f2c36e447455e8d33607d586859d3d075cabf1d (patch)
tree003cd822d688acd7c074dd229663b4648d100f71 /tests
parent663732d85abbae400f2dbab2c411802a5b60e9b1 (diff)
parent661874d11de7d93ed52e08e020a9d4c7ee11122d (diff)
Merge branch 'main' into u0-lcd
Diffstat (limited to 'tests')
-rw-r--r--tests/mspm0/.cargo/config.toml (renamed from tests/nrf51422/.cargo/config.toml)3
-rw-r--r--tests/mspm0/Cargo.toml68
-rw-r--r--tests/mspm0/build.rs (renamed from tests/nrf52840/build.rs)14
-rw-r--r--tests/mspm0/memory_g3507.x6
-rw-r--r--tests/mspm0/memory_g3519.x6
-rw-r--r--tests/mspm0/src/bin/dma.rs503
-rw-r--r--tests/mspm0/src/bin/uart.rs86
-rw-r--r--tests/mspm0/src/bin/uart_buffered.rs115
-rw-r--r--tests/nrf/.cargo/config.toml (renamed from tests/nrf52840/.cargo/config.toml)6
-rw-r--r--tests/nrf/Cargo.toml125
-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.rs (renamed from tests/nrf52840/src/bin/buffered_uart.rs)33
-rw-r--r--tests/nrf/src/bin/buffered_uart_full.rs (renamed from tests/nrf52840/src/bin/buffered_uart_full.rs)31
-rw-r--r--tests/nrf/src/bin/buffered_uart_halves.rs (renamed from tests/nrf52840/src/bin/buffered_uart_halves.rs)34
-rw-r--r--tests/nrf/src/bin/buffered_uart_spam.rs (renamed from tests/nrf52840/src/bin/buffered_uart_spam.rs)49
-rw-r--r--tests/nrf/src/bin/ethernet_enc28j60_perf.rs (renamed from tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs)19
-rw-r--r--tests/nrf/src/bin/gpio.rs (renamed from tests/nrf51422/src/bin/gpio.rs)11
-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/spim.rs42
-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.rs51
-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)33
-rw-r--r--tests/nrf/src/common.rs117
-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/perf-client/Cargo.toml12
-rw-r--r--tests/perf-client/src/lib.rs11
-rw-r--r--tests/perf-server/Cargo.toml4
-rw-r--r--tests/riscv32/Cargo.toml16
-rw-r--r--tests/rp/.cargo/config.toml7
-rw-r--r--tests/rp/Cargo.toml71
-rw-r--r--tests/rp/readme.md8
-rw-r--r--tests/rp/src/bin/adc.rs57
-rw-r--r--tests/rp/src/bin/bootsel.rs5
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs54
-rw-r--r--tests/rp/src/bin/dma_copy_async.rs3
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs21
-rw-r--r--tests/rp/src/bin/flash.rs19
-rw-r--r--tests/rp/src/bin/gpio.rs84
-rw-r--r--tests/rp/src/bin/gpio_async.rs27
-rw-r--r--tests/rp/src/bin/gpio_multicore.rs16
-rw-r--r--tests/rp/src/bin/i2c.rs25
-rw-r--r--tests/rp/src/bin/multicore.rs9
-rw-r--r--tests/rp/src/bin/overclock.rs69
-rw-r--r--tests/rp/src/bin/pio_irq.rs6
-rw-r--r--tests/rp/src/bin/pio_multi_load.rs21
-rw-r--r--tests/rp/src/bin/pwm.rs61
-rw-r--r--tests/rp/src/bin/rtc.rs125
-rw-r--r--tests/rp/src/bin/spi.rs3
-rw-r--r--tests/rp/src/bin/spi_async.rs3
-rw-r--r--tests/rp/src/bin/spinlock_mutex_multicore.rs54
-rw-r--r--tests/rp/src/bin/timer.rs (renamed from tests/nrf52840/src/bin/timer.rs)10
-rw-r--r--tests/rp/src/bin/uart.rs23
-rw-r--r--tests/rp/src/bin/uart_buffered.rs47
-rw-r--r--tests/rp/src/bin/uart_dma.rs47
-rw-r--r--tests/rp/src/bin/uart_upgrade.rs3
-rw-r--r--tests/stm32/.cargo/config.toml1
-rw-r--r--tests/stm32/Cargo.toml111
-rw-r--r--tests/stm32/build.rs1
-rw-r--r--tests/stm32/src/bin/afio.rs1158
-rw-r--r--tests/stm32/src/bin/can.rs5
-rw-r--r--tests/stm32/src/bin/cordic.rs6
-rw-r--r--tests/stm32/src/bin/cryp.rs6
-rw-r--r--tests/stm32/src/bin/dac.rs14
-rw-r--r--tests/stm32/src/bin/dac_l1.rs16
-rw-r--r--tests/stm32/src/bin/eeprom.rs30
-rw-r--r--tests/stm32/src/bin/eth.rs33
-rw-r--r--tests/stm32/src/bin/fdcan.rs7
-rw-r--r--tests/stm32/src/bin/gpio.rs48
-rw-r--r--tests/stm32/src/bin/hash.rs49
-rw-r--r--tests/stm32/src/bin/hsem.rs50
-rw-r--r--tests/stm32/src/bin/rng.rs2
-rw-r--r--tests/stm32/src/bin/rtc.rs25
-rw-r--r--tests/stm32/src/bin/sdmmc.rs56
-rw-r--r--tests/stm32/src/bin/spi.rs109
-rw-r--r--tests/stm32/src/bin/spi_dma.rs137
-rw-r--r--tests/stm32/src/bin/stop.rs35
-rw-r--r--tests/stm32/src/bin/timer.rs2
-rw-r--r--tests/stm32/src/bin/ucpd.rs16
-rw-r--r--tests/stm32/src/bin/usart.rs17
-rw-r--r--tests/stm32/src/bin/usart_dma.rs19
-rw-r--r--tests/stm32/src/bin/usart_rx_ringbuffered.rs9
-rw-r--r--tests/stm32/src/bin/wpan_ble.rs8
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs6
-rw-r--r--tests/stm32/src/can_common.rs (renamed from tests/stm32/src/bin/can_common.rs)0
-rw-r--r--tests/stm32/src/common.rs40
-rw-r--r--tests/utils/Cargo.toml6
-rw-r--r--tests/utils/src/bin/saturate_serial.rs7
98 files changed, 3860 insertions, 686 deletions
diff --git a/tests/nrf51422/.cargo/config.toml b/tests/mspm0/.cargo/config.toml
index 634805633..825bf3ae9 100644
--- a/tests/nrf51422/.cargo/config.toml
+++ b/tests/mspm0/.cargo/config.toml
@@ -1,6 +1,5 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2#runner = "teleprobe local run --chip nRF51422_xxAA --elf" 2runner = "teleprobe local run --chip MSPM0G3507 --protocol swd --elf"
3runner = "teleprobe client run"
4 3
5[build] 4[build]
6target = "thumbv6m-none-eabi" 5target = "thumbv6m-none-eabi"
diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml
new file mode 100644
index 000000000..df52b538d
--- /dev/null
+++ b/tests/mspm0/Cargo.toml
@@ -0,0 +1,68 @@
1[package]
2edition = "2024"
3name = "embassy-mspm0-tests"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6publish = false
7
8[features]
9mspm0g3507 = [ "embassy-mspm0/mspm0g3507pm" ]
10mspm0g3519 = [ "embassy-mspm0/mspm0g3519pz" ]
11
12[dependencies]
13teleprobe-meta = "1.1"
14
15embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = [ "defmt" ] }
16embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] }
17embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
18embassy-time = { version = "0.5.0", path = "../../embassy-time", features = [ "defmt" ] }
19embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [ "rt", "defmt", "unstable-pac", "time-driver-any" ] }
20embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"}
21
22defmt = "1.0.1"
23defmt-rtt = "1.0.0"
24
25cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-single-core" ]}
26cortex-m-rt = "0.7.0"
27embedded-hal = { package = "embedded-hal", version = "1.0" }
28embedded-hal-async = { version = "1.0" }
29embedded-io = { version = "0.6.1", features = ["defmt-03"] }
30embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
31panic-probe = { version = "1.0.0", features = ["print-defmt"] }
32static_cell = "2"
33portable-atomic = { version = "1.5", features = ["critical-section"] }
34
35[profile.dev]
36debug = 2
37debug-assertions = true
38opt-level = 's'
39overflow-checks = true
40
41[profile.release]
42codegen-units = 1
43debug = 2
44debug-assertions = false
45incremental = false
46lto = "fat"
47opt-level = 's'
48overflow-checks = false
49
50# do not optimize proc-macro crates = faster builds from scratch
51[profile.dev.build-override]
52codegen-units = 8
53debug = false
54debug-assertions = false
55opt-level = 0
56overflow-checks = false
57
58[profile.release.build-override]
59codegen-units = 8
60debug = false
61debug-assertions = false
62opt-level = 0
63overflow-checks = false
64
65[package.metadata.embassy]
66build = [
67 { target = "thumbv6m-none-eabi", features = ["mspm0g3507"], artifact-dir = "out/tests/mspm0g3507" }
68]
diff --git a/tests/nrf52840/build.rs b/tests/mspm0/build.rs
index 71c82a70f..43a9ac04f 100644
--- a/tests/nrf52840/build.rs
+++ b/tests/mspm0/build.rs
@@ -4,14 +4,26 @@ use std::{env, fs};
4 4
5fn main() -> Result<(), Box<dyn Error>> { 5fn main() -> Result<(), Box<dyn Error>> {
6 let out = PathBuf::from(env::var("OUT_DIR").unwrap()); 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(); 7
8 #[cfg(feature = "mspm0g3507")]
9 let memory_x = include_bytes!("memory_g3507.x");
10
11 #[cfg(feature = "mspm0g3519")]
12 let memory_x = include_bytes!("memory_g3519.x");
13
14 fs::write(out.join("memory.x"), memory_x).unwrap();
15
8 println!("cargo:rustc-link-search={}", out.display()); 16 println!("cargo:rustc-link-search={}", out.display());
9 println!("cargo:rerun-if-changed=link_ram.x"); 17 println!("cargo:rerun-if-changed=link_ram.x");
18 // copy main linker script.
19 fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap();
10 20
11 println!("cargo:rustc-link-arg-bins=--nmagic"); 21 println!("cargo:rustc-link-arg-bins=--nmagic");
12 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); 22 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x");
13 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 23 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
14 println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); 24 println!("cargo:rustc-link-arg-bins=-Tteleprobe.x");
25 // You must tell cargo to link interrupt groups if the rt feature is enabled.
26 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
15 27
16 Ok(()) 28 Ok(())
17} 29}
diff --git a/tests/mspm0/memory_g3507.x b/tests/mspm0/memory_g3507.x
new file mode 100644
index 000000000..37e381fbd
--- /dev/null
+++ b/tests/mspm0/memory_g3507.x
@@ -0,0 +1,6 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 128K
4 /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */
5 RAM : ORIGIN = 0x20200000, LENGTH = 32K
6}
diff --git a/tests/mspm0/memory_g3519.x b/tests/mspm0/memory_g3519.x
new file mode 100644
index 000000000..d62f10360
--- /dev/null
+++ b/tests/mspm0/memory_g3519.x
@@ -0,0 +1,6 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 128K
4 /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */
5 RAM : ORIGIN = 0x20200000, LENGTH = 64K
6}
diff --git a/tests/mspm0/src/bin/dma.rs b/tests/mspm0/src/bin/dma.rs
new file mode 100644
index 000000000..9c56acadc
--- /dev/null
+++ b/tests/mspm0/src/bin/dma.rs
@@ -0,0 +1,503 @@
1#![no_std]
2#![no_main]
3
4#[cfg(feature = "mspm0g3507")]
5teleprobe_meta::target!(b"lp-mspm0g3507");
6
7#[cfg(feature = "mspm0g3519")]
8teleprobe_meta::target!(b"lp-mspm0g3519");
9
10use core::slice;
11
12use defmt::{assert, assert_eq, *};
13use embassy_executor::Spawner;
14use embassy_mspm0::Peri;
15use embassy_mspm0::dma::{Channel, Transfer, TransferMode, TransferOptions, Word};
16use {defmt_rtt as _, panic_probe as _};
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let mut p = embassy_mspm0::init(Default::default());
21 info!("Hello World!");
22
23 {
24 info!("Single u8 read (blocking)");
25 single_read(p.DMA_CH0.reborrow(), 0x41_u8);
26
27 info!("Single u16 read (blocking)");
28 single_read(p.DMA_CH0.reborrow(), 0xFF41_u16);
29
30 info!("Single u32 read (blocking)");
31 single_read(p.DMA_CH0.reborrow(), 0xFFEE_FF41_u32);
32
33 info!("Single u64 read (blocking)");
34 single_read(p.DMA_CH0.reborrow(), 0x0011_2233_FFEE_FF41_u64);
35 }
36
37 // Widening transfers
38 {
39 info!("Single u8 read to u16");
40 widening_single_read::<u8, u16>(p.DMA_CH0.reborrow(), 0x41);
41
42 info!("Single u8 read to u32");
43 widening_single_read::<u8, u32>(p.DMA_CH0.reborrow(), 0x43);
44
45 info!("Single u8 read to u64");
46 widening_single_read::<u8, u64>(p.DMA_CH0.reborrow(), 0x47);
47
48 info!("Single u16 read to u32");
49 widening_single_read::<u16, u32>(p.DMA_CH0.reborrow(), 0xAE43);
50
51 info!("Single u16 read to u64");
52 widening_single_read::<u16, u64>(p.DMA_CH0.reborrow(), 0xAF47);
53
54 info!("Single u32 read to u64");
55 widening_single_read::<u32, u64>(p.DMA_CH0.reborrow(), 0xDEAD_AF47);
56 }
57
58 // Narrowing transfers.
59 {
60 info!("Single u16 read to u8");
61 narrowing_single_read::<u16, u8>(p.DMA_CH0.reborrow(), 0x4142);
62
63 info!("Single u32 read to u8");
64 narrowing_single_read::<u32, u8>(p.DMA_CH0.reborrow(), 0x4142_2414);
65
66 info!("Single u64 read to u8");
67 narrowing_single_read::<u64, u8>(p.DMA_CH0.reborrow(), 0x4142_2414_5153_7776);
68
69 info!("Single u32 read to u16");
70 narrowing_single_read::<u32, u16>(p.DMA_CH0.reborrow(), 0x4142_2414);
71
72 info!("Single u64 read to u16");
73 narrowing_single_read::<u64, u16>(p.DMA_CH0.reborrow(), 0x4142_2414_5153_7776);
74
75 info!("Single u64 read to u32");
76 narrowing_single_read::<u64, u32>(p.DMA_CH0.reborrow(), 0x4142_2414_5153_7776);
77 }
78
79 {
80 info!("Single u8 read (async)");
81 async_single_read(p.DMA_CH0.reborrow(), 0x42_u8).await;
82
83 info!("Single u16 read (async)");
84 async_single_read(p.DMA_CH0.reborrow(), 0xAE42_u16).await;
85
86 info!("Single u32 read (async)");
87 async_single_read(p.DMA_CH0.reborrow(), 0xFE44_1500_u32).await;
88
89 info!("Single u64 read (async)");
90 async_single_read(p.DMA_CH0.reborrow(), 0x8F7F_6F5F_4F3F_2F1F_u64).await;
91 }
92
93 {
94 info!("Multiple u8 reads (blocking)");
95 block_read::<_, 16>(p.DMA_CH0.reborrow(), 0x98_u8);
96
97 info!("Multiple u16 reads (blocking)");
98 block_read::<_, 2>(p.DMA_CH0.reborrow(), 0x9801_u16);
99
100 info!("Multiple u32 reads (blocking)");
101 block_read::<_, 4>(p.DMA_CH0.reborrow(), 0x9821_9801_u32);
102
103 info!("Multiple u64 reads (blocking)");
104 block_read::<_, 4>(p.DMA_CH0.reborrow(), 0xABCD_EF01_2345_6789_u64);
105 }
106
107 {
108 info!("Multiple u8 reads (async)");
109 async_block_read::<_, 8>(p.DMA_CH0.reborrow(), 0x86_u8).await;
110
111 info!("Multiple u16 reads (async)");
112 async_block_read::<_, 6>(p.DMA_CH0.reborrow(), 0x7777_u16).await;
113
114 info!("Multiple u32 reads (async)");
115 async_block_read::<_, 3>(p.DMA_CH0.reborrow(), 0xA5A5_A5A5_u32).await;
116
117 info!("Multiple u64 reads (async)");
118 async_block_read::<_, 14>(p.DMA_CH0.reborrow(), 0x5A5A_5A5A_A5A5_A5A5_u64).await;
119 }
120
121 // Intentionally skip testing multiple reads in single transfer mode.
122 //
123 // If the destination length is greater than 1 and single transfer mode is used then two transfers
124 // are performed in a trigger. Similarly with any other length of destination above 2, only 2 transfers
125 // are performed. Issuing another trigger (resume) results in no further progress. More than likely
126 // the test does not work due to some combination of a hardware bug and the datasheet being unclear
127 // regarding what ends a software trigger.
128 //
129 // However this case works fine with a hardware trigger (such as the ADC hardware trigger).
130
131 {
132 info!("Single u8 write (blocking)");
133 single_write(p.DMA_CH0.reborrow(), 0x41_u8);
134
135 info!("Single u16 write (blocking)");
136 single_write(p.DMA_CH0.reborrow(), 0x4142_u16);
137
138 info!("Single u32 write (blocking)");
139 single_write(p.DMA_CH0.reborrow(), 0x4142_4344_u32);
140
141 info!("Single u64 write (blocking)");
142 single_write(p.DMA_CH0.reborrow(), 0x4142_4344_4546_4748_u64);
143 }
144
145 {
146 info!("Single u8 write (async)");
147 async_single_write(p.DMA_CH0.reborrow(), 0xAA_u8).await;
148
149 info!("Single u16 write (async)");
150 async_single_write(p.DMA_CH0.reborrow(), 0xBBBB_u16).await;
151
152 info!("Single u32 write (async)");
153 async_single_write(p.DMA_CH0.reborrow(), 0xCCCC_CCCC_u32).await;
154
155 info!("Single u64 write (async)");
156 async_single_write(p.DMA_CH0.reborrow(), 0xDDDD_DDDD_DDDD_DDDD_u64).await;
157 }
158
159 {
160 info!("Multiple u8 writes (blocking)");
161 block_write(p.DMA_CH0.reborrow(), &[0xFF_u8, 0x7F, 0x3F, 0x1F]);
162
163 info!("Multiple u16 writes (blocking)");
164 block_write(p.DMA_CH0.reborrow(), &[0xFFFF_u16, 0xFF7F, 0xFF3F, 0xFF1F]);
165
166 info!("Multiple u32 writes (blocking)");
167 block_write(
168 p.DMA_CH0.reborrow(),
169 &[0xFF00_00FF_u32, 0xFF00_007F, 0x0000_FF3F, 0xFF1F_0000],
170 );
171
172 info!("Multiple u64 writes (blocking)");
173 block_write(
174 p.DMA_CH0.reborrow(),
175 &[
176 0xFF00_0000_0000_00FF_u64,
177 0x0000_FF00_007F_0000,
178 0x0000_FF3F_0000_0000,
179 0xFF1F_0000_1111_837A,
180 ],
181 );
182 }
183
184 {
185 info!("Multiple u8 writes (async)");
186 async_block_write(p.DMA_CH0.reborrow(), &[0u8, 1, 2, 3]).await;
187
188 info!("Multiple u16 writes (async)");
189 async_block_write(p.DMA_CH0.reborrow(), &[0x9801u16, 0x9802, 0x9803, 0x9800, 0x9000]).await;
190
191 info!("Multiple u32 writes (async)");
192 async_block_write(p.DMA_CH0.reborrow(), &[0x9801_ABCDu32, 0xFFAC_9802, 0xDEAD_9803]).await;
193
194 info!("Multiple u64 writes (async)");
195 async_block_write(
196 p.DMA_CH0.reborrow(),
197 &[
198 0xA55A_1111_3333_5555_u64,
199 0x1111_A55A_3333_5555,
200 0x5555_A55A_3333_1111,
201 0x01234_5678_89AB_CDEF,
202 ],
203 )
204 .await;
205 }
206
207 // TODO: Mixed byte and word transfers.
208
209 info!("Test OK");
210 cortex_m::asm::bkpt();
211}
212
213fn single_read<W: Word + Copy + Default + Eq + defmt::Format>(mut channel: Peri<'_, impl Channel>, mut src: W) {
214 let options = TransferOptions::default();
215 let mut dst = W::default();
216
217 // SAFETY: src and dst outlive the transfer.
218 let transfer = unsafe {
219 unwrap!(Transfer::new_read(
220 channel.reborrow(),
221 Transfer::SOFTWARE_TRIGGER,
222 &mut src,
223 slice::from_mut(&mut dst),
224 options,
225 ))
226 };
227 transfer.blocking_wait();
228
229 assert_eq!(src, dst);
230}
231
232async fn async_single_read<W: Word + Copy + Default + Eq + defmt::Format>(
233 mut channel: Peri<'_, impl Channel>,
234 mut src: W,
235) {
236 let options = TransferOptions::default();
237 let mut dst = W::default();
238
239 // SAFETY: src and dst outlive the transfer.
240 let transfer = unsafe {
241 unwrap!(Transfer::new_read(
242 channel.reborrow(),
243 Transfer::SOFTWARE_TRIGGER,
244 &mut src,
245 slice::from_mut(&mut dst),
246 options,
247 ))
248 };
249 transfer.await;
250
251 assert_eq!(src, dst);
252}
253
254fn block_read<W: Word + Copy + Default + Eq + defmt::Format, const N: usize>(
255 mut channel: Peri<'_, impl Channel>,
256 mut src: W,
257) {
258 let mut options = TransferOptions::default();
259 // Complete the entire transfer.
260 options.mode = TransferMode::Block;
261
262 let mut dst = [W::default(); N];
263
264 // SAFETY: src and dst outlive the transfer.
265 let transfer = unsafe {
266 unwrap!(Transfer::new_read(
267 channel.reborrow(),
268 Transfer::SOFTWARE_TRIGGER,
269 &mut src,
270 &mut dst[..],
271 options,
272 ))
273 };
274 transfer.blocking_wait();
275
276 assert_eq!(dst, [src; N]);
277}
278
279async fn async_block_read<W: Word + Copy + Default + Eq + defmt::Format, const N: usize>(
280 mut channel: Peri<'_, impl Channel>,
281 mut src: W,
282) {
283 let mut options = TransferOptions::default();
284 // Complete the entire transfer.
285 options.mode = TransferMode::Block;
286
287 let mut dst = [W::default(); N];
288
289 // SAFETY: src and dst outlive the transfer.
290 let transfer = unsafe {
291 unwrap!(Transfer::new_read(
292 channel.reborrow(),
293 Transfer::SOFTWARE_TRIGGER,
294 &mut src,
295 &mut dst[..],
296 options,
297 ))
298 };
299 transfer.await;
300
301 assert_eq!(dst, [src; N]);
302}
303
304fn single_write<W: Word + Default + Eq + defmt::Format>(mut channel: Peri<'_, impl Channel>, src: W) {
305 let options = TransferOptions::default();
306 let mut dst = W::default();
307
308 // SAFETY: src and dst outlive the transfer.
309 let transfer = unsafe {
310 unwrap!(Transfer::new_write(
311 channel.reborrow(),
312 Transfer::SOFTWARE_TRIGGER,
313 slice::from_ref(&src),
314 &mut dst,
315 options,
316 ))
317 };
318 transfer.blocking_wait();
319
320 assert_eq!(src, dst);
321}
322
323async fn async_single_write<W: Word + Default + Eq + defmt::Format>(mut channel: Peri<'_, impl Channel>, src: W) {
324 let options = TransferOptions::default();
325 let mut dst = W::default();
326
327 // SAFETY: src and dst outlive the transfer.
328 let transfer = unsafe {
329 unwrap!(Transfer::new_write(
330 channel.reborrow(),
331 Transfer::SOFTWARE_TRIGGER,
332 slice::from_ref(&src),
333 &mut dst,
334 options,
335 ))
336 };
337 transfer.await;
338
339 assert_eq!(src, dst);
340}
341
342fn block_write<W: Word + Default + Eq + defmt::Format>(mut channel: Peri<'_, impl Channel>, src: &[W]) {
343 let mut options = TransferOptions::default();
344 // Complete the entire transfer.
345 options.mode = TransferMode::Block;
346
347 let mut dst = W::default();
348
349 // Starting from 1 because a zero length transfer does nothing.
350 for i in 1..src.len() {
351 info!("-> {} write(s)", i);
352
353 // SAFETY: src and dst outlive the transfer.
354 let transfer = unsafe {
355 unwrap!(Transfer::new_write(
356 channel.reborrow(),
357 Transfer::SOFTWARE_TRIGGER,
358 &src[..i],
359 &mut dst,
360 options,
361 ))
362 };
363 transfer.blocking_wait();
364
365 // The result will be the last value written.
366 assert_eq!(dst, src[i - 1]);
367 }
368}
369
370async fn async_block_write<W: Word + Default + Eq + defmt::Format>(mut channel: Peri<'_, impl Channel>, src: &[W]) {
371 let mut options = TransferOptions::default();
372 // Complete the entire transfer.
373 options.mode = TransferMode::Block;
374
375 let mut dst = W::default();
376
377 // Starting from 1 because a zero length transfer does nothing.
378 for i in 1..src.len() {
379 info!("-> {} write(s)", i);
380 // SAFETY: src and dst outlive the transfer.
381 let transfer = unsafe {
382 unwrap!(Transfer::new_write(
383 channel.reborrow(),
384 Transfer::SOFTWARE_TRIGGER,
385 &src[..i],
386 &mut dst,
387 options,
388 ))
389 };
390 transfer.await;
391
392 // The result will be the last value written.
393 assert_eq!(dst, src[i - 1]);
394 }
395}
396
397/// [`single_read`], but testing when the destination is wider than the source.
398///
399/// The MSPM0 DMA states that the upper bytes when the destination is longer than the source are zeroed.
400/// This matches the behavior in Rust for all unsigned integer types.
401fn widening_single_read<SW, DW>(mut channel: Peri<'_, impl Channel>, mut src: SW)
402where
403 SW: Word + Copy + Default + Eq + defmt::Format,
404 DW: Word + Copy + Default + Eq + defmt::Format + From<SW>,
405{
406 assert!(
407 DW::size() > SW::size(),
408 "This test only works when the destination is larger than the source"
409 );
410
411 let options = TransferOptions::default();
412 let mut dst = DW::default();
413
414 // SAFETY: src and dst outlive the transfer.
415 let transfer = unsafe {
416 unwrap!(Transfer::new_read(
417 channel.reborrow(),
418 Transfer::SOFTWARE_TRIGGER,
419 &mut src,
420 slice::from_mut(&mut dst),
421 options,
422 ))
423 };
424 transfer.blocking_wait();
425
426 assert_eq!(DW::from(src), dst);
427}
428
429/// [`single_read`], but testing when the destination is narrower than the source.
430///
431/// The MSPM0 DMA states that the upper bytes when the source is longer than the destination are dropped.
432/// This matches the behavior in Rust for all unsigned integer types.
433fn narrowing_single_read<SW, DW>(mut channel: Peri<'_, impl Channel>, mut src: SW)
434where
435 SW: Word + Copy + Default + Eq + defmt::Format + From<DW>,
436 DW: Word + Copy + Default + Eq + defmt::Format + Narrow<SW>,
437{
438 assert!(
439 SW::size() > DW::size(),
440 "This test only works when the source is larger than the destination"
441 );
442
443 let options = TransferOptions::default();
444 let mut dst = DW::default();
445
446 // SAFETY: src and dst outlive the transfer.
447 let transfer = unsafe {
448 unwrap!(Transfer::new_read(
449 channel.reborrow(),
450 Transfer::SOFTWARE_TRIGGER,
451 &mut src,
452 slice::from_mut(&mut dst),
453 options,
454 ))
455 };
456 transfer.blocking_wait();
457
458 // The expected value is the source value masked by the maximum destination value.
459 // This is effectively `src as DW as SW` to drop the upper byte(s).
460 let expect = SW::from(DW::narrow(src));
461 assert_eq!(expect, dst.into());
462}
463
464/// A pseudo `as` trait to allow downcasting integer types (TryFrom could fail).
465trait Narrow<T> {
466 fn narrow(value: T) -> Self;
467}
468
469impl Narrow<u16> for u8 {
470 fn narrow(value: u16) -> Self {
471 value as u8
472 }
473}
474
475impl Narrow<u32> for u8 {
476 fn narrow(value: u32) -> Self {
477 value as u8
478 }
479}
480
481impl Narrow<u64> for u8 {
482 fn narrow(value: u64) -> Self {
483 value as u8
484 }
485}
486
487impl Narrow<u32> for u16 {
488 fn narrow(value: u32) -> Self {
489 value as u16
490 }
491}
492
493impl Narrow<u64> for u16 {
494 fn narrow(value: u64) -> Self {
495 value as u16
496 }
497}
498
499impl Narrow<u64> for u32 {
500 fn narrow(value: u64) -> Self {
501 value as u32
502 }
503}
diff --git a/tests/mspm0/src/bin/uart.rs b/tests/mspm0/src/bin/uart.rs
new file mode 100644
index 000000000..916ce0d4b
--- /dev/null
+++ b/tests/mspm0/src/bin/uart.rs
@@ -0,0 +1,86 @@
1#![no_std]
2#![no_main]
3
4#[cfg(feature = "mspm0g3507")]
5teleprobe_meta::target!(b"lp-mspm0g3507");
6
7#[cfg(feature = "mspm0g3519")]
8teleprobe_meta::target!(b"lp-mspm0g3519");
9
10use defmt::{assert_eq, unwrap, *};
11use embassy_executor::Spawner;
12use embassy_mspm0::mode::Blocking;
13use embassy_mspm0::uart::{ClockSel, Config, Error, Uart};
14use {defmt_rtt as _, panic_probe as _};
15
16fn read<const N: usize>(uart: &mut Uart<'_, Blocking>) -> Result<[u8; N], Error> {
17 let mut buf = [255; N];
18 uart.blocking_read(&mut buf)?;
19 Ok(buf)
20}
21
22#[embassy_executor::main]
23async fn main(_spawner: Spawner) {
24 let p = embassy_mspm0::init(Default::default());
25 info!("Hello World!");
26
27 // TODO: Allow creating a looped-back UART (so pins are not needed).
28 // Do not select default UART since the virtual COM port is attached to UART0.
29 #[cfg(any(feature = "mspm0g3507", feature = "mspm0g3519"))]
30 let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1);
31
32 const MFCLK_BUAD_RATES: &[u32] = &[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200];
33
34 for &rate in MFCLK_BUAD_RATES {
35 info!("{} baud using MFCLK", rate);
36
37 let mut config = Config::default();
38 // MSPM0 hardware supports a loopback mode to allow self test.
39 config.loop_back_enable = true;
40 config.baudrate = rate;
41
42 let mut uart = unwrap!(Uart::new_blocking(
43 uart.reborrow(),
44 rx.reborrow(),
45 tx.reborrow(),
46 config
47 ));
48
49 // We can't send too many bytes, they have to fit in the FIFO.
50 // This is because we aren't sending+receiving at the same time.
51
52 let data = [0xC0, 0xDE];
53 unwrap!(uart.blocking_write(&data));
54 assert_eq!(unwrap!(read(&mut uart)), data);
55 }
56
57 // 9600 is the maximum possible value for 32.768 kHz.
58 const LFCLK_BAUD_RATES: &[u32] = &[1200, 2400, 4800, 9600];
59
60 for &rate in LFCLK_BAUD_RATES {
61 info!("{} baud using LFCLK", rate);
62
63 let mut config = Config::default();
64 // MSPM0 hardware supports a loopback mode to allow self test.
65 config.loop_back_enable = true;
66 config.baudrate = rate;
67 config.clock_source = ClockSel::LfClk;
68
69 let mut uart = expect!(Uart::new_blocking(
70 uart.reborrow(),
71 rx.reborrow(),
72 tx.reborrow(),
73 config,
74 ));
75
76 // We can't send too many bytes, they have to fit in the FIFO.
77 // This is because we aren't sending+receiving at the same time.
78
79 let data = [0xC0, 0xDE];
80 unwrap!(uart.blocking_write(&data));
81 assert_eq!(unwrap!(read(&mut uart)), data);
82 }
83
84 info!("Test OK");
85 cortex_m::asm::bkpt();
86}
diff --git a/tests/mspm0/src/bin/uart_buffered.rs b/tests/mspm0/src/bin/uart_buffered.rs
new file mode 100644
index 000000000..135ac1287
--- /dev/null
+++ b/tests/mspm0/src/bin/uart_buffered.rs
@@ -0,0 +1,115 @@
1#![no_std]
2#![no_main]
3
4#[cfg(feature = "mspm0g3507")]
5teleprobe_meta::target!(b"lp-mspm0g3507");
6
7use defmt::{assert_eq, unwrap, *};
8use embassy_executor::Spawner;
9use embassy_mspm0::uart::{BufferedInterruptHandler, BufferedUart, Config};
10use embassy_mspm0::{bind_interrupts, peripherals};
11use {defmt_rtt as _, panic_probe as _};
12
13bind_interrupts!(struct Irqs {
14 UART1 => BufferedInterruptHandler<peripherals::UART1>;
15});
16
17#[embassy_executor::main]
18async fn main(_spawner: Spawner) {
19 let p = embassy_mspm0::init(Default::default());
20 info!("Hello World!");
21
22 // TODO: Allow creating a looped-back UART (so pins are not needed).
23 // Do not select default UART since the virtual COM port is attached to UART0.
24 #[cfg(any(feature = "mspm0g3507"))]
25 let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1);
26
27 {
28 use embedded_io_async::{Read, Write};
29
30 let mut config = Config::default();
31 config.loop_back_enable = true;
32 config.fifo_enable = false;
33
34 let tx_buf = &mut [0u8; 16];
35 let rx_buf = &mut [0u8; 16];
36 let mut uart = unwrap!(BufferedUart::new(
37 uart.reborrow(),
38 tx.reborrow(),
39 rx.reborrow(),
40 Irqs,
41 tx_buf,
42 rx_buf,
43 config
44 ));
45
46 let mut buf = [0; 16];
47 for (j, b) in buf.iter_mut().enumerate() {
48 *b = j as u8;
49 }
50
51 unwrap!(uart.write_all(&buf).await);
52 unwrap!(uart.flush().await);
53
54 unwrap!(uart.read_exact(&mut buf).await);
55 for (j, b) in buf.iter().enumerate() {
56 assert_eq!(*b, j as u8);
57 }
58
59 // Buffer is unclogged, should be able to write again.
60 unwrap!(uart.write_all(&buf).await);
61 unwrap!(uart.flush().await);
62
63 unwrap!(uart.read_exact(&mut buf).await);
64 for (j, b) in buf.iter().enumerate() {
65 assert_eq!(*b, j as u8);
66 }
67 }
68
69 info!("Blocking buffered");
70 {
71 use embedded_io::{Read, Write};
72
73 let mut config = Config::default();
74 config.loop_back_enable = true;
75 config.fifo_enable = false;
76
77 let tx_buf = &mut [0u8; 16];
78 let rx_buf = &mut [0u8; 16];
79 let mut uart = unwrap!(BufferedUart::new(
80 uart.reborrow(),
81 tx.reborrow(),
82 rx.reborrow(),
83 Irqs,
84 tx_buf,
85 rx_buf,
86 config
87 ));
88
89 let mut buf = [0; 16];
90
91 for (j, b) in buf.iter_mut().enumerate() {
92 *b = j as u8;
93 }
94
95 unwrap!(uart.write_all(&buf));
96 unwrap!(uart.blocking_flush());
97 unwrap!(uart.read_exact(&mut buf));
98
99 for (j, b) in buf.iter().enumerate() {
100 assert_eq!(*b, j as u8);
101 }
102
103 // Buffer is unclogged, should be able to write again.
104 unwrap!(uart.write_all(&buf));
105 unwrap!(uart.blocking_flush());
106 unwrap!(uart.read_exact(&mut buf));
107
108 for (j, b) in buf.iter().enumerate() {
109 assert_eq!(*b, j as u8, "at {}", j);
110 }
111 }
112
113 info!("Test OK");
114 cortex_m::asm::bkpt();
115}
diff --git a/tests/nrf52840/.cargo/config.toml b/tests/nrf/.cargo/config.toml
index 9d6b0313a..0192c10ae 100644
--- a/tests/nrf52840/.cargo/config.toml
+++ b/tests/nrf/.cargo/config.toml
@@ -1,9 +1,11 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2#runner = "teleprobe local run --chip nRF52840_xxAA --elf" 2runner = "teleprobe local run --chip nRF52840_xxAA --elf"
3runner = "teleprobe client run" 3#runner = "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..3a9b86cef
--- /dev/null
+++ b/tests/nrf/Cargo.toml
@@ -0,0 +1,125 @@
1[package]
2edition = "2024"
3name = "embassy-nrf-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6publish = false
7
8[dependencies]
9teleprobe-meta = "1"
10
11embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
12embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt", ] }
13embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
14embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
15embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] }
16embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
17embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
18embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
19embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] }
20embedded-hal-async = { version = "1.0" }
21embedded-hal-bus = { version = "0.1", features = ["async"] }
22static_cell = "2"
23perf-client = { path = "../perf-client" }
24
25defmt = "1.0.1"
26defmt-rtt = "1.0.0"
27
28cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
29cortex-m-rt = "0.7.0"
30panic-probe = { version = "1.0.0", features = ["print-defmt"] }
31portable-atomic = { version = "1.6.0" }
32
33[features]
34nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"]
35nrf52832 = ["embassy-nrf/nrf52832", "easydma"]
36nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"]
37nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"]
38nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"]
39nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"]
40
41easydma = []
42two-uarts = []
43
44[profile.release]
45codegen-units = 1
46debug = 2
47debug-assertions = false
48incremental = false
49lto = "fat"
50opt-level = 's'
51overflow-checks = false
52
53# BEGIN TESTS
54# Generated by gen_test.py. DO NOT EDIT.
55[[bin]]
56name = "buffered_uart"
57path = "src/bin/buffered_uart.rs"
58required-features = [ "easydma",]
59
60[[bin]]
61name = "buffered_uart_full"
62path = "src/bin/buffered_uart_full.rs"
63required-features = [ "easydma",]
64
65[[bin]]
66name = "buffered_uart_halves"
67path = "src/bin/buffered_uart_halves.rs"
68required-features = [ "two-uarts",]
69
70[[bin]]
71name = "buffered_uart_spam"
72path = "src/bin/buffered_uart_spam.rs"
73required-features = [ "two-uarts",]
74
75[[bin]]
76name = "ethernet_enc28j60_perf"
77path = "src/bin/ethernet_enc28j60_perf.rs"
78required-features = [ "nrf52840",]
79
80[[bin]]
81name = "gpio"
82path = "src/bin/gpio.rs"
83required-features = []
84
85[[bin]]
86name = "gpiote"
87path = "src/bin/gpiote.rs"
88required-features = []
89
90[[bin]]
91name = "spim"
92path = "src/bin/spim.rs"
93required-features = [ "easydma",]
94
95[[bin]]
96name = "timer"
97path = "src/bin/timer.rs"
98required-features = []
99
100[[bin]]
101name = "uart_halves"
102path = "src/bin/uart_halves.rs"
103required-features = [ "two-uarts",]
104
105[[bin]]
106name = "uart_split"
107path = "src/bin/uart_split.rs"
108required-features = [ "easydma",]
109
110[[bin]]
111name = "wifi_esp_hosted_perf"
112path = "src/bin/wifi_esp_hosted_perf.rs"
113required-features = [ "nrf52840",]
114
115# END TESTS
116
117[package.metadata.embassy]
118build = [
119 { target = "thumbv6m-none-eabi", features = ["nrf51422"], artifact-dir = "out/tests/nrf51422-dk" },
120 { target = "thumbv7em-none-eabi", features = ["nrf52832"], artifact-dir = "out/tests/nrf52832-dk" },
121 { target = "thumbv7em-none-eabi", features = ["nrf52833"], artifact-dir = "out/tests/nrf52833-dk" },
122 { target = "thumbv7em-none-eabi", features = ["nrf52840"], artifact-dir = "out/tests/nrf52840-dk" },
123 { target = "thumbv8m.main-none-eabihf", features = ["nrf5340"], artifact-dir = "out/tests/nrf5340-dk" },
124 { target = "thumbv8m.main-none-eabihf", features = ["nrf9160"], artifact-dir = "out/tests/nrf9160-dk" }
125]
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/nrf52840/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs
index a01d66d85..8c4827464 100644
--- a/tests/nrf52840/src/bin/buffered_uart.rs
+++ b/tests/nrf/src/bin/buffered_uart.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 4
5use defmt::{assert_eq, *}; 5#[path = "../common.rs"]
6mod common;
7
8use defmt::{panic, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_futures::join::join; 10use embassy_futures::join::join;
8use embassy_nrf::buffered_uarte::{self, BufferedUarte}; 11use embassy_nrf::buffered_uarte::{self, BufferedUarte};
9use embassy_nrf::{bind_interrupts, peripherals, uarte}; 12use embassy_nrf::{peripherals, uarte};
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 mut p = embassy_nrf::init(Default::default()); 17 let mut p = embassy_nrf::init(Default::default());
@@ -26,14 +25,14 @@ async fn main(_spawner: Spawner) {
26 // test teardown + recreate of the buffereduarte works fine. 25 // test teardown + recreate of the buffereduarte works fine.
27 for _ in 0..2 { 26 for _ in 0..2 {
28 let u = BufferedUarte::new( 27 let u = BufferedUarte::new(
29 &mut p.UARTE0, 28 peri!(p, UART0).reborrow(),
30 &mut p.TIMER0, 29 p.TIMER0.reborrow(),
31 &mut p.PPI_CH0, 30 p.PPI_CH0.reborrow(),
32 &mut p.PPI_CH1, 31 p.PPI_CH1.reborrow(),
33 &mut p.PPI_GROUP0, 32 p.PPI_GROUP0.reborrow(),
34 Irqs, 33 peri!(p, PIN_A).reborrow(),
35 &mut p.P1_03, 34 peri!(p, PIN_B).reborrow(),
36 &mut p.P1_02, 35 irqs!(UART0_BUFFERED),
37 config.clone(), 36 config.clone(),
38 &mut rx_buffer, 37 &mut rx_buffer,
39 &mut tx_buffer, 38 &mut tx_buffer,
@@ -64,7 +63,9 @@ async fn main(_spawner: Spawner) {
64 let buf = unwrap!(rx.fill_buf().await); 63 let buf = unwrap!(rx.fill_buf().await);
65 64
66 for &b in buf { 65 for &b in buf {
67 assert_eq!(b, i as u8); 66 if b != i as u8 {
67 panic!("mismatch {} vs {}, index {}", b, i as u8, i);
68 }
68 i = i + 1; 69 i = i + 1;
69 } 70 }
70 71
diff --git a/tests/nrf52840/src/bin/buffered_uart_full.rs b/tests/nrf/src/bin/buffered_uart_full.rs
index 62edaed25..e0f41b891 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 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 peri!(p, PIN_A),
33 p.P1_03, 32 peri!(p, PIN_B),
34 p.P1_02, 33 irqs!(UART0_BUFFERED),
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/nrf52840/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs
index 54a9fef5b..e6debd76e 100644
--- a/tests/nrf52840/src/bin/buffered_uart_halves.rs
+++ b/tests/nrf/src/bin/buffered_uart_halves.rs
@@ -1,19 +1,17 @@
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 defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_futures::join::join; 10use embassy_futures::join::join;
8use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; 11use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx};
9use embassy_nrf::{bind_interrupts, peripherals, uarte}; 12use embassy_nrf::{peripherals, uarte};
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 UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;
15});
16
17#[embassy_executor::main] 15#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
19 let mut p = embassy_nrf::init(Default::default()); 17 let mut p = embassy_nrf::init(Default::default());
@@ -28,16 +26,22 @@ async fn main(_spawner: Spawner) {
28 for _ in 0..2 { 26 for _ in 0..2 {
29 const COUNT: usize = 40_000; 27 const COUNT: usize = 40_000;
30 28
31 let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer); 29 let mut tx = BufferedUarteTx::new(
30 peri!(p, UART1).reborrow(),
31 peri!(p, PIN_A).reborrow(),
32 irqs!(UART1_BUFFERED),
33 config.clone(),
34 &mut tx_buffer,
35 );
32 36
33 let mut rx = BufferedUarteRx::new( 37 let mut rx = BufferedUarteRx::new(
34 &mut p.UARTE0, 38 peri!(p, UART0).reborrow(),
35 &mut p.TIMER0, 39 p.TIMER0.reborrow(),
36 &mut p.PPI_CH0, 40 p.PPI_CH0.reborrow(),
37 &mut p.PPI_CH1, 41 p.PPI_CH1.reborrow(),
38 &mut p.PPI_GROUP0, 42 p.PPI_GROUP0.reborrow(),
39 Irqs, 43 irqs!(UART0_BUFFERED),
40 &mut p.P1_03, 44 peri!(p, PIN_B).reborrow(),
41 config.clone(), 45 config.clone(),
42 &mut rx_buffer, 46 &mut rx_buffer,
43 ); 47 );
diff --git a/tests/nrf52840/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs
index 400c0df99..6d862e19d 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,24 @@ 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(
31 peri!(p, PIN_A).reborrow(),
32 Level::High,
33 OutputDrive::Standard,
34 ));
34 35
35 let mut u = BufferedUarte::new( 36 let mut u = BufferedUarteRx::new(
36 p.UARTE0, 37 peri!(p, UART0),
37 p.TIMER0, 38 p.TIMER0,
38 p.PPI_CH0, 39 p.PPI_CH0,
39 p.PPI_CH1, 40 p.PPI_CH1,
40 p.PPI_GROUP0, 41 p.PPI_GROUP0,
41 Irqs, 42 irqs!(UART0_BUFFERED),
42 p.P1_03, 43 peri!(p, PIN_B),
43 p.P1_04,
44 config.clone(), 44 config.clone(),
45 &mut rx_buffer, 45 &mut rx_buffer,
46 &mut tx_buffer,
47 ); 46 );
48 47
49 info!("uarte initialized!"); 48 info!("uarte initialized!");
@@ -54,16 +53,16 @@ async fn main(_spawner: Spawner) {
54 // Tx spam in a loop. 53 // Tx spam in a loop.
55 const NSPAM: usize = 17; 54 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]; 55 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()); 56 let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone());
58 let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; 57 let spam_peri = pac::UARTE1;
59 let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; 58 let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_dma().tx().end().as_ptr())) };
60 let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; 59 let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_dma().tx().start().as_ptr())) };
61 let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); 60 let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task);
62 spam_ppi.enable(); 61 spam_ppi.enable();
63 let p = unsafe { TX_BUF.as_mut_ptr() }; 62 let p = (&raw mut TX_BUF) as *mut u8;
64 spam_peri.txd.ptr.write(|w| unsafe { w.ptr().bits(p as u32) }); 63 spam_peri.dma().tx().ptr().write_value(p as u32);
65 spam_peri.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(NSPAM as _) }); 64 spam_peri.dma().tx().maxcnt().write(|w| w.set_maxcnt(NSPAM as _));
66 spam_peri.tasks_starttx.write(|w| unsafe { w.bits(1) }); 65 spam_peri.tasks_dma().tx().start().write_value(1);
67 66
68 let mut i = 0; 67 let mut i = 0;
69 let mut total = 0; 68 let mut total = 0;
diff --git a/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
index 33c2f4235..bd6a2effd 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;
@@ -21,11 +22,11 @@ bind_interrupts!(struct Irqs {
21 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; 22 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
22}); 23});
23 24
24type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; 25type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static>, 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 spawner.spawn(unwrap!(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..4995d244c 100644
--- a/tests/nrf51422/src/bin/gpio.rs
+++ b/tests/nrf/src/bin/gpio.rs
@@ -1,25 +1,28 @@
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();
20 assert!(output.is_set_low());
19 Timer::after_millis(10).await; 21 Timer::after_millis(10).await;
20 assert!(input.is_low()); 22 assert!(input.is_low());
21 23
22 output.set_high(); 24 output.set_high();
25 assert!(output.is_set_high());
23 Timer::after_millis(10).await; 26 Timer::after_millis(10).await;
24 assert!(input.is_high()); 27 assert!(input.is_high());
25 28
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/nrf/src/bin/spim.rs b/tests/nrf/src/bin/spim.rs
new file mode 100644
index 000000000..2b38f0409
--- /dev/null
+++ b/tests/nrf/src/bin/spim.rs
@@ -0,0 +1,42 @@
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_nrf::spim::Spim;
11use embassy_nrf::{peripherals, spim};
12use {defmt_rtt as _, panic_probe as _};
13
14#[embassy_executor::main]
15async fn main(_spawner: Spawner) {
16 let mut p = embassy_nrf::init(Default::default());
17 let mut config = spim::Config::default();
18 config.frequency = spim::Frequency::M1;
19 let mut spim = Spim::new(
20 peri!(p, SPIM0).reborrow(),
21 irqs!(SPIM0),
22 peri!(p, PIN_X).reborrow(),
23 peri!(p, PIN_A).reborrow(), // MISO
24 peri!(p, PIN_B).reborrow(), // MOSI
25 config.clone(),
26 );
27 let data = [
28 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
29 ];
30 let mut buf = [0u8; 16];
31
32 buf.fill(0);
33 spim.blocking_transfer(&mut buf, &data).unwrap();
34 assert_eq!(data, buf);
35
36 buf.fill(0);
37 spim.transfer(&mut buf, &data).await.unwrap();
38 assert_eq!(data, buf);
39
40 info!("Test OK");
41 cortex_m::asm::bkpt();
42}
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..a462f80ce
--- /dev/null
+++ b/tests/nrf/src/bin/uart_halves.rs
@@ -0,0 +1,51 @@
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(
23 peri!(p, UART0).reborrow(),
24 irqs!(UART0),
25 peri!(p, PIN_A).reborrow(),
26 config.clone(),
27 );
28 let mut rx = UarteRx::new(
29 peri!(p, UART1).reborrow(),
30 irqs!(UART1),
31 peri!(p, PIN_B).reborrow(),
32 config.clone(),
33 );
34
35 let data = [
36 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
37 ];
38
39 let tx_fut = async {
40 tx.write(&data).await.unwrap();
41 };
42 let rx_fut = async {
43 let mut buf = [0u8; 16];
44 rx.read(&mut buf).await.unwrap();
45 assert_eq!(data, buf);
46 };
47 join(rx_fut, tx_fut).await;
48
49 info!("Test OK");
50 cortex_m::asm::bkpt();
51}
diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs
new file mode 100644
index 000000000..8fe710068
--- /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 peri!(p, UART0).reborrow(),
25 peri!(p, PIN_A).reborrow(),
26 peri!(p, PIN_B).reborrow(),
27 irqs!(UART0),
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..ac082dbb8 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};
@@ -28,8 +29,7 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
28async fn wifi_task( 29async fn wifi_task(
29 runner: hosted::Runner< 30 runner: hosted::Runner<
30 'static, 31 'static,
31 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, 32 hosted::SpiInterface<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Input<'static>>,
32 Input<'static>,
33 Output<'static>, 33 Output<'static>,
34 >, 34 >,
35) -> ! { 35) -> ! {
@@ -39,8 +39,8 @@ async fn wifi_task(
39type MyDriver = hosted::NetDriver<'static>; 39type MyDriver = hosted::NetDriver<'static>;
40 40
41#[embassy_executor::task] 41#[embassy_executor::task]
42async fn net_task(stack: &'static Stack<MyDriver>) -> ! { 42async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! {
43 stack.run().await 43 runner.run().await
44} 44}
45 45
46#[embassy_executor::main] 46#[embassy_executor::main]
@@ -63,17 +63,13 @@ async fn main(spawner: Spawner) {
63 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); 63 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config);
64 let spi = ExclusiveDevice::new(spi, cs, Delay); 64 let spi = ExclusiveDevice::new(spi, cs, Delay);
65 65
66 let iface = hosted::SpiInterface::new(spi, handshake, ready);
67
66 static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); 68 static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new();
67 let (device, mut control, runner) = embassy_net_esp_hosted::new( 69 let (device, mut control, runner) =
68 STATE.init(embassy_net_esp_hosted::State::new()), 70 embassy_net_esp_hosted::new(STATE.init(embassy_net_esp_hosted::State::new()), iface, reset).await;
69 spi,
70 handshake,
71 ready,
72 reset,
73 )
74 .await;
75 71
76 unwrap!(spawner.spawn(wifi_task(runner))); 72 spawner.spawn(unwrap!(wifi_task(runner)));
77 73
78 unwrap!(control.init().await); 74 unwrap!(control.init().await);
79 unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); 75 unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await);
@@ -85,16 +81,15 @@ async fn main(spawner: Spawner) {
85 let seed = u64::from_le_bytes(seed); 81 let seed = u64::from_le_bytes(seed);
86 82
87 // Init network stack 83 // Init network stack
88 static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new();
89 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); 84 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
90 let stack = &*STACK.init(Stack::new( 85 let (stack, runner) = embassy_net::new(
91 device, 86 device,
92 Config::dhcpv4(Default::default()), 87 Config::dhcpv4(Default::default()),
93 RESOURCES.init(StackResources::<2>::new()), 88 RESOURCES.init(StackResources::new()),
94 seed, 89 seed,
95 )); 90 );
96 91
97 unwrap!(spawner.spawn(net_task(stack))); 92 spawner.spawn(unwrap!(net_task(runner)));
98 93
99 perf_client::run( 94 perf_client::run(
100 stack, 95 stack,
diff --git a/tests/nrf/src/common.rs b/tests/nrf/src/common.rs
new file mode 100644
index 000000000..ebd332d15
--- /dev/null
+++ b/tests/nrf/src/common.rs
@@ -0,0 +1,117 @@
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 PIN_X = P0_13,
56 UART0 = UARTE0,
57 SPIM0 = TWISPI0,
58 @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;},
59 @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
60 @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;},
61);
62
63#[cfg(feature = "nrf52833")]
64define_peris!(
65 PIN_A = P1_01, PIN_B = P1_02,
66 PIN_X = P1_03,
67 UART0 = UARTE0,
68 UART1 = UARTE1,
69 SPIM0 = TWISPI0,
70 @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;},
71 @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;},
72 @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
73 @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;},
74 @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;},
75);
76
77#[cfg(feature = "nrf52840")]
78define_peris!(
79 PIN_A = P1_02, PIN_B = P1_03,
80 PIN_X = P1_04,
81 UART0 = UARTE0,
82 UART1 = UARTE1,
83 SPIM0 = TWISPI0,
84 @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;},
85 @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;},
86 @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
87 @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;},
88 @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;},
89);
90
91#[cfg(feature = "nrf5340")]
92define_peris!(
93 PIN_A = P1_08, PIN_B = P1_09,
94 PIN_X = P1_10,
95 UART0 = SERIAL0,
96 UART1 = SERIAL1,
97 SPIM0 = SERIAL0,
98 @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;},
99 @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;},
100 @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;},
101 @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;},
102 @irq SPIM0 = {SERIAL0 => spim::InterruptHandler<peripherals::SERIAL0>;},
103);
104
105#[cfg(feature = "nrf9160")]
106define_peris!(
107 PIN_A = P0_00, PIN_B = P0_01,
108 PIN_X = P0_02,
109 UART0 = SERIAL0,
110 UART1 = SERIAL1,
111 SPIM0 = SERIAL0,
112 @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;},
113 @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;},
114 @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;},
115 @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;},
116 @irq SPIM0 = {SERIAL0 => spim::InterruptHandler<peripherals::SERIAL0>;},
117);
diff --git a/tests/nrf51422/Cargo.toml b/tests/nrf51422/Cargo.toml
deleted file mode 100644
index 8bfcc2922..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.6.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.1", 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 1670b92ad..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.6.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.1", 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/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml
index 6ecc2d5e1..3756046fa 100644
--- a/tests/perf-client/Cargo.toml
+++ b/tests/perf-client/Cargo.toml
@@ -1,10 +1,12 @@
1[package] 1[package]
2name = "perf-client" 2name = "perf-client"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2024"
5license = "MIT OR Apache-2.0"
6publish = false
5 7
6[dependencies] 8[dependencies]
7embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } 9embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
8embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", ] } 10embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", ] }
9embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 11embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
10defmt = "0.3.0" 12defmt = "1.0.1"
diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs
index 54762379a..1ba071e8d 100644
--- a/tests/perf-client/src/lib.rs
+++ b/tests/perf-client/src/lib.rs
@@ -2,10 +2,9 @@
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::{Duration, Timer, with_timeout};
9 8
10pub struct Expected { 9pub struct Expected {
11 pub down_kbps: usize, 10 pub down_kbps: usize,
@@ -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/perf-server/Cargo.toml b/tests/perf-server/Cargo.toml
index 532039050..72f92ed8d 100644
--- a/tests/perf-server/Cargo.toml
+++ b/tests/perf-server/Cargo.toml
@@ -1,7 +1,9 @@
1[package] 1[package]
2name = "perf-server" 2name = "perf-server"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2024"
5license = "MIT OR Apache-2.0"
6publish = false
5 7
6[dependencies] 8[dependencies]
7log = "0.4.17" 9log = "0.4.17"
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml
index 4f1d3e5c6..935c6a2ee 100644
--- a/tests/riscv32/Cargo.toml
+++ b/tests/riscv32/Cargo.toml
@@ -1,15 +1,16 @@
1[package] 1[package]
2edition = "2021" 2edition = "2024"
3name = "embassy-riscv-tests" 3name = "embassy-riscv-tests"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6publish = false
6 7
7[dependencies] 8[dependencies]
8critical-section = { version = "1.1.1", features = ["restore-state-bool"] } 9critical-section = { version = "1.1.1", features = ["restore-state-bool"] }
9embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } 10embassy-sync = { version = "0.7.2", path = "../../embassy-sync" }
10embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } 11embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] }
11embassy-time = { version = "0.3.1", path = "../../embassy-time" } 12embassy-time = { version = "0.5.0", path = "../../embassy-time" }
12embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
13 14
14riscv-rt = "0.12.2" 15riscv-rt = "0.12.2"
15riscv = { version = "0.11.1", features = ["critical-section-single-hart"] } 16riscv = { version = "0.11.1", features = ["critical-section-single-hart"] }
@@ -44,3 +45,8 @@ debug = false
44debug-assertions = false 45debug-assertions = false
45opt-level = 0 46opt-level = 0
46overflow-checks = false 47overflow-checks = false
48
49[package.metadata.embassy]
50build = [
51 { target = "riscv32imac-unknown-none-elf" }
52]
diff --git a/tests/rp/.cargo/config.toml b/tests/rp/.cargo/config.toml
index de7bb0e56..649c15048 100644
--- a/tests/rp/.cargo/config.toml
+++ b/tests/rp/.cargo/config.toml
@@ -5,18 +5,19 @@
5#build-std-features = ["panic_immediate_abort"] 5#build-std-features = ["panic_immediate_abort"]
6 6
7[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 7[target.'cfg(all(target_arch = "arm", target_os = "none"))']
8runner = "teleprobe client run" 8#runner = "teleprobe client run"
9#runner = "teleprobe local run --chip RP2040 --elf" 9#runner = "teleprobe local run --chip RP2040 --elf"
10runner = "teleprobe local run --chip RP235X --elf"
10 11
11rustflags = [ 12rustflags = [
12 # Code-size optimizations. 13 # Code-size optimizations.
13 #"-Z", "trap-unreachable=no", 14 #"-Z", "trap-unreachable=no",
14 "-C", "inline-threshold=5",
15 "-C", "no-vectorize-loops", 15 "-C", "no-vectorize-loops",
16] 16]
17 17
18[build] 18[build]
19target = "thumbv6m-none-eabi" 19#target = "thumbv6m-none-eabi"
20target = "thumbv8m.main-none-eabihf"
20 21
21[env] 22[env]
22DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info" 23DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info"
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 45050ee0e..640e58f11 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -1,26 +1,32 @@
1[package] 1[package]
2edition = "2021" 2edition = "2024"
3name = "embassy-rp-tests" 3name = "embassy-rp-tests"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6publish = false
7
8[features]
9rp2040 = ["embassy-rp/rp2040"]
10rp235xa = ["embassy-rp/rp235xa"]
11rp235xb = ["embassy-rp/rp235xb"]
6 12
7[dependencies] 13[dependencies]
8teleprobe-meta = "1.1" 14teleprobe-meta = "1.1"
9 15
10embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } 16embassy-sync = { version = "0.7.2", 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"] } 17embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", ] } 18embassy-time = { version = "0.5.0", 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"] } 19embassy-rp = { version = "0.8.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 20embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
15embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 21embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 22embassy-net-wiznet = { version = "0.2.1", path = "../../embassy-net-wiznet", features = ["defmt"] }
17embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal/"} 23embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"}
18cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } 24cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
19cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } 25cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] }
20perf-client = { path = "../perf-client" } 26perf-client = { path = "../perf-client" }
21 27
22defmt = "0.3.0" 28defmt = "1.0.1"
23defmt-rtt = "0.4" 29defmt-rtt = "1.0.0"
24 30
25cortex-m = { version = "0.7.6" } 31cortex-m = { version = "0.7.6" }
26cortex-m-rt = "0.7.0" 32cortex-m-rt = "0.7.0"
@@ -28,14 +34,41 @@ embedded-hal = "0.2.6"
28embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 34embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
29embedded-hal-async = { version = "1.0" } 35embedded-hal-async = { version = "1.0" }
30embedded-hal-bus = { version = "0.1", features = ["async"] } 36embedded-hal-bus = { version = "0.1", features = ["async"] }
31panic-probe = { version = "0.3.0", features = ["print-defmt"] } 37panic-probe = { version = "1.0.0", features = ["print-defmt"] }
32embedded-io-async = { version = "0.6.1" } 38embedded-io-async = { version = "0.6.1" }
33embedded-storage = { version = "0.3" } 39embedded-storage = { version = "0.3" }
34static_cell = "2" 40static_cell = "2"
35portable-atomic = { version = "1.5", features = ["critical-section"] } 41portable-atomic = { version = "1.5", features = ["critical-section"] }
36pio = "0.2" 42
37pio-proc = "0.2" 43# bootsel not currently supported on 2350
38rand = { version = "0.8.5", default-features = false } 44[[bin]]
45name = "bootsel"
46path = "src/bin/bootsel.rs"
47required-features = [ "rp2040",]
48
49# 2350 devboard isn't a W
50[[bin]]
51name = "cyw43-perf"
52path = "src/bin/cyw43-perf.rs"
53required-features = [ "rp2040",]
54
55# Eth test only for the w5100s-evb-pico
56[[bin]]
57name = "ethernet_w5100s_perf"
58path = "src/bin/ethernet_w5100s_perf.rs"
59required-features = [ "rp2040",]
60
61# Float intrinsics are only relevant for the 2040
62[[bin]]
63name = "float"
64path = "src/bin/float.rs"
65required-features = [ "rp2040",]
66
67# RTC is only available on RP2040
68[[bin]]
69name = "rtc"
70path = "src/bin/rtc.rs"
71required-features = [ "rp2040",]
39 72
40[profile.dev] 73[profile.dev]
41debug = 2 74debug = 2
@@ -66,3 +99,9 @@ debug = false
66debug-assertions = false 99debug-assertions = false
67opt-level = 0 100opt-level = 0
68overflow-checks = false 101overflow-checks = false
102
103[package.metadata.embassy]
104build = [
105 { target = "thumbv6m-none-eabi", features = ["rp2040"], artifact-dir = "out/tests/rpi-pico" },
106 { target = "thumbv8m.main-none-eabihf", features = ["rp235xb"], artifact-dir = "out/tests/pimoroni-pico-plus-2" }
107]
diff --git a/tests/rp/readme.md b/tests/rp/readme.md
new file mode 100644
index 000000000..f8192a95a
--- /dev/null
+++ b/tests/rp/readme.md
@@ -0,0 +1,8 @@
1# Pico and Pico 2 Plus connections
2
3GP0-GP1
4GP3-GP4
5GP6-GP9
6GP7-GP11
7GP18-GP20 with 10k pullup
8GP19-GP21 with 10k pullup
diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs
index 29eda95bf..c2175bc03 100644
--- a/tests/rp/src/bin/adc.rs
+++ b/tests/rp/src/bin/adc.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::*; 8use defmt::*;
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -20,14 +23,19 @@ async fn main(_spawner: Spawner) {
20 let _wifi_off = Output::new(p.PIN_25, Level::High); 23 let _wifi_off = Output::new(p.PIN_25, Level::High);
21 let mut adc = Adc::new(p.ADC, Irqs, Config::default()); 24 let mut adc = Adc::new(p.ADC, Irqs, Config::default());
22 25
26 #[cfg(any(feature = "rp2040", feature = "rp235xa"))]
27 let (mut a, mut b, mut c, mut d) = (p.PIN_26, p.PIN_27, p.PIN_28, p.PIN_29);
28 #[cfg(feature = "rp235xb")]
29 let (mut a, mut b, mut c, mut d) = (p.PIN_44, p.PIN_45, p.PIN_46, p.PIN_47);
30
23 { 31 {
24 { 32 {
25 let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Down); 33 let mut p = Channel::new_pin(a.reborrow(), Pull::Down);
26 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 34 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
27 defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); 35 defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000);
28 } 36 }
29 { 37 {
30 let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Up); 38 let mut p = Channel::new_pin(a.reborrow(), Pull::Up);
31 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 39 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
32 defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); 40 defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000);
33 } 41 }
@@ -35,21 +43,21 @@ async fn main(_spawner: Spawner) {
35 // not bothering with async reads from now on 43 // not bothering with async reads from now on
36 { 44 {
37 { 45 {
38 let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Down); 46 let mut p = Channel::new_pin(b.reborrow(), Pull::Down);
39 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 47 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
40 } 48 }
41 { 49 {
42 let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Up); 50 let mut p = Channel::new_pin(b.reborrow(), Pull::Up);
43 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 51 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
44 } 52 }
45 } 53 }
46 { 54 {
47 { 55 {
48 let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Down); 56 let mut p = Channel::new_pin(c.reborrow(), Pull::Down);
49 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 57 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
50 } 58 }
51 { 59 {
52 let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Up); 60 let mut p = Channel::new_pin(c.reborrow(), Pull::Up);
53 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 61 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
54 } 62 }
55 } 63 }
@@ -57,15 +65,15 @@ async fn main(_spawner: Spawner) {
57 // gp29 is connected to vsys through a 200k/100k divider, 65 // gp29 is connected to vsys through a 200k/100k divider,
58 // adding pulls should change the value 66 // adding pulls should change the value
59 let low = { 67 let low = {
60 let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Down); 68 let mut p = Channel::new_pin(d.reborrow(), Pull::Down);
61 adc.blocking_read(&mut p).unwrap() 69 adc.blocking_read(&mut p).unwrap()
62 }; 70 };
63 let none = { 71 let none = {
64 let mut p = Channel::new_pin(&mut p.PIN_29, Pull::None); 72 let mut p = Channel::new_pin(d.reborrow(), Pull::None);
65 adc.blocking_read(&mut p).unwrap() 73 adc.blocking_read(&mut p).unwrap()
66 }; 74 };
67 let up = { 75 let up = {
68 let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Up); 76 let mut p = Channel::new_pin(d.reborrow(), Pull::Up);
69 adc.blocking_read(&mut p).unwrap() 77 adc.blocking_read(&mut p).unwrap()
70 }; 78 };
71 defmt::assert!(low < none); 79 defmt::assert!(low < none);
@@ -73,7 +81,7 @@ async fn main(_spawner: Spawner) {
73 } 81 }
74 { 82 {
75 let temp = convert_to_celsius( 83 let temp = convert_to_celsius(
76 adc.read(&mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR)) 84 adc.read(&mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()))
77 .await 85 .await
78 .unwrap(), 86 .unwrap(),
79 ); 87 );
@@ -90,26 +98,26 @@ async fn main(_spawner: Spawner) {
90 let mut none = [0u8; 16]; 98 let mut none = [0u8; 16];
91 let mut up = [Sample::default(); 16]; 99 let mut up = [Sample::default(); 16];
92 adc.read_many( 100 adc.read_many(
93 &mut Channel::new_pin(&mut p.PIN_29, Pull::Down), 101 &mut Channel::new_pin(d.reborrow(), Pull::Down),
94 &mut low, 102 &mut low,
95 1, 103 1,
96 &mut p.DMA_CH0, 104 p.DMA_CH0.reborrow(),
97 ) 105 )
98 .await 106 .await
99 .unwrap(); 107 .unwrap();
100 adc.read_many( 108 adc.read_many(
101 &mut Channel::new_pin(&mut p.PIN_29, Pull::None), 109 &mut Channel::new_pin(d.reborrow(), Pull::None),
102 &mut none, 110 &mut none,
103 1, 111 1,
104 &mut p.DMA_CH0, 112 p.DMA_CH0.reborrow(),
105 ) 113 )
106 .await 114 .await
107 .unwrap(); 115 .unwrap();
108 adc.read_many_raw( 116 adc.read_many_raw(
109 &mut Channel::new_pin(&mut p.PIN_29, Pull::Up), 117 &mut Channel::new_pin(d.reborrow(), Pull::Up),
110 &mut up, 118 &mut up,
111 1, 119 1,
112 &mut p.DMA_CH0, 120 p.DMA_CH0.reborrow(),
113 ) 121 )
114 .await; 122 .await;
115 defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); 123 defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16));
@@ -119,10 +127,10 @@ async fn main(_spawner: Spawner) {
119 { 127 {
120 let mut temp = [0u16; 16]; 128 let mut temp = [0u16; 16];
121 adc.read_many( 129 adc.read_many(
122 &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), 130 &mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()),
123 &mut temp, 131 &mut temp,
124 1, 132 1,
125 &mut p.DMA_CH0, 133 p.DMA_CH0.reborrow(),
126 ) 134 )
127 .await 135 .await
128 .unwrap(); 136 .unwrap();
@@ -130,6 +138,19 @@ async fn main(_spawner: Spawner) {
130 defmt::assert!(temp.iter().all(|t| *t > 0.0)); 138 defmt::assert!(temp.iter().all(|t| *t > 0.0));
131 defmt::assert!(temp.iter().all(|t| *t < 60.0)); 139 defmt::assert!(temp.iter().all(|t| *t < 60.0));
132 } 140 }
141 {
142 let mut multi = [0u16; 2];
143 let mut channels = [
144 Channel::new_pin(a.reborrow(), Pull::Up),
145 Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()),
146 ];
147 adc.read_many_multichannel(&mut channels, &mut multi, 1, p.DMA_CH0.reborrow())
148 .await
149 .unwrap();
150 defmt::assert!(multi[0] > 3_000);
151 let temp = convert_to_celsius(multi[1]);
152 defmt::assert!(temp > 0.0 && temp < 60.0);
153 }
133 154
134 info!("Test OK"); 155 info!("Test OK");
135 cortex_m::asm::bkpt(); 156 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs
index e88d8bf6c..aa123ab03 100644
--- a/tests/rp/src/bin/bootsel.rs
+++ b/tests/rp/src/bin/bootsel.rs
@@ -4,12 +4,13 @@ teleprobe_meta::target!(b"rpi-pico");
4 4
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::bootsel::is_bootsel_pressed;
7use embassy_time::Timer; 8use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
9 10
10#[embassy_executor::main] 11#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
12 let mut p = embassy_rp::init(Default::default()); 13 let p = embassy_rp::init(Default::default());
13 info!("Hello World!"); 14 info!("Hello World!");
14 15
15 // add some delay to give an attached debug probe time to parse the 16 // add some delay to give an attached debug probe time to parse the
@@ -18,7 +19,7 @@ async fn main(_spawner: Spawner) {
18 // https://github.com/knurling-rs/defmt/pull/683 19 // https://github.com/knurling-rs/defmt/pull/683
19 Timer::after_millis(10).await; 20 Timer::after_millis(10).await;
20 21
21 assert_eq!(p.BOOTSEL.is_pressed(), false); 22 assert_eq!(is_bootsel_pressed(p.BOOTSEL), false);
22 23
23 info!("Test OK"); 24 info!("Test OK");
24 cortex_m::asm::bkpt(); 25 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs
index 4b0c7f7b9..9487f5e1a 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_pio::PioSpi; 5use cyw43::JoinOptions;
6use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, 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};
@@ -20,7 +21,7 @@ bind_interrupts!(struct Irqs {
20teleprobe_meta::timeout!(120); 21teleprobe_meta::timeout!(120);
21 22
22// Test-only wifi network, no internet access! 23// Test-only wifi network, no internet access!
23const WIFI_NETWORK: &str = "EmbassyTest"; 24const WIFI_NETWORK: &str = "EmbassyTestWPA2";
24const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; 25const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
25 26
26#[embassy_executor::task] 27#[embassy_executor::task]
@@ -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,20 +46,31 @@ 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 ---binary-format --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 ---binary-format --chip RP2040 --base-address 0x101f8000 50 // probe-rs download 43439A0_btfw.bin --binary-format bin --chip RP2040 --base-address 0x101f0000
50 let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 230321) }; 51 // probe-rs download 43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x101f8000
51 let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; 52 let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 231077) };
53 let _btfw = unsafe { core::slice::from_raw_parts(0x101f0000 as *const u8, 6164) };
54 let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 984) };
52 55
53 let pwr = Output::new(p.PIN_23, Level::Low); 56 let pwr = Output::new(p.PIN_23, Level::Low);
54 let cs = Output::new(p.PIN_25, Level::High); 57 let cs = Output::new(p.PIN_25, Level::High);
55 let mut pio = Pio::new(p.PIO0, Irqs); 58 let mut pio = Pio::new(p.PIO0, Irqs);
56 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 59 let spi = PioSpi::new(
60 &mut pio.common,
61 pio.sm0,
62 DEFAULT_CLOCK_DIVIDER,
63 pio.irq0,
64 cs,
65 p.PIN_24,
66 p.PIN_29,
67 p.DMA_CH0,
68 );
57 69
58 static STATE: StaticCell<cyw43::State> = StaticCell::new(); 70 static STATE: StaticCell<cyw43::State> = StaticCell::new();
59 let state = STATE.init(cyw43::State::new()); 71 let state = STATE.init(cyw43::State::new());
60 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 72 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
61 unwrap!(spawner.spawn(wifi_task(runner))); 73 spawner.spawn(unwrap!(wifi_task(runner)));
62 74
63 control.init(clm).await; 75 control.init(clm).await;
64 control 76 control
@@ -69,19 +81,21 @@ async fn main(spawner: Spawner) {
69 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. 81 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
70 82
71 // Init network stack 83 // Init network stack
72 static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
73 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); 84 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
74 let stack = &*STACK.init(Stack::new( 85 let (stack, runner) = embassy_net::new(
75 net_device, 86 net_device,
76 Config::dhcpv4(Default::default()), 87 Config::dhcpv4(Default::default()),
77 RESOURCES.init(StackResources::<2>::new()), 88 RESOURCES.init(StackResources::new()),
78 seed, 89 seed,
79 )); 90 );
80 91
81 unwrap!(spawner.spawn(net_task(stack))); 92 spawner.spawn(unwrap!(net_task(runner)));
82 93
83 loop { 94 loop {
84 match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { 95 match control
96 .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
97 .await
98 {
85 Ok(_) => break, 99 Ok(_) => break,
86 Err(err) => { 100 Err(err) => {
87 panic!("join failed with status={}", err.status); 101 panic!("join failed with status={}", err.status);
@@ -92,9 +106,9 @@ async fn main(spawner: Spawner) {
92 perf_client::run( 106 perf_client::run(
93 stack, 107 stack,
94 perf_client::Expected { 108 perf_client::Expected {
95 down_kbps: 300, 109 down_kbps: 200,
96 up_kbps: 300, 110 up_kbps: 200,
97 updown_kbps: 300, 111 updown_kbps: 200,
98 }, 112 },
99 ) 113 )
100 .await; 114 .await;
diff --git a/tests/rp/src/bin/dma_copy_async.rs b/tests/rp/src/bin/dma_copy_async.rs
index 7c64bc396..3dcf4f4d8 100644
--- a/tests/rp/src/bin/dma_copy_async.rs
+++ b/tests/rp/src/bin/dma_copy_async.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs
index 5d5547773..3f2bc728d 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;
@@ -14,7 +14,6 @@ use embassy_rp::peripherals::SPI0;
14use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 14use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
15use embassy_time::Delay; 15use embassy_time::Delay;
16use embedded_hal_bus::spi::ExclusiveDevice; 16use embedded_hal_bus::spi::ExclusiveDevice;
17use rand::RngCore;
18use static_cell::StaticCell; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
@@ -32,8 +31,8 @@ async fn ethernet_task(
32} 31}
33 32
34#[embassy_executor::task] 33#[embassy_executor::task]
35async fn net_task(stack: &'static Stack<Device<'static>>) -> ! { 34async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
36 stack.run().await 35 runner.run().await
37} 36}
38 37
39#[embassy_executor::main] 38#[embassy_executor::main]
@@ -59,24 +58,24 @@ async fn main(spawner: Spawner) {
59 w5500_int, 58 w5500_int,
60 w5500_reset, 59 w5500_reset,
61 ) 60 )
62 .await; 61 .await
63 unwrap!(spawner.spawn(ethernet_task(runner))); 62 .unwrap();
63 spawner.spawn(unwrap!(ethernet_task(runner)));
64 64
65 // Generate random seed 65 // Generate random seed
66 let seed = rng.next_u64(); 66 let seed = rng.next_u64();
67 67
68 // Init network stack 68 // Init network stack
69 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
70 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); 69 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
71 let stack = &*STACK.init(Stack::new( 70 let (stack, runner) = embassy_net::new(
72 device, 71 device,
73 embassy_net::Config::dhcpv4(Default::default()), 72 embassy_net::Config::dhcpv4(Default::default()),
74 RESOURCES.init(StackResources::<2>::new()), 73 RESOURCES.init(StackResources::new()),
75 seed, 74 seed,
76 )); 75 );
77 76
78 // Launch network task 77 // Launch network task
79 unwrap!(spawner.spawn(net_task(&stack))); 78 spawner.spawn(unwrap!(net_task(runner)));
80 79
81 perf_client::run( 80 perf_client::run(
82 stack, 81 stack,
diff --git a/tests/rp/src/bin/flash.rs b/tests/rp/src/bin/flash.rs
index 310f0d586..548a6ee72 100644
--- a/tests/rp/src/bin/flash.rs
+++ b/tests/rp/src/bin/flash.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::*; 8use defmt::*;
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -24,13 +27,19 @@ async fn main(_spawner: Spawner) {
24 let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); 27 let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0);
25 28
26 // Get JEDEC id 29 // Get JEDEC id
27 let jedec = defmt::unwrap!(flash.blocking_jedec_id()); 30 #[cfg(feature = "rp2040")]
28 info!("jedec id: 0x{:x}", jedec); 31 {
32 let jedec = defmt::unwrap!(flash.blocking_jedec_id());
33 info!("jedec id: 0x{:x}", jedec);
34 }
29 35
30 // Get unique id 36 // Get unique id
31 let mut uid = [0; 8]; 37 #[cfg(feature = "rp2040")]
32 defmt::unwrap!(flash.blocking_unique_id(&mut uid)); 38 {
33 info!("unique id: {:?}", uid); 39 let mut uid = [0; 8];
40 defmt::unwrap!(flash.blocking_unique_id(&mut uid));
41 info!("unique id: {:?}", uid);
42 }
34 43
35 let mut buf = [0u8; ERASE_SIZE]; 44 let mut buf = [0u8; ERASE_SIZE];
36 defmt::unwrap!(flash.blocking_read(ADDR_OFFSET, &mut buf)); 45 defmt::unwrap!(flash.blocking_read(ADDR_OFFSET, &mut buf));
diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs
index e0c309887..8bd0df8d8 100644
--- a/tests/rp/src/bin/gpio.rs
+++ b/tests/rp/src/bin/gpio.rs
@@ -1,10 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert, *}; 8use defmt::{assert, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull}; 10#[cfg(feature = "rp2040")]
11use embassy_rp::gpio::OutputOpenDrain;
12use embassy_rp::gpio::{Flex, Input, Level, Output, Pull};
8use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
9 14
10#[embassy_executor::main] 15#[embassy_executor::main]
@@ -16,10 +21,10 @@ async fn main(_spawner: Spawner) {
16 21
17 // Test initial output 22 // Test initial output
18 { 23 {
19 let b = Input::new(&mut b, Pull::None); 24 let b = Input::new(b.reborrow(), Pull::None);
20 25
21 { 26 {
22 let a = Output::new(&mut a, Level::Low); 27 let a = Output::new(a.reborrow(), Level::Low);
23 delay(); 28 delay();
24 assert!(b.is_low()); 29 assert!(b.is_low());
25 assert!(!b.is_high()); 30 assert!(!b.is_high());
@@ -27,7 +32,7 @@ async fn main(_spawner: Spawner) {
27 assert!(!a.is_set_high()); 32 assert!(!a.is_set_high());
28 } 33 }
29 { 34 {
30 let mut a = Output::new(&mut a, Level::High); 35 let mut a = Output::new(a.reborrow(), Level::High);
31 delay(); 36 delay();
32 assert!(!b.is_low()); 37 assert!(!b.is_low());
33 assert!(b.is_high()); 38 assert!(b.is_high());
@@ -62,12 +67,46 @@ async fn main(_spawner: Spawner) {
62 } 67 }
63 } 68 }
64 69
70 // Test input inversion
71 {
72 let mut b = Input::new(b.reborrow(), Pull::None);
73 b.set_inversion(true);
74 // no pull, the status is undefined
75
76 let mut a = Output::new(a.reborrow(), Level::Low);
77 delay();
78 assert!(b.is_high());
79 a.set_high();
80 delay();
81 assert!(b.is_low());
82
83 b.set_inversion(false);
84 a.set_inversion(true);
85
86 a.set_low();
87 delay();
88 assert!(b.is_high());
89
90 a.set_high();
91 delay();
92 assert!(b.is_low());
93
94 b.set_inversion(true);
95 a.set_high();
96 delay();
97 assert!(b.is_high());
98
99 a.set_high();
100 delay();
101 assert!(b.is_high());
102 }
103
65 // Test input no pull 104 // Test input no pull
66 { 105 {
67 let b = Input::new(&mut b, Pull::None); 106 let b = Input::new(b.reborrow(), Pull::None);
68 // no pull, the status is undefined 107 // no pull, the status is undefined
69 108
70 let mut a = Output::new(&mut a, Level::Low); 109 let mut a = Output::new(a.reborrow(), Level::Low);
71 delay(); 110 delay();
72 assert!(b.is_low()); 111 assert!(b.is_low());
73 a.set_high(); 112 a.set_high();
@@ -76,12 +115,13 @@ async fn main(_spawner: Spawner) {
76 } 115 }
77 116
78 // Test input pulldown 117 // Test input pulldown
118 #[cfg(feature = "rp2040")]
79 { 119 {
80 let b = Input::new(&mut b, Pull::Down); 120 let b = Input::new(b.reborrow(), Pull::Down);
81 delay(); 121 delay();
82 assert!(b.is_low()); 122 assert!(b.is_low());
83 123
84 let mut a = Output::new(&mut a, Level::Low); 124 let mut a = Output::new(a.reborrow(), Level::Low);
85 delay(); 125 delay();
86 assert!(b.is_low()); 126 assert!(b.is_low());
87 a.set_high(); 127 a.set_high();
@@ -91,11 +131,11 @@ async fn main(_spawner: Spawner) {
91 131
92 // Test input pullup 132 // Test input pullup
93 { 133 {
94 let b = Input::new(&mut b, Pull::Up); 134 let b = Input::new(b.reborrow(), Pull::Up);
95 delay(); 135 delay();
96 assert!(b.is_high()); 136 assert!(b.is_high());
97 137
98 let mut a = Output::new(&mut a, Level::Low); 138 let mut a = Output::new(a.reborrow(), Level::Low);
99 delay(); 139 delay();
100 assert!(b.is_low()); 140 assert!(b.is_low());
101 a.set_high(); 141 a.set_high();
@@ -104,9 +144,10 @@ async fn main(_spawner: Spawner) {
104 } 144 }
105 145
106 // OUTPUT OPEN DRAIN 146 // OUTPUT OPEN DRAIN
147 #[cfg(feature = "rp2040")]
107 { 148 {
108 let mut b = OutputOpenDrain::new(&mut b, Level::High); 149 let mut b = OutputOpenDrain::new(b.reborrow(), Level::High);
109 let mut a = Flex::new(&mut a); 150 let mut a = Flex::new(a.reborrow());
110 a.set_as_input(); 151 a.set_as_input();
111 152
112 // When an OutputOpenDrain is high, it doesn't drive the pin. 153 // When an OutputOpenDrain is high, it doesn't drive the pin.
@@ -163,12 +204,12 @@ async fn main(_spawner: Spawner) {
163 // Test initial output 204 // Test initial output
164 { 205 {
165 //Flex pin configured as input 206 //Flex pin configured as input
166 let mut b = Flex::new(&mut b); 207 let mut b = Flex::new(b.reborrow());
167 b.set_as_input(); 208 b.set_as_input();
168 209
169 { 210 {
170 //Flex pin configured as output 211 //Flex pin configured as output
171 let mut a = Flex::new(&mut a); //Flex pin configured as output 212 let mut a = Flex::new(a.reborrow()); //Flex pin configured as output
172 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state 213 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state
173 a.set_as_output(); 214 a.set_as_output();
174 delay(); 215 delay();
@@ -176,7 +217,7 @@ async fn main(_spawner: Spawner) {
176 } 217 }
177 { 218 {
178 //Flex pin configured as output 219 //Flex pin configured as output
179 let mut a = Flex::new(&mut a); 220 let mut a = Flex::new(a.reborrow());
180 a.set_high(); 221 a.set_high();
181 a.set_as_output(); 222 a.set_as_output();
182 223
@@ -187,10 +228,10 @@ async fn main(_spawner: Spawner) {
187 228
188 // Test input no pull 229 // Test input no pull
189 { 230 {
190 let mut b = Flex::new(&mut b); 231 let mut b = Flex::new(b.reborrow());
191 b.set_as_input(); // no pull by default. 232 b.set_as_input(); // no pull by default.
192 233
193 let mut a = Flex::new(&mut a); 234 let mut a = Flex::new(a.reborrow());
194 a.set_low(); 235 a.set_low();
195 a.set_as_output(); 236 a.set_as_output();
196 237
@@ -202,14 +243,15 @@ async fn main(_spawner: Spawner) {
202 } 243 }
203 244
204 // Test input pulldown 245 // Test input pulldown
246 #[cfg(feature = "rp2040")]
205 { 247 {
206 let mut b = Flex::new(&mut b); 248 let mut b = Flex::new(b.reborrow());
207 b.set_as_input(); 249 b.set_as_input();
208 b.set_pull(Pull::Down); 250 b.set_pull(Pull::Down);
209 delay(); 251 delay();
210 assert!(b.is_low()); 252 assert!(b.is_low());
211 253
212 let mut a = Flex::new(&mut a); 254 let mut a = Flex::new(a.reborrow());
213 a.set_low(); 255 a.set_low();
214 a.set_as_output(); 256 a.set_as_output();
215 delay(); 257 delay();
@@ -221,13 +263,13 @@ async fn main(_spawner: Spawner) {
221 263
222 // Test input pullup 264 // Test input pullup
223 { 265 {
224 let mut b = Flex::new(&mut b); 266 let mut b = Flex::new(b.reborrow());
225 b.set_as_input(); 267 b.set_as_input();
226 b.set_pull(Pull::Up); 268 b.set_pull(Pull::Up);
227 delay(); 269 delay();
228 assert!(b.is_high()); 270 assert!(b.is_high());
229 271
230 let mut a = Flex::new(&mut a); 272 let mut a = Flex::new(a.reborrow());
231 a.set_high(); 273 a.set_high();
232 a.set_as_output(); 274 a.set_as_output();
233 delay(); 275 delay();
diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs
index 40a304464..72fb0910d 100644
--- a/tests/rp/src/bin/gpio_async.rs
+++ b/tests/rp/src/bin/gpio_async.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert, *}; 8use defmt::{assert, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -19,8 +22,8 @@ async fn main(_spawner: Spawner) {
19 22
20 { 23 {
21 info!("test wait_for_high"); 24 info!("test wait_for_high");
22 let mut output = Output::new(&mut output_pin, Level::Low); 25 let mut output = Output::new(output_pin.reborrow(), Level::Low);
23 let mut input = Input::new(&mut input_pin, Pull::None); 26 let mut input = Input::new(input_pin.reborrow(), Pull::None);
24 27
25 assert!(input.is_low(), "input was expected to be low"); 28 assert!(input.is_low(), "input was expected to be low");
26 29
@@ -40,8 +43,8 @@ async fn main(_spawner: Spawner) {
40 43
41 { 44 {
42 info!("test wait_for_low"); 45 info!("test wait_for_low");
43 let mut output = Output::new(&mut output_pin, Level::High); 46 let mut output = Output::new(output_pin.reborrow(), Level::High);
44 let mut input = Input::new(&mut input_pin, Pull::None); 47 let mut input = Input::new(input_pin.reborrow(), Pull::None);
45 48
46 assert!(input.is_high(), "input was expected to be high"); 49 assert!(input.is_high(), "input was expected to be high");
47 50
@@ -60,8 +63,8 @@ async fn main(_spawner: Spawner) {
60 63
61 { 64 {
62 info!("test wait_for_rising_edge"); 65 info!("test wait_for_rising_edge");
63 let mut output = Output::new(&mut output_pin, Level::Low); 66 let mut output = Output::new(output_pin.reborrow(), Level::Low);
64 let mut input = Input::new(&mut input_pin, Pull::None); 67 let mut input = Input::new(input_pin.reborrow(), Pull::None);
65 68
66 assert!(input.is_low(), "input was expected to be low"); 69 assert!(input.is_low(), "input was expected to be low");
67 70
@@ -80,8 +83,8 @@ async fn main(_spawner: Spawner) {
80 83
81 { 84 {
82 info!("test wait_for_falling_edge"); 85 info!("test wait_for_falling_edge");
83 let mut output = Output::new(&mut output_pin, Level::High); 86 let mut output = Output::new(output_pin.reborrow(), Level::High);
84 let mut input = Input::new(&mut input_pin, Pull::None); 87 let mut input = Input::new(input_pin.reborrow(), Pull::None);
85 88
86 assert!(input.is_high(), "input was expected to be high"); 89 assert!(input.is_high(), "input was expected to be high");
87 90
@@ -100,8 +103,8 @@ async fn main(_spawner: Spawner) {
100 103
101 { 104 {
102 info!("test wait_for_any_edge (falling)"); 105 info!("test wait_for_any_edge (falling)");
103 let mut output = Output::new(&mut output_pin, Level::High); 106 let mut output = Output::new(output_pin.reborrow(), Level::High);
104 let mut input = Input::new(&mut input_pin, Pull::None); 107 let mut input = Input::new(input_pin.reborrow(), Pull::None);
105 108
106 assert!(input.is_high(), "input was expected to be high"); 109 assert!(input.is_high(), "input was expected to be high");
107 110
@@ -120,8 +123,8 @@ async fn main(_spawner: Spawner) {
120 123
121 { 124 {
122 info!("test wait_for_any_edge (rising)"); 125 info!("test wait_for_any_edge (rising)");
123 let mut output = Output::new(&mut output_pin, Level::Low); 126 let mut output = Output::new(output_pin.reborrow(), Level::Low);
124 let mut input = Input::new(&mut input_pin, Pull::None); 127 let mut input = Input::new(input_pin.reborrow(), Pull::None);
125 128
126 assert!(input.is_low(), "input was expected to be low"); 129 assert!(input.is_low(), "input was expected to be low");
127 130
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs
index e9c6f3122..6abcba590 100644
--- a/tests/rp/src/bin/gpio_multicore.rs
+++ b/tests/rp/src/bin/gpio_multicore.rs
@@ -1,11 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{info, unwrap}; 8use defmt::{info, unwrap};
6use embassy_executor::Executor; 9use embassy_executor::Executor;
10use embassy_rp::Peri;
7use embassy_rp::gpio::{Input, Level, Output, Pull}; 11use embassy_rp::gpio::{Input, Level, Output, Pull};
8use embassy_rp::multicore::{spawn_core1, Stack}; 12use embassy_rp::multicore::{Stack, spawn_core1};
9use embassy_rp::peripherals::{PIN_0, PIN_1}; 13use embassy_rp::peripherals::{PIN_0, PIN_1};
10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
11use embassy_sync::channel::Channel; 15use embassy_sync::channel::Channel;
@@ -26,15 +30,15 @@ fn main() -> ! {
26 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 30 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
27 move || { 31 move || {
28 let executor1 = EXECUTOR1.init(Executor::new()); 32 let executor1 = EXECUTOR1.init(Executor::new());
29 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); 33 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(p.PIN_1))));
30 }, 34 },
31 ); 35 );
32 let executor0 = EXECUTOR0.init(Executor::new()); 36 let executor0 = EXECUTOR0.init(Executor::new());
33 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); 37 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task(p.PIN_0))));
34} 38}
35 39
36#[embassy_executor::task] 40#[embassy_executor::task]
37async fn core0_task(p: PIN_0) { 41async fn core0_task(p: Peri<'static, PIN_0>) {
38 info!("CORE0 is running"); 42 info!("CORE0 is running");
39 43
40 let mut pin = Output::new(p, Level::Low); 44 let mut pin = Output::new(p, Level::Low);
@@ -51,12 +55,12 @@ async fn core0_task(p: PIN_0) {
51} 55}
52 56
53#[embassy_executor::task] 57#[embassy_executor::task]
54async fn core1_task(p: PIN_1) { 58async fn core1_task(p: Peri<'static, PIN_1>) {
55 info!("CORE1 is running"); 59 info!("CORE1 is running");
56 60
57 CHANNEL0.receive().await; 61 CHANNEL0.receive().await;
58 62
59 let mut pin = Input::new(p, Pull::Down); 63 let mut pin = Input::new(p, Pull::None);
60 let wait = pin.wait_for_rising_edge(); 64 let wait = pin.wait_for_rising_edge();
61 65
62 CHANNEL1.send(()).await; 66 CHANNEL1.send(()).await;
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
index 9615007bd..21761b98b 100644
--- a/tests/rp/src/bin/i2c.rs
+++ b/tests/rp/src/bin/i2c.rs
@@ -1,23 +1,21 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, info, panic, unwrap}; 8use defmt::{assert_eq, info, panic};
6use embassy_embedded_hal::SetConfig; 9use embassy_embedded_hal::SetConfig;
7use embassy_executor::{Executor, Spawner}; 10use embassy_executor::Spawner;
8use embassy_rp::clocks::{PllConfig, XoscConfig}; 11use embassy_rp::clocks::{PllConfig, XoscConfig};
9use embassy_rp::config::Config as rpConfig; 12use embassy_rp::config::Config as rpConfig;
10use embassy_rp::multicore::{spawn_core1, Stack};
11use embassy_rp::peripherals::{I2C0, I2C1}; 13use embassy_rp::peripherals::{I2C0, I2C1};
12use embassy_rp::{bind_interrupts, i2c, i2c_slave}; 14use embassy_rp::{bind_interrupts, i2c, i2c_slave};
13use embedded_hal_1::i2c::Operation; 15use embedded_hal_1::i2c::Operation;
14use embedded_hal_async::i2c::I2c; 16use embedded_hal_async::i2c::I2c;
15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _};
17 18
18static mut CORE1_STACK: Stack<1024> = Stack::new();
19static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
20
21use crate::i2c::AbortReason; 19use crate::i2c::AbortReason;
22 20
23bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
@@ -106,7 +104,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
106} 104}
107 105
108async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { 106async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
109 info!("Device start"); 107 info!("Controller start");
110 108
111 { 109 {
112 let buf = [0xCA, 0x11]; 110 let buf = [0xCA, 0x11];
@@ -180,7 +178,7 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
180 } 178 }
181 179
182 #[embassy_executor::main] 180 #[embassy_executor::main]
183 async fn main(_core0_spawner: Spawner) { 181 async fn main(spawner: Spawner) {
184 let mut config = rpConfig::default(); 182 let mut config = rpConfig::default();
185 // Configure clk_sys to 48MHz to support 1kHz scl. 183 // Configure clk_sys to 48MHz to support 1kHz scl.
186 // In theory it can go lower, but we won't bother to test below 1kHz. 184 // In theory it can go lower, but we won't bother to test below 1kHz.
@@ -210,14 +208,7 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
210 config.addr = DEV_ADDR as u16; 208 config.addr = DEV_ADDR as u16;
211 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); 209 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
212 210
213 spawn_core1( 211 spawner.spawn(device_task(device).unwrap());
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 );
221 212
222 let c_sda = p.PIN_21; 213 let c_sda = p.PIN_21;
223 let c_scl = p.PIN_20; 214 let c_scl = p.PIN_20;
diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs
index 783ea0f27..7e34bc778 100644
--- a/tests/rp/src/bin/multicore.rs
+++ b/tests/rp/src/bin/multicore.rs
@@ -1,10 +1,13 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{info, unwrap}; 8use defmt::{info, unwrap};
6use embassy_executor::Executor; 9use embassy_executor::Executor;
7use embassy_rp::multicore::{spawn_core1, Stack}; 10use embassy_rp::multicore::{Stack, spawn_core1};
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 11use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel; 12use embassy_sync::channel::Channel;
10use static_cell::StaticCell; 13use static_cell::StaticCell;
@@ -24,11 +27,11 @@ fn main() -> ! {
24 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
25 move || { 28 move || {
26 let executor1 = EXECUTOR1.init(Executor::new()); 29 let executor1 = EXECUTOR1.init(Executor::new());
27 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); 30 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
28 }, 31 },
29 ); 32 );
30 let executor0 = EXECUTOR0.init(Executor::new()); 33 let executor0 = EXECUTOR0.init(Executor::new());
31 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 34 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
32} 35}
33 36
34#[embassy_executor::task] 37#[embassy_executor::task]
diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs
new file mode 100644
index 000000000..87a03b5e2
--- /dev/null
+++ b/tests/rp/src/bin/overclock.rs
@@ -0,0 +1,69 @@
1#![no_std]
2#![no_main]
3
4#[cfg(feature = "rp2040")]
5teleprobe_meta::target!(b"rpi-pico");
6#[cfg(feature = "rp235xb")]
7teleprobe_meta::target!(b"pimoroni-pico-plus-2");
8
9use defmt::info;
10use embassy_executor::Spawner;
11use embassy_rp::clocks::{ClockConfig, CoreVoltage, clk_sys_freq, core_voltage};
12use embassy_rp::config::Config;
13use embassy_time::Instant;
14use {defmt_rtt as _, panic_probe as _};
15
16const COUNT_TO: i64 = 10_000_000;
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let mut config = Config::default();
21
22 // Initialize with 200MHz clock configuration
23 config.clocks = ClockConfig::system_freq(200_000_000).unwrap();
24
25 // if we are rp235x, we need to manually set the core voltage. rp2040 should do this automatically
26 #[cfg(feature = "rp235xb")]
27 {
28 config.clocks.core_voltage = CoreVoltage::V1_15;
29 }
30
31 let _p = embassy_rp::init(config);
32
33 // We should be at core voltage of 1.15V
34 assert_eq!(core_voltage().unwrap(), CoreVoltage::V1_15, "Core voltage is not 1.15V");
35 // We should be at 200MHz
36 assert_eq!(clk_sys_freq(), 200_000_000, "System clock frequency is not 200MHz");
37
38 // Test the system speed
39 let time_elapsed = {
40 let mut counter = 0;
41 let start = Instant::now();
42 while counter < COUNT_TO {
43 counter += 1;
44 }
45 let elapsed = Instant::now() - start;
46
47 elapsed.as_millis()
48 };
49
50 // Tests will fail if unused variables are detected:
51 // Report the elapsed time, so that the compiler doesn't optimize it away for the chip not on test
52 info!(
53 "At {}Mhz: Elapsed time to count to {}: {}ms",
54 clk_sys_freq() / 1_000_000,
55 COUNT_TO,
56 time_elapsed
57 );
58
59 // Check if the elapsed time is within expected limits
60 // for rp2040 we expect about 600ms
61 #[cfg(feature = "rp2040")]
62 // allow 1% error
63 assert!(time_elapsed < 606, "Elapsed time is too long");
64 // for rp235x we expect about 450ms
65 #[cfg(feature = "rp235xb")]
66 assert!(time_elapsed < 455, "Elapsed time is too long");
67
68 cortex_m::asm::bkpt();
69}
diff --git a/tests/rp/src/bin/pio_irq.rs b/tests/rp/src/bin/pio_irq.rs
index 33cdaaac9..dc37dd83d 100644
--- a/tests/rp/src/bin/pio_irq.rs
+++ b/tests/rp/src/bin/pio_irq.rs
@@ -1,11 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::info; 8use defmt::info;
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 11use embassy_rp::peripherals::PIO0;
12use embassy_rp::pio::program::pio_asm;
9use embassy_rp::pio::{Config, InterruptHandler, Pio}; 13use embassy_rp::pio::{Config, InterruptHandler, Pio};
10use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
11 15
@@ -24,7 +28,7 @@ async fn main(_spawner: Spawner) {
24 .. 28 ..
25 } = Pio::new(pio, Irqs); 29 } = Pio::new(pio, Irqs);
26 30
27 let prg = pio_proc::pio_asm!( 31 let prg = pio_asm!(
28 "irq set 0", 32 "irq set 0",
29 "irq wait 0", 33 "irq wait 0",
30 "irq set 1", 34 "irq set 1",
diff --git a/tests/rp/src/bin/pio_multi_load.rs b/tests/rp/src/bin/pio_multi_load.rs
index cd28f99b6..82bbab272 100644
--- a/tests/rp/src/bin/pio_multi_load.rs
+++ b/tests/rp/src/bin/pio_multi_load.rs
@@ -1,11 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::info; 8use defmt::info;
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 11use embassy_rp::peripherals::PIO0;
12use embassy_rp::pio::program::pio_asm;
9use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio}; 13use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio};
10use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
11 15
@@ -27,7 +31,7 @@ async fn main(_spawner: Spawner) {
27 } = Pio::new(pio, Irqs); 31 } = Pio::new(pio, Irqs);
28 32
29 // load with explicit origin works 33 // load with explicit origin works
30 let prg1 = pio_proc::pio_asm!( 34 let prg1 = pio_asm!(
31 ".origin 4" 35 ".origin 4"
32 "nop", 36 "nop",
33 "nop", 37 "nop",
@@ -46,15 +50,16 @@ async fn main(_spawner: Spawner) {
46 assert_eq!(loaded1.wrap.target, 4); 50 assert_eq!(loaded1.wrap.target, 4);
47 51
48 // load without origin chooses a free space 52 // load without origin chooses a free space
49 let prg2 = pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",); 53 let prg2 = pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",);
50 let loaded2 = common.load_program(&prg2.program); 54 let loaded2 = common.load_program(&prg2.program);
51 assert_eq!(loaded2.origin, 14); 55 assert_eq!(loaded2.origin, 14);
52 assert_eq!(loaded2.wrap.source, 23); 56 assert_eq!(loaded2.wrap.source, 23);
53 assert_eq!(loaded2.wrap.target, 14); 57 assert_eq!(loaded2.wrap.target, 14);
54 58
55 // wrapping around the end of program space automatically works 59 // wrapping around the end of program space automatically works
56 let prg3 = 60 let prg3 = pio_asm!(
57 pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2",); 61 "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2",
62 );
58 let loaded3 = common.load_program(&prg3.program); 63 let loaded3 = common.load_program(&prg3.program);
59 assert_eq!(loaded3.origin, 24); 64 assert_eq!(loaded3.origin, 24);
60 assert_eq!(loaded3.wrap.source, 3); 65 assert_eq!(loaded3.wrap.source, 3);
@@ -88,13 +93,13 @@ async fn main(_spawner: Spawner) {
88 93
89 // instruction memory is full now. all loads should fail. 94 // instruction memory is full now. all loads should fail.
90 { 95 {
91 let prg = pio_proc::pio_asm!(".origin 0", "nop"); 96 let prg = pio_asm!(".origin 0", "nop");
92 match common.try_load_program(&prg.program) { 97 match common.try_load_program(&prg.program) {
93 Err(LoadError::AddressInUse(0)) => (), 98 Err(LoadError::AddressInUse(0)) => (),
94 _ => panic!("program loaded when it shouldn't"), 99 _ => panic!("program loaded when it shouldn't"),
95 }; 100 };
96 101
97 let prg = pio_proc::pio_asm!("nop"); 102 let prg = pio_asm!("nop");
98 match common.try_load_program(&prg.program) { 103 match common.try_load_program(&prg.program) {
99 Err(LoadError::InsufficientSpace) => (), 104 Err(LoadError::InsufficientSpace) => (),
100 _ => panic!("program loaded when it shouldn't"), 105 _ => panic!("program loaded when it shouldn't"),
@@ -106,13 +111,13 @@ async fn main(_spawner: Spawner) {
106 common.free_instr(loaded3.used_memory); 111 common.free_instr(loaded3.used_memory);
107 } 112 }
108 { 113 {
109 let prg = pio_proc::pio_asm!(".origin 0", "nop"); 114 let prg = pio_asm!(".origin 0", "nop");
110 match common.try_load_program(&prg.program) { 115 match common.try_load_program(&prg.program) {
111 Ok(_) => (), 116 Ok(_) => (),
112 _ => panic!("program didn't loaded when it shouldn"), 117 _ => panic!("program didn't loaded when it shouldn"),
113 }; 118 };
114 119
115 let prg = pio_proc::pio_asm!("nop"); 120 let prg = pio_asm!("nop");
116 match common.try_load_program(&prg.program) { 121 match common.try_load_program(&prg.program) {
117 Ok(_) => (), 122 Ok(_) => (),
118 _ => panic!("program didn't loaded when it shouldn"), 123 _ => panic!("program didn't loaded when it shouldn"),
diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs
index c05197000..5f890cd50 100644
--- a/tests/rp/src/bin/pwm.rs
+++ b/tests/rp/src/bin/pwm.rs
@@ -1,10 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert, assert_eq, assert_ne, *}; 8use defmt::{assert, assert_eq, assert_ne, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::gpio::{Input, Level, Output, Pull}; 10use embassy_rp::gpio::{Input, Pull};
11#[cfg(feature = "rp2040")]
12use embassy_rp::gpio::{Level, Output};
8use embassy_rp::pwm::{Config, InputMode, Pwm}; 13use embassy_rp::pwm::{Config, InputMode, Pwm};
9use embassy_time::Timer; 14use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
@@ -28,7 +33,7 @@ async fn main(_spawner: Spawner) {
28 33
29 // Test free-running clock 34 // Test free-running clock
30 { 35 {
31 let pwm = Pwm::new_free(&mut p.PWM_SLICE3, cfg.clone()); 36 let pwm = Pwm::new_free(p.PWM_SLICE3.reborrow(), cfg.clone());
32 cortex_m::asm::delay(125); 37 cortex_m::asm::delay(125);
33 let ctr = pwm.counter(); 38 let ctr = pwm.counter();
34 assert!(ctr > 0); 39 assert!(ctr > 0);
@@ -45,8 +50,8 @@ async fn main(_spawner: Spawner) {
45 50
46 // Test output from A 51 // Test output from A
47 { 52 {
48 let pin1 = Input::new(&mut p9, Pull::None); 53 let pin1 = Input::new(p9.reborrow(), Pull::None);
49 let _pwm = Pwm::new_output_a(&mut p.PWM_SLICE3, &mut p6, cfg.clone()); 54 let _pwm = Pwm::new_output_a(p.PWM_SLICE3.reborrow(), p6.reborrow(), cfg.clone());
50 Timer::after_millis(1).await; 55 Timer::after_millis(1).await;
51 assert_eq!(pin1.is_low(), invert_a); 56 assert_eq!(pin1.is_low(), invert_a);
52 Timer::after_millis(5).await; 57 Timer::after_millis(5).await;
@@ -59,8 +64,8 @@ async fn main(_spawner: Spawner) {
59 64
60 // Test output from B 65 // Test output from B
61 { 66 {
62 let pin2 = Input::new(&mut p11, Pull::None); 67 let pin2 = Input::new(p11.reborrow(), Pull::None);
63 let _pwm = Pwm::new_output_b(&mut p.PWM_SLICE3, &mut p7, cfg.clone()); 68 let _pwm = Pwm::new_output_b(p.PWM_SLICE3.reborrow(), p7.reborrow(), cfg.clone());
64 Timer::after_millis(1).await; 69 Timer::after_millis(1).await;
65 assert_ne!(pin2.is_low(), invert_a); 70 assert_ne!(pin2.is_low(), invert_a);
66 Timer::after_millis(5).await; 71 Timer::after_millis(5).await;
@@ -73,9 +78,9 @@ async fn main(_spawner: Spawner) {
73 78
74 // Test output from A+B 79 // Test output from A+B
75 { 80 {
76 let pin1 = Input::new(&mut p9, Pull::None); 81 let pin1 = Input::new(p9.reborrow(), Pull::None);
77 let pin2 = Input::new(&mut p11, Pull::None); 82 let pin2 = Input::new(p11.reborrow(), Pull::None);
78 let _pwm = Pwm::new_output_ab(&mut p.PWM_SLICE3, &mut p6, &mut p7, cfg.clone()); 83 let _pwm = Pwm::new_output_ab(p.PWM_SLICE3.reborrow(), p6.reborrow(), p7.reborrow(), cfg.clone());
79 Timer::after_millis(1).await; 84 Timer::after_millis(1).await;
80 assert_eq!(pin1.is_low(), invert_a); 85 assert_eq!(pin1.is_low(), invert_a);
81 assert_ne!(pin2.is_low(), invert_a); 86 assert_ne!(pin2.is_low(), invert_a);
@@ -92,9 +97,16 @@ async fn main(_spawner: Spawner) {
92 } 97 }
93 98
94 // Test level-gated 99 // Test level-gated
100 #[cfg(feature = "rp2040")]
95 { 101 {
96 let mut pin2 = Output::new(&mut p11, Level::Low); 102 let mut pin2 = Output::new(p11.reborrow(), Level::Low);
97 let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, Pull::None, InputMode::Level, cfg.clone()); 103 let pwm = Pwm::new_input(
104 p.PWM_SLICE3.reborrow(),
105 p7.reborrow(),
106 Pull::None,
107 InputMode::Level,
108 cfg.clone(),
109 );
98 assert_eq!(pwm.counter(), 0); 110 assert_eq!(pwm.counter(), 0);
99 Timer::after_millis(5).await; 111 Timer::after_millis(5).await;
100 assert_eq!(pwm.counter(), 0); 112 assert_eq!(pwm.counter(), 0);
@@ -102,17 +114,19 @@ async fn main(_spawner: Spawner) {
102 Timer::after_millis(1).await; 114 Timer::after_millis(1).await;
103 pin2.set_low(); 115 pin2.set_low();
104 let ctr = pwm.counter(); 116 let ctr = pwm.counter();
117 info!("ctr: {}", ctr);
105 assert!(ctr >= 1000); 118 assert!(ctr >= 1000);
106 Timer::after_millis(1).await; 119 Timer::after_millis(1).await;
107 assert_eq!(pwm.counter(), ctr); 120 assert_eq!(pwm.counter(), ctr);
108 } 121 }
109 122
110 // Test rising-gated 123 // Test rising-gated
124 #[cfg(feature = "rp2040")]
111 { 125 {
112 let mut pin2 = Output::new(&mut p11, Level::Low); 126 let mut pin2 = Output::new(p11.reborrow(), Level::Low);
113 let pwm = Pwm::new_input( 127 let pwm = Pwm::new_input(
114 &mut p.PWM_SLICE3, 128 p.PWM_SLICE3.reborrow(),
115 &mut p7, 129 p7.reborrow(),
116 Pull::None, 130 Pull::None,
117 InputMode::RisingEdge, 131 InputMode::RisingEdge,
118 cfg.clone(), 132 cfg.clone(),
@@ -129,11 +143,12 @@ async fn main(_spawner: Spawner) {
129 } 143 }
130 144
131 // Test falling-gated 145 // Test falling-gated
146 #[cfg(feature = "rp2040")]
132 { 147 {
133 let mut pin2 = Output::new(&mut p11, Level::High); 148 let mut pin2 = Output::new(p11.reborrow(), Level::High);
134 let pwm = Pwm::new_input( 149 let pwm = Pwm::new_input(
135 &mut p.PWM_SLICE3, 150 p.PWM_SLICE3.reborrow(),
136 &mut p7, 151 p7.reborrow(),
137 Pull::None, 152 Pull::None,
138 InputMode::FallingEdge, 153 InputMode::FallingEdge,
139 cfg.clone(), 154 cfg.clone(),
@@ -151,10 +166,10 @@ async fn main(_spawner: Spawner) {
151 166
152 // pull-down 167 // pull-down
153 { 168 {
154 let pin2 = Input::new(&mut p11, Pull::None); 169 let pin2 = Input::new(p11.reborrow(), Pull::None);
155 Pwm::new_input( 170 Pwm::new_input(
156 &mut p.PWM_SLICE3, 171 p.PWM_SLICE3.reborrow(),
157 &mut p7, 172 p7.reborrow(),
158 Pull::Down, 173 Pull::Down,
159 InputMode::FallingEdge, 174 InputMode::FallingEdge,
160 cfg.clone(), 175 cfg.clone(),
@@ -165,10 +180,10 @@ async fn main(_spawner: Spawner) {
165 180
166 // pull-up 181 // pull-up
167 { 182 {
168 let pin2 = Input::new(&mut p11, Pull::None); 183 let pin2 = Input::new(p11.reborrow(), Pull::None);
169 Pwm::new_input( 184 Pwm::new_input(
170 &mut p.PWM_SLICE3, 185 p.PWM_SLICE3.reborrow(),
171 &mut p7, 186 p7.reborrow(),
172 Pull::Up, 187 Pull::Up,
173 InputMode::FallingEdge, 188 InputMode::FallingEdge,
174 cfg.clone(), 189 cfg.clone(),
diff --git a/tests/rp/src/bin/rtc.rs b/tests/rp/src/bin/rtc.rs
new file mode 100644
index 000000000..e1def7b5b
--- /dev/null
+++ b/tests/rp/src/bin/rtc.rs
@@ -0,0 +1,125 @@
1#![no_std]
2#![no_main]
3#[cfg(feature = "rp2040")]
4teleprobe_meta::target!(b"rpi-pico");
5
6use defmt::{assert, *};
7use embassy_executor::Spawner;
8use embassy_futures::select::{Either, select};
9use embassy_rp::bind_interrupts;
10use embassy_rp::rtc::{DateTime, DateTimeFilter, DayOfWeek, Rtc};
11use embassy_time::{Duration, Instant, Timer};
12use {defmt_rtt as _, panic_probe as _};
13
14// Bind the RTC interrupt to the handler
15bind_interrupts!(struct Irqs {
16 RTC_IRQ => embassy_rp::rtc::InterruptHandler;
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 let p = embassy_rp::init(Default::default());
22 let mut rtc = Rtc::new(p.RTC, Irqs);
23
24 info!("RTC test started");
25
26 // Initialize RTC if not running
27 if !rtc.is_running() {
28 info!("Starting RTC");
29 let now = DateTime {
30 year: 2000,
31 month: 1,
32 day: 1,
33 day_of_week: DayOfWeek::Saturday,
34 hour: 0,
35 minute: 0,
36 second: 0,
37 };
38 rtc.set_datetime(now).unwrap();
39 Timer::after_millis(100).await;
40 }
41
42 // Test 1: Basic RTC functionality - read current time
43 let initial_time = rtc.now().unwrap();
44 info!(
45 "Initial time: {}-{:02}-{:02} {}:{:02}:{:02}",
46 initial_time.year,
47 initial_time.month,
48 initial_time.day,
49 initial_time.hour,
50 initial_time.minute,
51 initial_time.second
52 );
53
54 // Test 2: Schedule and wait for alarm
55 info!("Testing alarm scheduling");
56
57 // Wait until we're at a predictable second, then schedule for a future second
58 loop {
59 let current = rtc.now().unwrap();
60 if current.second <= 55 {
61 break;
62 }
63 Timer::after_millis(100).await;
64 }
65
66 // Now schedule alarm for 3 seconds from current time
67 let current_time = rtc.now().unwrap();
68 let alarm_second = (current_time.second + 3) % 60;
69 let alarm_filter = DateTimeFilter::default().second(alarm_second);
70
71 info!("Scheduling alarm for second: {}", alarm_second);
72 rtc.schedule_alarm(alarm_filter);
73
74 // Verify alarm is scheduled
75 let scheduled = rtc.alarm_scheduled();
76 assert!(scheduled.is_some(), "Alarm should be scheduled");
77 info!("Alarm scheduled successfully: {}", scheduled.unwrap());
78
79 // Wait for alarm with timeout
80 let alarm_start = Instant::now();
81 match select(Timer::after_secs(5), rtc.wait_for_alarm()).await {
82 Either::First(_) => {
83 core::panic!("Alarm timeout - alarm should have triggered by now");
84 }
85 Either::Second(_) => {
86 let alarm_duration = Instant::now() - alarm_start;
87 info!("ALARM TRIGGERED after {:?}", alarm_duration);
88
89 // Verify timing is reasonable (should be around 3 seconds)
90 assert!(
91 alarm_duration >= Duration::from_secs(2) && alarm_duration <= Duration::from_secs(4),
92 "Alarm timing incorrect: {:?}",
93 alarm_duration
94 );
95 }
96 }
97
98 // Test 3: Verify RTC is still running and time has advanced
99 let final_time = rtc.now().unwrap();
100 info!(
101 "Final time: {}-{:02}-{:02} {}:{:02}:{:02}",
102 final_time.year, final_time.month, final_time.day, final_time.hour, final_time.minute, final_time.second
103 );
104
105 // Verify time has advanced (allowing for minute/hour rollover)
106 let time_diff = if final_time.second >= initial_time.second {
107 final_time.second - initial_time.second
108 } else {
109 60 - initial_time.second + final_time.second
110 };
111
112 assert!(time_diff >= 3, "RTC should have advanced by at least 3 seconds");
113 info!("Time advanced by {} seconds", time_diff);
114
115 // Test 4: Verify alarm is no longer scheduled after triggering
116 let post_alarm_scheduled = rtc.alarm_scheduled();
117 assert!(
118 post_alarm_scheduled.is_none(),
119 "Alarm should not be scheduled after triggering"
120 );
121 info!("Alarm correctly cleared after triggering");
122
123 info!("Test OK");
124 cortex_m::asm::bkpt();
125}
diff --git a/tests/rp/src/bin/spi.rs b/tests/rp/src/bin/spi.rs
index 4b02942a7..6802bfc99 100644
--- a/tests/rp/src/bin/spi.rs
+++ b/tests/rp/src/bin/spi.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/tests/rp/src/bin/spi_async.rs b/tests/rp/src/bin/spi_async.rs
index efdc80b53..e50667435 100644
--- a/tests/rp/src/bin/spi_async.rs
+++ b/tests/rp/src/bin/spi_async.rs
@@ -3,7 +3,10 @@
3//! 3//!
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#[cfg(feature = "rp2040")]
6teleprobe_meta::target!(b"rpi-pico"); 7teleprobe_meta::target!(b"rpi-pico");
8#[cfg(feature = "rp235xb")]
9teleprobe_meta::target!(b"pimoroni-pico-plus-2");
7 10
8use defmt::{assert_eq, *}; 11use defmt::{assert_eq, *};
9use embassy_executor::Spawner; 12use embassy_executor::Spawner;
diff --git a/tests/rp/src/bin/spinlock_mutex_multicore.rs b/tests/rp/src/bin/spinlock_mutex_multicore.rs
new file mode 100644
index 000000000..25c4faf37
--- /dev/null
+++ b/tests/rp/src/bin/spinlock_mutex_multicore.rs
@@ -0,0 +1,54 @@
1#![no_std]
2#![no_main]
3#[cfg(feature = "rp2040")]
4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
7
8use defmt::{info, unwrap};
9use embassy_executor::Executor;
10use embassy_rp::multicore::{Stack, spawn_core1};
11use embassy_rp::spinlock_mutex::SpinlockRawMutex;
12use embassy_sync::channel::Channel;
13use static_cell::StaticCell;
14use {defmt_rtt as _, panic_probe as _};
15
16static mut CORE1_STACK: Stack<1024> = Stack::new();
17static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
18static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
19static CHANNEL0: Channel<SpinlockRawMutex<0>, bool, 1> = Channel::new();
20static CHANNEL1: Channel<SpinlockRawMutex<1>, bool, 1> = Channel::new();
21
22#[cortex_m_rt::entry]
23fn main() -> ! {
24 let p = embassy_rp::init(Default::default());
25 spawn_core1(
26 p.CORE1,
27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
28 move || {
29 let executor1 = EXECUTOR1.init(Executor::new());
30 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
31 },
32 );
33 let executor0 = EXECUTOR0.init(Executor::new());
34 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
35}
36
37#[embassy_executor::task]
38async fn core0_task() {
39 info!("CORE0 is running");
40 let ping = true;
41 CHANNEL0.send(ping).await;
42 let pong = CHANNEL1.receive().await;
43 assert_eq!(ping, pong);
44
45 info!("Test OK");
46 cortex_m::asm::bkpt();
47}
48
49#[embassy_executor::task]
50async fn core1_task() {
51 info!("CORE1 is running");
52 let ping = CHANNEL0.receive().await;
53 CHANNEL1.send(ping).await;
54}
diff --git a/tests/nrf52840/src/bin/timer.rs b/tests/rp/src/bin/timer.rs
index 117947a94..12a4d7daa 100644
--- a/tests/nrf52840/src/bin/timer.rs
+++ b/tests/rp/src/bin/timer.rs
@@ -1,15 +1,18 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3teleprobe_meta::target!(b"nrf52840-dk"); 3#[cfg(feature = "rp2040")]
4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert, info}; 8use defmt::{assert, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_time::{Instant, Timer}; 10use embassy_time::{Instant, Timer};
8use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
9 12
10#[embassy_executor::main] 13#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
12 let _p = embassy_nrf::init(Default::default()); 15 let _p = embassy_rp::init(Default::default());
13 info!("Hello World!"); 16 info!("Hello World!");
14 17
15 let start = Instant::now(); 18 let start = Instant::now();
@@ -18,6 +21,7 @@ async fn main(_spawner: Spawner) {
18 let ms = (end - start).as_millis(); 21 let ms = (end - start).as_millis();
19 info!("slept for {} ms", ms); 22 info!("slept for {} ms", ms);
20 assert!(ms >= 99); 23 assert!(ms >= 99);
24 assert!(ms < 110);
21 25
22 info!("Test OK"); 26 info!("Test OK");
23 cortex_m::asm::bkpt(); 27 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs
index 6e6e5517b..80230f3fe 100644
--- a/tests/rp/src/bin/uart.rs
+++ b/tests/rp/src/bin/uart.rs
@@ -1,21 +1,24 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::gpio::{Level, Output}; 10use embassy_rp::gpio::{Level, Output};
8use embassy_rp::uart::{Blocking, Config, Error, Instance, Parity, Uart, UartRx}; 11use embassy_rp::uart::{Blocking, Config, Error, Parity, Uart, UartRx};
9use embassy_time::Timer; 12use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
11 14
12fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { 15fn read<const N: usize>(uart: &mut Uart<'_, Blocking>) -> Result<[u8; N], Error> {
13 let mut buf = [255; N]; 16 let mut buf = [255; N];
14 uart.blocking_read(&mut buf)?; 17 uart.blocking_read(&mut buf)?;
15 Ok(buf) 18 Ok(buf)
16} 19}
17 20
18fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { 21fn read1<const N: usize>(uart: &mut UartRx<'_, Blocking>) -> Result<[u8; N], Error> {
19 let mut buf = [255; N]; 22 let mut buf = [255; N];
20 uart.blocking_read(&mut buf)?; 23 uart.blocking_read(&mut buf)?;
21 Ok(buf) 24 Ok(buf)
@@ -53,7 +56,7 @@ async fn main(_spawner: Spawner) {
53 56
54 { 57 {
55 let config = Config::default(); 58 let config = Config::default();
56 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 59 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
57 60
58 // We can't send too many bytes, they have to fit in the FIFO. 61 // We can't send too many bytes, they have to fit in the FIFO.
59 // This is because we aren't sending+receiving at the same time. 62 // This is because we aren't sending+receiving at the same time.
@@ -66,7 +69,7 @@ async fn main(_spawner: Spawner) {
66 info!("test overflow detection"); 69 info!("test overflow detection");
67 { 70 {
68 let config = Config::default(); 71 let config = Config::default();
69 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 72 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
70 73
71 let data = [ 74 let data = [
72 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 75 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
@@ -90,7 +93,7 @@ async fn main(_spawner: Spawner) {
90 info!("test break detection"); 93 info!("test break detection");
91 { 94 {
92 let config = Config::default(); 95 let config = Config::default();
93 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 96 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
94 97
95 // break on empty fifo 98 // break on empty fifo
96 uart.send_break(20).await; 99 uart.send_break(20).await;
@@ -110,11 +113,11 @@ async fn main(_spawner: Spawner) {
110 // parity detection. here we bitbang to not require two uarts. 113 // parity detection. here we bitbang to not require two uarts.
111 info!("test parity error detection"); 114 info!("test parity error detection");
112 { 115 {
113 let mut pin = Output::new(&mut tx, Level::High); 116 let mut pin = Output::new(tx.reborrow(), Level::High);
114 let mut config = Config::default(); 117 let mut config = Config::default();
115 config.baudrate = 1000; 118 config.baudrate = 1000;
116 config.parity = Parity::ParityEven; 119 config.parity = Parity::ParityEven;
117 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); 120 let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config);
118 121
119 async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { 122 async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) {
120 send(pin, v, Some(parity != 0)).await; 123 send(pin, v, Some(parity != 0)).await;
@@ -137,10 +140,10 @@ async fn main(_spawner: Spawner) {
137 // framing error detection. here we bitbang because there's no other way. 140 // framing error detection. here we bitbang because there's no other way.
138 info!("test framing error detection"); 141 info!("test framing error detection");
139 { 142 {
140 let mut pin = Output::new(&mut tx, Level::High); 143 let mut pin = Output::new(tx.reborrow(), Level::High);
141 let mut config = Config::default(); 144 let mut config = Config::default();
142 config.baudrate = 1000; 145 config.baudrate = 1000;
143 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); 146 let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config);
144 147
145 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 148 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
146 if good { 149 if good {
diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs
index d68c23cbd..cb78fc142 100644
--- a/tests/rp/src/bin/uart_buffered.rs
+++ b/tests/rp/src/bin/uart_buffered.rs
@@ -1,13 +1,16 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, panic, *}; 8use defmt::{assert_eq, panic, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
8use embassy_rp::gpio::{Level, Output}; 11use embassy_rp::gpio::{Level, Output};
9use embassy_rp::peripherals::UART0; 12use embassy_rp::peripherals::UART0;
10use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Instance, Parity}; 13use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Parity};
11use embassy_time::Timer; 14use embassy_time::Timer;
12use embedded_io_async::{Read, ReadExactError, Write}; 15use embedded_io_async::{Read, ReadExactError, Write};
13use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
@@ -16,7 +19,7 @@ bind_interrupts!(struct Irqs {
16 UART0_IRQ => BufferedInterruptHandler<UART0>; 19 UART0_IRQ => BufferedInterruptHandler<UART0>;
17}); 20});
18 21
19async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Result<[u8; N], Error> { 22async fn read<const N: usize>(uart: &mut BufferedUart) -> Result<[u8; N], Error> {
20 let mut buf = [255; N]; 23 let mut buf = [255; N];
21 match uart.read_exact(&mut buf).await { 24 match uart.read_exact(&mut buf).await {
22 Ok(()) => Ok(buf), 25 Ok(()) => Ok(buf),
@@ -26,7 +29,7 @@ async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Res
26 } 29 }
27} 30}
28 31
29async fn read1<const N: usize>(uart: &mut BufferedUartRx<'_, impl Instance>) -> Result<[u8; N], Error> { 32async fn read1<const N: usize>(uart: &mut BufferedUartRx) -> Result<[u8; N], Error> {
30 let mut buf = [255; N]; 33 let mut buf = [255; N];
31 match uart.read_exact(&mut buf).await { 34 match uart.read_exact(&mut buf).await {
32 Ok(()) => Ok(buf), 35 Ok(()) => Ok(buf),
@@ -70,7 +73,15 @@ async fn main(_spawner: Spawner) {
70 let config = Config::default(); 73 let config = Config::default();
71 let tx_buf = &mut [0u8; 16]; 74 let tx_buf = &mut [0u8; 16];
72 let rx_buf = &mut [0u8; 16]; 75 let rx_buf = &mut [0u8; 16];
73 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 76 let mut uart = BufferedUart::new(
77 uart.reborrow(),
78 tx.reborrow(),
79 rx.reborrow(),
80 Irqs,
81 tx_buf,
82 rx_buf,
83 config,
84 );
74 85
75 // Make sure we send more bytes than fits in the FIFO, to test the actual 86 // Make sure we send more bytes than fits in the FIFO, to test the actual
76 // bufferedUart. 87 // bufferedUart.
@@ -90,7 +101,15 @@ async fn main(_spawner: Spawner) {
90 let config = Config::default(); 101 let config = Config::default();
91 let tx_buf = &mut [0u8; 16]; 102 let tx_buf = &mut [0u8; 16];
92 let rx_buf = &mut [0u8; 16]; 103 let rx_buf = &mut [0u8; 16];
93 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 104 let mut uart = BufferedUart::new(
105 uart.reborrow(),
106 tx.reborrow(),
107 rx.reborrow(),
108 Irqs,
109 tx_buf,
110 rx_buf,
111 config,
112 );
94 113
95 // Make sure we send more bytes than fits in the FIFO, to test the actual 114 // Make sure we send more bytes than fits in the FIFO, to test the actual
96 // bufferedUart. 115 // bufferedUart.
@@ -125,7 +144,15 @@ async fn main(_spawner: Spawner) {
125 config.baudrate = 1000; 144 config.baudrate = 1000;
126 let tx_buf = &mut [0u8; 16]; 145 let tx_buf = &mut [0u8; 16];
127 let rx_buf = &mut [0u8; 16]; 146 let rx_buf = &mut [0u8; 16];
128 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 147 let mut uart = BufferedUart::new(
148 uart.reborrow(),
149 tx.reborrow(),
150 rx.reborrow(),
151 Irqs,
152 tx_buf,
153 rx_buf,
154 config,
155 );
129 156
130 // break on empty buffer 157 // break on empty buffer
131 uart.send_break(20).await; 158 uart.send_break(20).await;
@@ -153,13 +180,13 @@ async fn main(_spawner: Spawner) {
153 // parity detection. here we bitbang to not require two uarts. 180 // parity detection. here we bitbang to not require two uarts.
154 info!("test parity error detection"); 181 info!("test parity error detection");
155 { 182 {
156 let mut pin = Output::new(&mut tx, Level::High); 183 let mut pin = Output::new(tx.reborrow(), Level::High);
157 // choose a very slow baud rate to make tests reliable even with O0 184 // choose a very slow baud rate to make tests reliable even with O0
158 let mut config = Config::default(); 185 let mut config = Config::default();
159 config.baudrate = 1000; 186 config.baudrate = 1000;
160 config.parity = Parity::ParityEven; 187 config.parity = Parity::ParityEven;
161 let rx_buf = &mut [0u8; 16]; 188 let rx_buf = &mut [0u8; 16];
162 let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); 189 let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config);
163 190
164 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { 191 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) {
165 send(pin, v, Some(parity != 0)).await; 192 send(pin, v, Some(parity != 0)).await;
@@ -201,12 +228,12 @@ async fn main(_spawner: Spawner) {
201 // framing error detection. here we bitbang because there's no other way. 228 // framing error detection. here we bitbang because there's no other way.
202 info!("test framing error detection"); 229 info!("test framing error detection");
203 { 230 {
204 let mut pin = Output::new(&mut tx, Level::High); 231 let mut pin = Output::new(tx.reborrow(), Level::High);
205 // choose a very slow baud rate to make tests reliable even with O0 232 // choose a very slow baud rate to make tests reliable even with O0
206 let mut config = Config::default(); 233 let mut config = Config::default();
207 config.baudrate = 1000; 234 config.baudrate = 1000;
208 let rx_buf = &mut [0u8; 16]; 235 let rx_buf = &mut [0u8; 16];
209 let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); 236 let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config);
210 237
211 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 238 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
212 if good { 239 if good {
diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs
index edc87175a..a7af81f5f 100644
--- a/tests/rp/src/bin/uart_dma.rs
+++ b/tests/rp/src/bin/uart_dma.rs
@@ -1,13 +1,16 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
8use embassy_rp::gpio::{Level, Output}; 11use embassy_rp::gpio::{Level, Output};
9use embassy_rp::peripherals::UART0; 12use embassy_rp::peripherals::UART0;
10use embassy_rp::uart::{Async, Config, Error, Instance, InterruptHandler, Parity, Uart, UartRx}; 13use embassy_rp::uart::{Async, Config, Error, InterruptHandler, Parity, Uart, UartRx};
11use embassy_time::Timer; 14use embassy_time::Timer;
12use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
13 16
@@ -15,13 +18,13 @@ bind_interrupts!(struct Irqs {
15 UART0_IRQ => InterruptHandler<UART0>; 18 UART0_IRQ => InterruptHandler<UART0>;
16}); 19});
17 20
18async fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Async>) -> Result<[u8; N], Error> { 21async fn read<const N: usize>(uart: &mut Uart<'_, Async>) -> Result<[u8; N], Error> {
19 let mut buf = [255; N]; 22 let mut buf = [255; N];
20 uart.read(&mut buf).await?; 23 uart.read(&mut buf).await?;
21 Ok(buf) 24 Ok(buf)
22} 25}
23 26
24async fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Async>) -> Result<[u8; N], Error> { 27async fn read1<const N: usize>(uart: &mut UartRx<'_, Async>) -> Result<[u8; N], Error> {
25 let mut buf = [255; N]; 28 let mut buf = [255; N];
26 uart.read(&mut buf).await?; 29 uart.read(&mut buf).await?;
27 Ok(buf) 30 Ok(buf)
@@ -62,12 +65,12 @@ async fn main(_spawner: Spawner) {
62 { 65 {
63 let config = Config::default(); 66 let config = Config::default();
64 let mut uart = Uart::new( 67 let mut uart = Uart::new(
65 &mut uart, 68 uart.reborrow(),
66 &mut tx, 69 tx.reborrow(),
67 &mut rx, 70 rx.reborrow(),
68 Irqs, 71 Irqs,
69 &mut p.DMA_CH0, 72 p.DMA_CH0.reborrow(),
70 &mut p.DMA_CH1, 73 p.DMA_CH1.reborrow(),
71 config, 74 config,
72 ); 75 );
73 76
@@ -83,12 +86,12 @@ async fn main(_spawner: Spawner) {
83 { 86 {
84 let config = Config::default(); 87 let config = Config::default();
85 let mut uart = Uart::new( 88 let mut uart = Uart::new(
86 &mut uart, 89 uart.reborrow(),
87 &mut tx, 90 tx.reborrow(),
88 &mut rx, 91 rx.reborrow(),
89 Irqs, 92 Irqs,
90 &mut p.DMA_CH0, 93 p.DMA_CH0.reborrow(),
91 &mut p.DMA_CH1, 94 p.DMA_CH1.reborrow(),
92 config, 95 config,
93 ); 96 );
94 97
@@ -112,12 +115,12 @@ async fn main(_spawner: Spawner) {
112 { 115 {
113 let config = Config::default(); 116 let config = Config::default();
114 let (mut tx, mut rx) = Uart::new( 117 let (mut tx, mut rx) = Uart::new(
115 &mut uart, 118 uart.reborrow(),
116 &mut tx, 119 tx.reborrow(),
117 &mut rx, 120 rx.reborrow(),
118 Irqs, 121 Irqs,
119 &mut p.DMA_CH0, 122 p.DMA_CH0.reborrow(),
120 &mut p.DMA_CH1, 123 p.DMA_CH1.reborrow(),
121 config, 124 config,
122 ) 125 )
123 .split(); 126 .split();
@@ -153,12 +156,12 @@ async fn main(_spawner: Spawner) {
153 // parity detection. here we bitbang to not require two uarts. 156 // parity detection. here we bitbang to not require two uarts.
154 info!("test parity error detection"); 157 info!("test parity error detection");
155 { 158 {
156 let mut pin = Output::new(&mut tx, Level::High); 159 let mut pin = Output::new(tx.reborrow(), Level::High);
157 // choose a very slow baud rate to make tests reliable even with O0 160 // choose a very slow baud rate to make tests reliable even with O0
158 let mut config = Config::default(); 161 let mut config = Config::default();
159 config.baudrate = 1000; 162 config.baudrate = 1000;
160 config.parity = Parity::ParityEven; 163 config.parity = Parity::ParityEven;
161 let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); 164 let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config);
162 165
163 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { 166 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) {
164 send(pin, v, Some(parity != 0)).await; 167 send(pin, v, Some(parity != 0)).await;
@@ -199,11 +202,11 @@ async fn main(_spawner: Spawner) {
199 // framing error detection. here we bitbang because there's no other way. 202 // framing error detection. here we bitbang because there's no other way.
200 info!("test framing error detection"); 203 info!("test framing error detection");
201 { 204 {
202 let mut pin = Output::new(&mut tx, Level::High); 205 let mut pin = Output::new(tx.reborrow(), Level::High);
203 // choose a very slow baud rate to make tests reliable even with O0 206 // choose a very slow baud rate to make tests reliable even with O0
204 let mut config = Config::default(); 207 let mut config = Config::default();
205 config.baudrate = 1000; 208 config.baudrate = 1000;
206 let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); 209 let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config);
207 210
208 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 211 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
209 if good { 212 if good {
diff --git a/tests/rp/src/bin/uart_upgrade.rs b/tests/rp/src/bin/uart_upgrade.rs
index 603e20f2f..f658b6b8c 100644
--- a/tests/rp/src/bin/uart_upgrade.rs
+++ b/tests/rp/src/bin/uart_upgrade.rs
@@ -1,6 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#[cfg(feature = "rp2040")]
3teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5#[cfg(feature = "rp235xb")]
6teleprobe_meta::target!(b"pimoroni-pico-plus-2");
4 7
5use defmt::{assert_eq, *}; 8use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml
index 8752da59b..d94342598 100644
--- a/tests/stm32/.cargo/config.toml
+++ b/tests/stm32/.cargo/config.toml
@@ -9,7 +9,6 @@ runner = "teleprobe client run"
9rustflags = [ 9rustflags = [
10 # Code-size optimizations. 10 # Code-size optimizations.
11 #"-Z", "trap-unreachable=no", 11 #"-Z", "trap-unreachable=no",
12 "-C", "inline-threshold=5",
13 "-C", "no-vectorize-loops", 12 "-C", "no-vectorize-loops",
14] 13]
15 14
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index f94814e70..8fcb6b2b4 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -1,45 +1,50 @@
1[package] 1[package]
2edition = "2021" 2edition = "2024"
3name = "embassy-stm32-tests" 3name = "embassy-stm32-tests"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6autobins = false 6autobins = false
7publish = false
7 8
8[features] 9[features]
9stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] 10stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
10stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma"] 11stm32c071rb = ["embassy-stm32/stm32c071rb", "cm0", "not-gpdma"]
12stm32f100rd = ["embassy-stm32/stm32f100rd", "spi-v1", "not-gpdma", "afio", "afio-value-line"]
13stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma", "afio"]
14stm32f107vc = ["embassy-stm32/stm32f107vc", "spi-v1", "not-gpdma", "afio", "afio-connectivity-line"]
11stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"] 15stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"]
12stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] 16stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"]
13stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] 17stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"]
14stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] 18stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"]
15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] 19stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng", "single-bank"]
16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] 20stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"]
17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] 21stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"]
18stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"] 22stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash-v34", "cordic", "stop"]
19stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] 23stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"]
20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] 24stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"]
21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] 25stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"]
22stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] 26stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng", "eeprom"]
23stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma"] 27stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma", "eeprom"]
24stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] 28stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"]
25stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] 29stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"]
26stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] 30stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng", "dual-bank"]
27stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] 31stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash", "dual-bank"]
28stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"] 32stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"]
29stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash 33stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash
30stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] 34stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng", "hsem", "stop"]
31stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"] 35stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"]
32stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] 36stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono", "hsem"]
33stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] 37stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
34stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] 38stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"]
35stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs. 39stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash-v34"] # TODO: fdcan crashes, cryp dma hangs.
36stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] 40stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"]
37 41
38spi-v1 = [] 42spi-v1 = []
39spi-v345 = [] 43spi-v345 = []
40cryp = [] 44cryp = []
41hash = [] 45hash = []
42eth = ["embassy-executor/task-arena-size-16384"] 46hash-v34 = ["hash"]
47eth = []
43rng = [] 48rng = []
44sdmmc = [] 49sdmmc = []
45stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] 50stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"]
@@ -53,23 +58,30 @@ not-gpdma = []
53dac = [] 58dac = []
54ucpd = [] 59ucpd = []
55cordic = ["dep:num-traits"] 60cordic = ["dep:num-traits"]
61hsem = []
62dual-bank = ["embassy-stm32/dual-bank"]
63single-bank = ["embassy-stm32/single-bank"]
64eeprom = []
65afio = []
66afio-connectivity-line = []
67afio-value-line = []
56 68
57cm0 = ["portable-atomic/unsafe-assume-single-core"] 69cm0 = ["portable-atomic/unsafe-assume-single-core"]
58 70
59[dependencies] 71[dependencies]
60teleprobe-meta = "1" 72teleprobe-meta = "1"
61 73
62embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } 74embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
63embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 75embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
64embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } 76embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] }
65embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } 77embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any", "_allow-disable-rtc"] }
66embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 78embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
67embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } 79embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] }
68embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 80embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
69perf-client = { path = "../perf-client" } 81perf-client = { path = "../perf-client" }
70 82
71defmt = "0.3.0" 83defmt = "1.0.1"
72defmt-rtt = "0.4" 84defmt-rtt = "1.0.0"
73 85
74cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 86cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
75cortex-m-rt = "0.7.0" 87cortex-m-rt = "0.7.0"
@@ -78,21 +90,27 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
78embedded-hal-async = { version = "1.0" } 90embedded-hal-async = { version = "1.0" }
79embedded-can = { version = "0.4" } 91embedded-can = { version = "0.4" }
80micromath = "2.0.0" 92micromath = "2.0.0"
81panic-probe = { version = "0.3.0", features = ["print-defmt"] } 93panic-probe = { version = "1.0.0", features = ["print-defmt"] }
82rand_core = { version = "0.6", default-features = false } 94rand_core = { version = "0.9.1", default-features = false }
83rand_chacha = { version = "0.3", default-features = false } 95rand_chacha = { version = "0.9.0", default-features = false }
84static_cell = "2" 96static_cell = "2"
85portable-atomic = { version = "1.5", features = [] } 97portable-atomic = { version = "1.5", features = [] }
98critical-section = "1.1"
86 99
87chrono = { version = "^0.4", default-features = false, optional = true} 100chrono = { version = "^0.4", default-features = false, optional = true}
88sha2 = { version = "0.10.8", default-features = false } 101sha2 = { version = "0.10.8", default-features = false }
89hmac = "0.12.1" 102hmac = "0.12.1"
90aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] } 103aes-gcm = { version = "0.10.3", default-features = false, features = ["aes", "heapless"] }
91num-traits = {version="0.2", default-features = false,features = ["libm"], optional = true} 104num-traits = { version="0.2", default-features = false,features = ["libm"], optional = true}
92 105
93# BEGIN TESTS 106# BEGIN TESTS
94# Generated by gen_test.py. DO NOT EDIT. 107# Generated by gen_test.py. DO NOT EDIT.
95[[bin]] 108[[bin]]
109name = "afio"
110path = "src/bin/afio.rs"
111required-features = [ "afio",]
112
113[[bin]]
96name = "can" 114name = "can"
97path = "src/bin/can.rs" 115path = "src/bin/can.rs"
98required-features = [ "can",] 116required-features = [ "can",]
@@ -118,6 +136,11 @@ path = "src/bin/dac_l1.rs"
118required-features = [ "stm32l152re",] 136required-features = [ "stm32l152re",]
119 137
120[[bin]] 138[[bin]]
139name = "eeprom"
140path = "src/bin/eeprom.rs"
141required-features = [ "eeprom",]
142
143[[bin]]
121name = "eth" 144name = "eth"
122path = "src/bin/eth.rs" 145path = "src/bin/eth.rs"
123required-features = [ "eth",] 146required-features = [ "eth",]
@@ -202,6 +225,11 @@ name = "wpan_mac"
202path = "src/bin/wpan_mac.rs" 225path = "src/bin/wpan_mac.rs"
203required-features = [ "mac",] 226required-features = [ "mac",]
204 227
228[[bin]]
229name = "hsem"
230path = "src/bin/hsem.rs"
231required-features = [ "hsem",]
232
205# END TESTS 233# END TESTS
206 234
207[profile.dev] 235[profile.dev]
@@ -233,3 +261,36 @@ debug = false
233debug-assertions = false 261debug-assertions = false
234opt-level = 0 262opt-level = 0
235overflow-checks = false 263overflow-checks = false
264
265[package.metadata.embassy]
266build = [
267 { target = "thumbv7m-none-eabi", features = ["stm32f103c8"], artifact-dir = "out/tests/stm32f103c8" },
268 { target = "thumbv7em-none-eabi", features = ["stm32f429zi"], artifact-dir = "out/tests/stm32f429zi" },
269 { target = "thumbv7em-none-eabi", features = ["stm32f446re"], artifact-dir = "out/tests/stm32f446re" },
270 { target = "thumbv7em-none-eabi", features = ["stm32g491re"], artifact-dir = "out/tests/stm32g491re" },
271 { target = "thumbv6m-none-eabi", features = ["stm32g071rb"], artifact-dir = "out/tests/stm32g071rb" },
272 { target = "thumbv6m-none-eabi", features = ["stm32c031c6"], artifact-dir = "out/tests/stm32c031c6" },
273 { target = "thumbv6m-none-eabi", features = ["stm32c071rb"], artifact-dir = "out/tests/stm32c071rb" },
274 { target = "thumbv7em-none-eabi", features = ["stm32h755zi"], artifact-dir = "out/tests/stm32h755zi" },
275 { target = "thumbv7em-none-eabi", features = ["stm32h753zi"], artifact-dir = "out/tests/stm32h753zi" },
276 { target = "thumbv7em-none-eabi", features = ["stm32h7a3zi"], artifact-dir = "out/tests/stm32h7a3zi" },
277 { target = "thumbv7em-none-eabi", features = ["stm32wb55rg"], artifact-dir = "out/tests/stm32wb55rg" },
278 { target = "thumbv8m.main-none-eabihf", features = ["stm32h563zi"], artifact-dir = "out/tests/stm32h563zi" },
279 { target = "thumbv8m.main-none-eabihf", features = ["stm32u585ai"], artifact-dir = "out/tests/stm32u585ai" },
280 { target = "thumbv8m.main-none-eabihf", features = ["stm32u5a5zj"], artifact-dir = "out/tests/stm32u5a5zj" },
281 { target = "thumbv8m.main-none-eabihf", features = ["stm32wba52cg"], artifact-dir = "out/tests/stm32wba52cg" },
282 { target = "thumbv6m-none-eabi", features = ["stm32l073rz"], artifact-dir = "out/tests/stm32l073rz" },
283 { target = "thumbv7m-none-eabi", features = ["stm32l152re"], artifact-dir = "out/tests/stm32l152re" },
284 { target = "thumbv7em-none-eabi", features = ["stm32l4a6zg"], artifact-dir = "out/tests/stm32l4a6zg" },
285 { target = "thumbv7em-none-eabi", features = ["stm32l4r5zi"], artifact-dir = "out/tests/stm32l4r5zi" },
286 { target = "thumbv8m.main-none-eabihf", features = ["stm32l552ze"], artifact-dir = "out/tests/stm32l552ze" },
287 { target = "thumbv7em-none-eabi", features = ["stm32f767zi"], artifact-dir = "out/tests/stm32f767zi" },
288 { target = "thumbv7m-none-eabi", features = ["stm32f207zg"], artifact-dir = "out/tests/stm32f207zg" },
289 { target = "thumbv7em-none-eabi", features = ["stm32f303ze"], artifact-dir = "out/tests/stm32f303ze" },
290 { target = "thumbv7em-none-eabi", features = ["stm32l496zg"], artifact-dir = "out/tests/stm32l496zg" },
291 { target = "thumbv7em-none-eabi", features = ["stm32wl55jc"], artifact-dir = "out/tests/stm32wl55jc" },
292 { target = "thumbv7em-none-eabi", features = ["stm32h7s3l8"], artifact-dir = "out/tests/stm32h7s3l8" },
293 { target = "thumbv6m-none-eabi", features = ["stm32f091rc"], artifact-dir = "out/tests/stm32f091rc" },
294 { target = "thumbv8m.main-none-eabihf", features = ["stm32h503rb"], artifact-dir = "out/tests/stm32h503rb" },
295 { target = "thumbv6m-none-eabi", features = ["stm32u083rc"], artifact-dir = "out/tests/stm32u083rc" }
296]
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs
index 722671bf1..556d77a20 100644
--- a/tests/stm32/build.rs
+++ b/tests/stm32/build.rs
@@ -12,6 +12,7 @@ fn main() -> Result<(), Box<dyn Error>> {
12 // too little RAM to run from RAM. 12 // too little RAM to run from RAM.
13 feature = "stm32f103c8", // 20 kb 13 feature = "stm32f103c8", // 20 kb
14 feature = "stm32c031c6", // 6 kb 14 feature = "stm32c031c6", // 6 kb
15 feature = "stm32c071rb", // 24 kb
15 feature = "stm32l073rz", // 20 kb 16 feature = "stm32l073rz", // 20 kb
16 feature = "stm32h503rb", // 32 kb 17 feature = "stm32h503rb", // 32 kb
17 // no VTOR, so interrupts can't work when running from RAM 18 // no VTOR, so interrupts can't work when running from RAM
diff --git a/tests/stm32/src/bin/afio.rs b/tests/stm32/src/bin/afio.rs
new file mode 100644
index 000000000..d88765717
--- /dev/null
+++ b/tests/stm32/src/bin/afio.rs
@@ -0,0 +1,1158 @@
1// required-features: afio
2#![no_std]
3#![no_main]
4#[path = "../common.rs"]
5mod common;
6
7use common::*;
8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{AfioRemap, OutputType, Pull};
10use embassy_stm32::pac::AFIO;
11use embassy_stm32::time::khz;
12use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
13use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
14use embassy_stm32::timer::pwm_input::PwmInput;
15use embassy_stm32::timer::qei::Qei;
16use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
17use embassy_stm32::timer::{Ch1, Ch2};
18use embassy_stm32::usart::{Uart, UartRx, UartTx};
19use embassy_stm32::{Peripherals, bind_interrupts};
20
21#[cfg(not(feature = "afio-connectivity-line"))]
22bind_interrupts!(struct Irqs {
23 USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;
24 TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>;
25});
26
27#[cfg(feature = "afio-connectivity-line")]
28bind_interrupts!(struct Irqs {
29 CAN1_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN1>;
30 CAN1_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN1>;
31 CAN1_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN1>;
32 CAN1_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN1>;
33
34 CAN2_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN2>;
35 CAN2_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN2>;
36 CAN2_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN2>;
37 CAN2_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN2>;
38
39 ETH => embassy_stm32::eth::InterruptHandler;
40 USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;
41 TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>;
42});
43
44#[embassy_executor::main]
45async fn main(_spawner: Spawner) {
46 let mut p = init();
47 info!("Hello World!");
48
49 // USART3
50 {
51 // no remap RX/TX/RTS/CTS
52 afio_registers_set_remap();
53 Uart::new_blocking_with_rtscts(
54 p.USART3.reborrow(),
55 p.PB11.reborrow(),
56 p.PB10.reborrow(),
57 p.PB14.reborrow(),
58 p.PB13.reborrow(),
59 Default::default(),
60 )
61 .unwrap();
62 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
63 }
64 {
65 // no remap RX/TX
66 afio_registers_set_remap();
67 Uart::new_blocking(
68 p.USART3.reborrow(),
69 p.PB11.reborrow(),
70 p.PB10.reborrow(),
71 Default::default(),
72 )
73 .unwrap();
74 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
75 }
76 {
77 // no remap TX
78 afio_registers_set_remap();
79 Uart::new_blocking_half_duplex(
80 p.USART3.reborrow(),
81 p.PB10.reborrow(),
82 Default::default(),
83 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
84 )
85 .unwrap();
86 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
87 }
88 {
89 // no remap TX async
90 afio_registers_set_remap();
91 UartTx::new(
92 p.USART3.reborrow(),
93 p.PB10.reborrow(),
94 p.DMA1_CH2.reborrow(),
95 Default::default(),
96 )
97 .unwrap();
98 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
99 }
100 {
101 // no remap TX/CTS async
102 afio_registers_set_remap();
103 UartTx::new_with_cts(
104 p.USART3.reborrow(),
105 p.PB10.reborrow(),
106 p.PB13.reborrow(),
107 p.DMA1_CH2.reborrow(),
108 Default::default(),
109 )
110 .unwrap();
111 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
112 }
113 {
114 // no remap RX async
115 afio_registers_set_remap();
116 UartRx::new(
117 p.USART3.reborrow(),
118 Irqs,
119 p.PB11.reborrow(),
120 p.DMA1_CH3.reborrow(),
121 Default::default(),
122 )
123 .unwrap();
124 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
125 }
126 {
127 // no remap RX async
128 afio_registers_set_remap();
129 UartRx::new_with_rts(
130 p.USART3.reborrow(),
131 Irqs,
132 p.PB11.reborrow(),
133 p.PB14.reborrow(),
134 p.DMA1_CH3.reborrow(),
135 Default::default(),
136 )
137 .unwrap();
138 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
139 }
140 {
141 // no remap RX/TX async
142 afio_registers_set_remap();
143 Uart::new(
144 p.USART3.reborrow(),
145 p.PB11.reborrow(),
146 p.PB10.reborrow(),
147 Irqs,
148 p.DMA1_CH2.reborrow(),
149 p.DMA1_CH3.reborrow(),
150 Default::default(),
151 )
152 .unwrap();
153 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
154 }
155 {
156 // no remap RX/TX/RTS/CTS async
157 afio_registers_set_remap();
158 Uart::new_with_rtscts(
159 p.USART3.reborrow(),
160 p.PB11.reborrow(),
161 p.PB10.reborrow(),
162 Irqs,
163 p.PB14.reborrow(),
164 p.PB13.reborrow(),
165 p.DMA1_CH2.reborrow(),
166 p.DMA1_CH3.reborrow(),
167 Default::default(),
168 )
169 .unwrap();
170 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
171 }
172
173 // TIM1
174 {
175 // no remap
176 afio_registers_set_remap();
177 SimplePwm::new::<AfioRemap<0>>(
178 p.TIM1.reborrow(),
179 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
180 Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)),
181 Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)),
182 Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)),
183 khz(10),
184 Default::default(),
185 );
186 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0);
187 }
188 {
189 // no remap
190 afio_registers_set_remap();
191 SimplePwm::new::<AfioRemap<0>>(
192 p.TIM1.reborrow(),
193 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
194 None,
195 None,
196 None,
197 khz(10),
198 Default::default(),
199 );
200 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0);
201 }
202 {
203 // partial remap
204 reset_afio_registers();
205 ComplementaryPwm::new::<AfioRemap<1>>(
206 p.TIM1.reborrow(),
207 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
208 None,
209 None,
210 None,
211 None,
212 None,
213 None,
214 None,
215 khz(10),
216 Default::default(),
217 );
218 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
219 }
220 {
221 // partial remap
222 reset_afio_registers();
223 ComplementaryPwm::new::<AfioRemap<1>>(
224 p.TIM1.reborrow(),
225 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
226 Some(ComplementaryPwmPin::new(p.PA7.reborrow(), OutputType::PushPull)),
227 Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)),
228 Some(ComplementaryPwmPin::new(p.PB0.reborrow(), OutputType::PushPull)),
229 Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)),
230 None, // pin does not exist on medium-density devices
231 Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)),
232 None, // signal does not exist
233 khz(10),
234 Default::default(),
235 );
236 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
237 }
238 {
239 // partial remap
240 reset_afio_registers();
241 InputCapture::new::<AfioRemap<1>>(
242 p.TIM1.reborrow(),
243 Some(CapturePin::new(p.PA8.reborrow(), Pull::Down)),
244 None,
245 None,
246 None,
247 Irqs,
248 khz(10),
249 Default::default(),
250 );
251 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
252 }
253 {
254 // partial remap
255 reset_afio_registers();
256 PwmInput::new_ch1::<AfioRemap<1>>(p.TIM1.reborrow(), p.PA8.reborrow(), Pull::Down, khz(10));
257 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
258 }
259 {
260 // partial remap
261 reset_afio_registers();
262 Qei::new::<Ch1, Ch2, AfioRemap<1>>(
263 p.TIM1.reborrow(),
264 p.PA8.reborrow(),
265 p.PA9.reborrow(),
266 Default::default(),
267 );
268 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
269 }
270
271 // TIM2
272 {
273 // no remap
274 afio_registers_set_remap();
275 SimplePwm::new::<AfioRemap<0>>(
276 p.TIM2.reborrow(),
277 Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)),
278 Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)),
279 Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)),
280 Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)),
281 khz(10),
282 Default::default(),
283 );
284 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 0);
285 }
286 {
287 // partial remap 1
288 reset_afio_registers();
289 SimplePwm::new::<AfioRemap<1>>(
290 p.TIM2.reborrow(),
291 Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)),
292 Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)),
293 Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)),
294 Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)),
295 khz(10),
296 Default::default(),
297 );
298 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 1);
299 }
300 {
301 // partial remap 2
302 reset_afio_registers();
303 SimplePwm::new::<AfioRemap<2>>(
304 p.TIM2.reborrow(),
305 Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)),
306 Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)),
307 Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)),
308 Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)),
309 khz(10),
310 Default::default(),
311 );
312 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 2);
313 }
314 {
315 // full remap
316 reset_afio_registers();
317 SimplePwm::new::<AfioRemap<3>>(
318 p.TIM2.reborrow(),
319 Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)),
320 Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)),
321 Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)),
322 Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)),
323 khz(10),
324 Default::default(),
325 );
326 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 3);
327 }
328
329 connectivity_line::run(&mut p);
330 value_line::run(&mut p);
331
332 info!("Test OK");
333 cortex_m::asm::bkpt();
334}
335
336#[cfg(feature = "afio-connectivity-line")]
337mod connectivity_line {
338 use embassy_stm32::can::Can;
339 use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue};
340 use embassy_stm32::i2s::I2S;
341 use embassy_stm32::spi::Spi;
342
343 use super::*;
344
345 pub fn run(p: &mut Peripherals) {
346 // USART3
347 {
348 // partial remap RX/TX/RTS/CTS
349 reset_afio_registers();
350 Uart::new_blocking_with_rtscts(
351 p.USART3.reborrow(),
352 p.PC11.reborrow(),
353 p.PC10.reborrow(),
354 p.PB14.reborrow(),
355 p.PB13.reborrow(),
356 Default::default(),
357 )
358 .unwrap();
359 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
360 }
361 {
362 // partial remap RX/TX
363 reset_afio_registers();
364 Uart::new_blocking(
365 p.USART3.reborrow(),
366 p.PC11.reborrow(),
367 p.PC10.reborrow(),
368 Default::default(),
369 )
370 .unwrap();
371 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
372 }
373 {
374 // partial remap TX
375 reset_afio_registers();
376 Uart::new_blocking_half_duplex(
377 p.USART3.reborrow(),
378 p.PC10.reborrow(),
379 Default::default(),
380 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
381 )
382 .unwrap();
383 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
384 }
385 {
386 // partial remap TX async
387 reset_afio_registers();
388 UartTx::new(
389 p.USART3.reborrow(),
390 p.PC10.reborrow(),
391 p.DMA1_CH2.reborrow(),
392 Default::default(),
393 )
394 .unwrap();
395 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
396 }
397 {
398 // partial remap TX/CTS async
399 reset_afio_registers();
400 UartTx::new_with_cts(
401 p.USART3.reborrow(),
402 p.PC10.reborrow(),
403 p.PB13.reborrow(),
404 p.DMA1_CH2.reborrow(),
405 Default::default(),
406 )
407 .unwrap();
408 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
409 }
410 {
411 // partial remap RX async
412 reset_afio_registers();
413 UartRx::new(
414 p.USART3.reborrow(),
415 Irqs,
416 p.PC11.reborrow(),
417 p.DMA1_CH3.reborrow(),
418 Default::default(),
419 )
420 .unwrap();
421 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
422 }
423 {
424 // partial remap RX async
425 reset_afio_registers();
426 UartRx::new_with_rts(
427 p.USART3.reborrow(),
428 Irqs,
429 p.PC11.reborrow(),
430 p.PB14.reborrow(),
431 p.DMA1_CH3.reborrow(),
432 Default::default(),
433 )
434 .unwrap();
435 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
436 }
437 {
438 // partial remap RX/TX async
439 reset_afio_registers();
440 Uart::new(
441 p.USART3.reborrow(),
442 p.PC11.reborrow(),
443 p.PC10.reborrow(),
444 Irqs,
445 p.DMA1_CH2.reborrow(),
446 p.DMA1_CH3.reborrow(),
447 Default::default(),
448 )
449 .unwrap();
450 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
451 }
452 {
453 // partial remap RX/TX/RTS/CTS async
454 reset_afio_registers();
455 Uart::new_with_rtscts(
456 p.USART3.reborrow(),
457 p.PC11.reborrow(),
458 p.PC10.reborrow(),
459 Irqs,
460 p.PB14.reborrow(),
461 p.PB13.reborrow(),
462 p.DMA1_CH2.reborrow(),
463 p.DMA1_CH3.reborrow(),
464 Default::default(),
465 )
466 .unwrap();
467 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
468 }
469 {
470 // full remap RX/TX/RTS/CTS
471 reset_afio_registers();
472 Uart::new_blocking_with_rtscts(
473 p.USART3.reborrow(),
474 p.PD9.reborrow(),
475 p.PD8.reborrow(),
476 p.PD12.reborrow(),
477 p.PD11.reborrow(),
478 Default::default(),
479 )
480 .unwrap();
481 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
482 }
483 {
484 // full remap RX/TX
485 reset_afio_registers();
486 Uart::new_blocking(
487 p.USART3.reborrow(),
488 p.PD9.reborrow(),
489 p.PD8.reborrow(),
490 Default::default(),
491 )
492 .unwrap();
493 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
494 }
495 {
496 // full remap TX
497 reset_afio_registers();
498 Uart::new_blocking_half_duplex(
499 p.USART3.reborrow(),
500 p.PD8.reborrow(),
501 Default::default(),
502 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
503 )
504 .unwrap();
505 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
506 }
507 {
508 // full remap TX async
509 reset_afio_registers();
510 UartTx::new(
511 p.USART3.reborrow(),
512 p.PD8.reborrow(),
513 p.DMA1_CH2.reborrow(),
514 Default::default(),
515 )
516 .unwrap();
517 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
518 }
519 {
520 // full remap TX/CTS async
521 reset_afio_registers();
522 UartTx::new_with_cts(
523 p.USART3.reborrow(),
524 p.PD8.reborrow(),
525 p.PD11.reborrow(),
526 p.DMA1_CH2.reborrow(),
527 Default::default(),
528 )
529 .unwrap();
530 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
531 }
532 {
533 // full remap RX async
534 reset_afio_registers();
535 UartRx::new(
536 p.USART3.reborrow(),
537 Irqs,
538 p.PD9.reborrow(),
539 p.DMA1_CH3.reborrow(),
540 Default::default(),
541 )
542 .unwrap();
543 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
544 }
545 {
546 // full remap RX async
547 reset_afio_registers();
548 UartRx::new_with_rts(
549 p.USART3.reborrow(),
550 Irqs,
551 p.PD9.reborrow(),
552 p.PD12.reborrow(),
553 p.DMA1_CH3.reborrow(),
554 Default::default(),
555 )
556 .unwrap();
557 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
558 }
559 {
560 // full remap RX/TX async
561 reset_afio_registers();
562 Uart::new(
563 p.USART3.reborrow(),
564 p.PD9.reborrow(),
565 p.PD8.reborrow(),
566 Irqs,
567 p.DMA1_CH2.reborrow(),
568 p.DMA1_CH3.reborrow(),
569 Default::default(),
570 )
571 .unwrap();
572 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
573 }
574 {
575 // full remap RX/TX/RTS/CTS async
576 reset_afio_registers();
577 Uart::new_with_rtscts(
578 p.USART3.reborrow(),
579 p.PD9.reborrow(),
580 p.PD8.reborrow(),
581 Irqs,
582 p.PD12.reborrow(),
583 p.PD11.reborrow(),
584 p.DMA1_CH2.reborrow(),
585 p.DMA1_CH3.reborrow(),
586 Default::default(),
587 )
588 .unwrap();
589 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
590 }
591
592 // SPI3
593 {
594 // no remap SCK/MISO/MOSI
595 afio_registers_set_remap();
596 Spi::new_blocking(
597 p.SPI3.reborrow(),
598 p.PB3.reborrow(),
599 p.PB5.reborrow(),
600 p.PB4.reborrow(),
601 Default::default(),
602 );
603 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
604 }
605 {
606 // no remap SCK/MOSI
607 afio_registers_set_remap();
608 Spi::new_blocking_txonly(
609 p.SPI3.reborrow(),
610 p.PB3.reborrow(),
611 p.PB5.reborrow(),
612 Default::default(),
613 );
614 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
615 }
616 {
617 // no remap MOSI
618 afio_registers_set_remap();
619 Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default());
620 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
621 }
622 {
623 // no remap SCK/MISO
624 afio_registers_set_remap();
625 Spi::new_blocking_rxonly(
626 p.SPI3.reborrow(),
627 p.PB3.reborrow(),
628 p.PB4.reborrow(),
629 Default::default(),
630 );
631 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
632 }
633 {
634 // remap SCK/MISO/MOSI
635 reset_afio_registers();
636 Spi::new_blocking(
637 p.SPI3.reborrow(),
638 p.PC10.reborrow(),
639 p.PC12.reborrow(),
640 p.PC11.reborrow(),
641 Default::default(),
642 );
643
644 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
645 }
646 {
647 // remap SCK/MOSI
648 reset_afio_registers();
649 Spi::new_blocking_txonly(
650 p.SPI3.reborrow(),
651 p.PC10.reborrow(),
652 p.PC12.reborrow(),
653 Default::default(),
654 );
655 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
656 }
657 {
658 // remap MOSI
659 reset_afio_registers();
660 Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default());
661 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
662 }
663 {
664 // remap SCK/MISO
665 reset_afio_registers();
666 Spi::new_blocking_rxonly(
667 p.SPI3.reborrow(),
668 p.PC10.reborrow(),
669 p.PC11.reborrow(),
670 Default::default(),
671 );
672 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
673 }
674
675 // I2S3
676 {
677 // no remap SD/WS/CK/MCK
678 afio_registers_set_remap();
679 I2S::new_txonly(
680 p.SPI3.reborrow(),
681 p.PB5.reborrow(),
682 p.PA15.reborrow(),
683 p.PB3.reborrow(),
684 p.PC7.reborrow(),
685 p.DMA2_CH2.reborrow(),
686 &mut [0u16; 0],
687 Default::default(),
688 );
689 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
690 }
691 {
692 // no remap SD/WS/CK
693 afio_registers_set_remap();
694 I2S::new_txonly_nomck(
695 p.SPI3.reborrow(),
696 p.PB5.reborrow(),
697 p.PA15.reborrow(),
698 p.PB3.reborrow(),
699 p.DMA2_CH2.reborrow(),
700 &mut [0u16; 0],
701 Default::default(),
702 );
703 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
704 }
705 {
706 // no remap SD/WS/CK/MCK
707 afio_registers_set_remap();
708 I2S::new_rxonly(
709 p.SPI3.reborrow(),
710 p.PB4.reborrow(),
711 p.PA15.reborrow(),
712 p.PB3.reborrow(),
713 p.PC7.reborrow(),
714 p.DMA2_CH1.reborrow(),
715 &mut [0u16; 0],
716 Default::default(),
717 );
718 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
719 }
720 {
721 // remap SD/WS/CK/MCK
722 reset_afio_registers();
723 I2S::new_txonly(
724 p.SPI3.reborrow(),
725 p.PC12.reborrow(),
726 p.PA4.reborrow(),
727 p.PC10.reborrow(),
728 p.PC7.reborrow(),
729 p.DMA2_CH2.reborrow(),
730 &mut [0u16; 0],
731 Default::default(),
732 );
733 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
734 }
735 {
736 // remap SD/WS/CK
737 reset_afio_registers();
738 I2S::new_txonly_nomck(
739 p.SPI3.reborrow(),
740 p.PC12.reborrow(),
741 p.PA4.reborrow(),
742 p.PC10.reborrow(),
743 p.DMA2_CH2.reborrow(),
744 &mut [0u16; 0],
745 Default::default(),
746 );
747 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
748 }
749 {
750 // remap SD/WS/CK/MCK
751 reset_afio_registers();
752 I2S::new_rxonly(
753 p.SPI3.reborrow(),
754 p.PC11.reborrow(),
755 p.PA4.reborrow(),
756 p.PC10.reborrow(),
757 p.PC7.reborrow(),
758 p.DMA2_CH1.reborrow(),
759 &mut [0u16; 0],
760 Default::default(),
761 );
762 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
763 }
764
765 // CAN2
766 {
767 // no remap
768 afio_registers_set_remap();
769 Can::new(p.CAN2.reborrow(), p.PB12.reborrow(), p.PB13.reborrow(), Irqs);
770 defmt::assert_eq!(AFIO.mapr().read().can2_remap(), false);
771 }
772 {
773 // remap
774 reset_afio_registers();
775 Can::new(p.CAN2.reborrow(), p.PB5.reborrow(), p.PB6.reborrow(), Irqs);
776 defmt::assert_eq!(AFIO.mapr().read().can2_remap(), true);
777 }
778
779 // Ethernet
780 {
781 // no remap RMII
782 afio_registers_set_remap();
783 Ethernet::new(
784 &mut PacketQueue::<1, 1>::new(),
785 p.ETH.reborrow(),
786 Irqs,
787 p.PA1.reborrow(),
788 p.PA2.reborrow(),
789 p.PC1.reborrow(),
790 p.PA7.reborrow(),
791 p.PC4.reborrow(),
792 p.PC5.reborrow(),
793 p.PB12.reborrow(),
794 p.PB13.reborrow(),
795 p.PB11.reborrow(),
796 GenericPhy::new_auto(),
797 Default::default(),
798 );
799 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false);
800 }
801 {
802 // no remap MII
803 afio_registers_set_remap();
804 Ethernet::new_mii(
805 &mut PacketQueue::<1, 1>::new(),
806 p.ETH.reborrow(),
807 Irqs,
808 p.PA1.reborrow(),
809 p.PC3.reborrow(),
810 p.PA2.reborrow(),
811 p.PC1.reborrow(),
812 p.PA7.reborrow(),
813 p.PC4.reborrow(),
814 p.PC5.reborrow(),
815 p.PB0.reborrow(),
816 p.PB1.reborrow(),
817 p.PB12.reborrow(),
818 p.PB13.reborrow(),
819 p.PC2.reborrow(),
820 p.PB8.reborrow(),
821 p.PB11.reborrow(),
822 GenericPhy::new_auto(),
823 Default::default(),
824 );
825 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false);
826 }
827 {
828 // remap RMII
829 reset_afio_registers();
830 Ethernet::new(
831 &mut PacketQueue::<1, 1>::new(),
832 p.ETH.reborrow(),
833 Irqs,
834 p.PA1.reborrow(),
835 p.PA2.reborrow(),
836 p.PC1.reborrow(),
837 p.PD8.reborrow(),
838 p.PD9.reborrow(),
839 p.PD10.reborrow(),
840 p.PB12.reborrow(),
841 p.PB13.reborrow(),
842 p.PB11.reborrow(),
843 GenericPhy::new_auto(),
844 Default::default(),
845 );
846 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true);
847 }
848 {
849 // remap MII
850 reset_afio_registers();
851 Ethernet::new_mii(
852 &mut PacketQueue::<1, 1>::new(),
853 p.ETH.reborrow(),
854 Irqs,
855 p.PA1.reborrow(),
856 p.PC3.reborrow(),
857 p.PA2.reborrow(),
858 p.PC1.reborrow(),
859 p.PD8.reborrow(),
860 p.PD9.reborrow(),
861 p.PD10.reborrow(),
862 p.PD11.reborrow(),
863 p.PD12.reborrow(),
864 p.PB12.reborrow(),
865 p.PB13.reborrow(),
866 p.PC2.reborrow(),
867 p.PB8.reborrow(),
868 p.PB11.reborrow(),
869 GenericPhy::new_auto(),
870 Default::default(),
871 );
872 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true);
873 }
874
875 // CAN1
876 {
877 // no remap
878 afio_registers_set_remap();
879 Can::new(p.CAN1.reborrow(), p.PA11.reborrow(), p.PA12.reborrow(), Irqs);
880 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 0);
881 }
882 {
883 // partial remap
884 reset_afio_registers();
885 Can::new(p.CAN1.reborrow(), p.PB8.reborrow(), p.PB9.reborrow(), Irqs);
886 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 2);
887 }
888 {
889 // full remap
890 reset_afio_registers();
891 Can::new(p.CAN1.reborrow(), p.PD0.reborrow(), p.PD1.reborrow(), Irqs);
892 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 3);
893 }
894
895 // USART2
896 {
897 // no remap RX/TX/RTS/CTS
898 afio_registers_set_remap();
899 Uart::new_blocking_with_rtscts(
900 p.USART2.reborrow(),
901 p.PA3.reborrow(),
902 p.PA2.reborrow(),
903 p.PA1.reborrow(),
904 p.PA0.reborrow(),
905 Default::default(),
906 )
907 .unwrap();
908 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
909 }
910 {
911 // no remap RX/TX
912 afio_registers_set_remap();
913 Uart::new_blocking(
914 p.USART2.reborrow(),
915 p.PA3.reborrow(),
916 p.PA2.reborrow(),
917 Default::default(),
918 )
919 .unwrap();
920 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
921 }
922 {
923 // no remap TX
924 afio_registers_set_remap();
925 Uart::new_blocking_half_duplex(
926 p.USART2.reborrow(),
927 p.PA2.reborrow(),
928 Default::default(),
929 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
930 )
931 .unwrap();
932 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
933 }
934 {
935 // full remap RX/TX/RTS/CTS
936 reset_afio_registers();
937 Uart::new_blocking_with_rtscts(
938 p.USART2.reborrow(),
939 p.PD6.reborrow(),
940 p.PD5.reborrow(),
941 p.PD4.reborrow(),
942 p.PD3.reborrow(),
943 Default::default(),
944 )
945 .unwrap();
946 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
947 }
948 {
949 // full remap RX/TX
950 reset_afio_registers();
951 Uart::new_blocking(
952 p.USART2.reborrow(),
953 p.PD6.reborrow(),
954 p.PD5.reborrow(),
955 Default::default(),
956 )
957 .unwrap();
958 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
959 }
960 {
961 // full remap TX
962 reset_afio_registers();
963 Uart::new_blocking_half_duplex(
964 p.USART2.reborrow(),
965 p.PD5.reborrow(),
966 Default::default(),
967 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
968 )
969 .unwrap();
970 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), true);
971 }
972
973 // USART1
974 {
975 // no remap RX/TX/RTS/CTS
976 afio_registers_set_remap();
977 Uart::new_blocking_with_rtscts(
978 p.USART1.reborrow(),
979 p.PA10.reborrow(),
980 p.PA9.reborrow(),
981 p.PA12.reborrow(),
982 p.PA11.reborrow(),
983 Default::default(),
984 )
985 .unwrap();
986 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
987 }
988 {
989 // no remap RX/TX
990 afio_registers_set_remap();
991 Uart::new_blocking(
992 p.USART1.reborrow(),
993 p.PA10.reborrow(),
994 p.PA9.reborrow(),
995 Default::default(),
996 )
997 .unwrap();
998 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
999 }
1000 {
1001 // no remap TX
1002 afio_registers_set_remap();
1003 Uart::new_blocking_half_duplex(
1004 p.USART1.reborrow(),
1005 p.PA9.reborrow(),
1006 Default::default(),
1007 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
1008 )
1009 .unwrap();
1010 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
1011 }
1012 {
1013 // remap RX/TX/RTS/CTS
1014 reset_afio_registers();
1015 Uart::new_blocking_with_rtscts(
1016 p.USART1.reborrow(),
1017 p.PB7.reborrow(),
1018 p.PB6.reborrow(),
1019 p.PA12.reborrow(),
1020 p.PA11.reborrow(),
1021 Default::default(),
1022 )
1023 .unwrap();
1024 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1025 }
1026 {
1027 // remap RX/TX
1028 reset_afio_registers();
1029 Uart::new_blocking(
1030 p.USART1.reborrow(),
1031 p.PB7.reborrow(),
1032 p.PB6.reborrow(),
1033 Default::default(),
1034 )
1035 .unwrap();
1036 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1037 }
1038 {
1039 // remap TX
1040 reset_afio_registers();
1041 Uart::new_blocking_half_duplex(
1042 p.USART1.reborrow(),
1043 p.PB6.reborrow(),
1044 Default::default(),
1045 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
1046 )
1047 .unwrap();
1048 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1049 }
1050
1051 // TIM1
1052 {
1053 // full remap
1054 reset_afio_registers();
1055 SimplePwm::new(
1056 p.TIM1.reborrow(),
1057 Some(PwmPin::new(p.PE9.reborrow(), OutputType::PushPull)),
1058 Some(PwmPin::new(p.PE11.reborrow(), OutputType::PushPull)),
1059 None,
1060 None,
1061 khz(10),
1062 Default::default(),
1063 );
1064 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 3);
1065 }
1066 }
1067}
1068
1069#[cfg(feature = "afio-value-line")]
1070mod value_line {
1071 use super::*;
1072
1073 pub fn run(p: &mut Peripherals) {
1074 // TIM13
1075 {
1076 // no remap
1077 reset_afio_registers();
1078 SimplePwm::new(
1079 p.TIM13.reborrow(),
1080 Some(PwmPin::new(p.PC8.reborrow(), OutputType::PushPull)),
1081 None,
1082 None,
1083 None,
1084 khz(10),
1085 Default::default(),
1086 );
1087 defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), false);
1088 }
1089 {
1090 // remap
1091 reset_afio_registers();
1092 SimplePwm::new(
1093 p.TIM13.reborrow(),
1094 Some(PwmPin::new(p.PB0.reborrow(), OutputType::PushPull)),
1095 None,
1096 None,
1097 None,
1098 khz(10),
1099 Default::default(),
1100 );
1101 defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), true);
1102 }
1103 }
1104}
1105
1106#[cfg(not(feature = "afio-connectivity-line"))]
1107mod connectivity_line {
1108 use super::*;
1109
1110 pub fn run(_: &mut Peripherals) {}
1111}
1112
1113#[cfg(not(feature = "afio-value-line"))]
1114mod value_line {
1115 use super::*;
1116
1117 pub fn run(_: &mut Peripherals) {}
1118}
1119
1120fn reset_afio_registers() {
1121 set_afio_registers(false, 0);
1122}
1123
1124fn afio_registers_set_remap() {
1125 set_afio_registers(true, 1);
1126}
1127
1128fn set_afio_registers(bool_val: bool, num_val: u8) {
1129 AFIO.mapr().modify(|w| {
1130 w.set_swj_cfg(embassy_stm32::pac::afio::vals::SwjCfg::NO_OP);
1131 w.set_can1_remap(num_val);
1132 w.set_can2_remap(bool_val);
1133 w.set_eth_remap(bool_val);
1134 w.set_i2c1_remap(bool_val);
1135 w.set_spi1_remap(bool_val);
1136 w.set_spi3_remap(bool_val);
1137 w.set_tim1_remap(num_val);
1138 w.set_tim2_remap(num_val);
1139 w.set_tim3_remap(num_val);
1140 w.set_tim4_remap(bool_val);
1141 w.set_usart1_remap(bool_val);
1142 w.set_usart2_remap(bool_val);
1143 w.set_usart3_remap(num_val);
1144 });
1145
1146 AFIO.mapr2().modify(|w| {
1147 w.set_cec_remap(bool_val);
1148 w.set_tim9_remap(bool_val);
1149 w.set_tim10_remap(bool_val);
1150 w.set_tim11_remap(bool_val);
1151 w.set_tim12_remap(bool_val);
1152 w.set_tim13_remap(bool_val);
1153 w.set_tim14_remap(bool_val);
1154 w.set_tim15_remap(bool_val);
1155 w.set_tim16_remap(bool_val);
1156 w.set_tim17_remap(bool_val);
1157 });
1158}
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index ba8a33e34..348cd049d 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -15,6 +15,7 @@ use embassy_stm32::peripherals::CAN1;
15use embassy_time::Duration; 15use embassy_time::Duration;
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17 17
18#[path = "../can_common.rs"]
18mod can_common; 19mod can_common;
19use can_common::*; 20use can_common::*;
20 21
@@ -27,7 +28,7 @@ bind_interrupts!(struct Irqs {
27 28
28#[embassy_executor::main] 29#[embassy_executor::main]
29async fn main(_spawner: Spawner) { 30async fn main(_spawner: Spawner) {
30 let p = embassy_stm32::init(config()); 31 let p = init();
31 info!("Hello World!"); 32 info!("Hello World!");
32 33
33 let options = TestOptions { 34 let options = TestOptions {
@@ -43,7 +44,7 @@ async fn main(_spawner: Spawner) {
43 // To synchronise to the bus the RX input needs to see a high level. 44 // To synchronise to the bus the RX input needs to see a high level.
44 // Use `mem::forget()` to release the borrow on the pin but keep the 45 // Use `mem::forget()` to release the borrow on the pin but keep the
45 // pull-up resistor enabled. 46 // pull-up resistor enabled.
46 let rx_pin = Input::new(&mut rx, Pull::Up); 47 let rx_pin = Input::new(rx.reborrow(), Pull::Up);
47 core::mem::forget(rx_pin); 48 core::mem::forget(rx_pin);
48 49
49 let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); 50 let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs);
diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs
index e09226de8..e86eea58b 100644
--- a/tests/stm32/src/bin/cordic.rs
+++ b/tests/stm32/src/bin/cordic.rs
@@ -29,7 +29,7 @@ const OUTPUT_LENGTH: usize = (INPUT_U32_COUNT - 1) * 2;
29 29
30#[embassy_executor::main] 30#[embassy_executor::main]
31async fn main(_spawner: Spawner) { 31async fn main(_spawner: Spawner) {
32 let dp = embassy_stm32::init(config()); 32 let dp = init();
33 33
34 // 34 //
35 // use RNG generate random Q1.31 value 35 // use RNG generate random Q1.31 value
@@ -82,8 +82,8 @@ async fn main(_spawner: Spawner) {
82 let cnt1 = defmt::unwrap!( 82 let cnt1 = defmt::unwrap!(
83 cordic 83 cordic
84 .async_calc_32bit( 84 .async_calc_32bit(
85 &mut write_dma, 85 write_dma.reborrow(),
86 &mut read_dma, 86 read_dma.reborrow(),
87 &input_q1_31[2..], 87 &input_q1_31[2..],
88 &mut output_q1_31[cnt0..], 88 &mut output_q1_31[cnt0..],
89 true, 89 true,
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs
index 60778bdaa..640de50e3 100644
--- a/tests/stm32/src/bin/cryp.rs
+++ b/tests/stm32/src/bin/cryp.rs
@@ -5,9 +5,9 @@
5#[path = "../common.rs"] 5#[path = "../common.rs"]
6mod common; 6mod common;
7 7
8use aes_gcm::Aes128Gcm;
8use aes_gcm::aead::heapless::Vec; 9use aes_gcm::aead::heapless::Vec;
9use aes_gcm::aead::{AeadInPlace, KeyInit}; 10use aes_gcm::aead::{AeadInPlace, KeyInit};
10use aes_gcm::Aes128Gcm;
11use common::*; 11use common::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::cryp::{self, *}; 13use embassy_stm32::cryp::{self, *};
@@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs {
20 20
21#[embassy_executor::main] 21#[embassy_executor::main]
22async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
23 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 23 let p: embassy_stm32::Peripherals = init();
24 24
25 const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567"; 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"; 26 const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh";
@@ -72,7 +72,7 @@ async fn main(_spawner: Spawner) {
72 defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); 72 defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]);
73 73
74 // Decrypt in software using AES-GCM 128-bit 74 // Decrypt in software using AES-GCM 128-bit
75 let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec); 75 cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec).unwrap();
76 76
77 info!("Test OK"); 77 info!("Test OK");
78 cortex_m::asm::bkpt(); 78 cortex_m::asm::bkpt();
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
index 06501ab14..747b11e7f 100644
--- a/tests/stm32/src/bin/dac.rs
+++ b/tests/stm32/src/bin/dac.rs
@@ -10,9 +10,8 @@ use core::f32::consts::PI;
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::{Adc, SampleTime};
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma;
16use embassy_time::Timer; 15use embassy_time::Timer;
17use micromath::F32Ext; 16use micromath::F32Ext;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
@@ -20,14 +19,14 @@ use {defmt_rtt as _, panic_probe as _};
20#[embassy_executor::main] 19#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 20async fn main(_spawner: Spawner) {
22 // Initialize the board and obtain a Peripherals instance 21 // Initialize the board and obtain a Peripherals instance
23 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 22 let p: embassy_stm32::Peripherals = init();
24 23
25 let adc = peri!(p, ADC); 24 let adc = peri!(p, ADC);
26 let dac = peri!(p, DAC); 25 let dac = peri!(p, DAC);
27 let dac_pin = peri!(p, DAC_PIN); 26 let dac_pin = peri!(p, DAC_PIN);
28 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; 27 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
29 28
30 let mut dac = DacCh1::new(dac, NoDma, dac_pin); 29 let mut dac = DacCh1::new_blocking(dac, dac_pin);
31 let mut adc = Adc::new(adc); 30 let mut adc = Adc::new(adc);
32 31
33 #[cfg(feature = "stm32h755zi")] 32 #[cfg(feature = "stm32h755zi")]
@@ -38,7 +37,7 @@ async fn main(_spawner: Spawner) {
38 dac.set(Value::Bit8(0)); 37 dac.set(Value::Bit8(0));
39 // Now wait a little to obtain a stable value 38 // Now wait a little to obtain a stable value
40 Timer::after_millis(30).await; 39 Timer::after_millis(30).await;
41 let offset = adc.read(&mut adc_pin); 40 let offset = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0));
42 41
43 for v in 0..=255 { 42 for v in 0..=255 {
44 // First set the DAC output value 43 // First set the DAC output value
@@ -49,7 +48,10 @@ async fn main(_spawner: Spawner) {
49 Timer::after_millis(30).await; 48 Timer::after_millis(30).await;
50 49
51 // Need to steal the peripherals here because PA4 is obviously in use already 50 // 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); 51 let measured = adc.blocking_read(
52 &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4,
53 SampleTime::from_bits(0),
54 );
53 // Calibrate and normalize the measurement to get close to the dac_output_val 55 // 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; 56 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
55 57
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs
index d5e9c9722..2fe0cf1f1 100644
--- a/tests/stm32/src/bin/dac_l1.rs
+++ b/tests/stm32/src/bin/dac_l1.rs
@@ -10,9 +10,8 @@ use core::f32::consts::PI;
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::{Adc, SampleTime};
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma;
16use embassy_stm32::{bind_interrupts, peripherals}; 15use embassy_stm32::{bind_interrupts, peripherals};
17use embassy_time::Timer; 16use embassy_time::Timer;
18use micromath::F32Ext; 17use micromath::F32Ext;
@@ -25,14 +24,14 @@ bind_interrupts!(struct Irqs {
25#[embassy_executor::main] 24#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 25async fn main(_spawner: Spawner) {
27 // Initialize the board and obtain a Peripherals instance 26 // Initialize the board and obtain a Peripherals instance
28 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 27 let p: embassy_stm32::Peripherals = init();
29 28
30 let adc = peri!(p, ADC); 29 let adc = peri!(p, ADC);
31 let dac = peri!(p, DAC); 30 let dac = peri!(p, DAC);
32 let dac_pin = peri!(p, DAC_PIN); 31 let dac_pin = peri!(p, DAC_PIN);
33 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; 32 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
34 33
35 let mut dac = DacCh1::new(dac, NoDma, dac_pin); 34 let mut dac = DacCh1::new_blocking(dac, dac_pin);
36 let mut adc = Adc::new(adc, Irqs); 35 let mut adc = Adc::new(adc, Irqs);
37 36
38 #[cfg(feature = "stm32h755zi")] 37 #[cfg(feature = "stm32h755zi")]
@@ -48,7 +47,7 @@ async fn main(_spawner: Spawner) {
48 dac.set(Value::Bit8(0)); 47 dac.set(Value::Bit8(0));
49 // Now wait a little to obtain a stable value 48 // Now wait a little to obtain a stable value
50 Timer::after_millis(30).await; 49 Timer::after_millis(30).await;
51 let offset = adc.read(&mut adc_pin).await; 50 let offset = adc.read(&mut adc_pin, SampleTime::from_bits(0)).await;
52 51
53 for v in 0..=255 { 52 for v in 0..=255 {
54 // First set the DAC output value 53 // First set the DAC output value
@@ -59,7 +58,12 @@ async fn main(_spawner: Spawner) {
59 Timer::after_millis(30).await; 58 Timer::after_millis(30).await;
60 59
61 // Need to steal the peripherals here because PA4 is obviously in use already 60 // Need to steal the peripherals here because PA4 is obviously in use already
62 let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4).await; 61 let measured = adc
62 .read(
63 &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4,
64 SampleTime::from_bits(0),
65 )
66 .await;
63 // Calibrate and normalize the measurement to get close to the dac_output_val 67 // Calibrate and normalize the measurement to get close to the dac_output_val
64 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; 68 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
65 69
diff --git a/tests/stm32/src/bin/eeprom.rs b/tests/stm32/src/bin/eeprom.rs
new file mode 100644
index 000000000..61d249fd7
--- /dev/null
+++ b/tests/stm32/src/bin/eeprom.rs
@@ -0,0 +1,30 @@
1#![no_std]
2#![no_main]
3
4// required-features: eeprom
5
6#[path = "../common.rs"]
7mod common;
8
9use common::*;
10use defmt::assert_eq;
11use embassy_executor::Spawner;
12use embassy_stm32::flash::Flash;
13use {defmt_rtt as _, panic_probe as _};
14
15#[embassy_executor::main]
16async fn main(_spawner: Spawner) {
17 // Initialize the board and obtain a Peripherals instance
18 let p: embassy_stm32::Peripherals = init();
19
20 let mut f = Flash::new_blocking(p.FLASH);
21 const ADDR: u32 = 0x0;
22
23 unwrap!(f.eeprom_write_slice(ADDR, &[1, 2, 3, 4, 5, 6, 7, 8]));
24 let mut buf = [0u8; 8];
25 unwrap!(f.eeprom_read_slice(ADDR, &mut buf));
26 assert_eq!(&buf[..], &[1, 2, 3, 4, 5, 6, 7, 8]);
27
28 info!("Test OK");
29 cortex_m::asm::bkpt();
30}
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs
index 7c02f0354..ffc76b96f 100644
--- a/tests/stm32/src/bin/eth.rs
+++ b/tests/stm32/src/bin/eth.rs
@@ -6,13 +6,11 @@
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::{Ethernet, GenericPhy, PacketQueue, Sma};
11use embassy_stm32::eth::{Ethernet, PacketQueue}; 11use embassy_stm32::peripherals::{ETH, ETH_SMA};
12use embassy_stm32::peripherals::ETH;
13use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
14use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; 13use embassy_stm32::{bind_interrupts, eth, peripherals, rng};
15use rand_core::RngCore;
16use static_cell::StaticCell; 14use static_cell::StaticCell;
17use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
18 16
@@ -29,16 +27,16 @@ bind_interrupts!(struct Irqs {
29 RNG => rng::InterruptHandler<peripherals::RNG>; 27 RNG => rng::InterruptHandler<peripherals::RNG>;
30}); 28});
31 29
32type Device = Ethernet<'static, ETH, GenericSMI>; 30type Device = Ethernet<'static, ETH, GenericPhy<Sma<'static, ETH_SMA>>>;
33 31
34#[embassy_executor::task] 32#[embassy_executor::task]
35async fn net_task(stack: &'static Stack<Device>) -> ! { 33async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
36 stack.run().await 34 runner.run().await
37} 35}
38 36
39#[embassy_executor::main] 37#[embassy_executor::main]
40async fn main(spawner: Spawner) { 38async fn main(spawner: Spawner) {
41 let p = embassy_stm32::init(config()); 39 let p = init();
42 info!("Hello World!"); 40 info!("Hello World!");
43 41
44 // Generate random seed. 42 // Generate random seed.
@@ -71,13 +69,12 @@ async fn main(spawner: Spawner) {
71 const PACKET_QUEUE_SIZE: usize = 4; 69 const PACKET_QUEUE_SIZE: usize = 4;
72 70
73 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); 71 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new();
72
74 let device = Ethernet::new( 73 let device = Ethernet::new(
75 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), 74 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()),
76 p.ETH, 75 p.ETH,
77 Irqs, 76 Irqs,
78 p.PA1, 77 p.PA1,
79 p.PA2,
80 p.PC1,
81 p.PA7, 78 p.PA7,
82 p.PC4, 79 p.PC4,
83 p.PC5, 80 p.PC5,
@@ -87,8 +84,10 @@ async fn main(spawner: Spawner) {
87 #[cfg(feature = "stm32h563zi")] 84 #[cfg(feature = "stm32h563zi")]
88 p.PB15, 85 p.PB15,
89 p.PG11, 86 p.PG11,
90 GenericSMI::new(0),
91 mac_addr, 87 mac_addr,
88 p.ETH_SMA,
89 p.PA2,
90 p.PC1,
92 ); 91 );
93 92
94 let config = embassy_net::Config::dhcpv4(Default::default()); 93 let config = embassy_net::Config::dhcpv4(Default::default());
@@ -99,17 +98,11 @@ async fn main(spawner: Spawner) {
99 //}); 98 //});
100 99
101 // Init network stack 100 // Init network stack
102 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
103 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); 101 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
104 let stack = &*STACK.init(Stack::new( 102 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 103
111 // Launch network task 104 // Launch network task
112 unwrap!(spawner.spawn(net_task(&stack))); 105 spawner.spawn(unwrap!(net_task(runner)));
113 106
114 perf_client::run( 107 perf_client::run(
115 stack, 108 stack,
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index bc2b7edd4..d97f493df 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -8,10 +8,11 @@ mod common;
8use common::*; 8use common::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::peripherals::*; 10use embassy_stm32::peripherals::*;
11use embassy_stm32::{bind_interrupts, can, Config}; 11use embassy_stm32::{Config, bind_interrupts, can};
12use embassy_time::Duration; 12use embassy_time::Duration;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
14 14
15#[path = "../can_common.rs"]
15mod can_common; 16mod can_common;
16use can_common::*; 17use can_common::*;
17 18
@@ -102,10 +103,10 @@ fn options() -> (Config, TestOptions) {
102 103
103#[embassy_executor::main] 104#[embassy_executor::main]
104async fn main(_spawner: Spawner) { 105async fn main(_spawner: Spawner) {
105 //let peripherals = embassy_stm32::init(config()); 106 //let peripherals = init();
106 107
107 let (config, options) = options(); 108 let (config, options) = options();
108 let peripherals = embassy_stm32::init(config); 109 let peripherals = init_with_config(config);
109 110
110 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); 111 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); 112 let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2);
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs
index dfa299ab5..40b03201c 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
@@ -20,10 +20,10 @@ async fn main(_spawner: Spawner) {
20 20
21 // Test initial output 21 // Test initial output
22 { 22 {
23 let b = Input::new(&mut b, Pull::None); 23 let b = Input::new(b.reborrow(), Pull::None);
24 24
25 { 25 {
26 let a = Output::new(&mut a, Level::Low, Speed::Low); 26 let a = Output::new(a.reborrow(), Level::Low, Speed::Low);
27 delay(); 27 delay();
28 assert!(b.is_low()); 28 assert!(b.is_low());
29 assert!(!b.is_high()); 29 assert!(!b.is_high());
@@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) {
31 assert!(!a.is_set_high()); 31 assert!(!a.is_set_high());
32 } 32 }
33 { 33 {
34 let mut a = Output::new(&mut a, Level::High, Speed::Low); 34 let mut a = Output::new(a.reborrow(), Level::High, Speed::Low);
35 delay(); 35 delay();
36 assert!(!b.is_low()); 36 assert!(!b.is_low());
37 assert!(b.is_high()); 37 assert!(b.is_high());
@@ -68,10 +68,10 @@ async fn main(_spawner: Spawner) {
68 68
69 // Test input no pull 69 // Test input no pull
70 { 70 {
71 let b = Input::new(&mut b, Pull::None); 71 let b = Input::new(b.reborrow(), Pull::None);
72 // no pull, the status is undefined 72 // no pull, the status is undefined
73 73
74 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 74 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
75 delay(); 75 delay();
76 assert!(b.is_low()); 76 assert!(b.is_low());
77 a.set_high(); 77 a.set_high();
@@ -81,11 +81,11 @@ async fn main(_spawner: Spawner) {
81 81
82 // Test input pulldown 82 // Test input pulldown
83 { 83 {
84 let b = Input::new(&mut b, Pull::Down); 84 let b = Input::new(b.reborrow(), Pull::Down);
85 delay(); 85 delay();
86 assert!(b.is_low()); 86 assert!(b.is_low());
87 87
88 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 88 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
89 delay(); 89 delay();
90 assert!(b.is_low()); 90 assert!(b.is_low());
91 a.set_high(); 91 a.set_high();
@@ -95,11 +95,11 @@ async fn main(_spawner: Spawner) {
95 95
96 // Test input pullup 96 // Test input pullup
97 { 97 {
98 let b = Input::new(&mut b, Pull::Up); 98 let b = Input::new(b.reborrow(), Pull::Up);
99 delay(); 99 delay();
100 assert!(b.is_high()); 100 assert!(b.is_high());
101 101
102 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 102 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
103 delay(); 103 delay();
104 assert!(b.is_low()); 104 assert!(b.is_low());
105 a.set_high(); 105 a.set_high();
@@ -109,10 +109,10 @@ async fn main(_spawner: Spawner) {
109 109
110 // Test output open drain 110 // Test output open drain
111 { 111 {
112 let b = Input::new(&mut b, Pull::Down); 112 let b = Input::new(b.reborrow(), 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(a.reborrow(), 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
@@ -124,12 +124,12 @@ async fn main(_spawner: Spawner) {
124 // Test initial output 124 // Test initial output
125 { 125 {
126 //Flex pin configured as input 126 //Flex pin configured as input
127 let mut b = Flex::new(&mut b); 127 let mut b = Flex::new(b.reborrow());
128 b.set_as_input(Pull::None); 128 b.set_as_input(Pull::None);
129 129
130 { 130 {
131 //Flex pin configured as output 131 //Flex pin configured as output
132 let mut a = Flex::new(&mut a); //Flex pin configured as output 132 let mut a = Flex::new(a.reborrow()); //Flex pin configured as output
133 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state 133 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state
134 a.set_as_output(Speed::Low); 134 a.set_as_output(Speed::Low);
135 delay(); 135 delay();
@@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) {
137 } 137 }
138 { 138 {
139 //Flex pin configured as output 139 //Flex pin configured as output
140 let mut a = Flex::new(&mut a); 140 let mut a = Flex::new(a.reborrow());
141 a.set_high(); 141 a.set_high();
142 a.set_as_output(Speed::Low); 142 a.set_as_output(Speed::Low);
143 143
@@ -148,10 +148,10 @@ async fn main(_spawner: Spawner) {
148 148
149 // Test input no pull 149 // Test input no pull
150 { 150 {
151 let mut b = Flex::new(&mut b); 151 let mut b = Flex::new(b.reborrow());
152 b.set_as_input(Pull::None); // no pull, the status is undefined 152 b.set_as_input(Pull::None); // no pull, the status is undefined
153 153
154 let mut a = Flex::new(&mut a); 154 let mut a = Flex::new(a.reborrow());
155 a.set_low(); 155 a.set_low();
156 a.set_as_output(Speed::Low); 156 a.set_as_output(Speed::Low);
157 157
@@ -164,12 +164,12 @@ async fn main(_spawner: Spawner) {
164 164
165 // Test input pulldown 165 // Test input pulldown
166 { 166 {
167 let mut b = Flex::new(&mut b); 167 let mut b = Flex::new(b.reborrow());
168 b.set_as_input(Pull::Down); 168 b.set_as_input(Pull::Down);
169 delay(); 169 delay();
170 assert!(b.is_low()); 170 assert!(b.is_low());
171 171
172 let mut a = Flex::new(&mut a); 172 let mut a = Flex::new(a.reborrow());
173 a.set_low(); 173 a.set_low();
174 a.set_as_output(Speed::Low); 174 a.set_as_output(Speed::Low);
175 delay(); 175 delay();
@@ -181,12 +181,12 @@ async fn main(_spawner: Spawner) {
181 181
182 // Test input pullup 182 // Test input pullup
183 { 183 {
184 let mut b = Flex::new(&mut b); 184 let mut b = Flex::new(b.reborrow());
185 b.set_as_input(Pull::Up); 185 b.set_as_input(Pull::Up);
186 delay(); 186 delay();
187 assert!(b.is_high()); 187 assert!(b.is_high());
188 188
189 let mut a = Flex::new(&mut a); 189 let mut a = Flex::new(a.reborrow());
190 a.set_high(); 190 a.set_high();
191 a.set_as_output(Speed::Low); 191 a.set_as_output(Speed::Low);
192 delay(); 192 delay();
@@ -198,12 +198,12 @@ async fn main(_spawner: Spawner) {
198 198
199 // Test output open drain 199 // Test output open drain
200 { 200 {
201 let mut b = Flex::new(&mut b); 201 let mut b = Flex::new(b.reborrow());
202 b.set_as_input(Pull::Down); 202 b.set_as_input(Pull::Down);
203 203
204 let mut a = Flex::new(&mut a); 204 let mut a = Flex::new(a.reborrow());
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
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs
index 5f54ea435..bb08d0cf1 100644
--- a/tests/stm32/src/bin/hash.rs
+++ b/tests/stm32/src/bin/hash.rs
@@ -6,8 +6,8 @@
6mod common; 6mod common;
7use common::*; 7use common::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::dma::NoDma;
10use embassy_stm32::hash::*; 9use embassy_stm32::hash::*;
10use embassy_stm32::mode::Blocking;
11use embassy_stm32::{bind_interrupts, hash, peripherals}; 11use embassy_stm32::{bind_interrupts, hash, peripherals};
12use hmac::{Hmac, Mac}; 12use hmac::{Hmac, Mac};
13use sha2::{Digest, Sha224, Sha256}; 13use sha2::{Digest, Sha224, Sha256};
@@ -33,11 +33,7 @@ bind_interrupts!(struct Irqs {
33 HASH => hash::InterruptHandler<peripherals::HASH>; 33 HASH => hash::InterruptHandler<peripherals::HASH>;
34}); 34});
35 35
36#[embassy_executor::main] 36fn test_interrupt(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) {
37async fn main(_spawner: Spawner) {
38 let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
39 let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs);
40
41 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; 37 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
42 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; 38 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
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 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";
@@ -96,6 +92,47 @@ async fn main(_spawner: Spawner) {
96 info!("Hardware HMAC: {:?}", hw_hmac); 92 info!("Hardware HMAC: {:?}", hw_hmac);
97 info!("Software HMAC: {:?}", sw_hmac[..]); 93 info!("Software HMAC: {:?}", sw_hmac[..]);
98 defmt::assert!(hw_hmac == sw_hmac[..]); 94 defmt::assert!(hw_hmac == sw_hmac[..]);
95}
96
97// This uses sha512, so only supported on hash_v3 and up
98#[cfg(feature = "hash-v34")]
99fn test_sizes(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) {
100 let in1 = b"4BPuGudaDK";
101 let in2 = b"cfFIGf0XSNhFBQ5LaIqzjnRKDRkoWweJI06HLUcicIUGjpuDNfOTQNSrRxDoveDPlazeZtt06SIYO5CvHvsJ98XSfO9yJEMHoDpDAmNQtwZOPlKmdiagRXsJ7w7IjdKpQH6I2t";
102
103 for i in 1..10 {
104 // sha512 block size is 128, so test around there
105 for j in [1, 1, 2, 3, 4, 5, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133] {
106 info!("test_sizes i {} j {}", i, j);
107 let mut sw = sha2::Sha512::new();
108 let mut ctx = hw_hasher.start(Algorithm::SHA512, DataType::Width8, None);
109
110 sw.update(&in1[..i]);
111 sw.update(&in2[..j]);
112 hw_hasher.update_blocking(&mut ctx, &in1[..i]);
113 hw_hasher.update_blocking(&mut ctx, &in2[..j]);
114
115 let sw_digest = sw.finalize();
116 let mut hw_digest = [0u8; 64];
117 hw_hasher.finish_blocking(ctx, &mut hw_digest);
118 info!("Hardware: {:?}", hw_digest);
119 info!("Software: {:?}", sw_digest[..]);
120 defmt::assert!(hw_digest == *sw_digest);
121 }
122 }
123}
124
125#[embassy_executor::main]
126async fn main(_spawner: Spawner) {
127 let p: embassy_stm32::Peripherals = init();
128 let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs);
129
130 test_interrupt(&mut hw_hasher);
131 // Run it a second time to check hash-after-hmac
132 test_interrupt(&mut hw_hasher);
133
134 #[cfg(feature = "hash-v34")]
135 test_sizes(&mut hw_hasher);
99 136
100 info!("Test OK"); 137 info!("Test OK");
101 cortex_m::asm::bkpt(); 138 cortex_m::asm::bkpt();
diff --git a/tests/stm32/src/bin/hsem.rs b/tests/stm32/src/bin/hsem.rs
new file mode 100644
index 000000000..fa69f22b2
--- /dev/null
+++ b/tests/stm32/src/bin/hsem.rs
@@ -0,0 +1,50 @@
1// required-features: hsem
2#![no_std]
3#![no_main]
4
5#[path = "../common.rs"]
6mod common;
7
8use common::*;
9use embassy_executor::Spawner;
10use embassy_stm32::bind_interrupts;
11use embassy_stm32::hsem::{HardwareSemaphore, HardwareSemaphoreInterruptHandler};
12use embassy_stm32::peripherals::HSEM;
13
14bind_interrupts!(struct Irqs{
15 HSEM => HardwareSemaphoreInterruptHandler<HSEM>;
16});
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let p: embassy_stm32::Peripherals = init();
21
22 let hsem = HardwareSemaphore::new(p.HSEM, Irqs);
23
24 // if hsem.channel_for(SemaphoreNumber::Channel5).is_semaphore_locked() {
25 // defmt::panic!("Semaphore 5 already locked!")
26 // }
27 //
28 // hsem.channel_for(SemaphoreNumber::Channel5).one_step_lock().unwrap();
29 // hsem.channel_for(SemaphoreNumber::Channel1).two_step_lock(0).unwrap();
30 //
31 // hsem.channel_for(SemaphoreNumber::Channel5).unlock(0);
32
33 #[cfg(feature = "stm32wb55rg")]
34 let [_channel1, _channel2, mut channel5, _channel6] = hsem.split();
35 #[cfg(not(feature = "stm32wb55rg"))]
36 let [_channel1, _channel2, _channel3, _channel4, mut channel5, _channel6] = hsem.split();
37
38 info!("Locking channel 5");
39
40 let mutex = channel5.lock(0).await;
41
42 info!("Locked channel 5");
43
44 drop(mutex);
45
46 info!("Unlocked channel 5");
47
48 info!("Test OK");
49 cortex_m::asm::bkpt();
50}
diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs
index 15ef4fb60..8438353a8 100644
--- a/tests/stm32/src/bin/rng.rs
+++ b/tests/stm32/src/bin/rng.rs
@@ -41,7 +41,7 @@ bind_interrupts!(struct Irqs {
41 41
42#[embassy_executor::main] 42#[embassy_executor::main]
43async fn main(_spawner: Spawner) { 43async fn main(_spawner: Spawner) {
44 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 44 let p: embassy_stm32::Peripherals = init();
45 45
46 let mut rng = Rng::new(p.RNG, Irqs); 46 let mut rng = Rng::new(p.RNG, Irqs);
47 47
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs
index c04d616ac..eb27af4ca 100644
--- a/tests/stm32/src/bin/rtc.rs
+++ b/tests/stm32/src/bin/rtc.rs
@@ -10,15 +10,21 @@ use common::*;
10use defmt::assert; 10use defmt::assert;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_stm32::rcc::LsConfig; 12use embassy_stm32::rcc::LsConfig;
13#[cfg(feature = "stop")]
14use embassy_stm32::rtc::Rtc;
15#[cfg(not(feature = "stop"))]
13use embassy_stm32::rtc::{Rtc, RtcConfig}; 16use embassy_stm32::rtc::{Rtc, RtcConfig};
14use embassy_time::Timer; 17use embassy_time::Timer;
15
16#[embassy_executor::main] 18#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
18 let mut config = config(); 20 let mut config = config();
19 config.rcc.ls = LsConfig::default_lse(); 21 config.rcc.ls = LsConfig::default_lse();
22 #[cfg(feature = "stop")]
23 {
24 config.rtc._disable_rtc = false;
25 }
20 26
21 let p = embassy_stm32::init(config); 27 let p = init_with_config(config);
22 info!("Hello World!"); 28 info!("Hello World!");
23 29
24 let now = NaiveDate::from_ymd_opt(2020, 5, 15) 30 let now = NaiveDate::from_ymd_opt(2020, 5, 15)
@@ -26,14 +32,25 @@ async fn main(_spawner: Spawner) {
26 .and_hms_opt(10, 30, 15) 32 .and_hms_opt(10, 30, 15)
27 .unwrap(); 33 .unwrap();
28 34
29 let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 35 #[cfg(not(feature = "stop"))]
36 let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default());
37
38 #[cfg(feature = "stop")]
39 let (rtc, time_provider) = Rtc::new(p.RTC);
30 40
41 #[cfg(not(feature = "stop"))]
31 rtc.set_datetime(now.into()).expect("datetime not set"); 42 rtc.set_datetime(now.into()).expect("datetime not set");
32 43
44 #[cfg(feature = "stop")]
45 critical_section::with(|cs| {
46 rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set");
47 });
48
33 info!("Waiting 5 seconds"); 49 info!("Waiting 5 seconds");
34 Timer::after_millis(5000).await; 50 Timer::after_millis(5000).await;
35 51
36 let then: NaiveDateTime = rtc.now().unwrap().into(); 52 let then: NaiveDateTime = time_provider.now().unwrap().into();
53
37 let seconds = (then - now).num_seconds(); 54 let seconds = (then - now).num_seconds();
38 55
39 info!("measured = {}", seconds); 56 info!("measured = {}", seconds);
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs
index 54f55d2d6..9f9c526e1 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);
@@ -34,27 +34,29 @@ async fn main(_spawner: Spawner) {
34 pattern1[i] = i as u8; 34 pattern1[i] = i as u8;
35 pattern2[i] = !i as u8; 35 pattern2[i] = !i as u8;
36 } 36 }
37 let patterns = [pattern1.clone(), pattern2.clone()];
37 38
38 let mut block = DataBlock([0u8; 512]); 39 let mut block = DataBlock([0u8; 512]);
40 let mut blocks = [DataBlock([0u8; 512]), DataBlock([0u8; 512])];
39 41
40 // ======== Try 4bit. ============== 42 // ======== Try 4bit. ==============
41 info!("initializing in 4-bit mode..."); 43 info!("initializing in 4-bit mode...");
42 let mut s = Sdmmc::new_4bit( 44 let mut s = Sdmmc::new_4bit(
43 &mut sdmmc, 45 sdmmc.reborrow(),
44 Irqs, 46 Irqs,
45 &mut dma, 47 dma.reborrow(),
46 &mut clk, 48 clk.reborrow(),
47 &mut cmd, 49 cmd.reborrow(),
48 &mut d0, 50 d0.reborrow(),
49 &mut d1, 51 d1.reborrow(),
50 &mut d2, 52 d2.reborrow(),
51 &mut d3, 53 d3.reborrow(),
52 Default::default(), 54 Default::default(),
53 ); 55 );
54 56
55 let mut err = None; 57 let mut err = None;
56 loop { 58 loop {
57 match s.init_card(mhz(24)).await { 59 match s.init_sd_card(mhz(24)).await {
58 Ok(_) => break, 60 Ok(_) => break,
59 Err(e) => { 61 Err(e) => {
60 if err != Some(e) { 62 if err != Some(e) {
@@ -84,23 +86,33 @@ async fn main(_spawner: Spawner) {
84 s.read_block(block_idx, &mut block).await.unwrap(); 86 s.read_block(block_idx, &mut block).await.unwrap();
85 assert_eq!(block, pattern2); 87 assert_eq!(block, pattern2);
86 88
89 info!("writing blocks [pattern1, pattern2]...");
90 s.write_blocks(block_idx, &patterns).await.unwrap();
91
92 info!("reading blocks...");
93 s.read_blocks(block_idx, &mut blocks).await.unwrap();
94 assert_eq!(&blocks, &patterns);
95
87 drop(s); 96 drop(s);
88 97
98 // FIXME: this hangs on Rust 1.86 and higher.
99 // I haven't been able to figure out why.
100 /*
89 // ======== Try 1bit. ============== 101 // ======== Try 1bit. ==============
90 info!("initializing in 1-bit mode..."); 102 info!("initializing in 1-bit mode...");
91 let mut s = Sdmmc::new_1bit( 103 let mut s = Sdmmc::new_1bit(
92 &mut sdmmc, 104 sdmmc.reborrow(),
93 Irqs, 105 Irqs,
94 &mut dma, 106 dma.reborrow(),
95 &mut clk, 107 clk.reborrow(),
96 &mut cmd, 108 cmd.reborrow(),
97 &mut d0, 109 d0.reborrow(),
98 Default::default(), 110 Default::default(),
99 ); 111 );
100 112
101 let mut err = None; 113 let mut err = None;
102 loop { 114 loop {
103 match s.init_card(mhz(24)).await { 115 match s.init_sd_card(mhz(24)).await {
104 Ok(_) => break, 116 Ok(_) => break,
105 Err(e) => { 117 Err(e) => {
106 if err != Some(e) { 118 if err != Some(e) {
@@ -116,9 +128,9 @@ async fn main(_spawner: Spawner) {
116 info!("Card: {:#?}", Debug2Format(card)); 128 info!("Card: {:#?}", Debug2Format(card));
117 info!("Clock: {}", s.clock()); 129 info!("Clock: {}", s.clock());
118 130
119 info!("reading pattern2 written in 4bit mode..."); 131 info!("reading pattern1 written in 4bit mode...");
120 s.read_block(block_idx, &mut block).await.unwrap(); 132 s.read_block(block_idx, &mut block).await.unwrap();
121 assert_eq!(block, pattern2); 133 assert_eq!(block, pattern1);
122 134
123 info!("writing pattern1..."); 135 info!("writing pattern1...");
124 s.write_block(block_idx, &pattern1).await.unwrap(); 136 s.write_block(block_idx, &pattern1).await.unwrap();
@@ -134,7 +146,15 @@ async fn main(_spawner: Spawner) {
134 s.read_block(block_idx, &mut block).await.unwrap(); 146 s.read_block(block_idx, &mut block).await.unwrap();
135 assert_eq!(block, pattern2); 147 assert_eq!(block, pattern2);
136 148
149 info!("writing blocks [pattern1, pattern2]...");
150 s.write_blocks(block_idx, &patterns).await.unwrap();
151
152 info!("reading blocks...");
153 s.read_blocks(block_idx, &mut blocks).await.unwrap();
154 assert_eq!(&blocks, &patterns);
155
137 drop(s); 156 drop(s);
157 */
138 158
139 info!("Test OK"); 159 info!("Test OK");
140 cortex_m::asm::bkpt(); 160 cortex_m::asm::bkpt();
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs
index 0ffd0f653..cedff772c 100644
--- a/tests/stm32/src/bin/spi.rs
+++ b/tests/stm32/src/bin/spi.rs
@@ -7,12 +7,14 @@ use common::*;
7use defmt::assert_eq; 7use defmt::assert_eq;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{Level, Output, Speed}; 9use embassy_stm32::gpio::{Level, Output, Speed};
10use embassy_stm32::spi::{self, Spi}; 10use embassy_stm32::mode::Blocking;
11use embassy_stm32::spi::mode::Master;
12use embassy_stm32::spi::{self, Spi, Word};
11use embassy_stm32::time::Hertz; 13use embassy_stm32::time::Hertz;
12 14
13#[embassy_executor::main] 15#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
15 let p = embassy_stm32::init(config()); 17 let p = init();
16 info!("Hello World!"); 18 info!("Hello World!");
17 19
18 let mut spi_peri = peri!(p, SPI); 20 let mut spi_peri = peri!(p, SPI);
@@ -24,18 +26,65 @@ async fn main(_spawner: Spawner) {
24 spi_config.frequency = Hertz(1_000_000); 26 spi_config.frequency = Hertz(1_000_000);
25 27
26 let mut spi = Spi::new_blocking( 28 let mut spi = Spi::new_blocking(
27 &mut spi_peri, 29 spi_peri.reborrow(),
28 &mut sck, // Arduino D13 30 sck.reborrow(), // Arduino D13
29 &mut mosi, // Arduino D11 31 mosi.reborrow(), // Arduino D11
30 &mut miso, // Arduino D12 32 miso.reborrow(), // Arduino D12
31 spi_config, 33 spi_config,
32 ); 34 );
33 35
34 let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; 36 test_txrx::<u8>(&mut spi);
37 test_txrx::<u16>(&mut spi);
38
39 // Assert the RCC bit gets disabled on drop.
40 #[cfg(feature = "stm32f429zi")]
41 defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en());
42 drop(spi);
43 #[cfg(feature = "stm32f429zi")]
44 defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en());
45
46 // test rx-only configuration
47 let mut spi = Spi::new_blocking_rxonly(spi_peri.reborrow(), sck.reborrow(), miso.reborrow(), spi_config);
48 let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh);
49
50 test_rx::<u8>(&mut spi, &mut mosi_out);
51 test_rx::<u16>(&mut spi, &mut mosi_out);
52 drop(spi);
53 drop(mosi_out);
54
55 let mut spi = Spi::new_blocking_txonly(spi_peri.reborrow(), sck.reborrow(), mosi.reborrow(), spi_config);
56 test_tx::<u8>(&mut spi);
57 test_tx::<u16>(&mut spi);
58 drop(spi);
59
60 let mut spi = Spi::new_blocking_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), spi_config);
61 test_tx::<u8>(&mut spi);
62 test_tx::<u16>(&mut spi);
63 drop(spi);
64
65 info!("Test OK");
66 cortex_m::asm::bkpt();
67}
68
69fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>)
70where
71 W: core::ops::Not<Output = W>,
72{
73 let data: [W; 9] = [
74 0x00u8.into(),
75 0xFFu8.into(),
76 0xAAu8.into(),
77 0x55u8.into(),
78 0xC0u8.into(),
79 0xFFu8.into(),
80 0xEEu8.into(),
81 0xC0u8.into(),
82 0xDEu8.into(),
83 ];
35 84
36 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. 85 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
37 // so we should get the data we sent back. 86 // so we should get the data we sent back.
38 let mut buf = [0; 9]; 87 let mut buf = [W::default(); 9];
39 spi.blocking_transfer(&mut buf, &data).unwrap(); 88 spi.blocking_transfer(&mut buf, &data).unwrap();
40 assert_eq!(buf, data); 89 assert_eq!(buf, data);
41 90
@@ -59,47 +108,33 @@ async fn main(_spawner: Spawner) {
59 spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); 108 spi.blocking_transfer_in_place::<u8>(&mut []).unwrap();
60 spi.blocking_read::<u8>(&mut []).unwrap(); 109 spi.blocking_read::<u8>(&mut []).unwrap();
61 spi.blocking_write::<u8>(&[]).unwrap(); 110 spi.blocking_write::<u8>(&[]).unwrap();
111}
62 112
63 // Assert the RCC bit gets disabled on drop. 113fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>, mosi_out: &mut Output<'_>)
64 #[cfg(feature = "stm32f429zi")] 114where
65 defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en()); 115 W: core::ops::Not<Output = W>,
66 drop(spi); 116{
67 #[cfg(feature = "stm32f429zi")] 117 let mut buf = [W::default(); 9];
68 defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en());
69 118
70 // test rx-only configuration
71 let mut spi = Spi::new_blocking_rxonly(&mut spi_peri, &mut sck, &mut miso, spi_config);
72 let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh);
73 mosi_out.set_high(); 119 mosi_out.set_high();
74 spi.blocking_read(&mut buf).unwrap(); 120 spi.blocking_read(&mut buf).unwrap();
75 assert_eq!(buf, [0xff; 9]); 121 assert_eq!(buf, [!W::default(); 9]);
76 mosi_out.set_low(); 122 mosi_out.set_low();
77 spi.blocking_read(&mut buf).unwrap(); 123 spi.blocking_read(&mut buf).unwrap();
78 assert_eq!(buf, [0x00; 9]); 124 assert_eq!(buf, [W::default(); 9]);
79 spi.blocking_read::<u8>(&mut []).unwrap(); 125 spi.blocking_read::<u8>(&mut []).unwrap();
80 spi.blocking_read::<u8>(&mut []).unwrap(); 126 spi.blocking_read::<u8>(&mut []).unwrap();
81 drop(mosi_out); 127}
82 drop(spi); 128
129fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>)
130where
131 W: core::ops::Not<Output = W>,
132{
133 let buf = [W::default(); 9];
83 134
84 // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. 135 // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave.
85 let mut spi = Spi::new_blocking_txonly(&mut spi_peri, &mut sck, &mut mosi, spi_config);
86 spi.blocking_transfer(&mut buf, &data).unwrap();
87 spi.blocking_transfer_in_place(&mut buf).unwrap();
88 spi.blocking_write(&buf).unwrap(); 136 spi.blocking_write(&buf).unwrap();
89 spi.blocking_read(&mut buf).unwrap();
90 spi.blocking_transfer::<u8>(&mut [], &[]).unwrap();
91 spi.blocking_transfer_in_place::<u8>(&mut []).unwrap();
92 spi.blocking_read::<u8>(&mut []).unwrap();
93 spi.blocking_write::<u8>(&[]).unwrap(); 137 spi.blocking_write::<u8>(&[]).unwrap();
94 drop(spi);
95
96 // Test tx-only nosck.
97 let mut spi = Spi::new_blocking_txonly_nosck(&mut spi_peri, &mut mosi, spi_config);
98 spi.blocking_write(&buf).unwrap(); 138 spi.blocking_write(&buf).unwrap();
99 spi.blocking_write::<u8>(&[]).unwrap(); 139 spi.blocking_write::<u8>(&[]).unwrap();
100 spi.blocking_write(&buf).unwrap();
101 drop(spi);
102
103 info!("Test OK");
104 cortex_m::asm::bkpt();
105} 140}
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs
index fd26d3f71..c8cd92401 100644
--- a/tests/stm32/src/bin/spi_dma.rs
+++ b/tests/stm32/src/bin/spi_dma.rs
@@ -7,12 +7,14 @@ use common::*;
7use defmt::assert_eq; 7use defmt::assert_eq;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{Level, Output, Speed}; 9use embassy_stm32::gpio::{Level, Output, Speed};
10use embassy_stm32::spi::{self, Spi}; 10use embassy_stm32::mode::Async;
11use embassy_stm32::spi::mode::Master;
12use embassy_stm32::spi::{self, Spi, Word};
11use embassy_stm32::time::Hertz; 13use embassy_stm32::time::Hertz;
12 14
13#[embassy_executor::main] 15#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
15 let p = embassy_stm32::init(config()); 17 let p = init();
16 info!("Hello World!"); 18 info!("Hello World!");
17 19
18 let mut spi_peri = peri!(p, SPI); 20 let mut spi_peri = peri!(p, SPI);
@@ -26,20 +28,76 @@ async fn main(_spawner: Spawner) {
26 spi_config.frequency = Hertz(1_000_000); 28 spi_config.frequency = Hertz(1_000_000);
27 29
28 let mut spi = Spi::new( 30 let mut spi = Spi::new(
29 &mut spi_peri, 31 spi_peri.reborrow(),
30 &mut sck, // Arduino D13 32 sck.reborrow(), // Arduino D13
31 &mut mosi, // Arduino D11 33 mosi.reborrow(), // Arduino D11
32 &mut miso, // Arduino D12 34 miso.reborrow(), // Arduino D12
33 &mut tx_dma, 35 tx_dma.reborrow(),
34 &mut rx_dma, 36 rx_dma.reborrow(),
35 spi_config, 37 spi_config,
36 ); 38 );
37 39
38 let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; 40 test_txrx::<u8>(&mut spi).await;
41 test_txrx::<u16>(&mut spi).await;
42 drop(spi);
43
44 // test rx-only configuration
45 let mut spi = Spi::new_rxonly(
46 spi_peri.reborrow(),
47 sck.reborrow(),
48 miso.reborrow(),
49 // SPIv1/f1 requires txdma even if rxonly.
50 #[cfg(not(feature = "spi-v345"))]
51 tx_dma.reborrow(),
52 rx_dma.reborrow(),
53 spi_config,
54 );
55 let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh);
56
57 test_rx::<u8>(&mut spi, &mut mosi_out).await;
58 test_rx::<u16>(&mut spi, &mut mosi_out).await;
59 drop(spi);
60 drop(mosi_out);
61
62 let mut spi = Spi::new_txonly(
63 spi_peri.reborrow(),
64 sck.reborrow(),
65 mosi.reborrow(),
66 tx_dma.reborrow(),
67 spi_config,
68 );
69 test_tx::<u8>(&mut spi).await;
70 test_tx::<u16>(&mut spi).await;
71 drop(spi);
72
73 let mut spi = Spi::new_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), tx_dma.reborrow(), spi_config);
74 test_tx::<u8>(&mut spi).await;
75 test_tx::<u16>(&mut spi).await;
76 drop(spi);
77
78 info!("Test OK");
79 cortex_m::asm::bkpt();
80}
81
82async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>)
83where
84 W: core::ops::Not<Output = W>,
85{
86 let data: [W; 9] = [
87 0x00u8.into(),
88 0xFFu8.into(),
89 0xAAu8.into(),
90 0x55u8.into(),
91 0xC0u8.into(),
92 0xFFu8.into(),
93 0xEEu8.into(),
94 0xC0u8.into(),
95 0xDEu8.into(),
96 ];
39 97
40 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. 98 // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
41 // so we should get the data we sent back. 99 // so we should get the data we sent back.
42 let mut buf = [0; 9]; 100 let mut buf = [W::default(); 9];
43 spi.transfer(&mut buf, &data).await.unwrap(); 101 spi.transfer(&mut buf, &data).await.unwrap();
44 assert_eq!(buf, data); 102 assert_eq!(buf, data);
45 103
@@ -83,56 +141,41 @@ async fn main(_spawner: Spawner) {
83 spi.blocking_write(&buf).unwrap(); 141 spi.blocking_write(&buf).unwrap();
84 spi.blocking_read(&mut buf).unwrap(); 142 spi.blocking_read(&mut buf).unwrap();
85 spi.write(&buf).await.unwrap(); 143 spi.write(&buf).await.unwrap();
144}
86 145
87 core::mem::drop(spi); 146async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>, mosi_out: &mut Output<'_>)
147where
148 W: core::ops::Not<Output = W>,
149{
150 let mut buf = [W::default(); 9];
88 151
89 // test rx-only configuration
90 let mut spi = Spi::new_rxonly(
91 &mut spi_peri,
92 &mut sck,
93 &mut miso,
94 // SPIv1/f1 requires txdma even if rxonly.
95 #[cfg(not(feature = "spi-v345"))]
96 &mut tx_dma,
97 &mut rx_dma,
98 spi_config,
99 );
100 let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh);
101 mosi_out.set_high(); 152 mosi_out.set_high();
102 spi.read(&mut buf).await.unwrap(); 153 spi.read(&mut buf).await.unwrap();
103 assert_eq!(buf, [0xff; 9]); 154 assert_eq!(buf, [!W::default(); 9]);
104 spi.blocking_read(&mut buf).unwrap(); 155 spi.blocking_read(&mut buf).unwrap();
105 assert_eq!(buf, [0xff; 9]); 156 assert_eq!(buf, [!W::default(); 9]);
106 spi.read(&mut buf).await.unwrap(); 157 spi.read(&mut buf).await.unwrap();
107 assert_eq!(buf, [0xff; 9]); 158 assert_eq!(buf, [!W::default(); 9]);
108 spi.read(&mut buf).await.unwrap(); 159 spi.read(&mut buf).await.unwrap();
109 assert_eq!(buf, [0xff; 9]); 160 assert_eq!(buf, [!W::default(); 9]);
110 spi.blocking_read(&mut buf).unwrap(); 161 spi.blocking_read(&mut buf).unwrap();
111 assert_eq!(buf, [0xff; 9]); 162 assert_eq!(buf, [!W::default(); 9]);
112 spi.blocking_read(&mut buf).unwrap(); 163 spi.blocking_read(&mut buf).unwrap();
113 assert_eq!(buf, [0xff; 9]); 164 assert_eq!(buf, [!W::default(); 9]);
114 mosi_out.set_low(); 165 mosi_out.set_low();
115 spi.read(&mut buf).await.unwrap(); 166 spi.read(&mut buf).await.unwrap();
116 assert_eq!(buf, [0x00; 9]); 167 assert_eq!(buf, [W::default(); 9]);
117 spi.read::<u8>(&mut []).await.unwrap(); 168 spi.read::<u8>(&mut []).await.unwrap();
118 spi.blocking_read::<u8>(&mut []).unwrap(); 169 spi.blocking_read::<u8>(&mut []).unwrap();
119 drop(mosi_out); 170}
120 drop(spi);
121 171
122 // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. 172async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>)
123 let mut spi = Spi::new_txonly(&mut spi_peri, &mut sck, &mut mosi, &mut tx_dma, spi_config); 173where
124 spi.blocking_write(&buf).unwrap(); 174 W: core::ops::Not<Output = W>,
125 spi.write(&buf).await.unwrap(); 175{
126 spi.blocking_write(&buf).unwrap(); 176 let buf = [W::default(); 9];
127 spi.blocking_write(&buf).unwrap();
128 spi.write(&buf).await.unwrap();
129 spi.write(&buf).await.unwrap();
130 spi.write::<u8>(&[]).await.unwrap();
131 spi.blocking_write::<u8>(&[]).unwrap();
132 drop(spi);
133 177
134 // Test tx-only nosck. 178 // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave.
135 let mut spi = Spi::new_txonly_nosck(&mut spi_peri, &mut mosi, &mut tx_dma, spi_config);
136 spi.blocking_write(&buf).unwrap(); 179 spi.blocking_write(&buf).unwrap();
137 spi.write(&buf).await.unwrap(); 180 spi.write(&buf).await.unwrap();
138 spi.blocking_write(&buf).unwrap(); 181 spi.blocking_write(&buf).unwrap();
@@ -141,8 +184,4 @@ async fn main(_spawner: Spawner) {
141 spi.write(&buf).await.unwrap(); 184 spi.write(&buf).await.unwrap();
142 spi.write::<u8>(&[]).await.unwrap(); 185 spi.write::<u8>(&[]).await.unwrap();
143 spi.blocking_write::<u8>(&[]).unwrap(); 186 spi.blocking_write::<u8>(&[]).unwrap();
144 drop(spi);
145
146 info!("Test OK");
147 cortex_m::asm::bkpt();
148} 187}
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index c1106bb2f..83c375bc5 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -7,21 +7,12 @@ mod common;
7 7
8use chrono::NaiveDate; 8use chrono::NaiveDate;
9use common::*; 9use common::*;
10use cortex_m_rt::entry;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
12use embassy_stm32::low_power::{stop_ready, stop_with_rtc, Executor, StopMode}; 11use embassy_stm32::low_power::{StopMode, stop_ready};
13use embassy_stm32::rcc::LsConfig; 12use embassy_stm32::rcc::LsConfig;
14use embassy_stm32::rtc::{Rtc, RtcConfig}; 13use embassy_stm32::rtc::Rtc;
15use embassy_stm32::Config; 14use embassy_stm32::{Config, low_power};
16use embassy_time::Timer; 15use embassy_time::Timer;
17use static_cell::StaticCell;
18
19#[entry]
20fn main() -> ! {
21 Executor::take().run(|spawner| {
22 unwrap!(spawner.spawn(async_main(spawner)));
23 });
24}
25 16
26#[embassy_executor::task] 17#[embassy_executor::task]
27async fn task_1() { 18async fn task_1() {
@@ -44,12 +35,13 @@ async fn task_2() {
44 cortex_m::asm::bkpt(); 35 cortex_m::asm::bkpt();
45} 36}
46 37
47#[embassy_executor::task] 38#[embassy_executor::main(executor = "low_power::Executor")]
48async fn async_main(spawner: Spawner) { 39async fn async_main(spawner: Spawner) {
49 let _ = config(); 40 let _ = config();
50 41
51 let mut config = Config::default(); 42 let mut config = Config::default();
52 config.rcc.ls = LsConfig::default_lse(); 43 config.rcc.ls = LsConfig::default_lse();
44 config.rtc._disable_rtc = false;
53 45
54 // System Clock seems cannot be greater than 16 MHz 46 // System Clock seems cannot be greater than 16 MHz
55 #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] 47 #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))]
@@ -58,7 +50,7 @@ async fn async_main(spawner: Spawner) {
58 config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4 50 config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4
59 } 51 }
60 52
61 let p = embassy_stm32::init(config); 53 let p = init_with_config(config);
62 info!("Hello World!"); 54 info!("Hello World!");
63 55
64 let now = NaiveDate::from_ymd_opt(2020, 5, 15) 56 let now = NaiveDate::from_ymd_opt(2020, 5, 15)
@@ -66,15 +58,12 @@ async fn async_main(spawner: Spawner) {
66 .and_hms_opt(10, 30, 15) 58 .and_hms_opt(10, 30, 15)
67 .unwrap(); 59 .unwrap();
68 60
69 let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 61 let (rtc, _time_provider) = Rtc::new(p.RTC);
70 62
71 rtc.set_datetime(now.into()).expect("datetime not set"); 63 critical_section::with(|cs| {
72 64 rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set");
73 static RTC: StaticCell<Rtc> = StaticCell::new(); 65 });
74 let rtc = RTC.init(rtc);
75
76 stop_with_rtc(rtc);
77 66
78 spawner.spawn(task_1()).unwrap(); 67 spawner.spawn(task_1().unwrap());
79 spawner.spawn(task_2()).unwrap(); 68 spawner.spawn(task_2().unwrap());
80} 69}
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
index c09334ec8..c794afff8 100644
--- a/tests/stm32/src/bin/ucpd.rs
+++ b/tests/stm32/src/bin/ucpd.rs
@@ -9,7 +9,7 @@ use defmt::{assert, assert_eq};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_futures::join::join; 10use embassy_futures::join::join;
11use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; 11use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd};
12use embassy_stm32::{bind_interrupts, peripherals}; 12use embassy_stm32::{Peri, bind_interrupts, peripherals};
13use embassy_time::Timer; 13use embassy_time::Timer;
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
@@ -28,8 +28,8 @@ async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: C
28 28
29async fn source( 29async fn source(
30 mut ucpd: Ucpd<'static, peripherals::UCPD1>, 30 mut ucpd: Ucpd<'static, peripherals::UCPD1>,
31 rx_dma: peripherals::DMA1_CH1, 31 rx_dma: Peri<'static, peripherals::DMA1_CH1>,
32 tx_dma: peripherals::DMA1_CH2, 32 tx_dma: Peri<'static, peripherals::DMA1_CH2>,
33) { 33) {
34 debug!("source: setting default current pull-up"); 34 debug!("source: setting default current pull-up");
35 ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); 35 ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb);
@@ -65,8 +65,8 @@ async fn source(
65 65
66async fn sink( 66async fn sink(
67 mut ucpd: Ucpd<'static, peripherals::UCPD2>, 67 mut ucpd: Ucpd<'static, peripherals::UCPD2>,
68 rx_dma: peripherals::DMA1_CH3, 68 rx_dma: Peri<'static, peripherals::DMA1_CH3>,
69 tx_dma: peripherals::DMA1_CH4, 69 tx_dma: Peri<'static, peripherals::DMA1_CH4>,
70) { 70) {
71 debug!("sink: setting pull down"); 71 debug!("sink: setting pull down");
72 ucpd.cc_phy().set_pull(CcPull::Sink); 72 ucpd.cc_phy().set_pull(CcPull::Sink);
@@ -102,12 +102,12 @@ async fn sink(
102 102
103#[embassy_executor::main] 103#[embassy_executor::main]
104async fn main(_spawner: Spawner) { 104async fn main(_spawner: Spawner) {
105 let p = embassy_stm32::init(config()); 105 let p = init();
106 info!("Hello World!"); 106 info!("Hello World!");
107 107
108 // Wire between PD0 and PA8 108 // Wire between PD0 and PA8
109 let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15); 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); 110 let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2, Default::default());
111 111
112 join( 112 join(
113 source(ucpd1, p.DMA1_CH1, p.DMA1_CH2), 113 source(ucpd1, p.DMA1_CH1, p.DMA1_CH2),
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs
index a6e34674d..0b98d3eeb 100644
--- a/tests/stm32/src/bin/usart.rs
+++ b/tests/stm32/src/bin/usart.rs
@@ -7,11 +7,11 @@ use common::*;
7use defmt::{assert, assert_eq, unreachable}; 7use defmt::{assert, assert_eq, unreachable};
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; 9use embassy_stm32::usart::{Config, ConfigError, Error, Uart};
10use embassy_time::{block_for, Duration, Instant}; 10use embassy_time::{Duration, Instant, block_for};
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
@@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) {
22 22
23 { 23 {
24 let config = Config::default(); 24 let config = Config::default();
25 let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); 25 let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap();
26 26
27 // 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.
28 // 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.
@@ -33,12 +33,19 @@ async fn main(_spawner: Spawner) {
33 let mut buf = [0; 2]; 33 let mut buf = [0; 2];
34 usart.blocking_read(&mut buf).unwrap(); 34 usart.blocking_read(&mut buf).unwrap();
35 assert_eq!(buf, data); 35 assert_eq!(buf, data);
36
37 // Test flush doesn't hang.
38 usart.blocking_write(&data).unwrap();
39 usart.blocking_flush().unwrap();
40
41 // Test flush doesn't hang if there's nothing to flush
42 usart.blocking_flush().unwrap();
36 } 43 }
37 44
38 // Test error handling with with an overflow error 45 // Test error handling with with an overflow error
39 { 46 {
40 let config = Config::default(); 47 let config = Config::default();
41 let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); 48 let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap();
42 49
43 // Send enough bytes to fill the RX FIFOs off all USART versions. 50 // Send enough bytes to fill the RX FIFOs off all USART versions.
44 let data = [0; 64]; 51 let data = [0; 64];
@@ -68,7 +75,7 @@ async fn main(_spawner: Spawner) {
68 75
69 let mut config = Config::default(); 76 let mut config = Config::default();
70 config.baudrate = baudrate; 77 config.baudrate = baudrate;
71 let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { 78 let mut usart = match Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config) {
72 Ok(x) => x, 79 Ok(x) => x,
73 Err(ConfigError::BaudrateTooHigh) => { 80 Err(ConfigError::BaudrateTooHigh) => {
74 info!("baudrate too high"); 81 info!("baudrate too high");
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs
index 24e2b2896..a34498376 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
@@ -51,6 +51,23 @@ async fn main(_spawner: Spawner) {
51 assert_eq!(tx_buf, rx_buf); 51 assert_eq!(tx_buf, rx_buf);
52 } 52 }
53 53
54 // Test flush doesn't hang. Check multiple combinations of async+blocking.
55 tx.write(&tx_buf).await.unwrap();
56 tx.flush().await.unwrap();
57 tx.flush().await.unwrap();
58
59 tx.write(&tx_buf).await.unwrap();
60 tx.blocking_flush().unwrap();
61 tx.flush().await.unwrap();
62
63 tx.blocking_write(&tx_buf).unwrap();
64 tx.blocking_flush().unwrap();
65 tx.flush().await.unwrap();
66
67 tx.blocking_write(&tx_buf).unwrap();
68 tx.flush().await.unwrap();
69 tx.blocking_flush().unwrap();
70
54 info!("Test OK"); 71 info!("Test OK");
55 cortex_m::asm::bkpt(); 72 cortex_m::asm::bkpt();
56} 73}
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
index ea1e52358..15a0b0d60 100644
--- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs
+++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
@@ -18,7 +18,7 @@ const DMA_BUF_SIZE: usize = 256;
18 18
19#[embassy_executor::main] 19#[embassy_executor::main]
20async fn main(spawner: Spawner) { 20async fn main(spawner: Spawner) {
21 let p = embassy_stm32::init(config()); 21 let p = init();
22 info!("Hello World!"); 22 info!("Hello World!");
23 23
24 // Arduino pins D0 and D1 24 // Arduino pins D0 and D1
@@ -43,12 +43,11 @@ async fn main(spawner: Spawner) {
43 let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap(); 43 let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap();
44 let (tx, rx) = usart.split(); 44 let (tx, rx) = usart.split();
45 static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE]; 45 static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE];
46 let dma_buf = unsafe { DMA_BUF.as_mut() }; 46 let rx = rx.into_ring_buffered(unsafe { &mut *core::ptr::addr_of_mut!(DMA_BUF) });
47 let rx = rx.into_ring_buffered(dma_buf);
48 47
49 info!("Spawning tasks"); 48 info!("Spawning tasks");
50 spawner.spawn(transmit_task(tx)).unwrap(); 49 spawner.spawn(transmit_task(tx).unwrap());
51 spawner.spawn(receive_task(rx)).unwrap(); 50 spawner.spawn(receive_task(rx).unwrap());
52} 51}
53 52
54#[embassy_executor::task] 53#[embassy_executor::task]
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs
index 82a540d45..0f396b848 100644
--- a/tests/stm32/src/bin/wpan_ble.rs
+++ b/tests/stm32/src/bin/wpan_ble.rs
@@ -12,16 +12,16 @@ use embassy_executor::Spawner;
12use embassy_stm32::bind_interrupts; 12use embassy_stm32::bind_interrupts;
13use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 13use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
14use embassy_stm32::rcc::WPAN_DEFAULT; 14use embassy_stm32::rcc::WPAN_DEFAULT;
15use embassy_stm32_wpan::TlMbox;
16use embassy_stm32_wpan::hci::BdAddr;
15use embassy_stm32_wpan::hci::host::uart::UartHci; 17use embassy_stm32_wpan::hci::host::uart::UartHci;
16use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; 18use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
17use embassy_stm32_wpan::hci::types::AdvertisingType; 19use embassy_stm32_wpan::hci::types::AdvertisingType;
18use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role}; 20use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role};
19use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands; 21use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands;
20use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel}; 22use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel};
21use embassy_stm32_wpan::hci::BdAddr;
22use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; 23use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp;
23use embassy_stm32_wpan::sub::mm; 24use embassy_stm32_wpan::sub::mm;
24use embassy_stm32_wpan::TlMbox;
25use {defmt_rtt as _, panic_probe as _}; 25use {defmt_rtt as _, panic_probe as _};
26 26
27bind_interrupts!(struct Irqs{ 27bind_interrupts!(struct Irqs{
@@ -41,13 +41,13 @@ 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();
48 let mut mbox = TlMbox::init(p.IPCC, Irqs, config); 48 let mut mbox = TlMbox::init(p.IPCC, Irqs, config);
49 49
50 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); 50 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
51 51
52 let sys_event = mbox.sys_subsystem.read().await; 52 let sys_event = mbox.sys_subsystem.read().await;
53 info!("sys event: {}", sys_event.payload()); 53 info!("sys event: {}", sys_event.payload());
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs
index fe53b8786..f27146c44 100644
--- a/tests/stm32/src/bin/wpan_mac.rs
+++ b/tests/stm32/src/bin/wpan_mac.rs
@@ -10,13 +10,13 @@ use embassy_executor::Spawner;
10use embassy_stm32::bind_interrupts; 10use embassy_stm32::bind_interrupts;
11use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 11use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
12use embassy_stm32::rcc::WPAN_DEFAULT; 12use embassy_stm32::rcc::WPAN_DEFAULT;
13use embassy_stm32_wpan::TlMbox;
13use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; 14use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest};
14use embassy_stm32_wpan::mac::event::MacEvent; 15use embassy_stm32_wpan::mac::event::MacEvent;
15use embassy_stm32_wpan::mac::typedefs::{ 16use embassy_stm32_wpan::mac::typedefs::{
16 AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PanId, PibId, SecurityLevel, 17 AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PanId, PibId, SecurityLevel,
17}; 18};
18use embassy_stm32_wpan::sub::mm; 19use embassy_stm32_wpan::sub::mm;
19use embassy_stm32_wpan::TlMbox;
20use {defmt_rtt as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _};
21 21
22bind_interrupts!(struct Irqs{ 22bind_interrupts!(struct Irqs{
@@ -34,13 +34,13 @@ 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();
41 let mbox = TlMbox::init(p.IPCC, Irqs, config); 41 let mbox = TlMbox::init(p.IPCC, Irqs, config);
42 42
43 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); 43 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
44 44
45 let sys_event = mbox.sys_subsystem.read().await; 45 let sys_event = mbox.sys_subsystem.read().await;
46 info!("sys event: {}", sys_event.payload()); 46 info!("sys event: {}", sys_event.payload());
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/can_common.rs
index 4e1740ad5..4e1740ad5 100644
--- a/tests/stm32/src/bin/can_common.rs
+++ b/tests/stm32/src/can_common.rs
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 4e0231858..096cce947 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -1,11 +1,11 @@
1#![macro_use] 1#![macro_use]
2 2
3pub use defmt::*; 3pub use defmt::*;
4use embassy_stm32::Config;
4#[allow(unused)] 5#[allow(unused)]
5use embassy_stm32::rcc::*; 6use embassy_stm32::rcc::*;
6#[allow(unused)] 7#[allow(unused)]
7use embassy_stm32::time::Hertz; 8use embassy_stm32::time::Hertz;
8use embassy_stm32::Config;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
11#[cfg(feature = "stm32f103c8")] 11#[cfg(feature = "stm32f103c8")]
@@ -34,6 +34,8 @@ teleprobe_meta::target!(b"nucleo-stm32u5a5zj");
34teleprobe_meta::target!(b"nucleo-stm32h563zi"); 34teleprobe_meta::target!(b"nucleo-stm32h563zi");
35#[cfg(feature = "stm32c031c6")] 35#[cfg(feature = "stm32c031c6")]
36teleprobe_meta::target!(b"nucleo-stm32c031c6"); 36teleprobe_meta::target!(b"nucleo-stm32c031c6");
37#[cfg(feature = "stm32c071rb")]
38teleprobe_meta::target!(b"nucleo-stm32c071rb");
37#[cfg(feature = "stm32l073rz")] 39#[cfg(feature = "stm32l073rz")]
38teleprobe_meta::target!(b"nucleo-stm32l073rz"); 40teleprobe_meta::target!(b"nucleo-stm32l073rz");
39#[cfg(feature = "stm32l152re")] 41#[cfg(feature = "stm32l152re")]
@@ -101,7 +103,7 @@ define_peris!(
101 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, 103 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>;}, 104 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
103); 105);
104#[cfg(feature = "stm32f103c8")] 106#[cfg(any(feature = "stm32f100rd", feature = "stm32f103c8", feature = "stm32f107vc"))]
105define_peris!( 107define_peris!(
106 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, 108 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5,
107 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, 109 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
@@ -186,6 +188,12 @@ define_peris!(
186 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, 188 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
187 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, 189 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
188); 190);
191#[cfg(feature = "stm32c071rb")]
192define_peris!(
193 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
194 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
195 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
196);
189#[cfg(feature = "stm32l496zg")] 197#[cfg(feature = "stm32l496zg")]
190define_peris!( 198define_peris!(
191 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, 199 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
@@ -271,7 +279,7 @@ pub fn config() -> Config {
271 #[allow(unused_mut)] 279 #[allow(unused_mut)]
272 let mut config = Config::default(); 280 let mut config = Config::default();
273 281
274 #[cfg(feature = "stm32c031c6")] 282 #[cfg(any(feature = "stm32c031c6", feature = "stm32c071rb"))]
275 { 283 {
276 config.rcc.hsi = Some(Hsi { 284 config.rcc.hsi = Some(Hsi {
277 sys_div: HsiSysDiv::DIV1, // 48Mhz 285 sys_div: HsiSysDiv::DIV1, // 48Mhz
@@ -284,7 +292,9 @@ pub fn config() -> Config {
284 292
285 #[cfg(feature = "stm32g071rb")] 293 #[cfg(feature = "stm32g071rb")]
286 { 294 {
287 config.rcc.hsi = true; 295 config.rcc.hsi = Some(Hsi {
296 sys_div: HsiSysDiv::DIV1,
297 });
288 config.rcc.pll = Some(Pll { 298 config.rcc.pll = Some(Pll {
289 source: PllSource::HSI, 299 source: PllSource::HSI,
290 prediv: PllPreDiv::DIV1, 300 prediv: PllPreDiv::DIV1,
@@ -458,6 +468,8 @@ pub fn config() -> Config {
458 config.rcc.apb3_pre = APBPrescaler::DIV1; 468 config.rcc.apb3_pre = APBPrescaler::DIV1;
459 config.rcc.sys = Sysclk::PLL1_P; 469 config.rcc.sys = Sysclk::PLL1_P;
460 config.rcc.voltage_scale = VoltageScale::Scale0; 470 config.rcc.voltage_scale = VoltageScale::Scale0;
471
472 config.rtc._disable_rtc = true;
461 } 473 }
462 474
463 #[cfg(feature = "stm32h503rb")] 475 #[cfg(feature = "stm32h503rb")]
@@ -671,6 +683,8 @@ pub fn config() -> Config {
671 divp: Some(PllDiv::DIV2), // 600Mhz 683 divp: Some(PllDiv::DIV2), // 600Mhz
672 divq: Some(PllDiv::DIV25), // 48Mhz 684 divq: Some(PllDiv::DIV25), // 48Mhz
673 divr: None, 685 divr: None,
686 divs: None,
687 divt: None,
674 }); 688 });
675 config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz 689 config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz
676 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz 690 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz
@@ -699,3 +713,21 @@ pub fn config() -> Config {
699 713
700 config 714 config
701} 715}
716
717#[allow(unused)]
718pub fn init() -> embassy_stm32::Peripherals {
719 init_with_config(config())
720}
721
722#[allow(unused)]
723pub fn init_with_config(config: Config) -> embassy_stm32::Peripherals {
724 #[cfg(any(feature = "stm32wl55jc", feature = "stm32h755zi"))]
725 {
726 // Not in shared memory, but we're not running the second core, so it's fine
727 static SHARED_DATA: core::mem::MaybeUninit<embassy_stm32::SharedData> = core::mem::MaybeUninit::uninit();
728 embassy_stm32::init_primary(config, &SHARED_DATA)
729 }
730
731 #[cfg(not(any(feature = "stm32wl55jc", feature = "stm32h755zi")))]
732 embassy_stm32::init(config)
733}
diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml
index 7b54a4f52..da04a1f5d 100644
--- a/tests/utils/Cargo.toml
+++ b/tests/utils/Cargo.toml
@@ -1,8 +1,10 @@
1[package] 1[package]
2name = "test-utils" 2name = "test-utils"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2024"
5license = "MIT OR Apache-2.0"
6publish = false
5 7
6[dependencies] 8[dependencies]
7rand = "0.8" 9rand = "0.9"
8serial = "0.4" 10serial = "0.4"
diff --git a/tests/utils/src/bin/saturate_serial.rs b/tests/utils/src/bin/saturate_serial.rs
index 18ca12fb7..1c8a8b322 100644
--- a/tests/utils/src/bin/saturate_serial.rs
+++ b/tests/utils/src/bin/saturate_serial.rs
@@ -2,7 +2,7 @@ use std::path::Path;
2use std::time::Duration; 2use std::time::Duration;
3use std::{env, io, process, thread}; 3use std::{env, io, process, thread};
4 4
5use rand::random; 5use rand::{Rng, rng};
6use serial::SerialPort; 6use serial::SerialPort;
7 7
8pub fn main() { 8pub fn main() {
@@ -34,14 +34,15 @@ fn saturate<T: SerialPort>(port: &mut T, idles: bool) -> io::Result<()> {
34 })?; 34 })?;
35 35
36 let mut written = 0; 36 let mut written = 0;
37 let mut rng = rng();
37 loop { 38 loop {
38 let len = random::<usize>() % 0x1000; 39 let len = rng.random_range(1..=0x1000);
39 let buf: Vec<u8> = (written..written + len).map(|x| x as u8).collect(); 40 let buf: Vec<u8> = (written..written + len).map(|x| x as u8).collect();
40 41
41 port.write_all(&buf)?; 42 port.write_all(&buf)?;
42 43
43 if idles { 44 if idles {
44 let micros = (random::<usize>() % 1000) as u64; 45 let micros = rng.random_range(1..=1000) as u64;
45 println!("Sleeping {}us", micros); 46 println!("Sleeping {}us", micros);
46 port.flush().unwrap(); 47 port.flush().unwrap();
47 thread::sleep(Duration::from_micros(micros)); 48 thread::sleep(Duration::from_micros(micros));