aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/mspm0/Cargo.toml22
-rw-r--r--tests/mspm0/build.rs5
-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.rs5
-rw-r--r--tests/mspm0/src/bin/uart_buffered.rs115
-rw-r--r--tests/nrf/Cargo.toml33
-rw-r--r--tests/nrf/src/bin/ethernet_enc28j60_perf.rs2
-rw-r--r--tests/nrf/src/bin/wifi_esp_hosted_perf.rs4
-rw-r--r--tests/perf-client/Cargo.toml9
-rw-r--r--tests/perf-server/Cargo.toml1
-rw-r--r--tests/riscv32/Cargo.toml14
-rw-r--r--tests/rp/Cargo.toml30
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs4
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs5
-rw-r--r--tests/rp/src/bin/gpio.rs34
-rw-r--r--tests/rp/src/bin/gpio_multicore.rs4
-rw-r--r--tests/rp/src/bin/i2c.rs2
-rw-r--r--tests/rp/src/bin/multicore.rs4
-rw-r--r--tests/rp/src/bin/overclock.rs49
-rw-r--r--tests/rp/src/bin/spinlock_mutex_multicore.rs4
-rw-r--r--tests/stm32/Cargo.toml84
-rw-r--r--tests/stm32/build.rs1
-rw-r--r--tests/stm32/src/bin/afio.rs1156
-rw-r--r--tests/stm32/src/bin/can.rs1
-rw-r--r--tests/stm32/src/bin/cryp.rs2
-rw-r--r--tests/stm32/src/bin/eeprom.rs30
-rw-r--r--tests/stm32/src/bin/eth.rs3
-rw-r--r--tests/stm32/src/bin/fdcan.rs1
-rw-r--r--tests/stm32/src/bin/hash.rs48
-rw-r--r--tests/stm32/src/bin/sdmmc.rs4
-rw-r--r--tests/stm32/src/bin/stop.rs6
-rw-r--r--tests/stm32/src/bin/usart_rx_ringbuffered.rs4
-rw-r--r--tests/stm32/src/bin/wpan_ble.rs2
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs2
-rw-r--r--tests/stm32/src/can_common.rs (renamed from tests/stm32/src/bin/can_common.rs)0
-rw-r--r--tests/stm32/src/common.rs14
-rw-r--r--tests/utils/Cargo.toml3
-rw-r--r--tests/utils/src/bin/saturate_serial.rs7
39 files changed, 2108 insertions, 115 deletions
diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml
index 0566807d7..227d898d5 100644
--- a/tests/mspm0/Cargo.toml
+++ b/tests/mspm0/Cargo.toml
@@ -3,18 +3,21 @@ edition = "2021"
3name = "embassy-mspm0-tests" 3name = "embassy-mspm0-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[features] 8[features]
8mspm0g3507 = [ "embassy-mspm0/mspm0g350x" ] 9mspm0g3507 = [ "embassy-mspm0/mspm0g3507pm" ]
10mspm0g3519 = [ "embassy-mspm0/mspm0g3519pz" ]
9 11
10[dependencies] 12[dependencies]
11teleprobe-meta = "1.1" 13teleprobe-meta = "1.1"
12 14
13embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] } 15embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = [ "defmt" ] }
14embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] } 16embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] }
15embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt" ] } 17embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
18embassy-time = { version = "0.5.0", path = "../../embassy-time", features = [ "defmt" ] }
16embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [ "rt", "defmt", "unstable-pac", "time-driver-any" ] } 19embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [ "rt", "defmt", "unstable-pac", "time-driver-any" ] }
17embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal/"} 20embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"}
18 21
19defmt = "1.0.1" 22defmt = "1.0.1"
20defmt-rtt = "1.0.0" 23defmt-rtt = "1.0.0"
@@ -23,7 +26,9 @@ cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-sin
23cortex-m-rt = "0.7.0" 26cortex-m-rt = "0.7.0"
24embedded-hal = { package = "embedded-hal", version = "1.0" } 27embedded-hal = { package = "embedded-hal", version = "1.0" }
25embedded-hal-async = { version = "1.0" } 28embedded-hal-async = { version = "1.0" }
26panic-probe = { version = "0.3.0", features = ["print-defmt"] } 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"] }
27static_cell = "2" 32static_cell = "2"
28portable-atomic = { version = "1.5", features = ["critical-section"] } 33portable-atomic = { version = "1.5", features = ["critical-section"] }
29 34
@@ -56,3 +61,8 @@ debug = false
56debug-assertions = false 61debug-assertions = false
57opt-level = 0 62opt-level = 0
58overflow-checks = false 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/mspm0/build.rs b/tests/mspm0/build.rs
index 57b592abf..43a9ac04f 100644
--- a/tests/mspm0/build.rs
+++ b/tests/mspm0/build.rs
@@ -8,6 +8,9 @@ fn main() -> Result<(), Box<dyn Error>> {
8 #[cfg(feature = "mspm0g3507")] 8 #[cfg(feature = "mspm0g3507")]
9 let memory_x = include_bytes!("memory_g3507.x"); 9 let memory_x = include_bytes!("memory_g3507.x");
10 10
11 #[cfg(feature = "mspm0g3519")]
12 let memory_x = include_bytes!("memory_g3519.x");
13
11 fs::write(out.join("memory.x"), memory_x).unwrap(); 14 fs::write(out.join("memory.x"), memory_x).unwrap();
12 15
13 println!("cargo:rustc-link-search={}", out.display()); 16 println!("cargo:rustc-link-search={}", out.display());
@@ -19,6 +22,8 @@ fn main() -> Result<(), Box<dyn Error>> {
19 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); 22 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x");
20 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 23 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
21 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");
22 27
23 Ok(()) 28 Ok(())
24} 29}
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..6fd973a18
--- /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::dma::{Channel, Transfer, TransferMode, TransferOptions, Word};
15use embassy_mspm0::Peri;
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
index 458129d44..916ce0d4b 100644
--- a/tests/mspm0/src/bin/uart.rs
+++ b/tests/mspm0/src/bin/uart.rs
@@ -4,6 +4,9 @@
4#[cfg(feature = "mspm0g3507")] 4#[cfg(feature = "mspm0g3507")]
5teleprobe_meta::target!(b"lp-mspm0g3507"); 5teleprobe_meta::target!(b"lp-mspm0g3507");
6 6
7#[cfg(feature = "mspm0g3519")]
8teleprobe_meta::target!(b"lp-mspm0g3519");
9
7use defmt::{assert_eq, unwrap, *}; 10use defmt::{assert_eq, unwrap, *};
8use embassy_executor::Spawner; 11use embassy_executor::Spawner;
9use embassy_mspm0::mode::Blocking; 12use embassy_mspm0::mode::Blocking;
@@ -23,7 +26,7 @@ async fn main(_spawner: Spawner) {
23 26
24 // TODO: Allow creating a looped-back UART (so pins are not needed). 27 // TODO: Allow creating a looped-back UART (so pins are not needed).
25 // Do not select default UART since the virtual COM port is attached to UART0. 28 // Do not select default UART since the virtual COM port is attached to UART0.
26 #[cfg(feature = "mspm0g3507")] 29 #[cfg(any(feature = "mspm0g3507", feature = "mspm0g3519"))]
27 let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1); 30 let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1);
28 31
29 const MFCLK_BUAD_RATES: &[u32] = &[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]; 32 const MFCLK_BUAD_RATES: &[u32] = &[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200];
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/nrf/Cargo.toml b/tests/nrf/Cargo.toml
index 410d62bdd..efc297ccf 100644
--- a/tests/nrf/Cargo.toml
+++ b/tests/nrf/Cargo.toml
@@ -3,30 +3,31 @@ edition = "2021"
3name = "embassy-nrf-examples" 3name = "embassy-nrf-examples"
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]
8teleprobe-meta = "1" 9teleprobe-meta = "1"
9 10
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 11embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt", ] } 12embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt", ] }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 13embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 14embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] } 15embassy-nrf = { version = "0.7.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] }
15embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 16embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
16embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } 17embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
17embassy-net-esp-hosted = { version = "0.2.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } 18embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
18embassy-net-enc28j60 = { version = "0.2.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } 19embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] }
19embedded-hal-async = { version = "1.0" } 20embedded-hal-async = { version = "1.0" }
20embedded-hal-bus = { version = "0.1", features = ["async"] } 21embedded-hal-bus = { version = "0.1", features = ["async"] }
21static_cell = "2" 22static_cell = "2"
22perf-client = { path = "../perf-client" } 23perf-client = { path = "../perf-client" }
23 24
24defmt = "0.3" 25defmt = "1.0.1"
25defmt-rtt = "0.4" 26defmt-rtt = "1.0.0"
26 27
27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 28cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
28cortex-m-rt = "0.7.0" 29cortex-m-rt = "0.7.0"
29panic-probe = { version = "0.3", features = ["print-defmt"] } 30panic-probe = { version = "1.0.0", features = ["print-defmt"] }
30portable-atomic = { version = "1.6.0" } 31portable-atomic = { version = "1.6.0" }
31 32
32[features] 33[features]
@@ -112,3 +113,13 @@ path = "src/bin/wifi_esp_hosted_perf.rs"
112required-features = [ "nrf52840",] 113required-features = [ "nrf52840",]
113 114
114# END TESTS 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/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
index ed58627f1..5f3fa1fd3 100644
--- a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
+++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
@@ -68,7 +68,7 @@ async fn main(spawner: Spawner) {
68 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); 68 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
69 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); 69 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
70 70
71 unwrap!(spawner.spawn(net_task(runner))); 71 spawner.spawn(unwrap!(net_task(runner)));
72 72
73 perf_client::run( 73 perf_client::run(
74 stack, 74 stack,
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
index 34fb8103b..34c33a4ad 100644
--- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
+++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
@@ -74,7 +74,7 @@ async fn main(spawner: Spawner) {
74 ) 74 )
75 .await; 75 .await;
76 76
77 unwrap!(spawner.spawn(wifi_task(runner))); 77 spawner.spawn(unwrap!(wifi_task(runner)));
78 78
79 unwrap!(control.init().await); 79 unwrap!(control.init().await);
80 unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); 80 unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await);
@@ -94,7 +94,7 @@ async fn main(spawner: Spawner) {
94 seed, 94 seed,
95 ); 95 );
96 96
97 unwrap!(spawner.spawn(net_task(runner))); 97 spawner.spawn(unwrap!(net_task(runner)));
98 98
99 perf_client::run( 99 perf_client::run(
100 stack, 100 stack,
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml
index 9620972c3..581b60d6f 100644
--- a/tests/perf-client/Cargo.toml
+++ b/tests/perf-client/Cargo.toml
@@ -2,9 +2,10 @@
2name = "perf-client" 2name = "perf-client"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5publish = false
5 6
6[dependencies] 7[dependencies]
7embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } 8embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
8embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] } 9embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", ] }
9embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 10embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
10defmt = "0.3" 11defmt = "1.0.1"
diff --git a/tests/perf-server/Cargo.toml b/tests/perf-server/Cargo.toml
index 532039050..22614a33a 100644
--- a/tests/perf-server/Cargo.toml
+++ b/tests/perf-server/Cargo.toml
@@ -2,6 +2,7 @@
2name = "perf-server" 2name = "perf-server"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5publish = false
5 6
6[dependencies] 7[dependencies]
7log = "0.4.17" 8log = "0.4.17"
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml
index 446326d8a..c441e8ed3 100644
--- a/tests/riscv32/Cargo.toml
+++ b/tests/riscv32/Cargo.toml
@@ -3,13 +3,14 @@ edition = "2021"
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.2", path = "../../embassy-sync" } 10embassy-sync = { version = "0.7.2", path = "../../embassy-sync" }
10embassy-executor = { version = "0.7.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.4.0", 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.toml b/tests/rp/Cargo.toml
index 1335aa84b..809346bed 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -3,6 +3,7 @@ edition = "2021"
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
6 7
7[features] 8[features]
8rp2040 = ["embassy-rp/rp2040"] 9rp2040 = ["embassy-rp/rp2040"]
@@ -12,20 +13,20 @@ rp235xb = ["embassy-rp/rp235xb"]
12[dependencies] 13[dependencies]
13teleprobe-meta = "1.1" 14teleprobe-meta = "1.1"
14 15
15embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 16embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
16embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 17embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
17embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] } 18embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", ] }
18embassy-rp = { version = "0.4.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"] }
19embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 20embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
20embassy-net = { version = "0.7.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"] }
21embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 22embassy-net-wiznet = { version = "0.2.1", path = "../../embassy-net-wiznet", features = ["defmt"] }
22embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal/"} 23embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"}
23cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } 24cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
24cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } 25cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] }
25perf-client = { path = "../perf-client" } 26perf-client = { path = "../perf-client" }
26 27
27defmt = "0.3" 28defmt = "1.0.1"
28defmt-rtt = "0.4" 29defmt-rtt = "1.0.0"
29 30
30cortex-m = { version = "0.7.6" } 31cortex-m = { version = "0.7.6" }
31cortex-m-rt = "0.7.0" 32cortex-m-rt = "0.7.0"
@@ -33,12 +34,11 @@ embedded-hal = "0.2.6"
33embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 34embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
34embedded-hal-async = { version = "1.0" } 35embedded-hal-async = { version = "1.0" }
35embedded-hal-bus = { version = "0.1", features = ["async"] } 36embedded-hal-bus = { version = "0.1", features = ["async"] }
36panic-probe = { version = "0.3.0", features = ["print-defmt"] } 37panic-probe = { version = "1.0.0", features = ["print-defmt"] }
37embedded-io-async = { version = "0.6.1" } 38embedded-io-async = { version = "0.6.1" }
38embedded-storage = { version = "0.3" } 39embedded-storage = { version = "0.3" }
39static_cell = "2" 40static_cell = "2"
40portable-atomic = { version = "1.5", features = ["critical-section"] } 41portable-atomic = { version = "1.5", features = ["critical-section"] }
41rand = { version = "0.8.5", default-features = false }
42 42
43# bootsel not currently supported on 2350 43# bootsel not currently supported on 2350
44[[bin]] 44[[bin]]
@@ -93,3 +93,9 @@ debug = false
93debug-assertions = false 93debug-assertions = false
94opt-level = 0 94opt-level = 0
95overflow-checks = false 95overflow-checks = false
96
97[package.metadata.embassy]
98build = [
99 { target = "thumbv6m-none-eabi", features = ["rp2040"], artifact-dir = "out/tests/rpi-pico" },
100 { target = "thumbv8m.main-none-eabihf", features = ["rp235xb"], artifact-dir = "out/tests/pimoroni-pico-plus-2" }
101]
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs
index dba1058a8..555134ffd 100644
--- a/tests/rp/src/bin/cyw43-perf.rs
+++ b/tests/rp/src/bin/cyw43-perf.rs
@@ -70,7 +70,7 @@ async fn main(spawner: Spawner) {
70 static STATE: StaticCell<cyw43::State> = StaticCell::new(); 70 static STATE: StaticCell<cyw43::State> = StaticCell::new();
71 let state = STATE.init(cyw43::State::new()); 71 let state = STATE.init(cyw43::State::new());
72 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;
73 unwrap!(spawner.spawn(wifi_task(runner))); 73 spawner.spawn(unwrap!(wifi_task(runner)));
74 74
75 control.init(clm).await; 75 control.init(clm).await;
76 control 76 control
@@ -89,7 +89,7 @@ async fn main(spawner: Spawner) {
89 seed, 89 seed,
90 ); 90 );
91 91
92 unwrap!(spawner.spawn(net_task(runner))); 92 spawner.spawn(unwrap!(net_task(runner)));
93 93
94 loop { 94 loop {
95 match control 95 match control
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs
index ae2adfa55..3f2bc728d 100644
--- a/tests/rp/src/bin/ethernet_w5100s_perf.rs
+++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs
@@ -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
@@ -61,7 +60,7 @@ async fn main(spawner: Spawner) {
61 ) 60 )
62 .await 61 .await
63 .unwrap(); 62 .unwrap();
64 unwrap!(spawner.spawn(ethernet_task(runner))); 63 spawner.spawn(unwrap!(ethernet_task(runner)));
65 64
66 // Generate random seed 65 // Generate random seed
67 let seed = rng.next_u64(); 66 let seed = rng.next_u64();
@@ -76,7 +75,7 @@ async fn main(spawner: Spawner) {
76 ); 75 );
77 76
78 // Launch network task 77 // Launch network task
79 unwrap!(spawner.spawn(net_task(runner))); 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/gpio.rs b/tests/rp/src/bin/gpio.rs
index 614b6317a..8bd0df8d8 100644
--- a/tests/rp/src/bin/gpio.rs
+++ b/tests/rp/src/bin/gpio.rs
@@ -67,6 +67,40 @@ async fn main(_spawner: Spawner) {
67 } 67 }
68 } 68 }
69 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
70 // Test input no pull 104 // Test input no pull
71 { 105 {
72 let b = Input::new(b.reborrow(), Pull::None); 106 let b = Input::new(b.reborrow(), Pull::None);
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs
index 857f36975..f48dd207b 100644
--- a/tests/rp/src/bin/gpio_multicore.rs
+++ b/tests/rp/src/bin/gpio_multicore.rs
@@ -30,11 +30,11 @@ fn main() -> ! {
30 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 30 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
31 move || { 31 move || {
32 let executor1 = EXECUTOR1.init(Executor::new()); 32 let executor1 = EXECUTOR1.init(Executor::new());
33 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); 33 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(p.PIN_1))));
34 }, 34 },
35 ); 35 );
36 let executor0 = EXECUTOR0.init(Executor::new()); 36 let executor0 = EXECUTOR0.init(Executor::new());
37 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); 37 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task(p.PIN_0))));
38} 38}
39 39
40#[embassy_executor::task] 40#[embassy_executor::task]
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
index 2c835bd5a..21761b98b 100644
--- a/tests/rp/src/bin/i2c.rs
+++ b/tests/rp/src/bin/i2c.rs
@@ -208,7 +208,7 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) {
208 config.addr = DEV_ADDR as u16; 208 config.addr = DEV_ADDR as u16;
209 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);
210 210
211 spawner.must_spawn(device_task(device)); 211 spawner.spawn(device_task(device).unwrap());
212 212
213 let c_sda = p.PIN_21; 213 let c_sda = p.PIN_21;
214 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 902169c40..11b03cfea 100644
--- a/tests/rp/src/bin/multicore.rs
+++ b/tests/rp/src/bin/multicore.rs
@@ -27,11 +27,11 @@ fn main() -> ! {
27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
28 move || { 28 move || {
29 let executor1 = EXECUTOR1.init(Executor::new()); 29 let executor1 = EXECUTOR1.init(Executor::new());
30 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); 30 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
31 }, 31 },
32 ); 32 );
33 let executor0 = EXECUTOR0.init(Executor::new()); 33 let executor0 = EXECUTOR0.init(Executor::new());
34 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 34 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
35} 35}
36 36
37#[embassy_executor::task] 37#[embassy_executor::task]
diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs
index be8e85a3f..167a26eb2 100644
--- a/tests/rp/src/bin/overclock.rs
+++ b/tests/rp/src/bin/overclock.rs
@@ -7,14 +7,8 @@ teleprobe_meta::target!(b"rpi-pico");
7teleprobe_meta::target!(b"pimoroni-pico-plus-2"); 7teleprobe_meta::target!(b"pimoroni-pico-plus-2");
8 8
9use defmt::info; 9use defmt::info;
10#[cfg(feature = "rp2040")]
11use defmt::{assert, assert_eq};
12use embassy_executor::Spawner; 10use embassy_executor::Spawner;
13use embassy_rp::clocks; 11use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage};
14#[cfg(feature = "rp2040")]
15use embassy_rp::clocks::ClockConfig;
16#[cfg(feature = "rp2040")]
17use embassy_rp::clocks::CoreVoltage;
18use embassy_rp::config::Config; 12use embassy_rp::config::Config;
19use embassy_time::Instant; 13use embassy_time::Instant;
20use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
@@ -23,23 +17,26 @@ const COUNT_TO: i64 = 10_000_000;
23 17
24#[embassy_executor::main] 18#[embassy_executor::main]
25async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
26 #[cfg(feature = "rp2040")]
27 let mut config = Config::default(); 20 let mut config = Config::default();
28 #[cfg(not(feature = "rp2040"))]
29 let config = Config::default();
30 21
31 // Initialize with 200MHz clock configuration for RP2040, other chips will use default clock 22 // Initialize with 200MHz clock configuration
32 #[cfg(feature = "rp2040")] 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")]
33 { 27 {
34 config.clocks = ClockConfig::system_freq(200_000_000); 28 config.clocks.core_voltage = CoreVoltage::V1_15;
35 let voltage = config.clocks.core_voltage;
36 assert!(matches!(voltage, CoreVoltage::V1_15), "Expected voltage scale V1_15");
37 } 29 }
38 30
39 let _p = embassy_rp::init(config); 31 let _p = embassy_rp::init(config);
40 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
41 // Test the system speed 38 // Test the system speed
42 let (time_elapsed, clk_sys_freq) = { 39 let time_elapsed = {
43 let mut counter = 0; 40 let mut counter = 0;
44 let start = Instant::now(); 41 let start = Instant::now();
45 while counter < COUNT_TO { 42 while counter < COUNT_TO {
@@ -47,24 +44,26 @@ async fn main(_spawner: Spawner) {
47 } 44 }
48 let elapsed = Instant::now() - start; 45 let elapsed = Instant::now() - start;
49 46
50 (elapsed.as_millis(), clocks::clk_sys_freq()) 47 elapsed.as_millis()
51 }; 48 };
52 49
53 // Report the elapsed time, so that the compiler doesn't optimize it away for chips other than RP2040 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
54 info!( 52 info!(
55 "At {}Mhz: Elapsed time to count to {}: {}ms", 53 "At {}Mhz: Elapsed time to count to {}: {}ms",
56 clk_sys_freq / 1_000_000, 54 clk_sys_freq() / 1_000_000,
57 COUNT_TO, 55 COUNT_TO,
58 time_elapsed 56 time_elapsed
59 ); 57 );
60 58
59 // Check if the elapsed time is within expected limits
60 // for rp2040 we expect about 600ms
61 #[cfg(feature = "rp2040")] 61 #[cfg(feature = "rp2040")]
62 { 62 // allow 1% error
63 // we should be at 200MHz 63 assert!(time_elapsed < 606, "Elapsed time is too long");
64 assert_eq!(clk_sys_freq, 200_000_000, "System clock frequency is not 200MHz"); 64 // for rp235x we expect about 450ms
65 // At 200MHz, the time to count to 10_000_000 should be at 600ms, testing with 1% margin 65 #[cfg(feature = "rp235xb")]
66 assert!(time_elapsed <= 606, "Elapsed time is too long"); 66 assert!(time_elapsed < 455, "Elapsed time is too long");
67 }
68 67
69 cortex_m::asm::bkpt(); 68 cortex_m::asm::bkpt();
70} 69}
diff --git a/tests/rp/src/bin/spinlock_mutex_multicore.rs b/tests/rp/src/bin/spinlock_mutex_multicore.rs
index ebcf1ca32..c56d43ade 100644
--- a/tests/rp/src/bin/spinlock_mutex_multicore.rs
+++ b/tests/rp/src/bin/spinlock_mutex_multicore.rs
@@ -27,11 +27,11 @@ fn main() -> ! {
27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
28 move || { 28 move || {
29 let executor1 = EXECUTOR1.init(Executor::new()); 29 let executor1 = EXECUTOR1.init(Executor::new());
30 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); 30 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
31 }, 31 },
32 ); 32 );
33 let executor0 = EXECUTOR0.init(Executor::new()); 33 let executor0 = EXECUTOR0.init(Executor::new());
34 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 34 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
35} 35}
36 36
37#[embassy_executor::task] 37#[embassy_executor::task]
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 3a347e279..891ec93fd 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -4,10 +4,14 @@ name = "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"]
@@ -15,12 +19,12 @@ stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "
15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng", "single-bank"] 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", "dual-bank"] 30stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng", "dual-bank"]
@@ -32,13 +36,14 @@ stm32wba52cg = ["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"]
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 = []
46hash-v34 = ["hash"]
42eth = [] 47eth = []
43rng = [] 48rng = []
44sdmmc = [] 49sdmmc = []
@@ -55,23 +60,27 @@ ucpd = []
55cordic = ["dep:num-traits"] 60cordic = ["dep:num-traits"]
56dual-bank = ["embassy-stm32/dual-bank"] 61dual-bank = ["embassy-stm32/dual-bank"]
57single-bank = ["embassy-stm32/single-bank"] 62single-bank = ["embassy-stm32/single-bank"]
63eeprom = []
64afio = []
65afio-connectivity-line = []
66afio-value-line = []
58 67
59cm0 = ["portable-atomic/unsafe-assume-single-core"] 68cm0 = ["portable-atomic/unsafe-assume-single-core"]
60 69
61[dependencies] 70[dependencies]
62teleprobe-meta = "1" 71teleprobe-meta = "1"
63 72
64embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 73embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
65embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 74embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
66embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } 75embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] }
67embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } 76embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] }
68embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 77embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
69embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } 78embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] }
70embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 79embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
71perf-client = { path = "../perf-client" } 80perf-client = { path = "../perf-client" }
72 81
73defmt = "0.3" 82defmt = "1.0.1"
74defmt-rtt = "0.4" 83defmt-rtt = "1.0.0"
75 84
76cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 85cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
77cortex-m-rt = "0.7.0" 86cortex-m-rt = "0.7.0"
@@ -80,9 +89,9 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
80embedded-hal-async = { version = "1.0" } 89embedded-hal-async = { version = "1.0" }
81embedded-can = { version = "0.4" } 90embedded-can = { version = "0.4" }
82micromath = "2.0.0" 91micromath = "2.0.0"
83panic-probe = { version = "0.3.0", features = ["print-defmt"] } 92panic-probe = { version = "1.0.0", features = ["print-defmt"] }
84rand_core = { version = "0.6", default-features = false } 93rand_core = { version = "0.9.1", default-features = false }
85rand_chacha = { version = "0.3", default-features = false } 94rand_chacha = { version = "0.9.0", default-features = false }
86static_cell = "2" 95static_cell = "2"
87portable-atomic = { version = "1.5", features = [] } 96portable-atomic = { version = "1.5", features = [] }
88 97
@@ -95,6 +104,11 @@ num-traits = { version="0.2", default-features = false,features = ["libm"], opti
95# BEGIN TESTS 104# BEGIN TESTS
96# Generated by gen_test.py. DO NOT EDIT. 105# Generated by gen_test.py. DO NOT EDIT.
97[[bin]] 106[[bin]]
107name = "afio"
108path = "src/bin/afio.rs"
109required-features = [ "afio",]
110
111[[bin]]
98name = "can" 112name = "can"
99path = "src/bin/can.rs" 113path = "src/bin/can.rs"
100required-features = [ "can",] 114required-features = [ "can",]
@@ -120,6 +134,11 @@ path = "src/bin/dac_l1.rs"
120required-features = [ "stm32l152re",] 134required-features = [ "stm32l152re",]
121 135
122[[bin]] 136[[bin]]
137name = "eeprom"
138path = "src/bin/eeprom.rs"
139required-features = [ "eeprom",]
140
141[[bin]]
123name = "eth" 142name = "eth"
124path = "src/bin/eth.rs" 143path = "src/bin/eth.rs"
125required-features = [ "eth",] 144required-features = [ "eth",]
@@ -235,3 +254,36 @@ debug = false
235debug-assertions = false 254debug-assertions = false
236opt-level = 0 255opt-level = 0
237overflow-checks = false 256overflow-checks = false
257
258[package.metadata.embassy]
259build = [
260 { target = "thumbv7m-none-eabi", features = ["stm32f103c8"], artifact-dir = "out/tests/stm32f103c8" },
261 { target = "thumbv7em-none-eabi", features = ["stm32f429zi"], artifact-dir = "out/tests/stm32f429zi" },
262 { target = "thumbv7em-none-eabi", features = ["stm32f446re"], artifact-dir = "out/tests/stm32f446re" },
263 { target = "thumbv7em-none-eabi", features = ["stm32g491re"], artifact-dir = "out/tests/stm32g491re" },
264 { target = "thumbv6m-none-eabi", features = ["stm32g071rb"], artifact-dir = "out/tests/stm32g071rb" },
265 { target = "thumbv6m-none-eabi", features = ["stm32c031c6"], artifact-dir = "out/tests/stm32c031c6" },
266 { target = "thumbv6m-none-eabi", features = ["stm32c071rb"], artifact-dir = "out/tests/stm32c071rb" },
267 { target = "thumbv7em-none-eabi", features = ["stm32h755zi"], artifact-dir = "out/tests/stm32h755zi" },
268 { target = "thumbv7em-none-eabi", features = ["stm32h753zi"], artifact-dir = "out/tests/stm32h753zi" },
269 { target = "thumbv7em-none-eabi", features = ["stm32h7a3zi"], artifact-dir = "out/tests/stm32h7a3zi" },
270 { target = "thumbv7em-none-eabi", features = ["stm32wb55rg"], artifact-dir = "out/tests/stm32wb55rg" },
271 { target = "thumbv8m.main-none-eabihf", features = ["stm32h563zi"], artifact-dir = "out/tests/stm32h563zi" },
272 { target = "thumbv8m.main-none-eabihf", features = ["stm32u585ai"], artifact-dir = "out/tests/stm32u585ai" },
273 { target = "thumbv8m.main-none-eabihf", features = ["stm32u5a5zj"], artifact-dir = "out/tests/stm32u5a5zj" },
274 { target = "thumbv8m.main-none-eabihf", features = ["stm32wba52cg"], artifact-dir = "out/tests/stm32wba52cg" },
275 { target = "thumbv6m-none-eabi", features = ["stm32l073rz"], artifact-dir = "out/tests/stm32l073rz" },
276 { target = "thumbv7m-none-eabi", features = ["stm32l152re"], artifact-dir = "out/tests/stm32l152re" },
277 { target = "thumbv7em-none-eabi", features = ["stm32l4a6zg"], artifact-dir = "out/tests/stm32l4a6zg" },
278 { target = "thumbv7em-none-eabi", features = ["stm32l4r5zi"], artifact-dir = "out/tests/stm32l4r5zi" },
279 { target = "thumbv8m.main-none-eabihf", features = ["stm32l552ze"], artifact-dir = "out/tests/stm32l552ze" },
280 { target = "thumbv7em-none-eabi", features = ["stm32f767zi"], artifact-dir = "out/tests/stm32f767zi" },
281 { target = "thumbv7m-none-eabi", features = ["stm32f207zg"], artifact-dir = "out/tests/stm32f207zg" },
282 { target = "thumbv7em-none-eabi", features = ["stm32f303ze"], artifact-dir = "out/tests/stm32f303ze" },
283 { target = "thumbv7em-none-eabi", features = ["stm32l496zg"], artifact-dir = "out/tests/stm32l496zg" },
284 { target = "thumbv7em-none-eabi", features = ["stm32wl55jc"], artifact-dir = "out/tests/stm32wl55jc" },
285 { target = "thumbv7em-none-eabi", features = ["stm32h7s3l8"], artifact-dir = "out/tests/stm32h7s3l8" },
286 { target = "thumbv6m-none-eabi", features = ["stm32f091rc"], artifact-dir = "out/tests/stm32f091rc" },
287 { target = "thumbv8m.main-none-eabihf", features = ["stm32h503rb"], artifact-dir = "out/tests/stm32h503rb" },
288 { target = "thumbv6m-none-eabi", features = ["stm32u083rc"], artifact-dir = "out/tests/stm32u083rc" }
289]
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..cc44dc59c
--- /dev/null
+++ b/tests/stm32/src/bin/afio.rs
@@ -0,0 +1,1156 @@
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, QeiPin};
16use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
17use embassy_stm32::usart::{Uart, UartRx, UartTx};
18use embassy_stm32::{bind_interrupts, Peripherals};
19
20#[cfg(not(feature = "afio-connectivity-line"))]
21bind_interrupts!(struct Irqs {
22 USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;
23 TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>;
24});
25
26#[cfg(feature = "afio-connectivity-line")]
27bind_interrupts!(struct Irqs {
28 CAN1_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN1>;
29 CAN1_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN1>;
30 CAN1_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN1>;
31 CAN1_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN1>;
32
33 CAN2_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN2>;
34 CAN2_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN2>;
35 CAN2_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN2>;
36 CAN2_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN2>;
37
38 ETH => embassy_stm32::eth::InterruptHandler;
39 USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;
40 TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>;
41});
42
43#[embassy_executor::main]
44async fn main(_spawner: Spawner) {
45 let mut p = init();
46 info!("Hello World!");
47
48 // USART3
49 {
50 // no remap RX/TX/RTS/CTS
51 afio_registers_set_remap();
52 Uart::new_blocking_with_rtscts(
53 p.USART3.reborrow(),
54 p.PB11.reborrow(),
55 p.PB10.reborrow(),
56 p.PB14.reborrow(),
57 p.PB13.reborrow(),
58 Default::default(),
59 )
60 .unwrap();
61 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
62 }
63 {
64 // no remap RX/TX
65 afio_registers_set_remap();
66 Uart::new_blocking(
67 p.USART3.reborrow(),
68 p.PB11.reborrow(),
69 p.PB10.reborrow(),
70 Default::default(),
71 )
72 .unwrap();
73 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
74 }
75 {
76 // no remap TX
77 afio_registers_set_remap();
78 Uart::new_blocking_half_duplex(
79 p.USART3.reborrow(),
80 p.PB10.reborrow(),
81 Default::default(),
82 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
83 )
84 .unwrap();
85 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
86 }
87 {
88 // no remap TX async
89 afio_registers_set_remap();
90 UartTx::new(
91 p.USART3.reborrow(),
92 p.PB10.reborrow(),
93 p.DMA1_CH2.reborrow(),
94 Default::default(),
95 )
96 .unwrap();
97 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
98 }
99 {
100 // no remap TX/CTS async
101 afio_registers_set_remap();
102 UartTx::new_with_cts(
103 p.USART3.reborrow(),
104 p.PB10.reborrow(),
105 p.PB13.reborrow(),
106 p.DMA1_CH2.reborrow(),
107 Default::default(),
108 )
109 .unwrap();
110 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
111 }
112 {
113 // no remap RX async
114 afio_registers_set_remap();
115 UartRx::new(
116 p.USART3.reborrow(),
117 Irqs,
118 p.PB11.reborrow(),
119 p.DMA1_CH3.reborrow(),
120 Default::default(),
121 )
122 .unwrap();
123 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
124 }
125 {
126 // no remap RX async
127 afio_registers_set_remap();
128 UartRx::new_with_rts(
129 p.USART3.reborrow(),
130 Irqs,
131 p.PB11.reborrow(),
132 p.PB14.reborrow(),
133 p.DMA1_CH3.reborrow(),
134 Default::default(),
135 )
136 .unwrap();
137 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
138 }
139 {
140 // no remap RX/TX async
141 afio_registers_set_remap();
142 Uart::new(
143 p.USART3.reborrow(),
144 p.PB11.reborrow(),
145 p.PB10.reborrow(),
146 Irqs,
147 p.DMA1_CH2.reborrow(),
148 p.DMA1_CH3.reborrow(),
149 Default::default(),
150 )
151 .unwrap();
152 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
153 }
154 {
155 // no remap RX/TX/RTS/CTS async
156 afio_registers_set_remap();
157 Uart::new_with_rtscts(
158 p.USART3.reborrow(),
159 p.PB11.reborrow(),
160 p.PB10.reborrow(),
161 Irqs,
162 p.PB14.reborrow(),
163 p.PB13.reborrow(),
164 p.DMA1_CH2.reborrow(),
165 p.DMA1_CH3.reborrow(),
166 Default::default(),
167 )
168 .unwrap();
169 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0);
170 }
171
172 // TIM1
173 {
174 // no remap
175 afio_registers_set_remap();
176 SimplePwm::new::<AfioRemap<0>>(
177 p.TIM1.reborrow(),
178 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
179 Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)),
180 Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)),
181 Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)),
182 khz(10),
183 Default::default(),
184 );
185 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0);
186 }
187 {
188 // no remap
189 afio_registers_set_remap();
190 SimplePwm::new::<AfioRemap<0>>(
191 p.TIM1.reborrow(),
192 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
193 None,
194 None,
195 None,
196 khz(10),
197 Default::default(),
198 );
199 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0);
200 }
201 {
202 // partial remap
203 reset_afio_registers();
204 ComplementaryPwm::new::<AfioRemap<1>>(
205 p.TIM1.reborrow(),
206 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
207 None,
208 None,
209 None,
210 None,
211 None,
212 None,
213 None,
214 khz(10),
215 Default::default(),
216 );
217 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
218 }
219 {
220 // partial remap
221 reset_afio_registers();
222 ComplementaryPwm::new::<AfioRemap<1>>(
223 p.TIM1.reborrow(),
224 Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)),
225 Some(ComplementaryPwmPin::new(p.PA7.reborrow(), OutputType::PushPull)),
226 Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)),
227 Some(ComplementaryPwmPin::new(p.PB0.reborrow(), OutputType::PushPull)),
228 Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)),
229 None, // pin does not exist on medium-density devices
230 Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)),
231 None, // signal does not exist
232 khz(10),
233 Default::default(),
234 );
235 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
236 }
237 {
238 // partial remap
239 reset_afio_registers();
240 InputCapture::new::<AfioRemap<1>>(
241 p.TIM1.reborrow(),
242 Some(CapturePin::new(p.PA8.reborrow(), Pull::Down)),
243 None,
244 None,
245 None,
246 Irqs,
247 khz(10),
248 Default::default(),
249 );
250 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
251 }
252 {
253 // partial remap
254 reset_afio_registers();
255 PwmInput::new_ch1::<AfioRemap<1>>(p.TIM1.reborrow(), p.PA8.reborrow(), Pull::Down, khz(10));
256 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
257 }
258 {
259 // partial remap
260 reset_afio_registers();
261 Qei::new::<AfioRemap<1>>(
262 p.TIM1.reborrow(),
263 QeiPin::new(p.PA8.reborrow()),
264 QeiPin::new(p.PA9.reborrow()),
265 );
266 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1);
267 }
268
269 // TIM2
270 {
271 // no remap
272 afio_registers_set_remap();
273 SimplePwm::new::<AfioRemap<0>>(
274 p.TIM2.reborrow(),
275 Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)),
276 Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)),
277 Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)),
278 Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)),
279 khz(10),
280 Default::default(),
281 );
282 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 0);
283 }
284 {
285 // partial remap 1
286 reset_afio_registers();
287 SimplePwm::new::<AfioRemap<1>>(
288 p.TIM2.reborrow(),
289 Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)),
290 Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)),
291 Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)),
292 Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)),
293 khz(10),
294 Default::default(),
295 );
296 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 1);
297 }
298 {
299 // partial remap 2
300 reset_afio_registers();
301 SimplePwm::new::<AfioRemap<2>>(
302 p.TIM2.reborrow(),
303 Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)),
304 Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)),
305 Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)),
306 Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)),
307 khz(10),
308 Default::default(),
309 );
310 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 2);
311 }
312 {
313 // full remap
314 reset_afio_registers();
315 SimplePwm::new::<AfioRemap<3>>(
316 p.TIM2.reborrow(),
317 Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)),
318 Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)),
319 Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)),
320 Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)),
321 khz(10),
322 Default::default(),
323 );
324 defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 3);
325 }
326
327 connectivity_line::run(&mut p);
328 value_line::run(&mut p);
329
330 info!("Test OK");
331 cortex_m::asm::bkpt();
332}
333
334#[cfg(feature = "afio-connectivity-line")]
335mod connectivity_line {
336 use embassy_stm32::can::Can;
337 use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue};
338 use embassy_stm32::i2s::I2S;
339 use embassy_stm32::spi::Spi;
340
341 use super::*;
342
343 pub fn run(p: &mut Peripherals) {
344 // USART3
345 {
346 // partial remap RX/TX/RTS/CTS
347 reset_afio_registers();
348 Uart::new_blocking_with_rtscts(
349 p.USART3.reborrow(),
350 p.PC11.reborrow(),
351 p.PC10.reborrow(),
352 p.PB14.reborrow(),
353 p.PB13.reborrow(),
354 Default::default(),
355 )
356 .unwrap();
357 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
358 }
359 {
360 // partial remap RX/TX
361 reset_afio_registers();
362 Uart::new_blocking(
363 p.USART3.reborrow(),
364 p.PC11.reborrow(),
365 p.PC10.reborrow(),
366 Default::default(),
367 )
368 .unwrap();
369 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
370 }
371 {
372 // partial remap TX
373 reset_afio_registers();
374 Uart::new_blocking_half_duplex(
375 p.USART3.reborrow(),
376 p.PC10.reborrow(),
377 Default::default(),
378 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
379 )
380 .unwrap();
381 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
382 }
383 {
384 // partial remap TX async
385 reset_afio_registers();
386 UartTx::new(
387 p.USART3.reborrow(),
388 p.PC10.reborrow(),
389 p.DMA1_CH2.reborrow(),
390 Default::default(),
391 )
392 .unwrap();
393 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
394 }
395 {
396 // partial remap TX/CTS async
397 reset_afio_registers();
398 UartTx::new_with_cts(
399 p.USART3.reborrow(),
400 p.PC10.reborrow(),
401 p.PB13.reborrow(),
402 p.DMA1_CH2.reborrow(),
403 Default::default(),
404 )
405 .unwrap();
406 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
407 }
408 {
409 // partial remap RX async
410 reset_afio_registers();
411 UartRx::new(
412 p.USART3.reborrow(),
413 Irqs,
414 p.PC11.reborrow(),
415 p.DMA1_CH3.reborrow(),
416 Default::default(),
417 )
418 .unwrap();
419 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
420 }
421 {
422 // partial remap RX async
423 reset_afio_registers();
424 UartRx::new_with_rts(
425 p.USART3.reborrow(),
426 Irqs,
427 p.PC11.reborrow(),
428 p.PB14.reborrow(),
429 p.DMA1_CH3.reborrow(),
430 Default::default(),
431 )
432 .unwrap();
433 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
434 }
435 {
436 // partial remap RX/TX async
437 reset_afio_registers();
438 Uart::new(
439 p.USART3.reborrow(),
440 p.PC11.reborrow(),
441 p.PC10.reborrow(),
442 Irqs,
443 p.DMA1_CH2.reborrow(),
444 p.DMA1_CH3.reborrow(),
445 Default::default(),
446 )
447 .unwrap();
448 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
449 }
450 {
451 // partial remap RX/TX/RTS/CTS async
452 reset_afio_registers();
453 Uart::new_with_rtscts(
454 p.USART3.reborrow(),
455 p.PC11.reborrow(),
456 p.PC10.reborrow(),
457 Irqs,
458 p.PB14.reborrow(),
459 p.PB13.reborrow(),
460 p.DMA1_CH2.reborrow(),
461 p.DMA1_CH3.reborrow(),
462 Default::default(),
463 )
464 .unwrap();
465 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1);
466 }
467 {
468 // full remap RX/TX/RTS/CTS
469 reset_afio_registers();
470 Uart::new_blocking_with_rtscts(
471 p.USART3.reborrow(),
472 p.PD9.reborrow(),
473 p.PD8.reborrow(),
474 p.PD12.reborrow(),
475 p.PD11.reborrow(),
476 Default::default(),
477 )
478 .unwrap();
479 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
480 }
481 {
482 // full remap RX/TX
483 reset_afio_registers();
484 Uart::new_blocking(
485 p.USART3.reborrow(),
486 p.PD9.reborrow(),
487 p.PD8.reborrow(),
488 Default::default(),
489 )
490 .unwrap();
491 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
492 }
493 {
494 // full remap TX
495 reset_afio_registers();
496 Uart::new_blocking_half_duplex(
497 p.USART3.reborrow(),
498 p.PD8.reborrow(),
499 Default::default(),
500 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
501 )
502 .unwrap();
503 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
504 }
505 {
506 // full remap TX async
507 reset_afio_registers();
508 UartTx::new(
509 p.USART3.reborrow(),
510 p.PD8.reborrow(),
511 p.DMA1_CH2.reborrow(),
512 Default::default(),
513 )
514 .unwrap();
515 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
516 }
517 {
518 // full remap TX/CTS async
519 reset_afio_registers();
520 UartTx::new_with_cts(
521 p.USART3.reborrow(),
522 p.PD8.reborrow(),
523 p.PD11.reborrow(),
524 p.DMA1_CH2.reborrow(),
525 Default::default(),
526 )
527 .unwrap();
528 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
529 }
530 {
531 // full remap RX async
532 reset_afio_registers();
533 UartRx::new(
534 p.USART3.reborrow(),
535 Irqs,
536 p.PD9.reborrow(),
537 p.DMA1_CH3.reborrow(),
538 Default::default(),
539 )
540 .unwrap();
541 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
542 }
543 {
544 // full remap RX async
545 reset_afio_registers();
546 UartRx::new_with_rts(
547 p.USART3.reborrow(),
548 Irqs,
549 p.PD9.reborrow(),
550 p.PD12.reborrow(),
551 p.DMA1_CH3.reborrow(),
552 Default::default(),
553 )
554 .unwrap();
555 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
556 }
557 {
558 // full remap RX/TX async
559 reset_afio_registers();
560 Uart::new(
561 p.USART3.reborrow(),
562 p.PD9.reborrow(),
563 p.PD8.reborrow(),
564 Irqs,
565 p.DMA1_CH2.reborrow(),
566 p.DMA1_CH3.reborrow(),
567 Default::default(),
568 )
569 .unwrap();
570 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
571 }
572 {
573 // full remap RX/TX/RTS/CTS async
574 reset_afio_registers();
575 Uart::new_with_rtscts(
576 p.USART3.reborrow(),
577 p.PD9.reborrow(),
578 p.PD8.reborrow(),
579 Irqs,
580 p.PD12.reborrow(),
581 p.PD11.reborrow(),
582 p.DMA1_CH2.reborrow(),
583 p.DMA1_CH3.reborrow(),
584 Default::default(),
585 )
586 .unwrap();
587 defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3);
588 }
589
590 // SPI3
591 {
592 // no remap SCK/MISO/MOSI
593 afio_registers_set_remap();
594 Spi::new_blocking(
595 p.SPI3.reborrow(),
596 p.PB3.reborrow(),
597 p.PB5.reborrow(),
598 p.PB4.reborrow(),
599 Default::default(),
600 );
601 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
602 }
603 {
604 // no remap SCK/MOSI
605 afio_registers_set_remap();
606 Spi::new_blocking_txonly(
607 p.SPI3.reborrow(),
608 p.PB3.reborrow(),
609 p.PB5.reborrow(),
610 Default::default(),
611 );
612 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
613 }
614 {
615 // no remap MOSI
616 afio_registers_set_remap();
617 Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default());
618 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
619 }
620 {
621 // no remap SCK/MISO
622 afio_registers_set_remap();
623 Spi::new_blocking_rxonly(
624 p.SPI3.reborrow(),
625 p.PB3.reborrow(),
626 p.PB4.reborrow(),
627 Default::default(),
628 );
629 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
630 }
631 {
632 // remap SCK/MISO/MOSI
633 reset_afio_registers();
634 Spi::new_blocking(
635 p.SPI3.reborrow(),
636 p.PC10.reborrow(),
637 p.PC12.reborrow(),
638 p.PC11.reborrow(),
639 Default::default(),
640 );
641
642 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
643 }
644 {
645 // remap SCK/MOSI
646 reset_afio_registers();
647 Spi::new_blocking_txonly(
648 p.SPI3.reborrow(),
649 p.PC10.reborrow(),
650 p.PC12.reborrow(),
651 Default::default(),
652 );
653 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
654 }
655 {
656 // remap MOSI
657 reset_afio_registers();
658 Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default());
659 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
660 }
661 {
662 // remap SCK/MISO
663 reset_afio_registers();
664 Spi::new_blocking_rxonly(
665 p.SPI3.reborrow(),
666 p.PC10.reborrow(),
667 p.PC11.reborrow(),
668 Default::default(),
669 );
670 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
671 }
672
673 // I2S3
674 {
675 // no remap SD/WS/CK/MCK
676 afio_registers_set_remap();
677 I2S::new_txonly(
678 p.SPI3.reborrow(),
679 p.PB5.reborrow(),
680 p.PA15.reborrow(),
681 p.PB3.reborrow(),
682 p.PC7.reborrow(),
683 p.DMA2_CH2.reborrow(),
684 &mut [0u16; 0],
685 Default::default(),
686 );
687 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
688 }
689 {
690 // no remap SD/WS/CK
691 afio_registers_set_remap();
692 I2S::new_txonly_nomck(
693 p.SPI3.reborrow(),
694 p.PB5.reborrow(),
695 p.PA15.reborrow(),
696 p.PB3.reborrow(),
697 p.DMA2_CH2.reborrow(),
698 &mut [0u16; 0],
699 Default::default(),
700 );
701 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false);
702 }
703 {
704 // no remap SD/WS/CK/MCK
705 afio_registers_set_remap();
706 I2S::new_rxonly(
707 p.SPI3.reborrow(),
708 p.PB4.reborrow(),
709 p.PA15.reborrow(),
710 p.PB3.reborrow(),
711 p.PC7.reborrow(),
712 p.DMA2_CH1.reborrow(),
713 &mut [0u16; 0],
714 Default::default(),
715 );
716 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
717 }
718 {
719 // remap SD/WS/CK/MCK
720 reset_afio_registers();
721 I2S::new_txonly(
722 p.SPI3.reborrow(),
723 p.PC12.reborrow(),
724 p.PA4.reborrow(),
725 p.PC10.reborrow(),
726 p.PC7.reborrow(),
727 p.DMA2_CH2.reborrow(),
728 &mut [0u16; 0],
729 Default::default(),
730 );
731 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
732 }
733 {
734 // remap SD/WS/CK
735 reset_afio_registers();
736 I2S::new_txonly_nomck(
737 p.SPI3.reborrow(),
738 p.PC12.reborrow(),
739 p.PA4.reborrow(),
740 p.PC10.reborrow(),
741 p.DMA2_CH2.reborrow(),
742 &mut [0u16; 0],
743 Default::default(),
744 );
745 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
746 }
747 {
748 // remap SD/WS/CK/MCK
749 reset_afio_registers();
750 I2S::new_rxonly(
751 p.SPI3.reborrow(),
752 p.PC11.reborrow(),
753 p.PA4.reborrow(),
754 p.PC10.reborrow(),
755 p.PC7.reborrow(),
756 p.DMA2_CH1.reborrow(),
757 &mut [0u16; 0],
758 Default::default(),
759 );
760 defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true);
761 }
762
763 // CAN2
764 {
765 // no remap
766 afio_registers_set_remap();
767 Can::new(p.CAN2.reborrow(), p.PB12.reborrow(), p.PB13.reborrow(), Irqs);
768 defmt::assert_eq!(AFIO.mapr().read().can2_remap(), false);
769 }
770 {
771 // remap
772 reset_afio_registers();
773 Can::new(p.CAN2.reborrow(), p.PB5.reborrow(), p.PB6.reborrow(), Irqs);
774 defmt::assert_eq!(AFIO.mapr().read().can2_remap(), true);
775 }
776
777 // Ethernet
778 {
779 // no remap RMII
780 afio_registers_set_remap();
781 Ethernet::new(
782 &mut PacketQueue::<1, 1>::new(),
783 p.ETH.reborrow(),
784 Irqs,
785 p.PA1.reborrow(),
786 p.PA2.reborrow(),
787 p.PC1.reborrow(),
788 p.PA7.reborrow(),
789 p.PC4.reborrow(),
790 p.PC5.reborrow(),
791 p.PB12.reborrow(),
792 p.PB13.reborrow(),
793 p.PB11.reborrow(),
794 GenericPhy::new_auto(),
795 Default::default(),
796 );
797 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false);
798 }
799 {
800 // no remap MII
801 afio_registers_set_remap();
802 Ethernet::new_mii(
803 &mut PacketQueue::<1, 1>::new(),
804 p.ETH.reborrow(),
805 Irqs,
806 p.PA1.reborrow(),
807 p.PC3.reborrow(),
808 p.PA2.reborrow(),
809 p.PC1.reborrow(),
810 p.PA7.reborrow(),
811 p.PC4.reborrow(),
812 p.PC5.reborrow(),
813 p.PB0.reborrow(),
814 p.PB1.reborrow(),
815 p.PB12.reborrow(),
816 p.PB13.reborrow(),
817 p.PC2.reborrow(),
818 p.PB8.reborrow(),
819 p.PB11.reborrow(),
820 GenericPhy::new_auto(),
821 Default::default(),
822 );
823 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false);
824 }
825 {
826 // remap RMII
827 reset_afio_registers();
828 Ethernet::new(
829 &mut PacketQueue::<1, 1>::new(),
830 p.ETH.reborrow(),
831 Irqs,
832 p.PA1.reborrow(),
833 p.PA2.reborrow(),
834 p.PC1.reborrow(),
835 p.PD8.reborrow(),
836 p.PD9.reborrow(),
837 p.PD10.reborrow(),
838 p.PB12.reborrow(),
839 p.PB13.reborrow(),
840 p.PB11.reborrow(),
841 GenericPhy::new_auto(),
842 Default::default(),
843 );
844 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true);
845 }
846 {
847 // remap MII
848 reset_afio_registers();
849 Ethernet::new_mii(
850 &mut PacketQueue::<1, 1>::new(),
851 p.ETH.reborrow(),
852 Irqs,
853 p.PA1.reborrow(),
854 p.PC3.reborrow(),
855 p.PA2.reborrow(),
856 p.PC1.reborrow(),
857 p.PD8.reborrow(),
858 p.PD9.reborrow(),
859 p.PD10.reborrow(),
860 p.PD11.reborrow(),
861 p.PD12.reborrow(),
862 p.PB12.reborrow(),
863 p.PB13.reborrow(),
864 p.PC2.reborrow(),
865 p.PB8.reborrow(),
866 p.PB11.reborrow(),
867 GenericPhy::new_auto(),
868 Default::default(),
869 );
870 defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true);
871 }
872
873 // CAN1
874 {
875 // no remap
876 afio_registers_set_remap();
877 Can::new(p.CAN1.reborrow(), p.PA11.reborrow(), p.PA12.reborrow(), Irqs);
878 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 0);
879 }
880 {
881 // partial remap
882 reset_afio_registers();
883 Can::new(p.CAN1.reborrow(), p.PB8.reborrow(), p.PB9.reborrow(), Irqs);
884 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 2);
885 }
886 {
887 // full remap
888 reset_afio_registers();
889 Can::new(p.CAN1.reborrow(), p.PD0.reborrow(), p.PD1.reborrow(), Irqs);
890 defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 3);
891 }
892
893 // USART2
894 {
895 // no remap RX/TX/RTS/CTS
896 afio_registers_set_remap();
897 Uart::new_blocking_with_rtscts(
898 p.USART2.reborrow(),
899 p.PA3.reborrow(),
900 p.PA2.reborrow(),
901 p.PA1.reborrow(),
902 p.PA0.reborrow(),
903 Default::default(),
904 )
905 .unwrap();
906 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
907 }
908 {
909 // no remap RX/TX
910 afio_registers_set_remap();
911 Uart::new_blocking(
912 p.USART2.reborrow(),
913 p.PA3.reborrow(),
914 p.PA2.reborrow(),
915 Default::default(),
916 )
917 .unwrap();
918 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
919 }
920 {
921 // no remap TX
922 afio_registers_set_remap();
923 Uart::new_blocking_half_duplex(
924 p.USART2.reborrow(),
925 p.PA2.reborrow(),
926 Default::default(),
927 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
928 )
929 .unwrap();
930 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
931 }
932 {
933 // full remap RX/TX/RTS/CTS
934 reset_afio_registers();
935 Uart::new_blocking_with_rtscts(
936 p.USART2.reborrow(),
937 p.PD6.reborrow(),
938 p.PD5.reborrow(),
939 p.PD4.reborrow(),
940 p.PD3.reborrow(),
941 Default::default(),
942 )
943 .unwrap();
944 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
945 }
946 {
947 // full remap RX/TX
948 reset_afio_registers();
949 Uart::new_blocking(
950 p.USART2.reborrow(),
951 p.PD6.reborrow(),
952 p.PD5.reborrow(),
953 Default::default(),
954 )
955 .unwrap();
956 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false);
957 }
958 {
959 // full remap TX
960 reset_afio_registers();
961 Uart::new_blocking_half_duplex(
962 p.USART2.reborrow(),
963 p.PD5.reborrow(),
964 Default::default(),
965 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
966 )
967 .unwrap();
968 defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), true);
969 }
970
971 // USART1
972 {
973 // no remap RX/TX/RTS/CTS
974 afio_registers_set_remap();
975 Uart::new_blocking_with_rtscts(
976 p.USART1.reborrow(),
977 p.PA10.reborrow(),
978 p.PA9.reborrow(),
979 p.PA12.reborrow(),
980 p.PA11.reborrow(),
981 Default::default(),
982 )
983 .unwrap();
984 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
985 }
986 {
987 // no remap RX/TX
988 afio_registers_set_remap();
989 Uart::new_blocking(
990 p.USART1.reborrow(),
991 p.PA10.reborrow(),
992 p.PA9.reborrow(),
993 Default::default(),
994 )
995 .unwrap();
996 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
997 }
998 {
999 // no remap TX
1000 afio_registers_set_remap();
1001 Uart::new_blocking_half_duplex(
1002 p.USART1.reborrow(),
1003 p.PA9.reborrow(),
1004 Default::default(),
1005 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
1006 )
1007 .unwrap();
1008 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false);
1009 }
1010 {
1011 // remap RX/TX/RTS/CTS
1012 reset_afio_registers();
1013 Uart::new_blocking_with_rtscts(
1014 p.USART1.reborrow(),
1015 p.PB7.reborrow(),
1016 p.PB6.reborrow(),
1017 p.PA12.reborrow(),
1018 p.PA11.reborrow(),
1019 Default::default(),
1020 )
1021 .unwrap();
1022 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1023 }
1024 {
1025 // remap RX/TX
1026 reset_afio_registers();
1027 Uart::new_blocking(
1028 p.USART1.reborrow(),
1029 p.PB7.reborrow(),
1030 p.PB6.reborrow(),
1031 Default::default(),
1032 )
1033 .unwrap();
1034 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1035 }
1036 {
1037 // remap TX
1038 reset_afio_registers();
1039 Uart::new_blocking_half_duplex(
1040 p.USART1.reborrow(),
1041 p.PB6.reborrow(),
1042 Default::default(),
1043 embassy_stm32::usart::HalfDuplexReadback::NoReadback,
1044 )
1045 .unwrap();
1046 defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true);
1047 }
1048
1049 // TIM1
1050 {
1051 // full remap
1052 reset_afio_registers();
1053 SimplePwm::new(
1054 p.TIM1.reborrow(),
1055 Some(PwmPin::new(p.PE9.reborrow(), OutputType::PushPull)),
1056 Some(PwmPin::new(p.PE11.reborrow(), OutputType::PushPull)),
1057 None,
1058 None,
1059 khz(10),
1060 Default::default(),
1061 );
1062 defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 3);
1063 }
1064 }
1065}
1066
1067#[cfg(feature = "afio-value-line")]
1068mod value_line {
1069 use super::*;
1070
1071 pub fn run(p: &mut Peripherals) {
1072 // TIM13
1073 {
1074 // no remap
1075 reset_afio_registers();
1076 SimplePwm::new(
1077 p.TIM13.reborrow(),
1078 Some(PwmPin::new(p.PC8.reborrow(), OutputType::PushPull)),
1079 None,
1080 None,
1081 None,
1082 khz(10),
1083 Default::default(),
1084 );
1085 defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), false);
1086 }
1087 {
1088 // remap
1089 reset_afio_registers();
1090 SimplePwm::new(
1091 p.TIM13.reborrow(),
1092 Some(PwmPin::new(p.PB0.reborrow(), OutputType::PushPull)),
1093 None,
1094 None,
1095 None,
1096 khz(10),
1097 Default::default(),
1098 );
1099 defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), true);
1100 }
1101 }
1102}
1103
1104#[cfg(not(feature = "afio-connectivity-line"))]
1105mod connectivity_line {
1106 use super::*;
1107
1108 pub fn run(_: &mut Peripherals) {}
1109}
1110
1111#[cfg(not(feature = "afio-value-line"))]
1112mod value_line {
1113 use super::*;
1114
1115 pub fn run(_: &mut Peripherals) {}
1116}
1117
1118fn reset_afio_registers() {
1119 set_afio_registers(false, 0);
1120}
1121
1122fn afio_registers_set_remap() {
1123 set_afio_registers(true, 1);
1124}
1125
1126fn set_afio_registers(bool_val: bool, num_val: u8) {
1127 AFIO.mapr().modify(|w| {
1128 w.set_swj_cfg(embassy_stm32::pac::afio::vals::SwjCfg::NO_OP);
1129 w.set_can1_remap(num_val);
1130 w.set_can2_remap(bool_val);
1131 w.set_eth_remap(bool_val);
1132 w.set_i2c1_remap(bool_val);
1133 w.set_spi1_remap(bool_val);
1134 w.set_spi3_remap(bool_val);
1135 w.set_tim1_remap(num_val);
1136 w.set_tim2_remap(num_val);
1137 w.set_tim3_remap(num_val);
1138 w.set_tim4_remap(bool_val);
1139 w.set_usart1_remap(bool_val);
1140 w.set_usart2_remap(bool_val);
1141 w.set_usart3_remap(num_val);
1142 });
1143
1144 AFIO.mapr2().modify(|w| {
1145 w.set_cec_remap(bool_val);
1146 w.set_tim9_remap(bool_val);
1147 w.set_tim10_remap(bool_val);
1148 w.set_tim11_remap(bool_val);
1149 w.set_tim12_remap(bool_val);
1150 w.set_tim13_remap(bool_val);
1151 w.set_tim14_remap(bool_val);
1152 w.set_tim15_remap(bool_val);
1153 w.set_tim16_remap(bool_val);
1154 w.set_tim17_remap(bool_val);
1155 });
1156}
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index 778d88a7b..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
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs
index 028775ac8..f54c99cc3 100644
--- a/tests/stm32/src/bin/cryp.rs
+++ b/tests/stm32/src/bin/cryp.rs
@@ -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/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 a7e76fd8e..a65682a02 100644
--- a/tests/stm32/src/bin/eth.rs
+++ b/tests/stm32/src/bin/eth.rs
@@ -11,7 +11,6 @@ use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::ETH;
12use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
13use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; 13use embassy_stm32::{bind_interrupts, eth, peripherals, rng};
14use rand_core::RngCore;
15use static_cell::StaticCell; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
@@ -102,7 +101,7 @@ async fn main(spawner: Spawner) {
102 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); 101 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
103 102
104 // Launch network task 103 // Launch network task
105 unwrap!(spawner.spawn(net_task(runner))); 104 spawner.spawn(unwrap!(net_task(runner)));
106 105
107 perf_client::run( 106 perf_client::run(
108 stack, 107 stack,
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index 83d7eca85..c2a1a7bb8 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -12,6 +12,7 @@ use embassy_stm32::{bind_interrupts, can, Config};
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
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs
index 52b84a499..bb08d0cf1 100644
--- a/tests/stm32/src/bin/hash.rs
+++ b/tests/stm32/src/bin/hash.rs
@@ -7,6 +7,7 @@ mod common;
7use common::*; 7use common::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::hash::*; 9use embassy_stm32::hash::*;
10use embassy_stm32::mode::Blocking;
10use embassy_stm32::{bind_interrupts, hash, peripherals}; 11use embassy_stm32::{bind_interrupts, hash, peripherals};
11use hmac::{Hmac, Mac}; 12use hmac::{Hmac, Mac};
12use sha2::{Digest, Sha224, Sha256}; 13use sha2::{Digest, Sha224, Sha256};
@@ -32,11 +33,7 @@ bind_interrupts!(struct Irqs {
32 HASH => hash::InterruptHandler<peripherals::HASH>; 33 HASH => hash::InterruptHandler<peripherals::HASH>;
33}); 34});
34 35
35#[embassy_executor::main] 36fn test_interrupt(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) {
36async fn main(_spawner: Spawner) {
37 let p: embassy_stm32::Peripherals = init();
38 let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs);
39
40 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; 37 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
41 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; 38 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
42 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";
@@ -95,6 +92,47 @@ async fn main(_spawner: Spawner) {
95 info!("Hardware HMAC: {:?}", hw_hmac); 92 info!("Hardware HMAC: {:?}", hw_hmac);
96 info!("Software HMAC: {:?}", sw_hmac[..]); 93 info!("Software HMAC: {:?}", sw_hmac[..]);
97 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);
98 136
99 info!("Test OK"); 137 info!("Test OK");
100 cortex_m::asm::bkpt(); 138 cortex_m::asm::bkpt();
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs
index 34a53a725..9f9c526e1 100644
--- a/tests/stm32/src/bin/sdmmc.rs
+++ b/tests/stm32/src/bin/sdmmc.rs
@@ -95,6 +95,9 @@ async fn main(_spawner: Spawner) {
95 95
96 drop(s); 96 drop(s);
97 97
98 // FIXME: this hangs on Rust 1.86 and higher.
99 // I haven't been able to figure out why.
100 /*
98 // ======== Try 1bit. ============== 101 // ======== Try 1bit. ==============
99 info!("initializing in 1-bit mode..."); 102 info!("initializing in 1-bit mode...");
100 let mut s = Sdmmc::new_1bit( 103 let mut s = Sdmmc::new_1bit(
@@ -151,6 +154,7 @@ async fn main(_spawner: Spawner) {
151 assert_eq!(&blocks, &patterns); 154 assert_eq!(&blocks, &patterns);
152 155
153 drop(s); 156 drop(s);
157 */
154 158
155 info!("Test OK"); 159 info!("Test OK");
156 cortex_m::asm::bkpt(); 160 cortex_m::asm::bkpt();
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 772bc527c..8119c1f39 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -19,7 +19,7 @@ use static_cell::StaticCell;
19#[entry] 19#[entry]
20fn main() -> ! { 20fn main() -> ! {
21 Executor::take().run(|spawner| { 21 Executor::take().run(|spawner| {
22 unwrap!(spawner.spawn(async_main(spawner))); 22 spawner.spawn(unwrap!(async_main(spawner)));
23 }); 23 });
24} 24}
25 25
@@ -75,6 +75,6 @@ async fn async_main(spawner: Spawner) {
75 75
76 stop_with_rtc(rtc); 76 stop_with_rtc(rtc);
77 77
78 spawner.spawn(task_1()).unwrap(); 78 spawner.spawn(task_1().unwrap());
79 spawner.spawn(task_2()).unwrap(); 79 spawner.spawn(task_2().unwrap());
80} 80}
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
index 83c0887ac..15a0b0d60 100644
--- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs
+++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
@@ -46,8 +46,8 @@ async fn main(spawner: Spawner) {
46 let rx = rx.into_ring_buffered(unsafe { &mut *core::ptr::addr_of_mut!(DMA_BUF) }); 46 let rx = rx.into_ring_buffered(unsafe { &mut *core::ptr::addr_of_mut!(DMA_BUF) });
47 47
48 info!("Spawning tasks"); 48 info!("Spawning tasks");
49 spawner.spawn(transmit_task(tx)).unwrap(); 49 spawner.spawn(transmit_task(tx).unwrap());
50 spawner.spawn(receive_task(rx)).unwrap(); 50 spawner.spawn(receive_task(rx).unwrap());
51} 51}
52 52
53#[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 fde1dfa9b..8957bfc04 100644
--- a/tests/stm32/src/bin/wpan_ble.rs
+++ b/tests/stm32/src/bin/wpan_ble.rs
@@ -47,7 +47,7 @@ async fn main(spawner: Spawner) {
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 b65ace40f..79e13d524 100644
--- a/tests/stm32/src/bin/wpan_mac.rs
+++ b/tests/stm32/src/bin/wpan_mac.rs
@@ -40,7 +40,7 @@ async fn main(spawner: Spawner) {
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 829f2cff0..f800769ab 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -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
@@ -673,6 +681,8 @@ pub fn config() -> Config {
673 divp: Some(PllDiv::DIV2), // 600Mhz 681 divp: Some(PllDiv::DIV2), // 600Mhz
674 divq: Some(PllDiv::DIV25), // 48Mhz 682 divq: Some(PllDiv::DIV25), // 48Mhz
675 divr: None, 683 divr: None,
684 divs: None,
685 divt: None,
676 }); 686 });
677 config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz 687 config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz
678 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz 688 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz
diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml
index 7b54a4f52..f76feaa20 100644
--- a/tests/utils/Cargo.toml
+++ b/tests/utils/Cargo.toml
@@ -2,7 +2,8 @@
2name = "test-utils" 2name = "test-utils"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5publish = false
5 6
6[dependencies] 7[dependencies]
7rand = "0.8" 8rand = "0.9"
8serial = "0.4" 9serial = "0.4"
diff --git a/tests/utils/src/bin/saturate_serial.rs b/tests/utils/src/bin/saturate_serial.rs
index 18ca12fb7..85676b106 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));