diff options
Diffstat (limited to 'tests')
98 files changed, 3860 insertions, 686 deletions
diff --git a/tests/nrf51422/.cargo/config.toml b/tests/mspm0/.cargo/config.toml index 634805633..825bf3ae9 100644 --- a/tests/nrf51422/.cargo/config.toml +++ b/tests/mspm0/.cargo/config.toml | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | #runner = "teleprobe local run --chip nRF51422_xxAA --elf" | 2 | runner = "teleprobe local run --chip MSPM0G3507 --protocol swd --elf" |
| 3 | runner = "teleprobe client run" | ||
| 4 | 3 | ||
| 5 | [build] | 4 | [build] |
| 6 | target = "thumbv6m-none-eabi" | 5 | target = "thumbv6m-none-eabi" |
diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml new file mode 100644 index 000000000..df52b538d --- /dev/null +++ b/tests/mspm0/Cargo.toml | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2024" | ||
| 3 | name = "embassy-mspm0-tests" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 7 | |||
| 8 | [features] | ||
| 9 | mspm0g3507 = [ "embassy-mspm0/mspm0g3507pm" ] | ||
| 10 | mspm0g3519 = [ "embassy-mspm0/mspm0g3519pz" ] | ||
| 11 | |||
| 12 | [dependencies] | ||
| 13 | teleprobe-meta = "1.1" | ||
| 14 | |||
| 15 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = [ "defmt" ] } | ||
| 16 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] } | ||
| 17 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | ||
| 18 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = [ "defmt" ] } | ||
| 19 | embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [ "rt", "defmt", "unstable-pac", "time-driver-any" ] } | ||
| 20 | embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"} | ||
| 21 | |||
| 22 | defmt = "1.0.1" | ||
| 23 | defmt-rtt = "1.0.0" | ||
| 24 | |||
| 25 | cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-single-core" ]} | ||
| 26 | cortex-m-rt = "0.7.0" | ||
| 27 | embedded-hal = { package = "embedded-hal", version = "1.0" } | ||
| 28 | embedded-hal-async = { version = "1.0" } | ||
| 29 | embedded-io = { version = "0.6.1", features = ["defmt-03"] } | ||
| 30 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 31 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | ||
| 32 | static_cell = "2" | ||
| 33 | portable-atomic = { version = "1.5", features = ["critical-section"] } | ||
| 34 | |||
| 35 | [profile.dev] | ||
| 36 | debug = 2 | ||
| 37 | debug-assertions = true | ||
| 38 | opt-level = 's' | ||
| 39 | overflow-checks = true | ||
| 40 | |||
| 41 | [profile.release] | ||
| 42 | codegen-units = 1 | ||
| 43 | debug = 2 | ||
| 44 | debug-assertions = false | ||
| 45 | incremental = false | ||
| 46 | lto = "fat" | ||
| 47 | opt-level = 's' | ||
| 48 | overflow-checks = false | ||
| 49 | |||
| 50 | # do not optimize proc-macro crates = faster builds from scratch | ||
| 51 | [profile.dev.build-override] | ||
| 52 | codegen-units = 8 | ||
| 53 | debug = false | ||
| 54 | debug-assertions = false | ||
| 55 | opt-level = 0 | ||
| 56 | overflow-checks = false | ||
| 57 | |||
| 58 | [profile.release.build-override] | ||
| 59 | codegen-units = 8 | ||
| 60 | debug = false | ||
| 61 | debug-assertions = false | ||
| 62 | opt-level = 0 | ||
| 63 | overflow-checks = false | ||
| 64 | |||
| 65 | [package.metadata.embassy] | ||
| 66 | build = [ | ||
| 67 | { target = "thumbv6m-none-eabi", features = ["mspm0g3507"], artifact-dir = "out/tests/mspm0g3507" } | ||
| 68 | ] | ||
diff --git a/tests/nrf52840/build.rs b/tests/mspm0/build.rs index 71c82a70f..43a9ac04f 100644 --- a/tests/nrf52840/build.rs +++ b/tests/mspm0/build.rs | |||
| @@ -4,14 +4,26 @@ use std::{env, fs}; | |||
| 4 | 4 | ||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | 5 | fn main() -> Result<(), Box<dyn Error>> { |
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 7 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); | 7 | |
| 8 | #[cfg(feature = "mspm0g3507")] | ||
| 9 | let memory_x = include_bytes!("memory_g3507.x"); | ||
| 10 | |||
| 11 | #[cfg(feature = "mspm0g3519")] | ||
| 12 | let memory_x = include_bytes!("memory_g3519.x"); | ||
| 13 | |||
| 14 | fs::write(out.join("memory.x"), memory_x).unwrap(); | ||
| 15 | |||
| 8 | println!("cargo:rustc-link-search={}", out.display()); | 16 | println!("cargo:rustc-link-search={}", out.display()); |
| 9 | println!("cargo:rerun-if-changed=link_ram.x"); | 17 | println!("cargo:rerun-if-changed=link_ram.x"); |
| 18 | // copy main linker script. | ||
| 19 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); | ||
| 10 | 20 | ||
| 11 | println!("cargo:rustc-link-arg-bins=--nmagic"); | 21 | println!("cargo:rustc-link-arg-bins=--nmagic"); |
| 12 | println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); | 22 | println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); |
| 13 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | 23 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); |
| 14 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | 24 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); |
| 25 | // You must tell cargo to link interrupt groups if the rt feature is enabled. | ||
| 26 | println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x"); | ||
| 15 | 27 | ||
| 16 | Ok(()) | 28 | Ok(()) |
| 17 | } | 29 | } |
diff --git a/tests/mspm0/memory_g3507.x b/tests/mspm0/memory_g3507.x new file mode 100644 index 000000000..37e381fbd --- /dev/null +++ b/tests/mspm0/memory_g3507.x | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ | ||
| 5 | RAM : ORIGIN = 0x20200000, LENGTH = 32K | ||
| 6 | } | ||
diff --git a/tests/mspm0/memory_g3519.x b/tests/mspm0/memory_g3519.x new file mode 100644 index 000000000..d62f10360 --- /dev/null +++ b/tests/mspm0/memory_g3519.x | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ | ||
| 5 | RAM : ORIGIN = 0x20200000, LENGTH = 64K | ||
| 6 | } | ||
diff --git a/tests/mspm0/src/bin/dma.rs b/tests/mspm0/src/bin/dma.rs new file mode 100644 index 000000000..9c56acadc --- /dev/null +++ b/tests/mspm0/src/bin/dma.rs | |||
| @@ -0,0 +1,503 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | #[cfg(feature = "mspm0g3507")] | ||
| 5 | teleprobe_meta::target!(b"lp-mspm0g3507"); | ||
| 6 | |||
| 7 | #[cfg(feature = "mspm0g3519")] | ||
| 8 | teleprobe_meta::target!(b"lp-mspm0g3519"); | ||
| 9 | |||
| 10 | use core::slice; | ||
| 11 | |||
| 12 | use defmt::{assert, assert_eq, *}; | ||
| 13 | use embassy_executor::Spawner; | ||
| 14 | use embassy_mspm0::Peri; | ||
| 15 | use embassy_mspm0::dma::{Channel, Transfer, TransferMode, TransferOptions, Word}; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async 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 | |||
| 213 | fn 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 | |||
| 232 | async 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 | |||
| 254 | fn 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 | |||
| 279 | async 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 | |||
| 304 | fn 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 | |||
| 323 | async 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 | |||
| 342 | fn 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 | |||
| 370 | async 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. | ||
| 401 | fn widening_single_read<SW, DW>(mut channel: Peri<'_, impl Channel>, mut src: SW) | ||
| 402 | where | ||
| 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. | ||
| 433 | fn narrowing_single_read<SW, DW>(mut channel: Peri<'_, impl Channel>, mut src: SW) | ||
| 434 | where | ||
| 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). | ||
| 465 | trait Narrow<T> { | ||
| 466 | fn narrow(value: T) -> Self; | ||
| 467 | } | ||
| 468 | |||
| 469 | impl Narrow<u16> for u8 { | ||
| 470 | fn narrow(value: u16) -> Self { | ||
| 471 | value as u8 | ||
| 472 | } | ||
| 473 | } | ||
| 474 | |||
| 475 | impl Narrow<u32> for u8 { | ||
| 476 | fn narrow(value: u32) -> Self { | ||
| 477 | value as u8 | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | impl Narrow<u64> for u8 { | ||
| 482 | fn narrow(value: u64) -> Self { | ||
| 483 | value as u8 | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | impl Narrow<u32> for u16 { | ||
| 488 | fn narrow(value: u32) -> Self { | ||
| 489 | value as u16 | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | impl Narrow<u64> for u16 { | ||
| 494 | fn narrow(value: u64) -> Self { | ||
| 495 | value as u16 | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 499 | impl Narrow<u64> for u32 { | ||
| 500 | fn narrow(value: u64) -> Self { | ||
| 501 | value as u32 | ||
| 502 | } | ||
| 503 | } | ||
diff --git a/tests/mspm0/src/bin/uart.rs b/tests/mspm0/src/bin/uart.rs new file mode 100644 index 000000000..916ce0d4b --- /dev/null +++ b/tests/mspm0/src/bin/uart.rs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | #[cfg(feature = "mspm0g3507")] | ||
| 5 | teleprobe_meta::target!(b"lp-mspm0g3507"); | ||
| 6 | |||
| 7 | #[cfg(feature = "mspm0g3519")] | ||
| 8 | teleprobe_meta::target!(b"lp-mspm0g3519"); | ||
| 9 | |||
| 10 | use defmt::{assert_eq, unwrap, *}; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_mspm0::mode::Blocking; | ||
| 13 | use embassy_mspm0::uart::{ClockSel, Config, Error, Uart}; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | fn read<const N: usize>(uart: &mut Uart<'_, Blocking>) -> Result<[u8; N], Error> { | ||
| 17 | let mut buf = [255; N]; | ||
| 18 | uart.blocking_read(&mut buf)?; | ||
| 19 | Ok(buf) | ||
| 20 | } | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(_spawner: Spawner) { | ||
| 24 | let p = embassy_mspm0::init(Default::default()); | ||
| 25 | info!("Hello World!"); | ||
| 26 | |||
| 27 | // TODO: Allow creating a looped-back UART (so pins are not needed). | ||
| 28 | // Do not select default UART since the virtual COM port is attached to UART0. | ||
| 29 | #[cfg(any(feature = "mspm0g3507", feature = "mspm0g3519"))] | ||
| 30 | let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1); | ||
| 31 | |||
| 32 | const MFCLK_BUAD_RATES: &[u32] = &[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]; | ||
| 33 | |||
| 34 | for &rate in MFCLK_BUAD_RATES { | ||
| 35 | info!("{} baud using MFCLK", rate); | ||
| 36 | |||
| 37 | let mut config = Config::default(); | ||
| 38 | // MSPM0 hardware supports a loopback mode to allow self test. | ||
| 39 | config.loop_back_enable = true; | ||
| 40 | config.baudrate = rate; | ||
| 41 | |||
| 42 | let mut uart = unwrap!(Uart::new_blocking( | ||
| 43 | uart.reborrow(), | ||
| 44 | rx.reborrow(), | ||
| 45 | tx.reborrow(), | ||
| 46 | config | ||
| 47 | )); | ||
| 48 | |||
| 49 | // We can't send too many bytes, they have to fit in the FIFO. | ||
| 50 | // This is because we aren't sending+receiving at the same time. | ||
| 51 | |||
| 52 | let data = [0xC0, 0xDE]; | ||
| 53 | unwrap!(uart.blocking_write(&data)); | ||
| 54 | assert_eq!(unwrap!(read(&mut uart)), data); | ||
| 55 | } | ||
| 56 | |||
| 57 | // 9600 is the maximum possible value for 32.768 kHz. | ||
| 58 | const LFCLK_BAUD_RATES: &[u32] = &[1200, 2400, 4800, 9600]; | ||
| 59 | |||
| 60 | for &rate in LFCLK_BAUD_RATES { | ||
| 61 | info!("{} baud using LFCLK", rate); | ||
| 62 | |||
| 63 | let mut config = Config::default(); | ||
| 64 | // MSPM0 hardware supports a loopback mode to allow self test. | ||
| 65 | config.loop_back_enable = true; | ||
| 66 | config.baudrate = rate; | ||
| 67 | config.clock_source = ClockSel::LfClk; | ||
| 68 | |||
| 69 | let mut uart = expect!(Uart::new_blocking( | ||
| 70 | uart.reborrow(), | ||
| 71 | rx.reborrow(), | ||
| 72 | tx.reborrow(), | ||
| 73 | config, | ||
| 74 | )); | ||
| 75 | |||
| 76 | // We can't send too many bytes, they have to fit in the FIFO. | ||
| 77 | // This is because we aren't sending+receiving at the same time. | ||
| 78 | |||
| 79 | let data = [0xC0, 0xDE]; | ||
| 80 | unwrap!(uart.blocking_write(&data)); | ||
| 81 | assert_eq!(unwrap!(read(&mut uart)), data); | ||
| 82 | } | ||
| 83 | |||
| 84 | info!("Test OK"); | ||
| 85 | cortex_m::asm::bkpt(); | ||
| 86 | } | ||
diff --git a/tests/mspm0/src/bin/uart_buffered.rs b/tests/mspm0/src/bin/uart_buffered.rs new file mode 100644 index 000000000..135ac1287 --- /dev/null +++ b/tests/mspm0/src/bin/uart_buffered.rs | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | #[cfg(feature = "mspm0g3507")] | ||
| 5 | teleprobe_meta::target!(b"lp-mspm0g3507"); | ||
| 6 | |||
| 7 | use defmt::{assert_eq, unwrap, *}; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_mspm0::uart::{BufferedInterruptHandler, BufferedUart, Config}; | ||
| 10 | use embassy_mspm0::{bind_interrupts, peripherals}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UART1 => BufferedInterruptHandler<peripherals::UART1>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | ||
| 18 | async fn main(_spawner: Spawner) { | ||
| 19 | let p = embassy_mspm0::init(Default::default()); | ||
| 20 | info!("Hello World!"); | ||
| 21 | |||
| 22 | // TODO: Allow creating a looped-back UART (so pins are not needed). | ||
| 23 | // Do not select default UART since the virtual COM port is attached to UART0. | ||
| 24 | #[cfg(any(feature = "mspm0g3507"))] | ||
| 25 | let (mut tx, mut rx, mut uart) = (p.PA8, p.PA9, p.UART1); | ||
| 26 | |||
| 27 | { | ||
| 28 | use embedded_io_async::{Read, Write}; | ||
| 29 | |||
| 30 | let mut config = Config::default(); | ||
| 31 | config.loop_back_enable = true; | ||
| 32 | config.fifo_enable = false; | ||
| 33 | |||
| 34 | let tx_buf = &mut [0u8; 16]; | ||
| 35 | let rx_buf = &mut [0u8; 16]; | ||
| 36 | let mut uart = unwrap!(BufferedUart::new( | ||
| 37 | uart.reborrow(), | ||
| 38 | tx.reborrow(), | ||
| 39 | rx.reborrow(), | ||
| 40 | Irqs, | ||
| 41 | tx_buf, | ||
| 42 | rx_buf, | ||
| 43 | config | ||
| 44 | )); | ||
| 45 | |||
| 46 | let mut buf = [0; 16]; | ||
| 47 | for (j, b) in buf.iter_mut().enumerate() { | ||
| 48 | *b = j as u8; | ||
| 49 | } | ||
| 50 | |||
| 51 | unwrap!(uart.write_all(&buf).await); | ||
| 52 | unwrap!(uart.flush().await); | ||
| 53 | |||
| 54 | unwrap!(uart.read_exact(&mut buf).await); | ||
| 55 | for (j, b) in buf.iter().enumerate() { | ||
| 56 | assert_eq!(*b, j as u8); | ||
| 57 | } | ||
| 58 | |||
| 59 | // Buffer is unclogged, should be able to write again. | ||
| 60 | unwrap!(uart.write_all(&buf).await); | ||
| 61 | unwrap!(uart.flush().await); | ||
| 62 | |||
| 63 | unwrap!(uart.read_exact(&mut buf).await); | ||
| 64 | for (j, b) in buf.iter().enumerate() { | ||
| 65 | assert_eq!(*b, j as u8); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | info!("Blocking buffered"); | ||
| 70 | { | ||
| 71 | use embedded_io::{Read, Write}; | ||
| 72 | |||
| 73 | let mut config = Config::default(); | ||
| 74 | config.loop_back_enable = true; | ||
| 75 | config.fifo_enable = false; | ||
| 76 | |||
| 77 | let tx_buf = &mut [0u8; 16]; | ||
| 78 | let rx_buf = &mut [0u8; 16]; | ||
| 79 | let mut uart = unwrap!(BufferedUart::new( | ||
| 80 | uart.reborrow(), | ||
| 81 | tx.reborrow(), | ||
| 82 | rx.reborrow(), | ||
| 83 | Irqs, | ||
| 84 | tx_buf, | ||
| 85 | rx_buf, | ||
| 86 | config | ||
| 87 | )); | ||
| 88 | |||
| 89 | let mut buf = [0; 16]; | ||
| 90 | |||
| 91 | for (j, b) in buf.iter_mut().enumerate() { | ||
| 92 | *b = j as u8; | ||
| 93 | } | ||
| 94 | |||
| 95 | unwrap!(uart.write_all(&buf)); | ||
| 96 | unwrap!(uart.blocking_flush()); | ||
| 97 | unwrap!(uart.read_exact(&mut buf)); | ||
| 98 | |||
| 99 | for (j, b) in buf.iter().enumerate() { | ||
| 100 | assert_eq!(*b, j as u8); | ||
| 101 | } | ||
| 102 | |||
| 103 | // Buffer is unclogged, should be able to write again. | ||
| 104 | unwrap!(uart.write_all(&buf)); | ||
| 105 | unwrap!(uart.blocking_flush()); | ||
| 106 | unwrap!(uart.read_exact(&mut buf)); | ||
| 107 | |||
| 108 | for (j, b) in buf.iter().enumerate() { | ||
| 109 | assert_eq!(*b, j as u8, "at {}", j); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | info!("Test OK"); | ||
| 114 | cortex_m::asm::bkpt(); | ||
| 115 | } | ||
diff --git a/tests/nrf52840/.cargo/config.toml b/tests/nrf/.cargo/config.toml index 9d6b0313a..0192c10ae 100644 --- a/tests/nrf52840/.cargo/config.toml +++ b/tests/nrf/.cargo/config.toml | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | #runner = "teleprobe local run --chip nRF52840_xxAA --elf" | 2 | runner = "teleprobe local run --chip nRF52840_xxAA --elf" |
| 3 | runner = "teleprobe client run" | 3 | #runner = "teleprobe client run" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | #target = "thumbv6m-none-eabi" | ||
| 6 | target = "thumbv7em-none-eabi" | 7 | target = "thumbv7em-none-eabi" |
| 8 | #target = "thumbv8m.main-none-eabihf" | ||
| 7 | 9 | ||
| 8 | [env] | 10 | [env] |
| 9 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" | 11 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml new file mode 100644 index 000000000..3a9b86cef --- /dev/null +++ b/tests/nrf/Cargo.toml | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2024" | ||
| 3 | name = "embassy-nrf-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | teleprobe-meta = "1" | ||
| 10 | |||
| 11 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | ||
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | ||
| 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 15 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] } | ||
| 16 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 17 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | ||
| 18 | embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | ||
| 19 | embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] } | ||
| 20 | embedded-hal-async = { version = "1.0" } | ||
| 21 | embedded-hal-bus = { version = "0.1", features = ["async"] } | ||
| 22 | static_cell = "2" | ||
| 23 | perf-client = { path = "../perf-client" } | ||
| 24 | |||
| 25 | defmt = "1.0.1" | ||
| 26 | defmt-rtt = "1.0.0" | ||
| 27 | |||
| 28 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 29 | cortex-m-rt = "0.7.0" | ||
| 30 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | ||
| 31 | portable-atomic = { version = "1.6.0" } | ||
| 32 | |||
| 33 | [features] | ||
| 34 | nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] | ||
| 35 | nrf52832 = ["embassy-nrf/nrf52832", "easydma"] | ||
| 36 | nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"] | ||
| 37 | nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"] | ||
| 38 | nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"] | ||
| 39 | nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"] | ||
| 40 | |||
| 41 | easydma = [] | ||
| 42 | two-uarts = [] | ||
| 43 | |||
| 44 | [profile.release] | ||
| 45 | codegen-units = 1 | ||
| 46 | debug = 2 | ||
| 47 | debug-assertions = false | ||
| 48 | incremental = false | ||
| 49 | lto = "fat" | ||
| 50 | opt-level = 's' | ||
| 51 | overflow-checks = false | ||
| 52 | |||
| 53 | # BEGIN TESTS | ||
| 54 | # Generated by gen_test.py. DO NOT EDIT. | ||
| 55 | [[bin]] | ||
| 56 | name = "buffered_uart" | ||
| 57 | path = "src/bin/buffered_uart.rs" | ||
| 58 | required-features = [ "easydma",] | ||
| 59 | |||
| 60 | [[bin]] | ||
| 61 | name = "buffered_uart_full" | ||
| 62 | path = "src/bin/buffered_uart_full.rs" | ||
| 63 | required-features = [ "easydma",] | ||
| 64 | |||
| 65 | [[bin]] | ||
| 66 | name = "buffered_uart_halves" | ||
| 67 | path = "src/bin/buffered_uart_halves.rs" | ||
| 68 | required-features = [ "two-uarts",] | ||
| 69 | |||
| 70 | [[bin]] | ||
| 71 | name = "buffered_uart_spam" | ||
| 72 | path = "src/bin/buffered_uart_spam.rs" | ||
| 73 | required-features = [ "two-uarts",] | ||
| 74 | |||
| 75 | [[bin]] | ||
| 76 | name = "ethernet_enc28j60_perf" | ||
| 77 | path = "src/bin/ethernet_enc28j60_perf.rs" | ||
| 78 | required-features = [ "nrf52840",] | ||
| 79 | |||
| 80 | [[bin]] | ||
| 81 | name = "gpio" | ||
| 82 | path = "src/bin/gpio.rs" | ||
| 83 | required-features = [] | ||
| 84 | |||
| 85 | [[bin]] | ||
| 86 | name = "gpiote" | ||
| 87 | path = "src/bin/gpiote.rs" | ||
| 88 | required-features = [] | ||
| 89 | |||
| 90 | [[bin]] | ||
| 91 | name = "spim" | ||
| 92 | path = "src/bin/spim.rs" | ||
| 93 | required-features = [ "easydma",] | ||
| 94 | |||
| 95 | [[bin]] | ||
| 96 | name = "timer" | ||
| 97 | path = "src/bin/timer.rs" | ||
| 98 | required-features = [] | ||
| 99 | |||
| 100 | [[bin]] | ||
| 101 | name = "uart_halves" | ||
| 102 | path = "src/bin/uart_halves.rs" | ||
| 103 | required-features = [ "two-uarts",] | ||
| 104 | |||
| 105 | [[bin]] | ||
| 106 | name = "uart_split" | ||
| 107 | path = "src/bin/uart_split.rs" | ||
| 108 | required-features = [ "easydma",] | ||
| 109 | |||
| 110 | [[bin]] | ||
| 111 | name = "wifi_esp_hosted_perf" | ||
| 112 | path = "src/bin/wifi_esp_hosted_perf.rs" | ||
| 113 | required-features = [ "nrf52840",] | ||
| 114 | |||
| 115 | # END TESTS | ||
| 116 | |||
| 117 | [package.metadata.embassy] | ||
| 118 | build = [ | ||
| 119 | { target = "thumbv6m-none-eabi", features = ["nrf51422"], artifact-dir = "out/tests/nrf51422-dk" }, | ||
| 120 | { target = "thumbv7em-none-eabi", features = ["nrf52832"], artifact-dir = "out/tests/nrf52832-dk" }, | ||
| 121 | { target = "thumbv7em-none-eabi", features = ["nrf52833"], artifact-dir = "out/tests/nrf52833-dk" }, | ||
| 122 | { target = "thumbv7em-none-eabi", features = ["nrf52840"], artifact-dir = "out/tests/nrf52840-dk" }, | ||
| 123 | { target = "thumbv8m.main-none-eabihf", features = ["nrf5340"], artifact-dir = "out/tests/nrf5340-dk" }, | ||
| 124 | { target = "thumbv8m.main-none-eabihf", features = ["nrf9160"], artifact-dir = "out/tests/nrf9160-dk" } | ||
| 125 | ] | ||
diff --git a/tests/nrf/build.rs b/tests/nrf/build.rs new file mode 100644 index 000000000..3c15cf10f --- /dev/null +++ b/tests/nrf/build.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | |||
| 8 | // copy the right memory.x | ||
| 9 | #[cfg(feature = "nrf51422")] | ||
| 10 | let memory_x = include_bytes!("memory-nrf51422.x"); | ||
| 11 | #[cfg(feature = "nrf52832")] | ||
| 12 | let memory_x = include_bytes!("memory-nrf52832.x"); | ||
| 13 | #[cfg(feature = "nrf52833")] | ||
| 14 | let memory_x = include_bytes!("memory-nrf52833.x"); | ||
| 15 | #[cfg(feature = "nrf52840")] | ||
| 16 | let memory_x = include_bytes!("memory-nrf52840.x"); | ||
| 17 | #[cfg(feature = "nrf5340")] | ||
| 18 | let memory_x = include_bytes!("memory-nrf5340.x"); | ||
| 19 | #[cfg(feature = "nrf9160")] | ||
| 20 | let memory_x = include_bytes!("memory-nrf9160.x"); | ||
| 21 | fs::write(out.join("memory.x"), memory_x).unwrap(); | ||
| 22 | |||
| 23 | // copy main linker script. | ||
| 24 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); | ||
| 25 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 26 | println!("cargo:rerun-if-changed=link_ram.x"); | ||
| 27 | |||
| 28 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 29 | #[cfg(feature = "nrf51422")] | ||
| 30 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 31 | #[cfg(not(feature = "nrf51422"))] | ||
| 32 | println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); | ||
| 33 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 34 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 35 | |||
| 36 | Ok(()) | ||
| 37 | } | ||
diff --git a/tests/nrf/gen_test.py b/tests/nrf/gen_test.py new file mode 100644 index 000000000..daf714376 --- /dev/null +++ b/tests/nrf/gen_test.py | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | import os | ||
| 2 | import toml | ||
| 3 | from glob import glob | ||
| 4 | |||
| 5 | abspath = os.path.abspath(__file__) | ||
| 6 | dname = os.path.dirname(abspath) | ||
| 7 | os.chdir(dname) | ||
| 8 | |||
| 9 | # ======= load test list | ||
| 10 | tests = {} | ||
| 11 | for f in sorted(glob('./src/bin/*.rs')): | ||
| 12 | name = os.path.splitext(os.path.basename(f))[0] | ||
| 13 | features = [] | ||
| 14 | with open(f, 'r') as f: | ||
| 15 | for line in f: | ||
| 16 | if line.startswith('// required-features:'): | ||
| 17 | features = [feature.strip() for feature in line.split(':', 2)[1].strip().split(',')] | ||
| 18 | |||
| 19 | tests[name] = features | ||
| 20 | |||
| 21 | # ========= Update Cargo.toml | ||
| 22 | |||
| 23 | things = { | ||
| 24 | 'bin': [ | ||
| 25 | { | ||
| 26 | 'name': f'{name}', | ||
| 27 | 'path': f'src/bin/{name}.rs', | ||
| 28 | 'required-features': features, | ||
| 29 | } | ||
| 30 | for name, features in tests.items() | ||
| 31 | ] | ||
| 32 | } | ||
| 33 | |||
| 34 | SEPARATOR_START = '# BEGIN TESTS\n' | ||
| 35 | SEPARATOR_END = '# END TESTS\n' | ||
| 36 | HELP = '# Generated by gen_test.py. DO NOT EDIT.\n' | ||
| 37 | with open('Cargo.toml', 'r') as f: | ||
| 38 | data = f.read() | ||
| 39 | before, data = data.split(SEPARATOR_START, maxsplit=1) | ||
| 40 | _, after = data.split(SEPARATOR_END, maxsplit=1) | ||
| 41 | data = before + SEPARATOR_START + HELP + \ | ||
| 42 | toml.dumps(things) + SEPARATOR_END + after | ||
| 43 | with open('Cargo.toml', 'w') as f: | ||
| 44 | f.write(data) | ||
diff --git a/tests/nrf/memory-nrf51422.x b/tests/nrf/memory-nrf51422.x new file mode 100644 index 000000000..c140005ce --- /dev/null +++ b/tests/nrf/memory-nrf51422.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 256K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 32K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf52832.x b/tests/nrf/memory-nrf52832.x new file mode 100644 index 000000000..c140005ce --- /dev/null +++ b/tests/nrf/memory-nrf52832.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 256K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 32K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf52833.x b/tests/nrf/memory-nrf52833.x new file mode 100644 index 000000000..a4baa2dc4 --- /dev/null +++ b/tests/nrf/memory-nrf52833.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 512K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 64K | ||
| 5 | } | ||
diff --git a/tests/nrf52840/memory.x b/tests/nrf/memory-nrf52840.x index 58900a7bd..58900a7bd 100644 --- a/tests/nrf52840/memory.x +++ b/tests/nrf/memory-nrf52840.x | |||
diff --git a/tests/nrf/memory-nrf5340.x b/tests/nrf/memory-nrf5340.x new file mode 100644 index 000000000..58900a7bd --- /dev/null +++ b/tests/nrf/memory-nrf5340.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 1024K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 5 | } | ||
diff --git a/tests/nrf/memory-nrf9160.x b/tests/nrf/memory-nrf9160.x new file mode 100644 index 000000000..58900a7bd --- /dev/null +++ b/tests/nrf/memory-nrf9160.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 1024K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 5 | } | ||
diff --git a/tests/nrf52840/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs index a01d66d85..8c4827464 100644 --- a/tests/nrf52840/src/bin/buffered_uart.rs +++ b/tests/nrf/src/bin/buffered_uart.rs | |||
| @@ -1,18 +1,17 @@ | |||
| 1 | // required-features: easydma | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 4 | 4 | ||
| 5 | use defmt::{assert_eq, *}; | 5 | #[path = "../common.rs"] |
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{panic, *}; | ||
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | 10 | use embassy_futures::join::join; |
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; |
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 12 | use embassy_nrf::{peripherals, uarte}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 18 | let mut p = embassy_nrf::init(Default::default()); | 17 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -26,14 +25,14 @@ async fn main(_spawner: Spawner) { | |||
| 26 | // test teardown + recreate of the buffereduarte works fine. | 25 | // test teardown + recreate of the buffereduarte works fine. |
| 27 | for _ in 0..2 { | 26 | for _ in 0..2 { |
| 28 | let u = BufferedUarte::new( | 27 | let u = BufferedUarte::new( |
| 29 | &mut p.UARTE0, | 28 | peri!(p, UART0).reborrow(), |
| 30 | &mut p.TIMER0, | 29 | p.TIMER0.reborrow(), |
| 31 | &mut p.PPI_CH0, | 30 | p.PPI_CH0.reborrow(), |
| 32 | &mut p.PPI_CH1, | 31 | p.PPI_CH1.reborrow(), |
| 33 | &mut p.PPI_GROUP0, | 32 | p.PPI_GROUP0.reborrow(), |
| 34 | Irqs, | 33 | peri!(p, PIN_A).reborrow(), |
| 35 | &mut p.P1_03, | 34 | peri!(p, PIN_B).reborrow(), |
| 36 | &mut p.P1_02, | 35 | irqs!(UART0_BUFFERED), |
| 37 | config.clone(), | 36 | config.clone(), |
| 38 | &mut rx_buffer, | 37 | &mut rx_buffer, |
| 39 | &mut tx_buffer, | 38 | &mut tx_buffer, |
| @@ -64,7 +63,9 @@ async fn main(_spawner: Spawner) { | |||
| 64 | let buf = unwrap!(rx.fill_buf().await); | 63 | let buf = unwrap!(rx.fill_buf().await); |
| 65 | 64 | ||
| 66 | for &b in buf { | 65 | for &b in buf { |
| 67 | assert_eq!(b, i as u8); | 66 | if b != i as u8 { |
| 67 | panic!("mismatch {} vs {}, index {}", b, i as u8, i); | ||
| 68 | } | ||
| 68 | i = i + 1; | 69 | i = i + 1; |
| 69 | } | 70 | } |
| 70 | 71 | ||
diff --git a/tests/nrf52840/src/bin/buffered_uart_full.rs b/tests/nrf/src/bin/buffered_uart_full.rs index 62edaed25..e0f41b891 100644 --- a/tests/nrf52840/src/bin/buffered_uart_full.rs +++ b/tests/nrf/src/bin/buffered_uart_full.rs | |||
| @@ -1,18 +1,17 @@ | |||
| 1 | // required-features: easydma | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 10 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; |
| 8 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 11 | use embassy_nrf::{peripherals, uarte}; |
| 9 | use embedded_io_async::{Read, Write}; | 12 | use embedded_io_async::{Read, Write}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_nrf::init(Default::default()); | 17 | let p = embassy_nrf::init(Default::default()); |
| @@ -20,18 +19,18 @@ async fn main(_spawner: Spawner) { | |||
| 20 | config.parity = uarte::Parity::EXCLUDED; | 19 | config.parity = uarte::Parity::EXCLUDED; |
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | 20 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 22 | 21 | ||
| 23 | let mut tx_buffer = [0u8; 1024]; | 22 | let mut tx_buffer = [0u8; 500]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 23 | let mut rx_buffer = [0u8; 500]; |
| 25 | 24 | ||
| 26 | let u = BufferedUarte::new( | 25 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 26 | peri!(p, UART0), |
| 28 | p.TIMER0, | 27 | p.TIMER0, |
| 29 | p.PPI_CH0, | 28 | p.PPI_CH0, |
| 30 | p.PPI_CH1, | 29 | p.PPI_CH1, |
| 31 | p.PPI_GROUP0, | 30 | p.PPI_GROUP0, |
| 32 | Irqs, | 31 | peri!(p, PIN_A), |
| 33 | p.P1_03, | 32 | peri!(p, PIN_B), |
| 34 | p.P1_02, | 33 | irqs!(UART0_BUFFERED), |
| 35 | config.clone(), | 34 | config.clone(), |
| 36 | &mut rx_buffer, | 35 | &mut rx_buffer, |
| 37 | &mut tx_buffer, | 36 | &mut tx_buffer, |
| @@ -41,22 +40,22 @@ async fn main(_spawner: Spawner) { | |||
| 41 | 40 | ||
| 42 | let (mut rx, mut tx) = u.split(); | 41 | let (mut rx, mut tx) = u.split(); |
| 43 | 42 | ||
| 44 | let mut buf = [0; 1024]; | 43 | let mut buf = [0; 500]; |
| 45 | for (j, b) in buf.iter_mut().enumerate() { | 44 | for (j, b) in buf.iter_mut().enumerate() { |
| 46 | *b = j as u8; | 45 | *b = j as u8; |
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | // Write 1024b. This causes the rx buffer to get exactly full. | 48 | // Write 500b. This causes the rx buffer to get exactly full. |
| 50 | unwrap!(tx.write_all(&buf).await); | 49 | unwrap!(tx.write_all(&buf).await); |
| 51 | unwrap!(tx.flush().await); | 50 | unwrap!(tx.flush().await); |
| 52 | 51 | ||
| 53 | // Read those 1024b. | 52 | // Read those 500b. |
| 54 | unwrap!(rx.read_exact(&mut buf).await); | 53 | unwrap!(rx.read_exact(&mut buf).await); |
| 55 | for (j, b) in buf.iter().enumerate() { | 54 | for (j, b) in buf.iter().enumerate() { |
| 56 | assert_eq!(*b, j as u8); | 55 | assert_eq!(*b, j as u8); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | // The buffer should now be unclogged. Write 1024b again. | 58 | // The buffer should now be unclogged. Write 500b again. |
| 60 | unwrap!(tx.write_all(&buf).await); | 59 | unwrap!(tx.write_all(&buf).await); |
| 61 | unwrap!(tx.flush().await); | 60 | unwrap!(tx.flush().await); |
| 62 | 61 | ||
diff --git a/tests/nrf52840/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs index 54a9fef5b..e6debd76e 100644 --- a/tests/nrf52840/src/bin/buffered_uart_halves.rs +++ b/tests/nrf/src/bin/buffered_uart_halves.rs | |||
| @@ -1,19 +1,17 @@ | |||
| 1 | // required-features: two-uarts | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | 10 | use embassy_futures::join::join; |
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; | 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; |
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 12 | use embassy_nrf::{peripherals, uarte}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 18 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 19 | let mut p = embassy_nrf::init(Default::default()); | 17 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -28,16 +26,22 @@ async fn main(_spawner: Spawner) { | |||
| 28 | for _ in 0..2 { | 26 | for _ in 0..2 { |
| 29 | const COUNT: usize = 40_000; | 27 | const COUNT: usize = 40_000; |
| 30 | 28 | ||
| 31 | let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer); | 29 | let mut tx = BufferedUarteTx::new( |
| 30 | peri!(p, UART1).reborrow(), | ||
| 31 | peri!(p, PIN_A).reborrow(), | ||
| 32 | irqs!(UART1_BUFFERED), | ||
| 33 | config.clone(), | ||
| 34 | &mut tx_buffer, | ||
| 35 | ); | ||
| 32 | 36 | ||
| 33 | let mut rx = BufferedUarteRx::new( | 37 | let mut rx = BufferedUarteRx::new( |
| 34 | &mut p.UARTE0, | 38 | peri!(p, UART0).reborrow(), |
| 35 | &mut p.TIMER0, | 39 | p.TIMER0.reborrow(), |
| 36 | &mut p.PPI_CH0, | 40 | p.PPI_CH0.reborrow(), |
| 37 | &mut p.PPI_CH1, | 41 | p.PPI_CH1.reborrow(), |
| 38 | &mut p.PPI_GROUP0, | 42 | p.PPI_GROUP0.reborrow(), |
| 39 | Irqs, | 43 | irqs!(UART0_BUFFERED), |
| 40 | &mut p.P1_03, | 44 | peri!(p, PIN_B).reborrow(), |
| 41 | config.clone(), | 45 | config.clone(), |
| 42 | &mut rx_buffer, | 46 | &mut rx_buffer, |
| 43 | ); | 47 | ); |
diff --git a/tests/nrf52840/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 400c0df99..6d862e19d 100644 --- a/tests/nrf52840/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -1,25 +1,23 @@ | |||
| 1 | // required-features: two-uarts | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 4 | 7 | ||
| 5 | use core::mem; | 8 | use core::mem; |
| 6 | use core::ptr::NonNull; | 9 | use core::ptr::NonNull; |
| 7 | 10 | ||
| 8 | use defmt::{assert_eq, *}; | 11 | use defmt::{assert_eq, *}; |
| 9 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 10 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 13 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx}; |
| 11 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 14 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 12 | use embassy_nrf::ppi::{Event, Ppi, Task}; | 15 | use embassy_nrf::ppi::{Event, Ppi, Task}; |
| 13 | use embassy_nrf::uarte::Uarte; | 16 | use embassy_nrf::uarte::UarteTx; |
| 14 | use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; | 17 | use embassy_nrf::{pac, peripherals, uarte}; |
| 15 | use embassy_time::Timer; | 18 | use embassy_time::Timer; |
| 16 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 17 | 20 | ||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 20 | UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 24 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 25 | let mut p = embassy_nrf::init(Default::default()); | 23 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -27,23 +25,24 @@ async fn main(_spawner: Spawner) { | |||
| 27 | config.parity = uarte::Parity::EXCLUDED; | 25 | config.parity = uarte::Parity::EXCLUDED; |
| 28 | config.baudrate = uarte::Baudrate::BAUD1M; | 26 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 29 | 27 | ||
| 30 | let mut tx_buffer = [0u8; 1024]; | ||
| 31 | let mut rx_buffer = [0u8; 1024]; | 28 | let mut rx_buffer = [0u8; 1024]; |
| 32 | 29 | ||
| 33 | mem::forget(Output::new(&mut p.P1_02, Level::High, OutputDrive::Standard)); | 30 | mem::forget(Output::new( |
| 31 | peri!(p, PIN_A).reborrow(), | ||
| 32 | Level::High, | ||
| 33 | OutputDrive::Standard, | ||
| 34 | )); | ||
| 34 | 35 | ||
| 35 | let mut u = BufferedUarte::new( | 36 | let mut u = BufferedUarteRx::new( |
| 36 | p.UARTE0, | 37 | peri!(p, UART0), |
| 37 | p.TIMER0, | 38 | p.TIMER0, |
| 38 | p.PPI_CH0, | 39 | p.PPI_CH0, |
| 39 | p.PPI_CH1, | 40 | p.PPI_CH1, |
| 40 | p.PPI_GROUP0, | 41 | p.PPI_GROUP0, |
| 41 | Irqs, | 42 | irqs!(UART0_BUFFERED), |
| 42 | p.P1_03, | 43 | peri!(p, PIN_B), |
| 43 | p.P1_04, | ||
| 44 | config.clone(), | 44 | config.clone(), |
| 45 | &mut rx_buffer, | 45 | &mut rx_buffer, |
| 46 | &mut tx_buffer, | ||
| 47 | ); | 46 | ); |
| 48 | 47 | ||
| 49 | info!("uarte initialized!"); | 48 | info!("uarte initialized!"); |
| @@ -54,16 +53,16 @@ async fn main(_spawner: Spawner) { | |||
| 54 | // Tx spam in a loop. | 53 | // Tx spam in a loop. |
| 55 | const NSPAM: usize = 17; | 54 | const NSPAM: usize = 17; |
| 56 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 55 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 57 | let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone()); | 56 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 58 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; | 57 | let spam_peri = pac::UARTE1; |
| 59 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; | 58 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_dma().tx().end().as_ptr())) }; |
| 60 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; | 59 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_dma().tx().start().as_ptr())) }; |
| 61 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); | 60 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); |
| 62 | spam_ppi.enable(); | 61 | spam_ppi.enable(); |
| 63 | let p = unsafe { TX_BUF.as_mut_ptr() }; | 62 | let p = (&raw mut TX_BUF) as *mut u8; |
| 64 | spam_peri.txd.ptr.write(|w| unsafe { w.ptr().bits(p as u32) }); | 63 | spam_peri.dma().tx().ptr().write_value(p as u32); |
| 65 | spam_peri.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(NSPAM as _) }); | 64 | spam_peri.dma().tx().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); |
| 66 | spam_peri.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 65 | spam_peri.tasks_dma().tx().start().write_value(1); |
| 67 | 66 | ||
| 68 | let mut i = 0; | 67 | let mut i = 0; |
| 69 | let mut total = 0; | 68 | let mut total = 0; |
diff --git a/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs index 33c2f4235..bd6a2effd 100644 --- a/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs +++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // required-features: nrf52840 | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"ak-gwe-r7"); | 4 | teleprobe_meta::target!(b"ak-gwe-r7"); |
| @@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 6 | ||
| 6 | use defmt::{info, unwrap}; | 7 | use defmt::{info, unwrap}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Stack, StackResources}; | 9 | use embassy_net::StackResources; |
| 9 | use embassy_net_enc28j60::Enc28j60; | 10 | use embassy_net_enc28j60::Enc28j60; |
| 10 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 11 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 11 | use embassy_nrf::rng::Rng; | 12 | use embassy_nrf::rng::Rng; |
| @@ -21,11 +22,11 @@ bind_interrupts!(struct Irqs { | |||
| 21 | RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; | 22 | RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; |
| 22 | }); | 23 | }); |
| 23 | 24 | ||
| 24 | type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; | 25 | type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Output<'static>>; |
| 25 | 26 | ||
| 26 | #[embassy_executor::task] | 27 | #[embassy_executor::task] |
| 27 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { | 28 | async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! { |
| 28 | stack.run().await | 29 | runner.run().await |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | #[embassy_executor::main] | 32 | #[embassy_executor::main] |
| @@ -64,16 +65,10 @@ async fn main(spawner: Spawner) { | |||
| 64 | let seed = u64::from_le_bytes(seed); | 65 | let seed = u64::from_le_bytes(seed); |
| 65 | 66 | ||
| 66 | // Init network stack | 67 | // Init network stack |
| 67 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||
| 68 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 68 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 69 | let stack = &*STACK.init(Stack::new( | 69 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 70 | device, | ||
| 71 | config, | ||
| 72 | RESOURCES.init(StackResources::<2>::new()), | ||
| 73 | seed, | ||
| 74 | )); | ||
| 75 | 70 | ||
| 76 | unwrap!(spawner.spawn(net_task(stack))); | 71 | spawner.spawn(unwrap!(net_task(runner))); |
| 77 | 72 | ||
| 78 | perf_client::run( | 73 | perf_client::run( |
| 79 | stack, | 74 | stack, |
diff --git a/tests/nrf51422/src/bin/gpio.rs b/tests/nrf/src/bin/gpio.rs index 6d5a87d0a..4995d244c 100644 --- a/tests/nrf51422/src/bin/gpio.rs +++ b/tests/nrf/src/bin/gpio.rs | |||
| @@ -1,25 +1,28 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 8 | use embassy_time::Timer; | 10 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | 11 | ||
| 11 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 13 | let p = embassy_nrf::init(Default::default()); | 14 | let p = embassy_nrf::init(Default::default()); |
| 14 | 15 | ||
| 15 | let input = Input::new(p.P0_13, Pull::Up); | 16 | let input = Input::new(peri!(p, PIN_A), Pull::Up); |
| 16 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | 17 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); |
| 17 | 18 | ||
| 18 | output.set_low(); | 19 | output.set_low(); |
| 20 | assert!(output.is_set_low()); | ||
| 19 | Timer::after_millis(10).await; | 21 | Timer::after_millis(10).await; |
| 20 | assert!(input.is_low()); | 22 | assert!(input.is_low()); |
| 21 | 23 | ||
| 22 | output.set_high(); | 24 | output.set_high(); |
| 25 | assert!(output.is_set_high()); | ||
| 23 | Timer::after_millis(10).await; | 26 | Timer::after_millis(10).await; |
| 24 | assert!(input.is_high()); | 27 | assert!(input.is_high()); |
| 25 | 28 | ||
diff --git a/tests/nrf51422/src/bin/gpiote.rs b/tests/nrf/src/bin/gpiote.rs index 330fe993e..0700016d1 100644 --- a/tests/nrf51422/src/bin/gpiote.rs +++ b/tests/nrf/src/bin/gpiote.rs | |||
| @@ -1,20 +1,21 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | 9 | use embassy_futures::join::join; |
| 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 10 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 9 | use embassy_time::{Duration, Instant, Timer}; | 11 | use embassy_time::{Duration, Instant, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | 12 | ||
| 12 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_nrf::init(Default::default()); | 15 | let p = embassy_nrf::init(Default::default()); |
| 15 | 16 | ||
| 16 | let mut input = Input::new(p.P0_13, Pull::Up); | 17 | let mut input = Input::new(peri!(p, PIN_A), Pull::Up); |
| 17 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | 18 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); |
| 18 | 19 | ||
| 19 | let fut1 = async { | 20 | let fut1 = async { |
| 20 | Timer::after_millis(100).await; | 21 | Timer::after_millis(100).await; |
| @@ -24,6 +25,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let start = Instant::now(); | 25 | let start = Instant::now(); |
| 25 | input.wait_for_high().await; | 26 | input.wait_for_high().await; |
| 26 | let dur = Instant::now() - start; | 27 | let dur = Instant::now() - start; |
| 28 | info!("took {} ms", dur.as_millis()); | ||
| 27 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | 29 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); |
| 28 | }; | 30 | }; |
| 29 | 31 | ||
| @@ -37,6 +39,7 @@ async fn main(_spawner: Spawner) { | |||
| 37 | let start = Instant::now(); | 39 | let start = Instant::now(); |
| 38 | input.wait_for_low().await; | 40 | input.wait_for_low().await; |
| 39 | let dur = Instant::now() - start; | 41 | let dur = Instant::now() - start; |
| 42 | info!("took {} ms", dur.as_millis()); | ||
| 40 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | 43 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
diff --git a/tests/nrf/src/bin/spim.rs b/tests/nrf/src/bin/spim.rs new file mode 100644 index 000000000..2b38f0409 --- /dev/null +++ b/tests/nrf/src/bin/spim.rs | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_nrf::spim::Spim; | ||
| 11 | use embassy_nrf::{peripherals, spim}; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | #[embassy_executor::main] | ||
| 15 | async fn main(_spawner: Spawner) { | ||
| 16 | let mut p = embassy_nrf::init(Default::default()); | ||
| 17 | let mut config = spim::Config::default(); | ||
| 18 | config.frequency = spim::Frequency::M1; | ||
| 19 | let mut spim = Spim::new( | ||
| 20 | peri!(p, SPIM0).reborrow(), | ||
| 21 | irqs!(SPIM0), | ||
| 22 | peri!(p, PIN_X).reborrow(), | ||
| 23 | peri!(p, PIN_A).reborrow(), // MISO | ||
| 24 | peri!(p, PIN_B).reborrow(), // MOSI | ||
| 25 | config.clone(), | ||
| 26 | ); | ||
| 27 | let data = [ | ||
| 28 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 29 | ]; | ||
| 30 | let mut buf = [0u8; 16]; | ||
| 31 | |||
| 32 | buf.fill(0); | ||
| 33 | spim.blocking_transfer(&mut buf, &data).unwrap(); | ||
| 34 | assert_eq!(data, buf); | ||
| 35 | |||
| 36 | buf.fill(0); | ||
| 37 | spim.transfer(&mut buf, &data).await.unwrap(); | ||
| 38 | assert_eq!(data, buf); | ||
| 39 | |||
| 40 | info!("Test OK"); | ||
| 41 | cortex_m::asm::bkpt(); | ||
| 42 | } | ||
diff --git a/tests/nrf51422/src/bin/timer.rs b/tests/nrf/src/bin/timer.rs index cf9ea41a8..1ae9dd647 100644 --- a/tests/nrf51422/src/bin/timer.rs +++ b/tests/nrf/src/bin/timer.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | 3 | |
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 4 | 6 | ||
| 5 | use defmt::{assert, info}; | 7 | use defmt::{assert, info}; |
| 6 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
diff --git a/tests/nrf/src/bin/uart_halves.rs b/tests/nrf/src/bin/uart_halves.rs new file mode 100644 index 000000000..a462f80ce --- /dev/null +++ b/tests/nrf/src/bin/uart_halves.rs | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | // required-features: two-uarts | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::{UarteRx, UarteTx}; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 21 | |||
| 22 | let mut tx = UarteTx::new( | ||
| 23 | peri!(p, UART0).reborrow(), | ||
| 24 | irqs!(UART0), | ||
| 25 | peri!(p, PIN_A).reborrow(), | ||
| 26 | config.clone(), | ||
| 27 | ); | ||
| 28 | let mut rx = UarteRx::new( | ||
| 29 | peri!(p, UART1).reborrow(), | ||
| 30 | irqs!(UART1), | ||
| 31 | peri!(p, PIN_B).reborrow(), | ||
| 32 | config.clone(), | ||
| 33 | ); | ||
| 34 | |||
| 35 | let data = [ | ||
| 36 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 37 | ]; | ||
| 38 | |||
| 39 | let tx_fut = async { | ||
| 40 | tx.write(&data).await.unwrap(); | ||
| 41 | }; | ||
| 42 | let rx_fut = async { | ||
| 43 | let mut buf = [0u8; 16]; | ||
| 44 | rx.read(&mut buf).await.unwrap(); | ||
| 45 | assert_eq!(data, buf); | ||
| 46 | }; | ||
| 47 | join(rx_fut, tx_fut).await; | ||
| 48 | |||
| 49 | info!("Test OK"); | ||
| 50 | cortex_m::asm::bkpt(); | ||
| 51 | } | ||
diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs new file mode 100644 index 000000000..8fe710068 --- /dev/null +++ b/tests/nrf/src/bin/uart_split.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::Uarte; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD9600; | ||
| 22 | |||
| 23 | let uarte = Uarte::new( | ||
| 24 | peri!(p, UART0).reborrow(), | ||
| 25 | peri!(p, PIN_A).reborrow(), | ||
| 26 | peri!(p, PIN_B).reborrow(), | ||
| 27 | irqs!(UART0), | ||
| 28 | config.clone(), | ||
| 29 | ); | ||
| 30 | let (mut tx, mut rx) = uarte.split(); | ||
| 31 | |||
| 32 | let data = [ | ||
| 33 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 34 | ]; | ||
| 35 | |||
| 36 | let tx_fut = async { | ||
| 37 | Timer::after_millis(10).await; | ||
| 38 | tx.write(&data).await.unwrap(); | ||
| 39 | }; | ||
| 40 | let rx_fut = async { | ||
| 41 | let mut buf = [0u8; 16]; | ||
| 42 | rx.read(&mut buf).await.unwrap(); | ||
| 43 | assert_eq!(data, buf); | ||
| 44 | }; | ||
| 45 | join(rx_fut, tx_fut).await; | ||
| 46 | |||
| 47 | info!("Test OK"); | ||
| 48 | cortex_m::asm::bkpt(); | ||
| 49 | } | ||
diff --git a/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs index b83edddc4..ac082dbb8 100644 --- a/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs +++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // required-features: nrf52840 | ||
| 1 | #![no_std] | 2 | #![no_std] |
| 2 | #![no_main] | 3 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | teleprobe_meta::target!(b"nrf52840-dk"); |
| @@ -5,7 +6,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 6 | ||
| 6 | use defmt::{info, unwrap}; | 7 | use defmt::{info, unwrap}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Config, Stack, StackResources}; | 9 | use embassy_net::{Config, StackResources}; |
| 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 10 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 10 | use embassy_nrf::rng::Rng; | 11 | use embassy_nrf::rng::Rng; |
| 11 | use embassy_nrf::spim::{self, Spim}; | 12 | use embassy_nrf::spim::{self, Spim}; |
| @@ -28,8 +29,7 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | |||
| 28 | async fn wifi_task( | 29 | async fn wifi_task( |
| 29 | runner: hosted::Runner< | 30 | runner: hosted::Runner< |
| 30 | 'static, | 31 | 'static, |
| 31 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, | 32 | hosted::SpiInterface<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Input<'static>>, |
| 32 | Input<'static>, | ||
| 33 | Output<'static>, | 33 | Output<'static>, |
| 34 | >, | 34 | >, |
| 35 | ) -> ! { | 35 | ) -> ! { |
| @@ -39,8 +39,8 @@ async fn wifi_task( | |||
| 39 | type MyDriver = hosted::NetDriver<'static>; | 39 | type MyDriver = hosted::NetDriver<'static>; |
| 40 | 40 | ||
| 41 | #[embassy_executor::task] | 41 | #[embassy_executor::task] |
| 42 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { | 42 | async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! { |
| 43 | stack.run().await | 43 | runner.run().await |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | #[embassy_executor::main] | 46 | #[embassy_executor::main] |
| @@ -63,17 +63,13 @@ async fn main(spawner: Spawner) { | |||
| 63 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | 63 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |
| 64 | let spi = ExclusiveDevice::new(spi, cs, Delay); | 64 | let spi = ExclusiveDevice::new(spi, cs, Delay); |
| 65 | 65 | ||
| 66 | let iface = hosted::SpiInterface::new(spi, handshake, ready); | ||
| 67 | |||
| 66 | static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | 68 | static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); |
| 67 | let (device, mut control, runner) = embassy_net_esp_hosted::new( | 69 | let (device, mut control, runner) = |
| 68 | STATE.init(embassy_net_esp_hosted::State::new()), | 70 | embassy_net_esp_hosted::new(STATE.init(embassy_net_esp_hosted::State::new()), iface, reset).await; |
| 69 | spi, | ||
| 70 | handshake, | ||
| 71 | ready, | ||
| 72 | reset, | ||
| 73 | ) | ||
| 74 | .await; | ||
| 75 | 71 | ||
| 76 | unwrap!(spawner.spawn(wifi_task(runner))); | 72 | spawner.spawn(unwrap!(wifi_task(runner))); |
| 77 | 73 | ||
| 78 | unwrap!(control.init().await); | 74 | unwrap!(control.init().await); |
| 79 | unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); | 75 | unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); |
| @@ -85,16 +81,15 @@ async fn main(spawner: Spawner) { | |||
| 85 | let seed = u64::from_le_bytes(seed); | 81 | let seed = u64::from_le_bytes(seed); |
| 86 | 82 | ||
| 87 | // Init network stack | 83 | // Init network stack |
| 88 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||
| 89 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 84 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 90 | let stack = &*STACK.init(Stack::new( | 85 | let (stack, runner) = embassy_net::new( |
| 91 | device, | 86 | device, |
| 92 | Config::dhcpv4(Default::default()), | 87 | Config::dhcpv4(Default::default()), |
| 93 | RESOURCES.init(StackResources::<2>::new()), | 88 | RESOURCES.init(StackResources::new()), |
| 94 | seed, | 89 | seed, |
| 95 | )); | 90 | ); |
| 96 | 91 | ||
| 97 | unwrap!(spawner.spawn(net_task(stack))); | 92 | spawner.spawn(unwrap!(net_task(runner))); |
| 98 | 93 | ||
| 99 | perf_client::run( | 94 | perf_client::run( |
| 100 | stack, | 95 | stack, |
diff --git a/tests/nrf/src/common.rs b/tests/nrf/src/common.rs new file mode 100644 index 000000000..ebd332d15 --- /dev/null +++ b/tests/nrf/src/common.rs | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use {defmt_rtt as _, panic_probe as _}; | ||
| 4 | |||
| 5 | #[cfg(feature = "nrf52832")] | ||
| 6 | teleprobe_meta::target!(b"nrf52832-dk"); | ||
| 7 | #[cfg(feature = "nrf52840")] | ||
| 8 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 9 | #[cfg(feature = "nrf52833")] | ||
| 10 | teleprobe_meta::target!(b"nrf52833-dk"); | ||
| 11 | #[cfg(feature = "nrf5340")] | ||
| 12 | teleprobe_meta::target!(b"nrf5340-dk"); | ||
| 13 | #[cfg(feature = "nrf9160")] | ||
| 14 | teleprobe_meta::target!(b"nrf9160-dk"); | ||
| 15 | #[cfg(feature = "nrf51422")] | ||
| 16 | teleprobe_meta::target!(b"nrf51-dk"); | ||
| 17 | |||
| 18 | macro_rules! define_peris { | ||
| 19 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { | ||
| 20 | #[allow(unused_macros)] | ||
| 21 | macro_rules! peri { | ||
| 22 | $( | ||
| 23 | ($p:expr, $name) => { | ||
| 24 | $p.$peri | ||
| 25 | }; | ||
| 26 | )* | ||
| 27 | } | ||
| 28 | #[allow(unused_macros)] | ||
| 29 | macro_rules! irqs { | ||
| 30 | $( | ||
| 31 | ($irq_name) => {{ | ||
| 32 | embassy_nrf::bind_interrupts!(struct Irqs $irq_code); | ||
| 33 | Irqs | ||
| 34 | }}; | ||
| 35 | )* | ||
| 36 | ( @ dummy ) => {}; | ||
| 37 | } | ||
| 38 | |||
| 39 | #[allow(unused)] | ||
| 40 | #[allow(non_camel_case_types)] | ||
| 41 | pub mod peris { | ||
| 42 | $( | ||
| 43 | pub type $name = embassy_nrf::peripherals::$peri; | ||
| 44 | )* | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | } | ||
| 48 | |||
| 49 | #[cfg(feature = "nrf51422")] | ||
| 50 | define_peris!(PIN_A = P0_13, PIN_B = P0_14,); | ||
| 51 | |||
| 52 | #[cfg(feature = "nrf52832")] | ||
| 53 | define_peris!( | ||
| 54 | PIN_A = P0_11, PIN_B = P0_12, | ||
| 55 | PIN_X = P0_13, | ||
| 56 | UART0 = UARTE0, | ||
| 57 | SPIM0 = TWISPI0, | ||
| 58 | @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 59 | @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 60 | @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 61 | ); | ||
| 62 | |||
| 63 | #[cfg(feature = "nrf52833")] | ||
| 64 | define_peris!( | ||
| 65 | PIN_A = P1_01, PIN_B = P1_02, | ||
| 66 | PIN_X = P1_03, | ||
| 67 | UART0 = UARTE0, | ||
| 68 | UART1 = UARTE1, | ||
| 69 | SPIM0 = TWISPI0, | ||
| 70 | @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 71 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 72 | @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 73 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 74 | @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 75 | ); | ||
| 76 | |||
| 77 | #[cfg(feature = "nrf52840")] | ||
| 78 | define_peris!( | ||
| 79 | PIN_A = P1_02, PIN_B = P1_03, | ||
| 80 | PIN_X = P1_04, | ||
| 81 | UART0 = UARTE0, | ||
| 82 | UART1 = UARTE1, | ||
| 83 | SPIM0 = TWISPI0, | ||
| 84 | @irq UART0 = {UARTE0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 85 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 86 | @irq UART0_BUFFERED = {UARTE0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 87 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 88 | @irq SPIM0 = {TWISPI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 89 | ); | ||
| 90 | |||
| 91 | #[cfg(feature = "nrf5340")] | ||
| 92 | define_peris!( | ||
| 93 | PIN_A = P1_08, PIN_B = P1_09, | ||
| 94 | PIN_X = P1_10, | ||
| 95 | UART0 = SERIAL0, | ||
| 96 | UART1 = SERIAL1, | ||
| 97 | SPIM0 = SERIAL0, | ||
| 98 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 99 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 100 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 101 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 102 | @irq SPIM0 = {SERIAL0 => spim::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 103 | ); | ||
| 104 | |||
| 105 | #[cfg(feature = "nrf9160")] | ||
| 106 | define_peris!( | ||
| 107 | PIN_A = P0_00, PIN_B = P0_01, | ||
| 108 | PIN_X = P0_02, | ||
| 109 | UART0 = SERIAL0, | ||
| 110 | UART1 = SERIAL1, | ||
| 111 | SPIM0 = SERIAL0, | ||
| 112 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 113 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 114 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 115 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 116 | @irq SPIM0 = {SERIAL0 => spim::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 117 | ); | ||
diff --git a/tests/nrf51422/Cargo.toml b/tests/nrf51422/Cargo.toml deleted file mode 100644 index 8bfcc2922..000000000 --- a/tests/nrf51422/Cargo.toml +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf51-tests" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-128", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "gpiote"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embedded-hal-async = { version = "1.0" } | ||
| 17 | |||
| 18 | defmt = "0.3" | ||
| 19 | defmt-rtt = "0.4" | ||
| 20 | |||
| 21 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 22 | cortex-m-rt = "0.7.0" | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
diff --git a/tests/nrf51422/build.rs b/tests/nrf51422/build.rs deleted file mode 100644 index 13ebbe4ee..000000000 --- a/tests/nrf51422/build.rs +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | fs::write(out.join("memory.x"), include_bytes!("memory.x")).unwrap(); | ||
| 8 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 9 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 10 | |||
| 11 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 12 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 13 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 14 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 15 | |||
| 16 | Ok(()) | ||
| 17 | } | ||
diff --git a/tests/nrf51422/memory.x b/tests/nrf51422/memory.x deleted file mode 100644 index a5881e66f..000000000 --- a/tests/nrf51422/memory.x +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 16K | ||
| 5 | } | ||
diff --git a/tests/nrf52840/Cargo.toml b/tests/nrf52840/Cargo.toml deleted file mode 100644 index 1670b92ad..000000000 --- a/tests/nrf52840/Cargo.toml +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | ||
| 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | ||
| 18 | embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } | ||
| 19 | embedded-hal-async = { version = "1.0" } | ||
| 20 | embedded-hal-bus = { version = "0.1", features = ["async"] } | ||
| 21 | static_cell = "2" | ||
| 22 | perf-client = { path = "../perf-client" } | ||
| 23 | |||
| 24 | defmt = "0.3" | ||
| 25 | defmt-rtt = "0.4" | ||
| 26 | |||
| 27 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 28 | cortex-m-rt = "0.7.0" | ||
| 29 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 6ecc2d5e1..3756046fa 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml | |||
| @@ -1,10 +1,12 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "perf-client" | 2 | name = "perf-client" |
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2024" |
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 5 | 7 | ||
| 6 | [dependencies] | 8 | [dependencies] |
| 7 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } | 9 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } |
| 8 | embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", ] } | 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", ] } |
| 9 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 11 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 10 | defmt = "0.3.0" | 12 | defmt = "1.0.1" |
diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs index 54762379a..1ba071e8d 100644 --- a/tests/perf-client/src/lib.rs +++ b/tests/perf-client/src/lib.rs | |||
| @@ -2,10 +2,9 @@ | |||
| 2 | 2 | ||
| 3 | use defmt::{assert, *}; | 3 | use defmt::{assert, *}; |
| 4 | use embassy_futures::join::join; | 4 | use embassy_futures::join::join; |
| 5 | use embassy_net::driver::Driver; | ||
| 6 | use embassy_net::tcp::TcpSocket; | 5 | use embassy_net::tcp::TcpSocket; |
| 7 | use embassy_net::{Ipv4Address, Stack}; | 6 | use embassy_net::{Ipv4Address, Stack}; |
| 8 | use embassy_time::{with_timeout, Duration, Timer}; | 7 | use embassy_time::{Duration, Timer, with_timeout}; |
| 9 | 8 | ||
| 10 | pub struct Expected { | 9 | pub struct Expected { |
| 11 | pub down_kbps: usize, | 10 | pub down_kbps: usize, |
| @@ -13,7 +12,7 @@ pub struct Expected { | |||
| 13 | pub updown_kbps: usize, | 12 | pub updown_kbps: usize, |
| 14 | } | 13 | } |
| 15 | 14 | ||
| 16 | pub async fn run<D: Driver>(stack: &Stack<D>, expected: Expected) { | 15 | pub async fn run(stack: Stack<'_>, expected: Expected) { |
| 17 | info!("Waiting for DHCP up..."); | 16 | info!("Waiting for DHCP up..."); |
| 18 | while stack.config_v4().is_none() { | 17 | while stack.config_v4().is_none() { |
| 19 | Timer::after_millis(100).await; | 18 | Timer::after_millis(100).await; |
| @@ -38,7 +37,7 @@ const DOWNLOAD_PORT: u16 = 4321; | |||
| 38 | const UPLOAD_PORT: u16 = 4322; | 37 | const UPLOAD_PORT: u16 = 4322; |
| 39 | const UPLOAD_DOWNLOAD_PORT: u16 = 4323; | 38 | const UPLOAD_DOWNLOAD_PORT: u16 = 4323; |
| 40 | 39 | ||
| 41 | async fn test_download<D: Driver>(stack: &Stack<D>) -> usize { | 40 | async fn test_download(stack: Stack<'_>) -> usize { |
| 42 | info!("Testing download..."); | 41 | info!("Testing download..."); |
| 43 | 42 | ||
| 44 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 43 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
| @@ -78,7 +77,7 @@ async fn test_download<D: Driver>(stack: &Stack<D>) -> usize { | |||
| 78 | kbps | 77 | kbps |
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize { | 80 | async fn test_upload(stack: Stack<'_>) -> usize { |
| 82 | info!("Testing upload..."); | 81 | info!("Testing upload..."); |
| 83 | 82 | ||
| 84 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 83 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
| @@ -118,7 +117,7 @@ async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize { | |||
| 118 | kbps | 117 | kbps |
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | async fn test_upload_download<D: Driver>(stack: &Stack<D>) -> usize { | 120 | async fn test_upload_download(stack: Stack<'_>) -> usize { |
| 122 | info!("Testing upload+download..."); | 121 | info!("Testing upload+download..."); |
| 123 | 122 | ||
| 124 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; | 123 | let mut rx_buffer = [0; RX_BUFFER_SIZE]; |
diff --git a/tests/perf-server/Cargo.toml b/tests/perf-server/Cargo.toml index 532039050..72f92ed8d 100644 --- a/tests/perf-server/Cargo.toml +++ b/tests/perf-server/Cargo.toml | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "perf-server" | 2 | name = "perf-server" |
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2024" |
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 5 | 7 | ||
| 6 | [dependencies] | 8 | [dependencies] |
| 7 | log = "0.4.17" | 9 | log = "0.4.17" |
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 4f1d3e5c6..935c6a2ee 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml | |||
| @@ -1,15 +1,16 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | edition = "2021" | 2 | edition = "2024" |
| 3 | name = "embassy-riscv-tests" | 3 | name = "embassy-riscv-tests" |
| 4 | version = "0.1.0" | 4 | version = "0.1.0" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | publish = false | ||
| 6 | 7 | ||
| 7 | [dependencies] | 8 | [dependencies] |
| 8 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } | 9 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } |
| 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } | 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync" } |
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } | 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } |
| 11 | embassy-time = { version = "0.3.1", path = "../../embassy-time" } | 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time" } |
| 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 13 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 13 | 14 | ||
| 14 | riscv-rt = "0.12.2" | 15 | riscv-rt = "0.12.2" |
| 15 | riscv = { version = "0.11.1", features = ["critical-section-single-hart"] } | 16 | riscv = { version = "0.11.1", features = ["critical-section-single-hart"] } |
| @@ -44,3 +45,8 @@ debug = false | |||
| 44 | debug-assertions = false | 45 | debug-assertions = false |
| 45 | opt-level = 0 | 46 | opt-level = 0 |
| 46 | overflow-checks = false | 47 | overflow-checks = false |
| 48 | |||
| 49 | [package.metadata.embassy] | ||
| 50 | build = [ | ||
| 51 | { target = "riscv32imac-unknown-none-elf" } | ||
| 52 | ] | ||
diff --git a/tests/rp/.cargo/config.toml b/tests/rp/.cargo/config.toml index de7bb0e56..649c15048 100644 --- a/tests/rp/.cargo/config.toml +++ b/tests/rp/.cargo/config.toml | |||
| @@ -5,18 +5,19 @@ | |||
| 5 | #build-std-features = ["panic_immediate_abort"] | 5 | #build-std-features = ["panic_immediate_abort"] |
| 6 | 6 | ||
| 7 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 7 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 8 | runner = "teleprobe client run" | 8 | #runner = "teleprobe client run" |
| 9 | #runner = "teleprobe local run --chip RP2040 --elf" | 9 | #runner = "teleprobe local run --chip RP2040 --elf" |
| 10 | runner = "teleprobe local run --chip RP235X --elf" | ||
| 10 | 11 | ||
| 11 | rustflags = [ | 12 | rustflags = [ |
| 12 | # Code-size optimizations. | 13 | # Code-size optimizations. |
| 13 | #"-Z", "trap-unreachable=no", | 14 | #"-Z", "trap-unreachable=no", |
| 14 | "-C", "inline-threshold=5", | ||
| 15 | "-C", "no-vectorize-loops", | 15 | "-C", "no-vectorize-loops", |
| 16 | ] | 16 | ] |
| 17 | 17 | ||
| 18 | [build] | 18 | [build] |
| 19 | target = "thumbv6m-none-eabi" | 19 | #target = "thumbv6m-none-eabi" |
| 20 | target = "thumbv8m.main-none-eabihf" | ||
| 20 | 21 | ||
| 21 | [env] | 22 | [env] |
| 22 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info" | 23 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info" |
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 45050ee0e..640e58f11 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -1,26 +1,32 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | edition = "2021" | 2 | edition = "2024" |
| 3 | name = "embassy-rp-tests" | 3 | name = "embassy-rp-tests" |
| 4 | version = "0.1.0" | 4 | version = "0.1.0" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | publish = false | ||
| 7 | |||
| 8 | [features] | ||
| 9 | rp2040 = ["embassy-rp/rp2040"] | ||
| 10 | rp235xa = ["embassy-rp/rp235xa"] | ||
| 11 | rp235xb = ["embassy-rp/rp235xb"] | ||
| 6 | 12 | ||
| 7 | [dependencies] | 13 | [dependencies] |
| 8 | teleprobe-meta = "1.1" | 14 | teleprobe-meta = "1.1" |
| 9 | 15 | ||
| 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } | 16 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 17 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 12 | embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", ] } | 18 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", ] } |
| 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } | 19 | embassy-rp = { version = "0.8.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 20 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 21 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } | 22 | embassy-net-wiznet = { version = "0.2.1", path = "../../embassy-net-wiznet", features = ["defmt"] } |
| 17 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal/"} | 23 | embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal/"} |
| 18 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } | 24 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } |
| 19 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } | 25 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } |
| 20 | perf-client = { path = "../perf-client" } | 26 | perf-client = { path = "../perf-client" } |
| 21 | 27 | ||
| 22 | defmt = "0.3.0" | 28 | defmt = "1.0.1" |
| 23 | defmt-rtt = "0.4" | 29 | defmt-rtt = "1.0.0" |
| 24 | 30 | ||
| 25 | cortex-m = { version = "0.7.6" } | 31 | cortex-m = { version = "0.7.6" } |
| 26 | cortex-m-rt = "0.7.0" | 32 | cortex-m-rt = "0.7.0" |
| @@ -28,14 +34,41 @@ embedded-hal = "0.2.6" | |||
| 28 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 34 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 29 | embedded-hal-async = { version = "1.0" } | 35 | embedded-hal-async = { version = "1.0" } |
| 30 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 36 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 31 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 37 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 32 | embedded-io-async = { version = "0.6.1" } | 38 | embedded-io-async = { version = "0.6.1" } |
| 33 | embedded-storage = { version = "0.3" } | 39 | embedded-storage = { version = "0.3" } |
| 34 | static_cell = "2" | 40 | static_cell = "2" |
| 35 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 41 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
| 36 | pio = "0.2" | 42 | |
| 37 | pio-proc = "0.2" | 43 | # bootsel not currently supported on 2350 |
| 38 | rand = { version = "0.8.5", default-features = false } | 44 | [[bin]] |
| 45 | name = "bootsel" | ||
| 46 | path = "src/bin/bootsel.rs" | ||
| 47 | required-features = [ "rp2040",] | ||
| 48 | |||
| 49 | # 2350 devboard isn't a W | ||
| 50 | [[bin]] | ||
| 51 | name = "cyw43-perf" | ||
| 52 | path = "src/bin/cyw43-perf.rs" | ||
| 53 | required-features = [ "rp2040",] | ||
| 54 | |||
| 55 | # Eth test only for the w5100s-evb-pico | ||
| 56 | [[bin]] | ||
| 57 | name = "ethernet_w5100s_perf" | ||
| 58 | path = "src/bin/ethernet_w5100s_perf.rs" | ||
| 59 | required-features = [ "rp2040",] | ||
| 60 | |||
| 61 | # Float intrinsics are only relevant for the 2040 | ||
| 62 | [[bin]] | ||
| 63 | name = "float" | ||
| 64 | path = "src/bin/float.rs" | ||
| 65 | required-features = [ "rp2040",] | ||
| 66 | |||
| 67 | # RTC is only available on RP2040 | ||
| 68 | [[bin]] | ||
| 69 | name = "rtc" | ||
| 70 | path = "src/bin/rtc.rs" | ||
| 71 | required-features = [ "rp2040",] | ||
| 39 | 72 | ||
| 40 | [profile.dev] | 73 | [profile.dev] |
| 41 | debug = 2 | 74 | debug = 2 |
| @@ -66,3 +99,9 @@ debug = false | |||
| 66 | debug-assertions = false | 99 | debug-assertions = false |
| 67 | opt-level = 0 | 100 | opt-level = 0 |
| 68 | overflow-checks = false | 101 | overflow-checks = false |
| 102 | |||
| 103 | [package.metadata.embassy] | ||
| 104 | build = [ | ||
| 105 | { target = "thumbv6m-none-eabi", features = ["rp2040"], artifact-dir = "out/tests/rpi-pico" }, | ||
| 106 | { target = "thumbv8m.main-none-eabihf", features = ["rp235xb"], artifact-dir = "out/tests/pimoroni-pico-plus-2" } | ||
| 107 | ] | ||
diff --git a/tests/rp/readme.md b/tests/rp/readme.md new file mode 100644 index 000000000..f8192a95a --- /dev/null +++ b/tests/rp/readme.md | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # Pico and Pico 2 Plus connections | ||
| 2 | |||
| 3 | GP0-GP1 | ||
| 4 | GP3-GP4 | ||
| 5 | GP6-GP9 | ||
| 6 | GP7-GP11 | ||
| 7 | GP18-GP20 with 10k pullup | ||
| 8 | GP19-GP21 with 10k pullup | ||
diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 29eda95bf..c2175bc03 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::*; | 8 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -20,14 +23,19 @@ async fn main(_spawner: Spawner) { | |||
| 20 | let _wifi_off = Output::new(p.PIN_25, Level::High); | 23 | let _wifi_off = Output::new(p.PIN_25, Level::High); |
| 21 | let mut adc = Adc::new(p.ADC, Irqs, Config::default()); | 24 | let mut adc = Adc::new(p.ADC, Irqs, Config::default()); |
| 22 | 25 | ||
| 26 | #[cfg(any(feature = "rp2040", feature = "rp235xa"))] | ||
| 27 | let (mut a, mut b, mut c, mut d) = (p.PIN_26, p.PIN_27, p.PIN_28, p.PIN_29); | ||
| 28 | #[cfg(feature = "rp235xb")] | ||
| 29 | let (mut a, mut b, mut c, mut d) = (p.PIN_44, p.PIN_45, p.PIN_46, p.PIN_47); | ||
| 30 | |||
| 23 | { | 31 | { |
| 24 | { | 32 | { |
| 25 | let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Down); | 33 | let mut p = Channel::new_pin(a.reborrow(), Pull::Down); |
| 26 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); | 34 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); |
| 27 | defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); | 35 | defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); |
| 28 | } | 36 | } |
| 29 | { | 37 | { |
| 30 | let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Up); | 38 | let mut p = Channel::new_pin(a.reborrow(), Pull::Up); |
| 31 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); | 39 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); |
| 32 | defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); | 40 | defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); |
| 33 | } | 41 | } |
| @@ -35,21 +43,21 @@ async fn main(_spawner: Spawner) { | |||
| 35 | // not bothering with async reads from now on | 43 | // not bothering with async reads from now on |
| 36 | { | 44 | { |
| 37 | { | 45 | { |
| 38 | let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Down); | 46 | let mut p = Channel::new_pin(b.reborrow(), Pull::Down); |
| 39 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); | 47 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); |
| 40 | } | 48 | } |
| 41 | { | 49 | { |
| 42 | let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Up); | 50 | let mut p = Channel::new_pin(b.reborrow(), Pull::Up); |
| 43 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); | 51 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); |
| 44 | } | 52 | } |
| 45 | } | 53 | } |
| 46 | { | 54 | { |
| 47 | { | 55 | { |
| 48 | let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Down); | 56 | let mut p = Channel::new_pin(c.reborrow(), Pull::Down); |
| 49 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); | 57 | defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); |
| 50 | } | 58 | } |
| 51 | { | 59 | { |
| 52 | let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Up); | 60 | let mut p = Channel::new_pin(c.reborrow(), Pull::Up); |
| 53 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); | 61 | defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); |
| 54 | } | 62 | } |
| 55 | } | 63 | } |
| @@ -57,15 +65,15 @@ async fn main(_spawner: Spawner) { | |||
| 57 | // gp29 is connected to vsys through a 200k/100k divider, | 65 | // gp29 is connected to vsys through a 200k/100k divider, |
| 58 | // adding pulls should change the value | 66 | // adding pulls should change the value |
| 59 | let low = { | 67 | let low = { |
| 60 | let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Down); | 68 | let mut p = Channel::new_pin(d.reborrow(), Pull::Down); |
| 61 | adc.blocking_read(&mut p).unwrap() | 69 | adc.blocking_read(&mut p).unwrap() |
| 62 | }; | 70 | }; |
| 63 | let none = { | 71 | let none = { |
| 64 | let mut p = Channel::new_pin(&mut p.PIN_29, Pull::None); | 72 | let mut p = Channel::new_pin(d.reborrow(), Pull::None); |
| 65 | adc.blocking_read(&mut p).unwrap() | 73 | adc.blocking_read(&mut p).unwrap() |
| 66 | }; | 74 | }; |
| 67 | let up = { | 75 | let up = { |
| 68 | let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Up); | 76 | let mut p = Channel::new_pin(d.reborrow(), Pull::Up); |
| 69 | adc.blocking_read(&mut p).unwrap() | 77 | adc.blocking_read(&mut p).unwrap() |
| 70 | }; | 78 | }; |
| 71 | defmt::assert!(low < none); | 79 | defmt::assert!(low < none); |
| @@ -73,7 +81,7 @@ async fn main(_spawner: Spawner) { | |||
| 73 | } | 81 | } |
| 74 | { | 82 | { |
| 75 | let temp = convert_to_celsius( | 83 | let temp = convert_to_celsius( |
| 76 | adc.read(&mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR)) | 84 | adc.read(&mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow())) |
| 77 | .await | 85 | .await |
| 78 | .unwrap(), | 86 | .unwrap(), |
| 79 | ); | 87 | ); |
| @@ -90,26 +98,26 @@ async fn main(_spawner: Spawner) { | |||
| 90 | let mut none = [0u8; 16]; | 98 | let mut none = [0u8; 16]; |
| 91 | let mut up = [Sample::default(); 16]; | 99 | let mut up = [Sample::default(); 16]; |
| 92 | adc.read_many( | 100 | adc.read_many( |
| 93 | &mut Channel::new_pin(&mut p.PIN_29, Pull::Down), | 101 | &mut Channel::new_pin(d.reborrow(), Pull::Down), |
| 94 | &mut low, | 102 | &mut low, |
| 95 | 1, | 103 | 1, |
| 96 | &mut p.DMA_CH0, | 104 | p.DMA_CH0.reborrow(), |
| 97 | ) | 105 | ) |
| 98 | .await | 106 | .await |
| 99 | .unwrap(); | 107 | .unwrap(); |
| 100 | adc.read_many( | 108 | adc.read_many( |
| 101 | &mut Channel::new_pin(&mut p.PIN_29, Pull::None), | 109 | &mut Channel::new_pin(d.reborrow(), Pull::None), |
| 102 | &mut none, | 110 | &mut none, |
| 103 | 1, | 111 | 1, |
| 104 | &mut p.DMA_CH0, | 112 | p.DMA_CH0.reborrow(), |
| 105 | ) | 113 | ) |
| 106 | .await | 114 | .await |
| 107 | .unwrap(); | 115 | .unwrap(); |
| 108 | adc.read_many_raw( | 116 | adc.read_many_raw( |
| 109 | &mut Channel::new_pin(&mut p.PIN_29, Pull::Up), | 117 | &mut Channel::new_pin(d.reborrow(), Pull::Up), |
| 110 | &mut up, | 118 | &mut up, |
| 111 | 1, | 119 | 1, |
| 112 | &mut p.DMA_CH0, | 120 | p.DMA_CH0.reborrow(), |
| 113 | ) | 121 | ) |
| 114 | .await; | 122 | .await; |
| 115 | defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); | 123 | defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); |
| @@ -119,10 +127,10 @@ async fn main(_spawner: Spawner) { | |||
| 119 | { | 127 | { |
| 120 | let mut temp = [0u16; 16]; | 128 | let mut temp = [0u16; 16]; |
| 121 | adc.read_many( | 129 | adc.read_many( |
| 122 | &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), | 130 | &mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()), |
| 123 | &mut temp, | 131 | &mut temp, |
| 124 | 1, | 132 | 1, |
| 125 | &mut p.DMA_CH0, | 133 | p.DMA_CH0.reborrow(), |
| 126 | ) | 134 | ) |
| 127 | .await | 135 | .await |
| 128 | .unwrap(); | 136 | .unwrap(); |
| @@ -130,6 +138,19 @@ async fn main(_spawner: Spawner) { | |||
| 130 | defmt::assert!(temp.iter().all(|t| *t > 0.0)); | 138 | defmt::assert!(temp.iter().all(|t| *t > 0.0)); |
| 131 | defmt::assert!(temp.iter().all(|t| *t < 60.0)); | 139 | defmt::assert!(temp.iter().all(|t| *t < 60.0)); |
| 132 | } | 140 | } |
| 141 | { | ||
| 142 | let mut multi = [0u16; 2]; | ||
| 143 | let mut channels = [ | ||
| 144 | Channel::new_pin(a.reborrow(), Pull::Up), | ||
| 145 | Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()), | ||
| 146 | ]; | ||
| 147 | adc.read_many_multichannel(&mut channels, &mut multi, 1, p.DMA_CH0.reborrow()) | ||
| 148 | .await | ||
| 149 | .unwrap(); | ||
| 150 | defmt::assert!(multi[0] > 3_000); | ||
| 151 | let temp = convert_to_celsius(multi[1]); | ||
| 152 | defmt::assert!(temp > 0.0 && temp < 60.0); | ||
| 153 | } | ||
| 133 | 154 | ||
| 134 | info!("Test OK"); | 155 | info!("Test OK"); |
| 135 | cortex_m::asm::bkpt(); | 156 | cortex_m::asm::bkpt(); |
diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs index e88d8bf6c..aa123ab03 100644 --- a/tests/rp/src/bin/bootsel.rs +++ b/tests/rp/src/bin/bootsel.rs | |||
| @@ -4,12 +4,13 @@ teleprobe_meta::target!(b"rpi-pico"); | |||
| 4 | 4 | ||
| 5 | use defmt::{assert_eq, *}; | 5 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::bootsel::is_bootsel_pressed; | ||
| 7 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 10 | ||
| 10 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 11 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 12 | let mut p = embassy_rp::init(Default::default()); | 13 | let p = embassy_rp::init(Default::default()); |
| 13 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 14 | 15 | ||
| 15 | // add some delay to give an attached debug probe time to parse the | 16 | // add some delay to give an attached debug probe time to parse the |
| @@ -18,7 +19,7 @@ async fn main(_spawner: Spawner) { | |||
| 18 | // https://github.com/knurling-rs/defmt/pull/683 | 19 | // https://github.com/knurling-rs/defmt/pull/683 |
| 19 | Timer::after_millis(10).await; | 20 | Timer::after_millis(10).await; |
| 20 | 21 | ||
| 21 | assert_eq!(p.BOOTSEL.is_pressed(), false); | 22 | assert_eq!(is_bootsel_pressed(p.BOOTSEL), false); |
| 22 | 23 | ||
| 23 | info!("Test OK"); | 24 | info!("Test OK"); |
| 24 | cortex_m::asm::bkpt(); | 25 | cortex_m::asm::bkpt(); |
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index 4b0c7f7b9..9487f5e1a 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs | |||
| @@ -2,10 +2,11 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use cyw43_pio::PioSpi; | 5 | use cyw43::JoinOptions; |
| 6 | use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; | ||
| 6 | use defmt::{panic, *}; | 7 | use defmt::{panic, *}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Config, Stack, StackResources}; | 9 | use embassy_net::{Config, StackResources}; |
| 9 | use embassy_rp::gpio::{Level, Output}; | 10 | use embassy_rp::gpio::{Level, Output}; |
| 10 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; | 11 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 11 | use embassy_rp::pio::{InterruptHandler, Pio}; | 12 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| @@ -20,7 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 20 | teleprobe_meta::timeout!(120); | 21 | teleprobe_meta::timeout!(120); |
| 21 | 22 | ||
| 22 | // Test-only wifi network, no internet access! | 23 | // Test-only wifi network, no internet access! |
| 23 | const WIFI_NETWORK: &str = "EmbassyTest"; | 24 | const WIFI_NETWORK: &str = "EmbassyTestWPA2"; |
| 24 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | 25 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; |
| 25 | 26 | ||
| 26 | #[embassy_executor::task] | 27 | #[embassy_executor::task] |
| @@ -29,8 +30,8 @@ async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stati | |||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | #[embassy_executor::task] | 32 | #[embassy_executor::task] |
| 32 | async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! { | 33 | async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! { |
| 33 | stack.run().await | 34 | runner.run().await |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | #[embassy_executor::main] | 37 | #[embassy_executor::main] |
| @@ -45,20 +46,31 @@ async fn main(spawner: Spawner) { | |||
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | // cyw43 firmware needs to be flashed manually: | 48 | // cyw43 firmware needs to be flashed manually: |
| 48 | // probe-rs download 43439A0.bin ---binary-format --chip RP2040 --base-address 0x101b0000 | 49 | // probe-rs download 43439A0.bin --binary-format bin --chip RP2040 --base-address 0x101b0000 |
| 49 | // probe-rs download 43439A0_clm.bin ---binary-format --chip RP2040 --base-address 0x101f8000 | 50 | // probe-rs download 43439A0_btfw.bin --binary-format bin --chip RP2040 --base-address 0x101f0000 |
| 50 | let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 230321) }; | 51 | // probe-rs download 43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x101f8000 |
| 51 | let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; | 52 | let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 231077) }; |
| 53 | let _btfw = unsafe { core::slice::from_raw_parts(0x101f0000 as *const u8, 6164) }; | ||
| 54 | let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 984) }; | ||
| 52 | 55 | ||
| 53 | let pwr = Output::new(p.PIN_23, Level::Low); | 56 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 54 | let cs = Output::new(p.PIN_25, Level::High); | 57 | let cs = Output::new(p.PIN_25, Level::High); |
| 55 | let mut pio = Pio::new(p.PIO0, Irqs); | 58 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 56 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 59 | let spi = PioSpi::new( |
| 60 | &mut pio.common, | ||
| 61 | pio.sm0, | ||
| 62 | DEFAULT_CLOCK_DIVIDER, | ||
| 63 | pio.irq0, | ||
| 64 | cs, | ||
| 65 | p.PIN_24, | ||
| 66 | p.PIN_29, | ||
| 67 | p.DMA_CH0, | ||
| 68 | ); | ||
| 57 | 69 | ||
| 58 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 70 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 59 | let state = STATE.init(cyw43::State::new()); | 71 | let state = STATE.init(cyw43::State::new()); |
| 60 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 72 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 61 | unwrap!(spawner.spawn(wifi_task(runner))); | 73 | spawner.spawn(unwrap!(wifi_task(runner))); |
| 62 | 74 | ||
| 63 | control.init(clm).await; | 75 | control.init(clm).await; |
| 64 | control | 76 | control |
| @@ -69,19 +81,21 @@ async fn main(spawner: Spawner) { | |||
| 69 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | 81 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |
| 70 | 82 | ||
| 71 | // Init network stack | 83 | // Init network stack |
| 72 | static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); | ||
| 73 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 84 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 74 | let stack = &*STACK.init(Stack::new( | 85 | let (stack, runner) = embassy_net::new( |
| 75 | net_device, | 86 | net_device, |
| 76 | Config::dhcpv4(Default::default()), | 87 | Config::dhcpv4(Default::default()), |
| 77 | RESOURCES.init(StackResources::<2>::new()), | 88 | RESOURCES.init(StackResources::new()), |
| 78 | seed, | 89 | seed, |
| 79 | )); | 90 | ); |
| 80 | 91 | ||
| 81 | unwrap!(spawner.spawn(net_task(stack))); | 92 | spawner.spawn(unwrap!(net_task(runner))); |
| 82 | 93 | ||
| 83 | loop { | 94 | loop { |
| 84 | match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { | 95 | match control |
| 96 | .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) | ||
| 97 | .await | ||
| 98 | { | ||
| 85 | Ok(_) => break, | 99 | Ok(_) => break, |
| 86 | Err(err) => { | 100 | Err(err) => { |
| 87 | panic!("join failed with status={}", err.status); | 101 | panic!("join failed with status={}", err.status); |
| @@ -92,9 +106,9 @@ async fn main(spawner: Spawner) { | |||
| 92 | perf_client::run( | 106 | perf_client::run( |
| 93 | stack, | 107 | stack, |
| 94 | perf_client::Expected { | 108 | perf_client::Expected { |
| 95 | down_kbps: 300, | 109 | down_kbps: 200, |
| 96 | up_kbps: 300, | 110 | up_kbps: 200, |
| 97 | updown_kbps: 300, | 111 | updown_kbps: 200, |
| 98 | }, | 112 | }, |
| 99 | ) | 113 | ) |
| 100 | .await; | 114 | .await; |
diff --git a/tests/rp/src/bin/dma_copy_async.rs b/tests/rp/src/bin/dma_copy_async.rs index 7c64bc396..3dcf4f4d8 100644 --- a/tests/rp/src/bin/dma_copy_async.rs +++ b/tests/rp/src/bin/dma_copy_async.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs index 5d5547773..3f2bc728d 100644 --- a/tests/rp/src/bin/ethernet_w5100s_perf.rs +++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs | |||
| @@ -5,7 +5,7 @@ teleprobe_meta::timeout!(120); | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_net::{Stack, StackResources}; | 8 | use embassy_net::StackResources; |
| 9 | use embassy_net_wiznet::chip::W5100S; | 9 | use embassy_net_wiznet::chip::W5100S; |
| 10 | use embassy_net_wiznet::*; | 10 | use embassy_net_wiznet::*; |
| 11 | use embassy_rp::clocks::RoscRng; | 11 | use embassy_rp::clocks::RoscRng; |
| @@ -14,7 +14,6 @@ use embassy_rp::peripherals::SPI0; | |||
| 14 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 14 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 15 | use embassy_time::Delay; | 15 | use embassy_time::Delay; |
| 16 | use embedded_hal_bus::spi::ExclusiveDevice; | 16 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 17 | use rand::RngCore; | ||
| 18 | use static_cell::StaticCell; | 17 | use static_cell::StaticCell; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | 19 | ||
| @@ -32,8 +31,8 @@ async fn ethernet_task( | |||
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | #[embassy_executor::task] | 33 | #[embassy_executor::task] |
| 35 | async fn net_task(stack: &'static Stack<Device<'static>>) -> ! { | 34 | async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! { |
| 36 | stack.run().await | 35 | runner.run().await |
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | #[embassy_executor::main] | 38 | #[embassy_executor::main] |
| @@ -59,24 +58,24 @@ async fn main(spawner: Spawner) { | |||
| 59 | w5500_int, | 58 | w5500_int, |
| 60 | w5500_reset, | 59 | w5500_reset, |
| 61 | ) | 60 | ) |
| 62 | .await; | 61 | .await |
| 63 | unwrap!(spawner.spawn(ethernet_task(runner))); | 62 | .unwrap(); |
| 63 | spawner.spawn(unwrap!(ethernet_task(runner))); | ||
| 64 | 64 | ||
| 65 | // Generate random seed | 65 | // Generate random seed |
| 66 | let seed = rng.next_u64(); | 66 | let seed = rng.next_u64(); |
| 67 | 67 | ||
| 68 | // Init network stack | 68 | // Init network stack |
| 69 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||
| 70 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 69 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 71 | let stack = &*STACK.init(Stack::new( | 70 | let (stack, runner) = embassy_net::new( |
| 72 | device, | 71 | device, |
| 73 | embassy_net::Config::dhcpv4(Default::default()), | 72 | embassy_net::Config::dhcpv4(Default::default()), |
| 74 | RESOURCES.init(StackResources::<2>::new()), | 73 | RESOURCES.init(StackResources::new()), |
| 75 | seed, | 74 | seed, |
| 76 | )); | 75 | ); |
| 77 | 76 | ||
| 78 | // Launch network task | 77 | // Launch network task |
| 79 | unwrap!(spawner.spawn(net_task(&stack))); | 78 | spawner.spawn(unwrap!(net_task(runner))); |
| 80 | 79 | ||
| 81 | perf_client::run( | 80 | perf_client::run( |
| 82 | stack, | 81 | stack, |
diff --git a/tests/rp/src/bin/flash.rs b/tests/rp/src/bin/flash.rs index 310f0d586..548a6ee72 100644 --- a/tests/rp/src/bin/flash.rs +++ b/tests/rp/src/bin/flash.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::*; | 8 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -24,13 +27,19 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); | 27 | let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); |
| 25 | 28 | ||
| 26 | // Get JEDEC id | 29 | // Get JEDEC id |
| 27 | let jedec = defmt::unwrap!(flash.blocking_jedec_id()); | 30 | #[cfg(feature = "rp2040")] |
| 28 | info!("jedec id: 0x{:x}", jedec); | 31 | { |
| 32 | let jedec = defmt::unwrap!(flash.blocking_jedec_id()); | ||
| 33 | info!("jedec id: 0x{:x}", jedec); | ||
| 34 | } | ||
| 29 | 35 | ||
| 30 | // Get unique id | 36 | // Get unique id |
| 31 | let mut uid = [0; 8]; | 37 | #[cfg(feature = "rp2040")] |
| 32 | defmt::unwrap!(flash.blocking_unique_id(&mut uid)); | 38 | { |
| 33 | info!("unique id: {:?}", uid); | 39 | let mut uid = [0; 8]; |
| 40 | defmt::unwrap!(flash.blocking_unique_id(&mut uid)); | ||
| 41 | info!("unique id: {:?}", uid); | ||
| 42 | } | ||
| 34 | 43 | ||
| 35 | let mut buf = [0u8; ERASE_SIZE]; | 44 | let mut buf = [0u8; ERASE_SIZE]; |
| 36 | defmt::unwrap!(flash.blocking_read(ADDR_OFFSET, &mut buf)); | 45 | defmt::unwrap!(flash.blocking_read(ADDR_OFFSET, &mut buf)); |
diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs index e0c309887..8bd0df8d8 100644 --- a/tests/rp/src/bin/gpio.rs +++ b/tests/rp/src/bin/gpio.rs | |||
| @@ -1,10 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert, *}; | 8 | use defmt::{assert, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull}; | 10 | #[cfg(feature = "rp2040")] |
| 11 | use embassy_rp::gpio::OutputOpenDrain; | ||
| 12 | use embassy_rp::gpio::{Flex, Input, Level, Output, Pull}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 14 | ||
| 10 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| @@ -16,10 +21,10 @@ async fn main(_spawner: Spawner) { | |||
| 16 | 21 | ||
| 17 | // Test initial output | 22 | // Test initial output |
| 18 | { | 23 | { |
| 19 | let b = Input::new(&mut b, Pull::None); | 24 | let b = Input::new(b.reborrow(), Pull::None); |
| 20 | 25 | ||
| 21 | { | 26 | { |
| 22 | let a = Output::new(&mut a, Level::Low); | 27 | let a = Output::new(a.reborrow(), Level::Low); |
| 23 | delay(); | 28 | delay(); |
| 24 | assert!(b.is_low()); | 29 | assert!(b.is_low()); |
| 25 | assert!(!b.is_high()); | 30 | assert!(!b.is_high()); |
| @@ -27,7 +32,7 @@ async fn main(_spawner: Spawner) { | |||
| 27 | assert!(!a.is_set_high()); | 32 | assert!(!a.is_set_high()); |
| 28 | } | 33 | } |
| 29 | { | 34 | { |
| 30 | let mut a = Output::new(&mut a, Level::High); | 35 | let mut a = Output::new(a.reborrow(), Level::High); |
| 31 | delay(); | 36 | delay(); |
| 32 | assert!(!b.is_low()); | 37 | assert!(!b.is_low()); |
| 33 | assert!(b.is_high()); | 38 | assert!(b.is_high()); |
| @@ -62,12 +67,46 @@ async fn main(_spawner: Spawner) { | |||
| 62 | } | 67 | } |
| 63 | } | 68 | } |
| 64 | 69 | ||
| 70 | // Test input inversion | ||
| 71 | { | ||
| 72 | let mut b = Input::new(b.reborrow(), Pull::None); | ||
| 73 | b.set_inversion(true); | ||
| 74 | // no pull, the status is undefined | ||
| 75 | |||
| 76 | let mut a = Output::new(a.reborrow(), Level::Low); | ||
| 77 | delay(); | ||
| 78 | assert!(b.is_high()); | ||
| 79 | a.set_high(); | ||
| 80 | delay(); | ||
| 81 | assert!(b.is_low()); | ||
| 82 | |||
| 83 | b.set_inversion(false); | ||
| 84 | a.set_inversion(true); | ||
| 85 | |||
| 86 | a.set_low(); | ||
| 87 | delay(); | ||
| 88 | assert!(b.is_high()); | ||
| 89 | |||
| 90 | a.set_high(); | ||
| 91 | delay(); | ||
| 92 | assert!(b.is_low()); | ||
| 93 | |||
| 94 | b.set_inversion(true); | ||
| 95 | a.set_high(); | ||
| 96 | delay(); | ||
| 97 | assert!(b.is_high()); | ||
| 98 | |||
| 99 | a.set_high(); | ||
| 100 | delay(); | ||
| 101 | assert!(b.is_high()); | ||
| 102 | } | ||
| 103 | |||
| 65 | // Test input no pull | 104 | // Test input no pull |
| 66 | { | 105 | { |
| 67 | let b = Input::new(&mut b, Pull::None); | 106 | let b = Input::new(b.reborrow(), Pull::None); |
| 68 | // no pull, the status is undefined | 107 | // no pull, the status is undefined |
| 69 | 108 | ||
| 70 | let mut a = Output::new(&mut a, Level::Low); | 109 | let mut a = Output::new(a.reborrow(), Level::Low); |
| 71 | delay(); | 110 | delay(); |
| 72 | assert!(b.is_low()); | 111 | assert!(b.is_low()); |
| 73 | a.set_high(); | 112 | a.set_high(); |
| @@ -76,12 +115,13 @@ async fn main(_spawner: Spawner) { | |||
| 76 | } | 115 | } |
| 77 | 116 | ||
| 78 | // Test input pulldown | 117 | // Test input pulldown |
| 118 | #[cfg(feature = "rp2040")] | ||
| 79 | { | 119 | { |
| 80 | let b = Input::new(&mut b, Pull::Down); | 120 | let b = Input::new(b.reborrow(), Pull::Down); |
| 81 | delay(); | 121 | delay(); |
| 82 | assert!(b.is_low()); | 122 | assert!(b.is_low()); |
| 83 | 123 | ||
| 84 | let mut a = Output::new(&mut a, Level::Low); | 124 | let mut a = Output::new(a.reborrow(), Level::Low); |
| 85 | delay(); | 125 | delay(); |
| 86 | assert!(b.is_low()); | 126 | assert!(b.is_low()); |
| 87 | a.set_high(); | 127 | a.set_high(); |
| @@ -91,11 +131,11 @@ async fn main(_spawner: Spawner) { | |||
| 91 | 131 | ||
| 92 | // Test input pullup | 132 | // Test input pullup |
| 93 | { | 133 | { |
| 94 | let b = Input::new(&mut b, Pull::Up); | 134 | let b = Input::new(b.reborrow(), Pull::Up); |
| 95 | delay(); | 135 | delay(); |
| 96 | assert!(b.is_high()); | 136 | assert!(b.is_high()); |
| 97 | 137 | ||
| 98 | let mut a = Output::new(&mut a, Level::Low); | 138 | let mut a = Output::new(a.reborrow(), Level::Low); |
| 99 | delay(); | 139 | delay(); |
| 100 | assert!(b.is_low()); | 140 | assert!(b.is_low()); |
| 101 | a.set_high(); | 141 | a.set_high(); |
| @@ -104,9 +144,10 @@ async fn main(_spawner: Spawner) { | |||
| 104 | } | 144 | } |
| 105 | 145 | ||
| 106 | // OUTPUT OPEN DRAIN | 146 | // OUTPUT OPEN DRAIN |
| 147 | #[cfg(feature = "rp2040")] | ||
| 107 | { | 148 | { |
| 108 | let mut b = OutputOpenDrain::new(&mut b, Level::High); | 149 | let mut b = OutputOpenDrain::new(b.reborrow(), Level::High); |
| 109 | let mut a = Flex::new(&mut a); | 150 | let mut a = Flex::new(a.reborrow()); |
| 110 | a.set_as_input(); | 151 | a.set_as_input(); |
| 111 | 152 | ||
| 112 | // When an OutputOpenDrain is high, it doesn't drive the pin. | 153 | // When an OutputOpenDrain is high, it doesn't drive the pin. |
| @@ -163,12 +204,12 @@ async fn main(_spawner: Spawner) { | |||
| 163 | // Test initial output | 204 | // Test initial output |
| 164 | { | 205 | { |
| 165 | //Flex pin configured as input | 206 | //Flex pin configured as input |
| 166 | let mut b = Flex::new(&mut b); | 207 | let mut b = Flex::new(b.reborrow()); |
| 167 | b.set_as_input(); | 208 | b.set_as_input(); |
| 168 | 209 | ||
| 169 | { | 210 | { |
| 170 | //Flex pin configured as output | 211 | //Flex pin configured as output |
| 171 | let mut a = Flex::new(&mut a); //Flex pin configured as output | 212 | let mut a = Flex::new(a.reborrow()); //Flex pin configured as output |
| 172 | a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state | 213 | a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state |
| 173 | a.set_as_output(); | 214 | a.set_as_output(); |
| 174 | delay(); | 215 | delay(); |
| @@ -176,7 +217,7 @@ async fn main(_spawner: Spawner) { | |||
| 176 | } | 217 | } |
| 177 | { | 218 | { |
| 178 | //Flex pin configured as output | 219 | //Flex pin configured as output |
| 179 | let mut a = Flex::new(&mut a); | 220 | let mut a = Flex::new(a.reborrow()); |
| 180 | a.set_high(); | 221 | a.set_high(); |
| 181 | a.set_as_output(); | 222 | a.set_as_output(); |
| 182 | 223 | ||
| @@ -187,10 +228,10 @@ async fn main(_spawner: Spawner) { | |||
| 187 | 228 | ||
| 188 | // Test input no pull | 229 | // Test input no pull |
| 189 | { | 230 | { |
| 190 | let mut b = Flex::new(&mut b); | 231 | let mut b = Flex::new(b.reborrow()); |
| 191 | b.set_as_input(); // no pull by default. | 232 | b.set_as_input(); // no pull by default. |
| 192 | 233 | ||
| 193 | let mut a = Flex::new(&mut a); | 234 | let mut a = Flex::new(a.reborrow()); |
| 194 | a.set_low(); | 235 | a.set_low(); |
| 195 | a.set_as_output(); | 236 | a.set_as_output(); |
| 196 | 237 | ||
| @@ -202,14 +243,15 @@ async fn main(_spawner: Spawner) { | |||
| 202 | } | 243 | } |
| 203 | 244 | ||
| 204 | // Test input pulldown | 245 | // Test input pulldown |
| 246 | #[cfg(feature = "rp2040")] | ||
| 205 | { | 247 | { |
| 206 | let mut b = Flex::new(&mut b); | 248 | let mut b = Flex::new(b.reborrow()); |
| 207 | b.set_as_input(); | 249 | b.set_as_input(); |
| 208 | b.set_pull(Pull::Down); | 250 | b.set_pull(Pull::Down); |
| 209 | delay(); | 251 | delay(); |
| 210 | assert!(b.is_low()); | 252 | assert!(b.is_low()); |
| 211 | 253 | ||
| 212 | let mut a = Flex::new(&mut a); | 254 | let mut a = Flex::new(a.reborrow()); |
| 213 | a.set_low(); | 255 | a.set_low(); |
| 214 | a.set_as_output(); | 256 | a.set_as_output(); |
| 215 | delay(); | 257 | delay(); |
| @@ -221,13 +263,13 @@ async fn main(_spawner: Spawner) { | |||
| 221 | 263 | ||
| 222 | // Test input pullup | 264 | // Test input pullup |
| 223 | { | 265 | { |
| 224 | let mut b = Flex::new(&mut b); | 266 | let mut b = Flex::new(b.reborrow()); |
| 225 | b.set_as_input(); | 267 | b.set_as_input(); |
| 226 | b.set_pull(Pull::Up); | 268 | b.set_pull(Pull::Up); |
| 227 | delay(); | 269 | delay(); |
| 228 | assert!(b.is_high()); | 270 | assert!(b.is_high()); |
| 229 | 271 | ||
| 230 | let mut a = Flex::new(&mut a); | 272 | let mut a = Flex::new(a.reborrow()); |
| 231 | a.set_high(); | 273 | a.set_high(); |
| 232 | a.set_as_output(); | 274 | a.set_as_output(); |
| 233 | delay(); | 275 | delay(); |
diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs index 40a304464..72fb0910d 100644 --- a/tests/rp/src/bin/gpio_async.rs +++ b/tests/rp/src/bin/gpio_async.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert, *}; | 8 | use defmt::{assert, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -19,8 +22,8 @@ async fn main(_spawner: Spawner) { | |||
| 19 | 22 | ||
| 20 | { | 23 | { |
| 21 | info!("test wait_for_high"); | 24 | info!("test wait_for_high"); |
| 22 | let mut output = Output::new(&mut output_pin, Level::Low); | 25 | let mut output = Output::new(output_pin.reborrow(), Level::Low); |
| 23 | let mut input = Input::new(&mut input_pin, Pull::None); | 26 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 24 | 27 | ||
| 25 | assert!(input.is_low(), "input was expected to be low"); | 28 | assert!(input.is_low(), "input was expected to be low"); |
| 26 | 29 | ||
| @@ -40,8 +43,8 @@ async fn main(_spawner: Spawner) { | |||
| 40 | 43 | ||
| 41 | { | 44 | { |
| 42 | info!("test wait_for_low"); | 45 | info!("test wait_for_low"); |
| 43 | let mut output = Output::new(&mut output_pin, Level::High); | 46 | let mut output = Output::new(output_pin.reborrow(), Level::High); |
| 44 | let mut input = Input::new(&mut input_pin, Pull::None); | 47 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 45 | 48 | ||
| 46 | assert!(input.is_high(), "input was expected to be high"); | 49 | assert!(input.is_high(), "input was expected to be high"); |
| 47 | 50 | ||
| @@ -60,8 +63,8 @@ async fn main(_spawner: Spawner) { | |||
| 60 | 63 | ||
| 61 | { | 64 | { |
| 62 | info!("test wait_for_rising_edge"); | 65 | info!("test wait_for_rising_edge"); |
| 63 | let mut output = Output::new(&mut output_pin, Level::Low); | 66 | let mut output = Output::new(output_pin.reborrow(), Level::Low); |
| 64 | let mut input = Input::new(&mut input_pin, Pull::None); | 67 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 65 | 68 | ||
| 66 | assert!(input.is_low(), "input was expected to be low"); | 69 | assert!(input.is_low(), "input was expected to be low"); |
| 67 | 70 | ||
| @@ -80,8 +83,8 @@ async fn main(_spawner: Spawner) { | |||
| 80 | 83 | ||
| 81 | { | 84 | { |
| 82 | info!("test wait_for_falling_edge"); | 85 | info!("test wait_for_falling_edge"); |
| 83 | let mut output = Output::new(&mut output_pin, Level::High); | 86 | let mut output = Output::new(output_pin.reborrow(), Level::High); |
| 84 | let mut input = Input::new(&mut input_pin, Pull::None); | 87 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 85 | 88 | ||
| 86 | assert!(input.is_high(), "input was expected to be high"); | 89 | assert!(input.is_high(), "input was expected to be high"); |
| 87 | 90 | ||
| @@ -100,8 +103,8 @@ async fn main(_spawner: Spawner) { | |||
| 100 | 103 | ||
| 101 | { | 104 | { |
| 102 | info!("test wait_for_any_edge (falling)"); | 105 | info!("test wait_for_any_edge (falling)"); |
| 103 | let mut output = Output::new(&mut output_pin, Level::High); | 106 | let mut output = Output::new(output_pin.reborrow(), Level::High); |
| 104 | let mut input = Input::new(&mut input_pin, Pull::None); | 107 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 105 | 108 | ||
| 106 | assert!(input.is_high(), "input was expected to be high"); | 109 | assert!(input.is_high(), "input was expected to be high"); |
| 107 | 110 | ||
| @@ -120,8 +123,8 @@ async fn main(_spawner: Spawner) { | |||
| 120 | 123 | ||
| 121 | { | 124 | { |
| 122 | info!("test wait_for_any_edge (rising)"); | 125 | info!("test wait_for_any_edge (rising)"); |
| 123 | let mut output = Output::new(&mut output_pin, Level::Low); | 126 | let mut output = Output::new(output_pin.reborrow(), Level::Low); |
| 124 | let mut input = Input::new(&mut input_pin, Pull::None); | 127 | let mut input = Input::new(input_pin.reborrow(), Pull::None); |
| 125 | 128 | ||
| 126 | assert!(input.is_low(), "input was expected to be low"); | 129 | assert!(input.is_low(), "input was expected to be low"); |
| 127 | 130 | ||
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index e9c6f3122..6abcba590 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{info, unwrap}; | 8 | use defmt::{info, unwrap}; |
| 6 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 10 | use embassy_rp::Peri; | ||
| 7 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 11 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 8 | use embassy_rp::multicore::{spawn_core1, Stack}; | 12 | use embassy_rp::multicore::{Stack, spawn_core1}; |
| 9 | use embassy_rp::peripherals::{PIN_0, PIN_1}; | 13 | use embassy_rp::peripherals::{PIN_0, PIN_1}; |
| 10 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 14 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 11 | use embassy_sync::channel::Channel; | 15 | use embassy_sync::channel::Channel; |
| @@ -26,15 +30,15 @@ fn main() -> ! { | |||
| 26 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | 30 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 27 | move || { | 31 | move || { |
| 28 | let executor1 = EXECUTOR1.init(Executor::new()); | 32 | let executor1 = EXECUTOR1.init(Executor::new()); |
| 29 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); | 33 | executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(p.PIN_1)))); |
| 30 | }, | 34 | }, |
| 31 | ); | 35 | ); |
| 32 | let executor0 = EXECUTOR0.init(Executor::new()); | 36 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 33 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); | 37 | executor0.run(|spawner| spawner.spawn(unwrap!(core0_task(p.PIN_0)))); |
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | #[embassy_executor::task] | 40 | #[embassy_executor::task] |
| 37 | async fn core0_task(p: PIN_0) { | 41 | async fn core0_task(p: Peri<'static, PIN_0>) { |
| 38 | info!("CORE0 is running"); | 42 | info!("CORE0 is running"); |
| 39 | 43 | ||
| 40 | let mut pin = Output::new(p, Level::Low); | 44 | let mut pin = Output::new(p, Level::Low); |
| @@ -51,12 +55,12 @@ async fn core0_task(p: PIN_0) { | |||
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | #[embassy_executor::task] | 57 | #[embassy_executor::task] |
| 54 | async fn core1_task(p: PIN_1) { | 58 | async fn core1_task(p: Peri<'static, PIN_1>) { |
| 55 | info!("CORE1 is running"); | 59 | info!("CORE1 is running"); |
| 56 | 60 | ||
| 57 | CHANNEL0.receive().await; | 61 | CHANNEL0.receive().await; |
| 58 | 62 | ||
| 59 | let mut pin = Input::new(p, Pull::Down); | 63 | let mut pin = Input::new(p, Pull::None); |
| 60 | let wait = pin.wait_for_rising_edge(); | 64 | let wait = pin.wait_for_rising_edge(); |
| 61 | 65 | ||
| 62 | CHANNEL1.send(()).await; | 66 | CHANNEL1.send(()).await; |
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs index 9615007bd..21761b98b 100644 --- a/tests/rp/src/bin/i2c.rs +++ b/tests/rp/src/bin/i2c.rs | |||
| @@ -1,23 +1,21 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, info, panic, unwrap}; | 8 | use defmt::{assert_eq, info, panic}; |
| 6 | use embassy_embedded_hal::SetConfig; | 9 | use embassy_embedded_hal::SetConfig; |
| 7 | use embassy_executor::{Executor, Spawner}; | 10 | use embassy_executor::Spawner; |
| 8 | use embassy_rp::clocks::{PllConfig, XoscConfig}; | 11 | use embassy_rp::clocks::{PllConfig, XoscConfig}; |
| 9 | use embassy_rp::config::Config as rpConfig; | 12 | use embassy_rp::config::Config as rpConfig; |
| 10 | use embassy_rp::multicore::{spawn_core1, Stack}; | ||
| 11 | use embassy_rp::peripherals::{I2C0, I2C1}; | 13 | use embassy_rp::peripherals::{I2C0, I2C1}; |
| 12 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; | 14 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; |
| 13 | use embedded_hal_1::i2c::Operation; | 15 | use embedded_hal_1::i2c::Operation; |
| 14 | use embedded_hal_async::i2c::I2c; | 16 | use embedded_hal_async::i2c::I2c; |
| 15 | use static_cell::StaticCell; | ||
| 16 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; |
| 17 | 18 | ||
| 18 | static mut CORE1_STACK: Stack<1024> = Stack::new(); | ||
| 19 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); | ||
| 20 | |||
| 21 | use crate::i2c::AbortReason; | 19 | use crate::i2c::AbortReason; |
| 22 | 20 | ||
| 23 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| @@ -106,7 +104,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 106 | } | 104 | } |
| 107 | 105 | ||
| 108 | async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { | 106 | async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { |
| 109 | info!("Device start"); | 107 | info!("Controller start"); |
| 110 | 108 | ||
| 111 | { | 109 | { |
| 112 | let buf = [0xCA, 0x11]; | 110 | let buf = [0xCA, 0x11]; |
| @@ -180,7 +178,7 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { | |||
| 180 | } | 178 | } |
| 181 | 179 | ||
| 182 | #[embassy_executor::main] | 180 | #[embassy_executor::main] |
| 183 | async fn main(_core0_spawner: Spawner) { | 181 | async fn main(spawner: Spawner) { |
| 184 | let mut config = rpConfig::default(); | 182 | let mut config = rpConfig::default(); |
| 185 | // Configure clk_sys to 48MHz to support 1kHz scl. | 183 | // Configure clk_sys to 48MHz to support 1kHz scl. |
| 186 | // In theory it can go lower, but we won't bother to test below 1kHz. | 184 | // In theory it can go lower, but we won't bother to test below 1kHz. |
| @@ -210,14 +208,7 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { | |||
| 210 | config.addr = DEV_ADDR as u16; | 208 | config.addr = DEV_ADDR as u16; |
| 211 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | 209 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); |
| 212 | 210 | ||
| 213 | spawn_core1( | 211 | spawner.spawn(device_task(device).unwrap()); |
| 214 | p.CORE1, | ||
| 215 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | ||
| 216 | move || { | ||
| 217 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 218 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | ||
| 219 | }, | ||
| 220 | ); | ||
| 221 | 212 | ||
| 222 | let c_sda = p.PIN_21; | 213 | let c_sda = p.PIN_21; |
| 223 | let c_scl = p.PIN_20; | 214 | let c_scl = p.PIN_20; |
diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs index 783ea0f27..7e34bc778 100644 --- a/tests/rp/src/bin/multicore.rs +++ b/tests/rp/src/bin/multicore.rs | |||
| @@ -1,10 +1,13 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{info, unwrap}; | 8 | use defmt::{info, unwrap}; |
| 6 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 7 | use embassy_rp::multicore::{spawn_core1, Stack}; | 10 | use embassy_rp::multicore::{Stack, spawn_core1}; |
| 8 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 11 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 9 | use embassy_sync::channel::Channel; | 12 | use embassy_sync::channel::Channel; |
| 10 | use static_cell::StaticCell; | 13 | use static_cell::StaticCell; |
| @@ -24,11 +27,11 @@ fn main() -> ! { | |||
| 24 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | 27 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 25 | move || { | 28 | move || { |
| 26 | let executor1 = EXECUTOR1.init(Executor::new()); | 29 | let executor1 = EXECUTOR1.init(Executor::new()); |
| 27 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); | 30 | executor1.run(|spawner| spawner.spawn(unwrap!(core1_task()))); |
| 28 | }, | 31 | }, |
| 29 | ); | 32 | ); |
| 30 | let executor0 = EXECUTOR0.init(Executor::new()); | 33 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 31 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); | 34 | executor0.run(|spawner| spawner.spawn(unwrap!(core0_task()))); |
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | #[embassy_executor::task] | 37 | #[embassy_executor::task] |
diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs new file mode 100644 index 000000000..87a03b5e2 --- /dev/null +++ b/tests/rp/src/bin/overclock.rs | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | #[cfg(feature = "rp2040")] | ||
| 5 | teleprobe_meta::target!(b"rpi-pico"); | ||
| 6 | #[cfg(feature = "rp235xb")] | ||
| 7 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 8 | |||
| 9 | use defmt::info; | ||
| 10 | use embassy_executor::Spawner; | ||
| 11 | use embassy_rp::clocks::{ClockConfig, CoreVoltage, clk_sys_freq, core_voltage}; | ||
| 12 | use embassy_rp::config::Config; | ||
| 13 | use embassy_time::Instant; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | const COUNT_TO: i64 = 10_000_000; | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async fn main(_spawner: Spawner) { | ||
| 20 | let mut config = Config::default(); | ||
| 21 | |||
| 22 | // Initialize with 200MHz clock configuration | ||
| 23 | config.clocks = ClockConfig::system_freq(200_000_000).unwrap(); | ||
| 24 | |||
| 25 | // if we are rp235x, we need to manually set the core voltage. rp2040 should do this automatically | ||
| 26 | #[cfg(feature = "rp235xb")] | ||
| 27 | { | ||
| 28 | config.clocks.core_voltage = CoreVoltage::V1_15; | ||
| 29 | } | ||
| 30 | |||
| 31 | let _p = embassy_rp::init(config); | ||
| 32 | |||
| 33 | // We should be at core voltage of 1.15V | ||
| 34 | assert_eq!(core_voltage().unwrap(), CoreVoltage::V1_15, "Core voltage is not 1.15V"); | ||
| 35 | // We should be at 200MHz | ||
| 36 | assert_eq!(clk_sys_freq(), 200_000_000, "System clock frequency is not 200MHz"); | ||
| 37 | |||
| 38 | // Test the system speed | ||
| 39 | let time_elapsed = { | ||
| 40 | let mut counter = 0; | ||
| 41 | let start = Instant::now(); | ||
| 42 | while counter < COUNT_TO { | ||
| 43 | counter += 1; | ||
| 44 | } | ||
| 45 | let elapsed = Instant::now() - start; | ||
| 46 | |||
| 47 | elapsed.as_millis() | ||
| 48 | }; | ||
| 49 | |||
| 50 | // Tests will fail if unused variables are detected: | ||
| 51 | // Report the elapsed time, so that the compiler doesn't optimize it away for the chip not on test | ||
| 52 | info!( | ||
| 53 | "At {}Mhz: Elapsed time to count to {}: {}ms", | ||
| 54 | clk_sys_freq() / 1_000_000, | ||
| 55 | COUNT_TO, | ||
| 56 | time_elapsed | ||
| 57 | ); | ||
| 58 | |||
| 59 | // Check if the elapsed time is within expected limits | ||
| 60 | // for rp2040 we expect about 600ms | ||
| 61 | #[cfg(feature = "rp2040")] | ||
| 62 | // allow 1% error | ||
| 63 | assert!(time_elapsed < 606, "Elapsed time is too long"); | ||
| 64 | // for rp235x we expect about 450ms | ||
| 65 | #[cfg(feature = "rp235xb")] | ||
| 66 | assert!(time_elapsed < 455, "Elapsed time is too long"); | ||
| 67 | |||
| 68 | cortex_m::asm::bkpt(); | ||
| 69 | } | ||
diff --git a/tests/rp/src/bin/pio_irq.rs b/tests/rp/src/bin/pio_irq.rs index 33cdaaac9..dc37dd83d 100644 --- a/tests/rp/src/bin/pio_irq.rs +++ b/tests/rp/src/bin/pio_irq.rs | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::info; | 8 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::bind_interrupts; | 10 | use embassy_rp::bind_interrupts; |
| 8 | use embassy_rp::peripherals::PIO0; | 11 | use embassy_rp::peripherals::PIO0; |
| 12 | use embassy_rp::pio::program::pio_asm; | ||
| 9 | use embassy_rp::pio::{Config, InterruptHandler, Pio}; | 13 | use embassy_rp::pio::{Config, InterruptHandler, Pio}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 15 | ||
| @@ -24,7 +28,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | .. | 28 | .. |
| 25 | } = Pio::new(pio, Irqs); | 29 | } = Pio::new(pio, Irqs); |
| 26 | 30 | ||
| 27 | let prg = pio_proc::pio_asm!( | 31 | let prg = pio_asm!( |
| 28 | "irq set 0", | 32 | "irq set 0", |
| 29 | "irq wait 0", | 33 | "irq wait 0", |
| 30 | "irq set 1", | 34 | "irq set 1", |
diff --git a/tests/rp/src/bin/pio_multi_load.rs b/tests/rp/src/bin/pio_multi_load.rs index cd28f99b6..82bbab272 100644 --- a/tests/rp/src/bin/pio_multi_load.rs +++ b/tests/rp/src/bin/pio_multi_load.rs | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::info; | 8 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::bind_interrupts; | 10 | use embassy_rp::bind_interrupts; |
| 8 | use embassy_rp::peripherals::PIO0; | 11 | use embassy_rp::peripherals::PIO0; |
| 12 | use embassy_rp::pio::program::pio_asm; | ||
| 9 | use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio}; | 13 | use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 15 | ||
| @@ -27,7 +31,7 @@ async fn main(_spawner: Spawner) { | |||
| 27 | } = Pio::new(pio, Irqs); | 31 | } = Pio::new(pio, Irqs); |
| 28 | 32 | ||
| 29 | // load with explicit origin works | 33 | // load with explicit origin works |
| 30 | let prg1 = pio_proc::pio_asm!( | 34 | let prg1 = pio_asm!( |
| 31 | ".origin 4" | 35 | ".origin 4" |
| 32 | "nop", | 36 | "nop", |
| 33 | "nop", | 37 | "nop", |
| @@ -46,15 +50,16 @@ async fn main(_spawner: Spawner) { | |||
| 46 | assert_eq!(loaded1.wrap.target, 4); | 50 | assert_eq!(loaded1.wrap.target, 4); |
| 47 | 51 | ||
| 48 | // load without origin chooses a free space | 52 | // load without origin chooses a free space |
| 49 | let prg2 = pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",); | 53 | let prg2 = pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",); |
| 50 | let loaded2 = common.load_program(&prg2.program); | 54 | let loaded2 = common.load_program(&prg2.program); |
| 51 | assert_eq!(loaded2.origin, 14); | 55 | assert_eq!(loaded2.origin, 14); |
| 52 | assert_eq!(loaded2.wrap.source, 23); | 56 | assert_eq!(loaded2.wrap.source, 23); |
| 53 | assert_eq!(loaded2.wrap.target, 14); | 57 | assert_eq!(loaded2.wrap.target, 14); |
| 54 | 58 | ||
| 55 | // wrapping around the end of program space automatically works | 59 | // wrapping around the end of program space automatically works |
| 56 | let prg3 = | 60 | let prg3 = pio_asm!( |
| 57 | pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2",); | 61 | "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2", |
| 62 | ); | ||
| 58 | let loaded3 = common.load_program(&prg3.program); | 63 | let loaded3 = common.load_program(&prg3.program); |
| 59 | assert_eq!(loaded3.origin, 24); | 64 | assert_eq!(loaded3.origin, 24); |
| 60 | assert_eq!(loaded3.wrap.source, 3); | 65 | assert_eq!(loaded3.wrap.source, 3); |
| @@ -88,13 +93,13 @@ async fn main(_spawner: Spawner) { | |||
| 88 | 93 | ||
| 89 | // instruction memory is full now. all loads should fail. | 94 | // instruction memory is full now. all loads should fail. |
| 90 | { | 95 | { |
| 91 | let prg = pio_proc::pio_asm!(".origin 0", "nop"); | 96 | let prg = pio_asm!(".origin 0", "nop"); |
| 92 | match common.try_load_program(&prg.program) { | 97 | match common.try_load_program(&prg.program) { |
| 93 | Err(LoadError::AddressInUse(0)) => (), | 98 | Err(LoadError::AddressInUse(0)) => (), |
| 94 | _ => panic!("program loaded when it shouldn't"), | 99 | _ => panic!("program loaded when it shouldn't"), |
| 95 | }; | 100 | }; |
| 96 | 101 | ||
| 97 | let prg = pio_proc::pio_asm!("nop"); | 102 | let prg = pio_asm!("nop"); |
| 98 | match common.try_load_program(&prg.program) { | 103 | match common.try_load_program(&prg.program) { |
| 99 | Err(LoadError::InsufficientSpace) => (), | 104 | Err(LoadError::InsufficientSpace) => (), |
| 100 | _ => panic!("program loaded when it shouldn't"), | 105 | _ => panic!("program loaded when it shouldn't"), |
| @@ -106,13 +111,13 @@ async fn main(_spawner: Spawner) { | |||
| 106 | common.free_instr(loaded3.used_memory); | 111 | common.free_instr(loaded3.used_memory); |
| 107 | } | 112 | } |
| 108 | { | 113 | { |
| 109 | let prg = pio_proc::pio_asm!(".origin 0", "nop"); | 114 | let prg = pio_asm!(".origin 0", "nop"); |
| 110 | match common.try_load_program(&prg.program) { | 115 | match common.try_load_program(&prg.program) { |
| 111 | Ok(_) => (), | 116 | Ok(_) => (), |
| 112 | _ => panic!("program didn't loaded when it shouldn"), | 117 | _ => panic!("program didn't loaded when it shouldn"), |
| 113 | }; | 118 | }; |
| 114 | 119 | ||
| 115 | let prg = pio_proc::pio_asm!("nop"); | 120 | let prg = pio_asm!("nop"); |
| 116 | match common.try_load_program(&prg.program) { | 121 | match common.try_load_program(&prg.program) { |
| 117 | Ok(_) => (), | 122 | Ok(_) => (), |
| 118 | _ => panic!("program didn't loaded when it shouldn"), | 123 | _ => panic!("program didn't loaded when it shouldn"), |
diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index c05197000..5f890cd50 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs | |||
| @@ -1,10 +1,15 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert, assert_eq, assert_ne, *}; | 8 | use defmt::{assert, assert_eq, assert_ne, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 10 | use embassy_rp::gpio::{Input, Pull}; |
| 11 | #[cfg(feature = "rp2040")] | ||
| 12 | use embassy_rp::gpio::{Level, Output}; | ||
| 8 | use embassy_rp::pwm::{Config, InputMode, Pwm}; | 13 | use embassy_rp::pwm::{Config, InputMode, Pwm}; |
| 9 | use embassy_time::Timer; | 14 | use embassy_time::Timer; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -28,7 +33,7 @@ async fn main(_spawner: Spawner) { | |||
| 28 | 33 | ||
| 29 | // Test free-running clock | 34 | // Test free-running clock |
| 30 | { | 35 | { |
| 31 | let pwm = Pwm::new_free(&mut p.PWM_SLICE3, cfg.clone()); | 36 | let pwm = Pwm::new_free(p.PWM_SLICE3.reborrow(), cfg.clone()); |
| 32 | cortex_m::asm::delay(125); | 37 | cortex_m::asm::delay(125); |
| 33 | let ctr = pwm.counter(); | 38 | let ctr = pwm.counter(); |
| 34 | assert!(ctr > 0); | 39 | assert!(ctr > 0); |
| @@ -45,8 +50,8 @@ async fn main(_spawner: Spawner) { | |||
| 45 | 50 | ||
| 46 | // Test output from A | 51 | // Test output from A |
| 47 | { | 52 | { |
| 48 | let pin1 = Input::new(&mut p9, Pull::None); | 53 | let pin1 = Input::new(p9.reborrow(), Pull::None); |
| 49 | let _pwm = Pwm::new_output_a(&mut p.PWM_SLICE3, &mut p6, cfg.clone()); | 54 | let _pwm = Pwm::new_output_a(p.PWM_SLICE3.reborrow(), p6.reborrow(), cfg.clone()); |
| 50 | Timer::after_millis(1).await; | 55 | Timer::after_millis(1).await; |
| 51 | assert_eq!(pin1.is_low(), invert_a); | 56 | assert_eq!(pin1.is_low(), invert_a); |
| 52 | Timer::after_millis(5).await; | 57 | Timer::after_millis(5).await; |
| @@ -59,8 +64,8 @@ async fn main(_spawner: Spawner) { | |||
| 59 | 64 | ||
| 60 | // Test output from B | 65 | // Test output from B |
| 61 | { | 66 | { |
| 62 | let pin2 = Input::new(&mut p11, Pull::None); | 67 | let pin2 = Input::new(p11.reborrow(), Pull::None); |
| 63 | let _pwm = Pwm::new_output_b(&mut p.PWM_SLICE3, &mut p7, cfg.clone()); | 68 | let _pwm = Pwm::new_output_b(p.PWM_SLICE3.reborrow(), p7.reborrow(), cfg.clone()); |
| 64 | Timer::after_millis(1).await; | 69 | Timer::after_millis(1).await; |
| 65 | assert_ne!(pin2.is_low(), invert_a); | 70 | assert_ne!(pin2.is_low(), invert_a); |
| 66 | Timer::after_millis(5).await; | 71 | Timer::after_millis(5).await; |
| @@ -73,9 +78,9 @@ async fn main(_spawner: Spawner) { | |||
| 73 | 78 | ||
| 74 | // Test output from A+B | 79 | // Test output from A+B |
| 75 | { | 80 | { |
| 76 | let pin1 = Input::new(&mut p9, Pull::None); | 81 | let pin1 = Input::new(p9.reborrow(), Pull::None); |
| 77 | let pin2 = Input::new(&mut p11, Pull::None); | 82 | let pin2 = Input::new(p11.reborrow(), Pull::None); |
| 78 | let _pwm = Pwm::new_output_ab(&mut p.PWM_SLICE3, &mut p6, &mut p7, cfg.clone()); | 83 | let _pwm = Pwm::new_output_ab(p.PWM_SLICE3.reborrow(), p6.reborrow(), p7.reborrow(), cfg.clone()); |
| 79 | Timer::after_millis(1).await; | 84 | Timer::after_millis(1).await; |
| 80 | assert_eq!(pin1.is_low(), invert_a); | 85 | assert_eq!(pin1.is_low(), invert_a); |
| 81 | assert_ne!(pin2.is_low(), invert_a); | 86 | assert_ne!(pin2.is_low(), invert_a); |
| @@ -92,9 +97,16 @@ async fn main(_spawner: Spawner) { | |||
| 92 | } | 97 | } |
| 93 | 98 | ||
| 94 | // Test level-gated | 99 | // Test level-gated |
| 100 | #[cfg(feature = "rp2040")] | ||
| 95 | { | 101 | { |
| 96 | let mut pin2 = Output::new(&mut p11, Level::Low); | 102 | let mut pin2 = Output::new(p11.reborrow(), Level::Low); |
| 97 | let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, Pull::None, InputMode::Level, cfg.clone()); | 103 | let pwm = Pwm::new_input( |
| 104 | p.PWM_SLICE3.reborrow(), | ||
| 105 | p7.reborrow(), | ||
| 106 | Pull::None, | ||
| 107 | InputMode::Level, | ||
| 108 | cfg.clone(), | ||
| 109 | ); | ||
| 98 | assert_eq!(pwm.counter(), 0); | 110 | assert_eq!(pwm.counter(), 0); |
| 99 | Timer::after_millis(5).await; | 111 | Timer::after_millis(5).await; |
| 100 | assert_eq!(pwm.counter(), 0); | 112 | assert_eq!(pwm.counter(), 0); |
| @@ -102,17 +114,19 @@ async fn main(_spawner: Spawner) { | |||
| 102 | Timer::after_millis(1).await; | 114 | Timer::after_millis(1).await; |
| 103 | pin2.set_low(); | 115 | pin2.set_low(); |
| 104 | let ctr = pwm.counter(); | 116 | let ctr = pwm.counter(); |
| 117 | info!("ctr: {}", ctr); | ||
| 105 | assert!(ctr >= 1000); | 118 | assert!(ctr >= 1000); |
| 106 | Timer::after_millis(1).await; | 119 | Timer::after_millis(1).await; |
| 107 | assert_eq!(pwm.counter(), ctr); | 120 | assert_eq!(pwm.counter(), ctr); |
| 108 | } | 121 | } |
| 109 | 122 | ||
| 110 | // Test rising-gated | 123 | // Test rising-gated |
| 124 | #[cfg(feature = "rp2040")] | ||
| 111 | { | 125 | { |
| 112 | let mut pin2 = Output::new(&mut p11, Level::Low); | 126 | let mut pin2 = Output::new(p11.reborrow(), Level::Low); |
| 113 | let pwm = Pwm::new_input( | 127 | let pwm = Pwm::new_input( |
| 114 | &mut p.PWM_SLICE3, | 128 | p.PWM_SLICE3.reborrow(), |
| 115 | &mut p7, | 129 | p7.reborrow(), |
| 116 | Pull::None, | 130 | Pull::None, |
| 117 | InputMode::RisingEdge, | 131 | InputMode::RisingEdge, |
| 118 | cfg.clone(), | 132 | cfg.clone(), |
| @@ -129,11 +143,12 @@ async fn main(_spawner: Spawner) { | |||
| 129 | } | 143 | } |
| 130 | 144 | ||
| 131 | // Test falling-gated | 145 | // Test falling-gated |
| 146 | #[cfg(feature = "rp2040")] | ||
| 132 | { | 147 | { |
| 133 | let mut pin2 = Output::new(&mut p11, Level::High); | 148 | let mut pin2 = Output::new(p11.reborrow(), Level::High); |
| 134 | let pwm = Pwm::new_input( | 149 | let pwm = Pwm::new_input( |
| 135 | &mut p.PWM_SLICE3, | 150 | p.PWM_SLICE3.reborrow(), |
| 136 | &mut p7, | 151 | p7.reborrow(), |
| 137 | Pull::None, | 152 | Pull::None, |
| 138 | InputMode::FallingEdge, | 153 | InputMode::FallingEdge, |
| 139 | cfg.clone(), | 154 | cfg.clone(), |
| @@ -151,10 +166,10 @@ async fn main(_spawner: Spawner) { | |||
| 151 | 166 | ||
| 152 | // pull-down | 167 | // pull-down |
| 153 | { | 168 | { |
| 154 | let pin2 = Input::new(&mut p11, Pull::None); | 169 | let pin2 = Input::new(p11.reborrow(), Pull::None); |
| 155 | Pwm::new_input( | 170 | Pwm::new_input( |
| 156 | &mut p.PWM_SLICE3, | 171 | p.PWM_SLICE3.reborrow(), |
| 157 | &mut p7, | 172 | p7.reborrow(), |
| 158 | Pull::Down, | 173 | Pull::Down, |
| 159 | InputMode::FallingEdge, | 174 | InputMode::FallingEdge, |
| 160 | cfg.clone(), | 175 | cfg.clone(), |
| @@ -165,10 +180,10 @@ async fn main(_spawner: Spawner) { | |||
| 165 | 180 | ||
| 166 | // pull-up | 181 | // pull-up |
| 167 | { | 182 | { |
| 168 | let pin2 = Input::new(&mut p11, Pull::None); | 183 | let pin2 = Input::new(p11.reborrow(), Pull::None); |
| 169 | Pwm::new_input( | 184 | Pwm::new_input( |
| 170 | &mut p.PWM_SLICE3, | 185 | p.PWM_SLICE3.reborrow(), |
| 171 | &mut p7, | 186 | p7.reborrow(), |
| 172 | Pull::Up, | 187 | Pull::Up, |
| 173 | InputMode::FallingEdge, | 188 | InputMode::FallingEdge, |
| 174 | cfg.clone(), | 189 | cfg.clone(), |
diff --git a/tests/rp/src/bin/rtc.rs b/tests/rp/src/bin/rtc.rs new file mode 100644 index 000000000..e1def7b5b --- /dev/null +++ b/tests/rp/src/bin/rtc.rs | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #[cfg(feature = "rp2040")] | ||
| 4 | teleprobe_meta::target!(b"rpi-pico"); | ||
| 5 | |||
| 6 | use defmt::{assert, *}; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_futures::select::{Either, select}; | ||
| 9 | use embassy_rp::bind_interrupts; | ||
| 10 | use embassy_rp::rtc::{DateTime, DateTimeFilter, DayOfWeek, Rtc}; | ||
| 11 | use embassy_time::{Duration, Instant, Timer}; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | // Bind the RTC interrupt to the handler | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | RTC_IRQ => embassy_rp::rtc::InterruptHandler; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | let p = embassy_rp::init(Default::default()); | ||
| 22 | let mut rtc = Rtc::new(p.RTC, Irqs); | ||
| 23 | |||
| 24 | info!("RTC test started"); | ||
| 25 | |||
| 26 | // Initialize RTC if not running | ||
| 27 | if !rtc.is_running() { | ||
| 28 | info!("Starting RTC"); | ||
| 29 | let now = DateTime { | ||
| 30 | year: 2000, | ||
| 31 | month: 1, | ||
| 32 | day: 1, | ||
| 33 | day_of_week: DayOfWeek::Saturday, | ||
| 34 | hour: 0, | ||
| 35 | minute: 0, | ||
| 36 | second: 0, | ||
| 37 | }; | ||
| 38 | rtc.set_datetime(now).unwrap(); | ||
| 39 | Timer::after_millis(100).await; | ||
| 40 | } | ||
| 41 | |||
| 42 | // Test 1: Basic RTC functionality - read current time | ||
| 43 | let initial_time = rtc.now().unwrap(); | ||
| 44 | info!( | ||
| 45 | "Initial time: {}-{:02}-{:02} {}:{:02}:{:02}", | ||
| 46 | initial_time.year, | ||
| 47 | initial_time.month, | ||
| 48 | initial_time.day, | ||
| 49 | initial_time.hour, | ||
| 50 | initial_time.minute, | ||
| 51 | initial_time.second | ||
| 52 | ); | ||
| 53 | |||
| 54 | // Test 2: Schedule and wait for alarm | ||
| 55 | info!("Testing alarm scheduling"); | ||
| 56 | |||
| 57 | // Wait until we're at a predictable second, then schedule for a future second | ||
| 58 | loop { | ||
| 59 | let current = rtc.now().unwrap(); | ||
| 60 | if current.second <= 55 { | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | Timer::after_millis(100).await; | ||
| 64 | } | ||
| 65 | |||
| 66 | // Now schedule alarm for 3 seconds from current time | ||
| 67 | let current_time = rtc.now().unwrap(); | ||
| 68 | let alarm_second = (current_time.second + 3) % 60; | ||
| 69 | let alarm_filter = DateTimeFilter::default().second(alarm_second); | ||
| 70 | |||
| 71 | info!("Scheduling alarm for second: {}", alarm_second); | ||
| 72 | rtc.schedule_alarm(alarm_filter); | ||
| 73 | |||
| 74 | // Verify alarm is scheduled | ||
| 75 | let scheduled = rtc.alarm_scheduled(); | ||
| 76 | assert!(scheduled.is_some(), "Alarm should be scheduled"); | ||
| 77 | info!("Alarm scheduled successfully: {}", scheduled.unwrap()); | ||
| 78 | |||
| 79 | // Wait for alarm with timeout | ||
| 80 | let alarm_start = Instant::now(); | ||
| 81 | match select(Timer::after_secs(5), rtc.wait_for_alarm()).await { | ||
| 82 | Either::First(_) => { | ||
| 83 | core::panic!("Alarm timeout - alarm should have triggered by now"); | ||
| 84 | } | ||
| 85 | Either::Second(_) => { | ||
| 86 | let alarm_duration = Instant::now() - alarm_start; | ||
| 87 | info!("ALARM TRIGGERED after {:?}", alarm_duration); | ||
| 88 | |||
| 89 | // Verify timing is reasonable (should be around 3 seconds) | ||
| 90 | assert!( | ||
| 91 | alarm_duration >= Duration::from_secs(2) && alarm_duration <= Duration::from_secs(4), | ||
| 92 | "Alarm timing incorrect: {:?}", | ||
| 93 | alarm_duration | ||
| 94 | ); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | // Test 3: Verify RTC is still running and time has advanced | ||
| 99 | let final_time = rtc.now().unwrap(); | ||
| 100 | info!( | ||
| 101 | "Final time: {}-{:02}-{:02} {}:{:02}:{:02}", | ||
| 102 | final_time.year, final_time.month, final_time.day, final_time.hour, final_time.minute, final_time.second | ||
| 103 | ); | ||
| 104 | |||
| 105 | // Verify time has advanced (allowing for minute/hour rollover) | ||
| 106 | let time_diff = if final_time.second >= initial_time.second { | ||
| 107 | final_time.second - initial_time.second | ||
| 108 | } else { | ||
| 109 | 60 - initial_time.second + final_time.second | ||
| 110 | }; | ||
| 111 | |||
| 112 | assert!(time_diff >= 3, "RTC should have advanced by at least 3 seconds"); | ||
| 113 | info!("Time advanced by {} seconds", time_diff); | ||
| 114 | |||
| 115 | // Test 4: Verify alarm is no longer scheduled after triggering | ||
| 116 | let post_alarm_scheduled = rtc.alarm_scheduled(); | ||
| 117 | assert!( | ||
| 118 | post_alarm_scheduled.is_none(), | ||
| 119 | "Alarm should not be scheduled after triggering" | ||
| 120 | ); | ||
| 121 | info!("Alarm correctly cleared after triggering"); | ||
| 122 | |||
| 123 | info!("Test OK"); | ||
| 124 | cortex_m::asm::bkpt(); | ||
| 125 | } | ||
diff --git a/tests/rp/src/bin/spi.rs b/tests/rp/src/bin/spi.rs index 4b02942a7..6802bfc99 100644 --- a/tests/rp/src/bin/spi.rs +++ b/tests/rp/src/bin/spi.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/tests/rp/src/bin/spi_async.rs b/tests/rp/src/bin/spi_async.rs index efdc80b53..e50667435 100644 --- a/tests/rp/src/bin/spi_async.rs +++ b/tests/rp/src/bin/spi_async.rs | |||
| @@ -3,7 +3,10 @@ | |||
| 3 | //! | 3 | //! |
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #[cfg(feature = "rp2040")] | ||
| 6 | teleprobe_meta::target!(b"rpi-pico"); | 7 | teleprobe_meta::target!(b"rpi-pico"); |
| 8 | #[cfg(feature = "rp235xb")] | ||
| 9 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 7 | 10 | ||
| 8 | use defmt::{assert_eq, *}; | 11 | use defmt::{assert_eq, *}; |
| 9 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
diff --git a/tests/rp/src/bin/spinlock_mutex_multicore.rs b/tests/rp/src/bin/spinlock_mutex_multicore.rs new file mode 100644 index 000000000..25c4faf37 --- /dev/null +++ b/tests/rp/src/bin/spinlock_mutex_multicore.rs | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #[cfg(feature = "rp2040")] | ||
| 4 | teleprobe_meta::target!(b"rpi-pico"); | ||
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 7 | |||
| 8 | use defmt::{info, unwrap}; | ||
| 9 | use embassy_executor::Executor; | ||
| 10 | use embassy_rp::multicore::{Stack, spawn_core1}; | ||
| 11 | use embassy_rp::spinlock_mutex::SpinlockRawMutex; | ||
| 12 | use embassy_sync::channel::Channel; | ||
| 13 | use static_cell::StaticCell; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | static mut CORE1_STACK: Stack<1024> = Stack::new(); | ||
| 17 | static EXECUTOR0: StaticCell<Executor> = StaticCell::new(); | ||
| 18 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); | ||
| 19 | static CHANNEL0: Channel<SpinlockRawMutex<0>, bool, 1> = Channel::new(); | ||
| 20 | static CHANNEL1: Channel<SpinlockRawMutex<1>, bool, 1> = Channel::new(); | ||
| 21 | |||
| 22 | #[cortex_m_rt::entry] | ||
| 23 | fn main() -> ! { | ||
| 24 | let p = embassy_rp::init(Default::default()); | ||
| 25 | spawn_core1( | ||
| 26 | p.CORE1, | ||
| 27 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | ||
| 28 | move || { | ||
| 29 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 30 | executor1.run(|spawner| spawner.spawn(unwrap!(core1_task()))); | ||
| 31 | }, | ||
| 32 | ); | ||
| 33 | let executor0 = EXECUTOR0.init(Executor::new()); | ||
| 34 | executor0.run(|spawner| spawner.spawn(unwrap!(core0_task()))); | ||
| 35 | } | ||
| 36 | |||
| 37 | #[embassy_executor::task] | ||
| 38 | async fn core0_task() { | ||
| 39 | info!("CORE0 is running"); | ||
| 40 | let ping = true; | ||
| 41 | CHANNEL0.send(ping).await; | ||
| 42 | let pong = CHANNEL1.receive().await; | ||
| 43 | assert_eq!(ping, pong); | ||
| 44 | |||
| 45 | info!("Test OK"); | ||
| 46 | cortex_m::asm::bkpt(); | ||
| 47 | } | ||
| 48 | |||
| 49 | #[embassy_executor::task] | ||
| 50 | async fn core1_task() { | ||
| 51 | info!("CORE1 is running"); | ||
| 52 | let ping = CHANNEL0.receive().await; | ||
| 53 | CHANNEL1.send(ping).await; | ||
| 54 | } | ||
diff --git a/tests/nrf52840/src/bin/timer.rs b/tests/rp/src/bin/timer.rs index 117947a94..12a4d7daa 100644 --- a/tests/nrf52840/src/bin/timer.rs +++ b/tests/rp/src/bin/timer.rs | |||
| @@ -1,15 +1,18 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | 3 | #[cfg(feature = "rp2040")] |
| 4 | teleprobe_meta::target!(b"rpi-pico"); | ||
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert, info}; | 8 | use defmt::{assert, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_time::{Instant, Timer}; | 10 | use embassy_time::{Instant, Timer}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 12 | ||
| 10 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 11 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 12 | let _p = embassy_nrf::init(Default::default()); | 15 | let _p = embassy_rp::init(Default::default()); |
| 13 | info!("Hello World!"); | 16 | info!("Hello World!"); |
| 14 | 17 | ||
| 15 | let start = Instant::now(); | 18 | let start = Instant::now(); |
| @@ -18,6 +21,7 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let ms = (end - start).as_millis(); | 21 | let ms = (end - start).as_millis(); |
| 19 | info!("slept for {} ms", ms); | 22 | info!("slept for {} ms", ms); |
| 20 | assert!(ms >= 99); | 23 | assert!(ms >= 99); |
| 24 | assert!(ms < 110); | ||
| 21 | 25 | ||
| 22 | info!("Test OK"); | 26 | info!("Test OK"); |
| 23 | cortex_m::asm::bkpt(); | 27 | cortex_m::asm::bkpt(); |
diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index 6e6e5517b..80230f3fe 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs | |||
| @@ -1,21 +1,24 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{Level, Output}; | 10 | use embassy_rp::gpio::{Level, Output}; |
| 8 | use embassy_rp::uart::{Blocking, Config, Error, Instance, Parity, Uart, UartRx}; | 11 | use embassy_rp::uart::{Blocking, Config, Error, Parity, Uart, UartRx}; |
| 9 | use embassy_time::Timer; | 12 | use embassy_time::Timer; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { | 15 | fn read<const N: usize>(uart: &mut Uart<'_, Blocking>) -> Result<[u8; N], Error> { |
| 13 | let mut buf = [255; N]; | 16 | let mut buf = [255; N]; |
| 14 | uart.blocking_read(&mut buf)?; | 17 | uart.blocking_read(&mut buf)?; |
| 15 | Ok(buf) | 18 | Ok(buf) |
| 16 | } | 19 | } |
| 17 | 20 | ||
| 18 | fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { | 21 | fn read1<const N: usize>(uart: &mut UartRx<'_, Blocking>) -> Result<[u8; N], Error> { |
| 19 | let mut buf = [255; N]; | 22 | let mut buf = [255; N]; |
| 20 | uart.blocking_read(&mut buf)?; | 23 | uart.blocking_read(&mut buf)?; |
| 21 | Ok(buf) | 24 | Ok(buf) |
| @@ -53,7 +56,7 @@ async fn main(_spawner: Spawner) { | |||
| 53 | 56 | ||
| 54 | { | 57 | { |
| 55 | let config = Config::default(); | 58 | let config = Config::default(); |
| 56 | let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); | 59 | let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); |
| 57 | 60 | ||
| 58 | // We can't send too many bytes, they have to fit in the FIFO. | 61 | // We can't send too many bytes, they have to fit in the FIFO. |
| 59 | // This is because we aren't sending+receiving at the same time. | 62 | // This is because we aren't sending+receiving at the same time. |
| @@ -66,7 +69,7 @@ async fn main(_spawner: Spawner) { | |||
| 66 | info!("test overflow detection"); | 69 | info!("test overflow detection"); |
| 67 | { | 70 | { |
| 68 | let config = Config::default(); | 71 | let config = Config::default(); |
| 69 | let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); | 72 | let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); |
| 70 | 73 | ||
| 71 | let data = [ | 74 | let data = [ |
| 72 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | 75 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
| @@ -90,7 +93,7 @@ async fn main(_spawner: Spawner) { | |||
| 90 | info!("test break detection"); | 93 | info!("test break detection"); |
| 91 | { | 94 | { |
| 92 | let config = Config::default(); | 95 | let config = Config::default(); |
| 93 | let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); | 96 | let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); |
| 94 | 97 | ||
| 95 | // break on empty fifo | 98 | // break on empty fifo |
| 96 | uart.send_break(20).await; | 99 | uart.send_break(20).await; |
| @@ -110,11 +113,11 @@ async fn main(_spawner: Spawner) { | |||
| 110 | // parity detection. here we bitbang to not require two uarts. | 113 | // parity detection. here we bitbang to not require two uarts. |
| 111 | info!("test parity error detection"); | 114 | info!("test parity error detection"); |
| 112 | { | 115 | { |
| 113 | let mut pin = Output::new(&mut tx, Level::High); | 116 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 114 | let mut config = Config::default(); | 117 | let mut config = Config::default(); |
| 115 | config.baudrate = 1000; | 118 | config.baudrate = 1000; |
| 116 | config.parity = Parity::ParityEven; | 119 | config.parity = Parity::ParityEven; |
| 117 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); | 120 | let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config); |
| 118 | 121 | ||
| 119 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { | 122 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { |
| 120 | send(pin, v, Some(parity != 0)).await; | 123 | send(pin, v, Some(parity != 0)).await; |
| @@ -137,10 +140,10 @@ async fn main(_spawner: Spawner) { | |||
| 137 | // framing error detection. here we bitbang because there's no other way. | 140 | // framing error detection. here we bitbang because there's no other way. |
| 138 | info!("test framing error detection"); | 141 | info!("test framing error detection"); |
| 139 | { | 142 | { |
| 140 | let mut pin = Output::new(&mut tx, Level::High); | 143 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 141 | let mut config = Config::default(); | 144 | let mut config = Config::default(); |
| 142 | config.baudrate = 1000; | 145 | config.baudrate = 1000; |
| 143 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); | 146 | let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config); |
| 144 | 147 | ||
| 145 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { | 148 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 146 | if good { | 149 | if good { |
diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index d68c23cbd..cb78fc142 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs | |||
| @@ -1,13 +1,16 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, panic, *}; | 8 | use defmt::{assert_eq, panic, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::bind_interrupts; | 10 | use embassy_rp::bind_interrupts; |
| 8 | use embassy_rp::gpio::{Level, Output}; | 11 | use embassy_rp::gpio::{Level, Output}; |
| 9 | use embassy_rp::peripherals::UART0; | 12 | use embassy_rp::peripherals::UART0; |
| 10 | use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Instance, Parity}; | 13 | use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Parity}; |
| 11 | use embassy_time::Timer; | 14 | use embassy_time::Timer; |
| 12 | use embedded_io_async::{Read, ReadExactError, Write}; | 15 | use embedded_io_async::{Read, ReadExactError, Write}; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 16 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -16,7 +19,7 @@ bind_interrupts!(struct Irqs { | |||
| 16 | UART0_IRQ => BufferedInterruptHandler<UART0>; | 19 | UART0_IRQ => BufferedInterruptHandler<UART0>; |
| 17 | }); | 20 | }); |
| 18 | 21 | ||
| 19 | async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Result<[u8; N], Error> { | 22 | async fn read<const N: usize>(uart: &mut BufferedUart) -> Result<[u8; N], Error> { |
| 20 | let mut buf = [255; N]; | 23 | let mut buf = [255; N]; |
| 21 | match uart.read_exact(&mut buf).await { | 24 | match uart.read_exact(&mut buf).await { |
| 22 | Ok(()) => Ok(buf), | 25 | Ok(()) => Ok(buf), |
| @@ -26,7 +29,7 @@ async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Res | |||
| 26 | } | 29 | } |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 29 | async fn read1<const N: usize>(uart: &mut BufferedUartRx<'_, impl Instance>) -> Result<[u8; N], Error> { | 32 | async fn read1<const N: usize>(uart: &mut BufferedUartRx) -> Result<[u8; N], Error> { |
| 30 | let mut buf = [255; N]; | 33 | let mut buf = [255; N]; |
| 31 | match uart.read_exact(&mut buf).await { | 34 | match uart.read_exact(&mut buf).await { |
| 32 | Ok(()) => Ok(buf), | 35 | Ok(()) => Ok(buf), |
| @@ -70,7 +73,15 @@ async fn main(_spawner: Spawner) { | |||
| 70 | let config = Config::default(); | 73 | let config = Config::default(); |
| 71 | let tx_buf = &mut [0u8; 16]; | 74 | let tx_buf = &mut [0u8; 16]; |
| 72 | let rx_buf = &mut [0u8; 16]; | 75 | let rx_buf = &mut [0u8; 16]; |
| 73 | let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); | 76 | let mut uart = BufferedUart::new( |
| 77 | uart.reborrow(), | ||
| 78 | tx.reborrow(), | ||
| 79 | rx.reborrow(), | ||
| 80 | Irqs, | ||
| 81 | tx_buf, | ||
| 82 | rx_buf, | ||
| 83 | config, | ||
| 84 | ); | ||
| 74 | 85 | ||
| 75 | // Make sure we send more bytes than fits in the FIFO, to test the actual | 86 | // Make sure we send more bytes than fits in the FIFO, to test the actual |
| 76 | // bufferedUart. | 87 | // bufferedUart. |
| @@ -90,7 +101,15 @@ async fn main(_spawner: Spawner) { | |||
| 90 | let config = Config::default(); | 101 | let config = Config::default(); |
| 91 | let tx_buf = &mut [0u8; 16]; | 102 | let tx_buf = &mut [0u8; 16]; |
| 92 | let rx_buf = &mut [0u8; 16]; | 103 | let rx_buf = &mut [0u8; 16]; |
| 93 | let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); | 104 | let mut uart = BufferedUart::new( |
| 105 | uart.reborrow(), | ||
| 106 | tx.reborrow(), | ||
| 107 | rx.reborrow(), | ||
| 108 | Irqs, | ||
| 109 | tx_buf, | ||
| 110 | rx_buf, | ||
| 111 | config, | ||
| 112 | ); | ||
| 94 | 113 | ||
| 95 | // Make sure we send more bytes than fits in the FIFO, to test the actual | 114 | // Make sure we send more bytes than fits in the FIFO, to test the actual |
| 96 | // bufferedUart. | 115 | // bufferedUart. |
| @@ -125,7 +144,15 @@ async fn main(_spawner: Spawner) { | |||
| 125 | config.baudrate = 1000; | 144 | config.baudrate = 1000; |
| 126 | let tx_buf = &mut [0u8; 16]; | 145 | let tx_buf = &mut [0u8; 16]; |
| 127 | let rx_buf = &mut [0u8; 16]; | 146 | let rx_buf = &mut [0u8; 16]; |
| 128 | let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); | 147 | let mut uart = BufferedUart::new( |
| 148 | uart.reborrow(), | ||
| 149 | tx.reborrow(), | ||
| 150 | rx.reborrow(), | ||
| 151 | Irqs, | ||
| 152 | tx_buf, | ||
| 153 | rx_buf, | ||
| 154 | config, | ||
| 155 | ); | ||
| 129 | 156 | ||
| 130 | // break on empty buffer | 157 | // break on empty buffer |
| 131 | uart.send_break(20).await; | 158 | uart.send_break(20).await; |
| @@ -153,13 +180,13 @@ async fn main(_spawner: Spawner) { | |||
| 153 | // parity detection. here we bitbang to not require two uarts. | 180 | // parity detection. here we bitbang to not require two uarts. |
| 154 | info!("test parity error detection"); | 181 | info!("test parity error detection"); |
| 155 | { | 182 | { |
| 156 | let mut pin = Output::new(&mut tx, Level::High); | 183 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 157 | // choose a very slow baud rate to make tests reliable even with O0 | 184 | // choose a very slow baud rate to make tests reliable even with O0 |
| 158 | let mut config = Config::default(); | 185 | let mut config = Config::default(); |
| 159 | config.baudrate = 1000; | 186 | config.baudrate = 1000; |
| 160 | config.parity = Parity::ParityEven; | 187 | config.parity = Parity::ParityEven; |
| 161 | let rx_buf = &mut [0u8; 16]; | 188 | let rx_buf = &mut [0u8; 16]; |
| 162 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); | 189 | let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config); |
| 163 | 190 | ||
| 164 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { | 191 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { |
| 165 | send(pin, v, Some(parity != 0)).await; | 192 | send(pin, v, Some(parity != 0)).await; |
| @@ -201,12 +228,12 @@ async fn main(_spawner: Spawner) { | |||
| 201 | // framing error detection. here we bitbang because there's no other way. | 228 | // framing error detection. here we bitbang because there's no other way. |
| 202 | info!("test framing error detection"); | 229 | info!("test framing error detection"); |
| 203 | { | 230 | { |
| 204 | let mut pin = Output::new(&mut tx, Level::High); | 231 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 205 | // choose a very slow baud rate to make tests reliable even with O0 | 232 | // choose a very slow baud rate to make tests reliable even with O0 |
| 206 | let mut config = Config::default(); | 233 | let mut config = Config::default(); |
| 207 | config.baudrate = 1000; | 234 | config.baudrate = 1000; |
| 208 | let rx_buf = &mut [0u8; 16]; | 235 | let rx_buf = &mut [0u8; 16]; |
| 209 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); | 236 | let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config); |
| 210 | 237 | ||
| 211 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { | 238 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 212 | if good { | 239 | if good { |
diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index edc87175a..a7af81f5f 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs | |||
| @@ -1,13 +1,16 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::bind_interrupts; | 10 | use embassy_rp::bind_interrupts; |
| 8 | use embassy_rp::gpio::{Level, Output}; | 11 | use embassy_rp::gpio::{Level, Output}; |
| 9 | use embassy_rp::peripherals::UART0; | 12 | use embassy_rp::peripherals::UART0; |
| 10 | use embassy_rp::uart::{Async, Config, Error, Instance, InterruptHandler, Parity, Uart, UartRx}; | 13 | use embassy_rp::uart::{Async, Config, Error, InterruptHandler, Parity, Uart, UartRx}; |
| 11 | use embassy_time::Timer; | 14 | use embassy_time::Timer; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 16 | ||
| @@ -15,13 +18,13 @@ bind_interrupts!(struct Irqs { | |||
| 15 | UART0_IRQ => InterruptHandler<UART0>; | 18 | UART0_IRQ => InterruptHandler<UART0>; |
| 16 | }); | 19 | }); |
| 17 | 20 | ||
| 18 | async fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Async>) -> Result<[u8; N], Error> { | 21 | async fn read<const N: usize>(uart: &mut Uart<'_, Async>) -> Result<[u8; N], Error> { |
| 19 | let mut buf = [255; N]; | 22 | let mut buf = [255; N]; |
| 20 | uart.read(&mut buf).await?; | 23 | uart.read(&mut buf).await?; |
| 21 | Ok(buf) | 24 | Ok(buf) |
| 22 | } | 25 | } |
| 23 | 26 | ||
| 24 | async fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Async>) -> Result<[u8; N], Error> { | 27 | async fn read1<const N: usize>(uart: &mut UartRx<'_, Async>) -> Result<[u8; N], Error> { |
| 25 | let mut buf = [255; N]; | 28 | let mut buf = [255; N]; |
| 26 | uart.read(&mut buf).await?; | 29 | uart.read(&mut buf).await?; |
| 27 | Ok(buf) | 30 | Ok(buf) |
| @@ -62,12 +65,12 @@ async fn main(_spawner: Spawner) { | |||
| 62 | { | 65 | { |
| 63 | let config = Config::default(); | 66 | let config = Config::default(); |
| 64 | let mut uart = Uart::new( | 67 | let mut uart = Uart::new( |
| 65 | &mut uart, | 68 | uart.reborrow(), |
| 66 | &mut tx, | 69 | tx.reborrow(), |
| 67 | &mut rx, | 70 | rx.reborrow(), |
| 68 | Irqs, | 71 | Irqs, |
| 69 | &mut p.DMA_CH0, | 72 | p.DMA_CH0.reborrow(), |
| 70 | &mut p.DMA_CH1, | 73 | p.DMA_CH1.reborrow(), |
| 71 | config, | 74 | config, |
| 72 | ); | 75 | ); |
| 73 | 76 | ||
| @@ -83,12 +86,12 @@ async fn main(_spawner: Spawner) { | |||
| 83 | { | 86 | { |
| 84 | let config = Config::default(); | 87 | let config = Config::default(); |
| 85 | let mut uart = Uart::new( | 88 | let mut uart = Uart::new( |
| 86 | &mut uart, | 89 | uart.reborrow(), |
| 87 | &mut tx, | 90 | tx.reborrow(), |
| 88 | &mut rx, | 91 | rx.reborrow(), |
| 89 | Irqs, | 92 | Irqs, |
| 90 | &mut p.DMA_CH0, | 93 | p.DMA_CH0.reborrow(), |
| 91 | &mut p.DMA_CH1, | 94 | p.DMA_CH1.reborrow(), |
| 92 | config, | 95 | config, |
| 93 | ); | 96 | ); |
| 94 | 97 | ||
| @@ -112,12 +115,12 @@ async fn main(_spawner: Spawner) { | |||
| 112 | { | 115 | { |
| 113 | let config = Config::default(); | 116 | let config = Config::default(); |
| 114 | let (mut tx, mut rx) = Uart::new( | 117 | let (mut tx, mut rx) = Uart::new( |
| 115 | &mut uart, | 118 | uart.reborrow(), |
| 116 | &mut tx, | 119 | tx.reborrow(), |
| 117 | &mut rx, | 120 | rx.reborrow(), |
| 118 | Irqs, | 121 | Irqs, |
| 119 | &mut p.DMA_CH0, | 122 | p.DMA_CH0.reborrow(), |
| 120 | &mut p.DMA_CH1, | 123 | p.DMA_CH1.reborrow(), |
| 121 | config, | 124 | config, |
| 122 | ) | 125 | ) |
| 123 | .split(); | 126 | .split(); |
| @@ -153,12 +156,12 @@ async fn main(_spawner: Spawner) { | |||
| 153 | // parity detection. here we bitbang to not require two uarts. | 156 | // parity detection. here we bitbang to not require two uarts. |
| 154 | info!("test parity error detection"); | 157 | info!("test parity error detection"); |
| 155 | { | 158 | { |
| 156 | let mut pin = Output::new(&mut tx, Level::High); | 159 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 157 | // choose a very slow baud rate to make tests reliable even with O0 | 160 | // choose a very slow baud rate to make tests reliable even with O0 |
| 158 | let mut config = Config::default(); | 161 | let mut config = Config::default(); |
| 159 | config.baudrate = 1000; | 162 | config.baudrate = 1000; |
| 160 | config.parity = Parity::ParityEven; | 163 | config.parity = Parity::ParityEven; |
| 161 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); | 164 | let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config); |
| 162 | 165 | ||
| 163 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { | 166 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { |
| 164 | send(pin, v, Some(parity != 0)).await; | 167 | send(pin, v, Some(parity != 0)).await; |
| @@ -199,11 +202,11 @@ async fn main(_spawner: Spawner) { | |||
| 199 | // framing error detection. here we bitbang because there's no other way. | 202 | // framing error detection. here we bitbang because there's no other way. |
| 200 | info!("test framing error detection"); | 203 | info!("test framing error detection"); |
| 201 | { | 204 | { |
| 202 | let mut pin = Output::new(&mut tx, Level::High); | 205 | let mut pin = Output::new(tx.reborrow(), Level::High); |
| 203 | // choose a very slow baud rate to make tests reliable even with O0 | 206 | // choose a very slow baud rate to make tests reliable even with O0 |
| 204 | let mut config = Config::default(); | 207 | let mut config = Config::default(); |
| 205 | config.baudrate = 1000; | 208 | config.baudrate = 1000; |
| 206 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); | 209 | let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config); |
| 207 | 210 | ||
| 208 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { | 211 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 209 | if good { | 212 | if good { |
diff --git a/tests/rp/src/bin/uart_upgrade.rs b/tests/rp/src/bin/uart_upgrade.rs index 603e20f2f..f658b6b8c 100644 --- a/tests/rp/src/bin/uart_upgrade.rs +++ b/tests/rp/src/bin/uart_upgrade.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #[cfg(feature = "rp2040")] | ||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 4 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | #[cfg(feature = "rp235xb")] | ||
| 6 | teleprobe_meta::target!(b"pimoroni-pico-plus-2"); | ||
| 4 | 7 | ||
| 5 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 6 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml index 8752da59b..d94342598 100644 --- a/tests/stm32/.cargo/config.toml +++ b/tests/stm32/.cargo/config.toml | |||
| @@ -9,7 +9,6 @@ runner = "teleprobe client run" | |||
| 9 | rustflags = [ | 9 | rustflags = [ |
| 10 | # Code-size optimizations. | 10 | # Code-size optimizations. |
| 11 | #"-Z", "trap-unreachable=no", | 11 | #"-Z", "trap-unreachable=no", |
| 12 | "-C", "inline-threshold=5", | ||
| 13 | "-C", "no-vectorize-loops", | 12 | "-C", "no-vectorize-loops", |
| 14 | ] | 13 | ] |
| 15 | 14 | ||
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index f94814e70..8fcb6b2b4 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -1,45 +1,50 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | edition = "2021" | 2 | edition = "2024" |
| 3 | name = "embassy-stm32-tests" | 3 | name = "embassy-stm32-tests" |
| 4 | version = "0.1.0" | 4 | version = "0.1.0" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | autobins = false | 6 | autobins = false |
| 7 | publish = false | ||
| 7 | 8 | ||
| 8 | [features] | 9 | [features] |
| 9 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] | 10 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] |
| 10 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma"] | 11 | stm32c071rb = ["embassy-stm32/stm32c071rb", "cm0", "not-gpdma"] |
| 12 | stm32f100rd = ["embassy-stm32/stm32f100rd", "spi-v1", "not-gpdma", "afio", "afio-value-line"] | ||
| 13 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma", "afio"] | ||
| 14 | stm32f107vc = ["embassy-stm32/stm32f107vc", "spi-v1", "not-gpdma", "afio", "afio-connectivity-line"] | ||
| 11 | stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"] | 15 | stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"] |
| 12 | stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] | 16 | stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] |
| 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] | 17 | stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] |
| 14 | stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] | 18 | stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] |
| 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] | 19 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng", "single-bank"] |
| 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] | 20 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] |
| 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] | 21 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] |
| 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"] | 22 | stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash-v34", "cordic", "stop"] |
| 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] | 23 | stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] |
| 20 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] | 24 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] |
| 21 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] | 25 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] |
| 22 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] | 26 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng", "eeprom"] |
| 23 | stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma"] | 27 | stm32l152re = ["embassy-stm32/stm32l152re", "spi-v1", "chrono", "not-gpdma", "eeprom"] |
| 24 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] | 28 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] |
| 25 | stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] | 29 | stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] |
| 26 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] | 30 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng", "dual-bank"] |
| 27 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] | 31 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash", "dual-bank"] |
| 28 | stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"] | 32 | stm32u585ai = ["embassy-stm32/stm32u585ai", "spi-v345", "chrono", "rng", "hash", "cordic"] |
| 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash | 33 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "spi-v345", "chrono", "rng", "hash"] # FIXME: cordic test cause it crash |
| 30 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] | 34 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng", "hsem", "stop"] |
| 31 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"] | 35 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash"] |
| 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] | 36 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono", "hsem"] |
| 33 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] | 37 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] |
| 34 | stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] | 38 | stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] |
| 35 | stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs. | 39 | stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash-v34"] # TODO: fdcan crashes, cryp dma hangs. |
| 36 | stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] | 40 | stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] |
| 37 | 41 | ||
| 38 | spi-v1 = [] | 42 | spi-v1 = [] |
| 39 | spi-v345 = [] | 43 | spi-v345 = [] |
| 40 | cryp = [] | 44 | cryp = [] |
| 41 | hash = [] | 45 | hash = [] |
| 42 | eth = ["embassy-executor/task-arena-size-16384"] | 46 | hash-v34 = ["hash"] |
| 47 | eth = [] | ||
| 43 | rng = [] | 48 | rng = [] |
| 44 | sdmmc = [] | 49 | sdmmc = [] |
| 45 | stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] | 50 | stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] |
| @@ -53,23 +58,30 @@ not-gpdma = [] | |||
| 53 | dac = [] | 58 | dac = [] |
| 54 | ucpd = [] | 59 | ucpd = [] |
| 55 | cordic = ["dep:num-traits"] | 60 | cordic = ["dep:num-traits"] |
| 61 | hsem = [] | ||
| 62 | dual-bank = ["embassy-stm32/dual-bank"] | ||
| 63 | single-bank = ["embassy-stm32/single-bank"] | ||
| 64 | eeprom = [] | ||
| 65 | afio = [] | ||
| 66 | afio-connectivity-line = [] | ||
| 67 | afio-value-line = [] | ||
| 56 | 68 | ||
| 57 | cm0 = ["portable-atomic/unsafe-assume-single-core"] | 69 | cm0 = ["portable-atomic/unsafe-assume-single-core"] |
| 58 | 70 | ||
| 59 | [dependencies] | 71 | [dependencies] |
| 60 | teleprobe-meta = "1" | 72 | teleprobe-meta = "1" |
| 61 | 73 | ||
| 62 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } | 74 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 63 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 75 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 64 | embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } | 76 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } |
| 65 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } | 77 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any", "_allow-disable-rtc"] } |
| 66 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 78 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 67 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } | 79 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } |
| 68 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 80 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 69 | perf-client = { path = "../perf-client" } | 81 | perf-client = { path = "../perf-client" } |
| 70 | 82 | ||
| 71 | defmt = "0.3.0" | 83 | defmt = "1.0.1" |
| 72 | defmt-rtt = "0.4" | 84 | defmt-rtt = "1.0.0" |
| 73 | 85 | ||
| 74 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | 86 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } |
| 75 | cortex-m-rt = "0.7.0" | 87 | cortex-m-rt = "0.7.0" |
| @@ -78,21 +90,27 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 78 | embedded-hal-async = { version = "1.0" } | 90 | embedded-hal-async = { version = "1.0" } |
| 79 | embedded-can = { version = "0.4" } | 91 | embedded-can = { version = "0.4" } |
| 80 | micromath = "2.0.0" | 92 | micromath = "2.0.0" |
| 81 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 93 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 82 | rand_core = { version = "0.6", default-features = false } | 94 | rand_core = { version = "0.9.1", default-features = false } |
| 83 | rand_chacha = { version = "0.3", default-features = false } | 95 | rand_chacha = { version = "0.9.0", default-features = false } |
| 84 | static_cell = "2" | 96 | static_cell = "2" |
| 85 | portable-atomic = { version = "1.5", features = [] } | 97 | portable-atomic = { version = "1.5", features = [] } |
| 98 | critical-section = "1.1" | ||
| 86 | 99 | ||
| 87 | chrono = { version = "^0.4", default-features = false, optional = true} | 100 | chrono = { version = "^0.4", default-features = false, optional = true} |
| 88 | sha2 = { version = "0.10.8", default-features = false } | 101 | sha2 = { version = "0.10.8", default-features = false } |
| 89 | hmac = "0.12.1" | 102 | hmac = "0.12.1" |
| 90 | aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] } | 103 | aes-gcm = { version = "0.10.3", default-features = false, features = ["aes", "heapless"] } |
| 91 | num-traits = {version="0.2", default-features = false,features = ["libm"], optional = true} | 104 | num-traits = { version="0.2", default-features = false,features = ["libm"], optional = true} |
| 92 | 105 | ||
| 93 | # BEGIN TESTS | 106 | # BEGIN TESTS |
| 94 | # Generated by gen_test.py. DO NOT EDIT. | 107 | # Generated by gen_test.py. DO NOT EDIT. |
| 95 | [[bin]] | 108 | [[bin]] |
| 109 | name = "afio" | ||
| 110 | path = "src/bin/afio.rs" | ||
| 111 | required-features = [ "afio",] | ||
| 112 | |||
| 113 | [[bin]] | ||
| 96 | name = "can" | 114 | name = "can" |
| 97 | path = "src/bin/can.rs" | 115 | path = "src/bin/can.rs" |
| 98 | required-features = [ "can",] | 116 | required-features = [ "can",] |
| @@ -118,6 +136,11 @@ path = "src/bin/dac_l1.rs" | |||
| 118 | required-features = [ "stm32l152re",] | 136 | required-features = [ "stm32l152re",] |
| 119 | 137 | ||
| 120 | [[bin]] | 138 | [[bin]] |
| 139 | name = "eeprom" | ||
| 140 | path = "src/bin/eeprom.rs" | ||
| 141 | required-features = [ "eeprom",] | ||
| 142 | |||
| 143 | [[bin]] | ||
| 121 | name = "eth" | 144 | name = "eth" |
| 122 | path = "src/bin/eth.rs" | 145 | path = "src/bin/eth.rs" |
| 123 | required-features = [ "eth",] | 146 | required-features = [ "eth",] |
| @@ -202,6 +225,11 @@ name = "wpan_mac" | |||
| 202 | path = "src/bin/wpan_mac.rs" | 225 | path = "src/bin/wpan_mac.rs" |
| 203 | required-features = [ "mac",] | 226 | required-features = [ "mac",] |
| 204 | 227 | ||
| 228 | [[bin]] | ||
| 229 | name = "hsem" | ||
| 230 | path = "src/bin/hsem.rs" | ||
| 231 | required-features = [ "hsem",] | ||
| 232 | |||
| 205 | # END TESTS | 233 | # END TESTS |
| 206 | 234 | ||
| 207 | [profile.dev] | 235 | [profile.dev] |
| @@ -233,3 +261,36 @@ debug = false | |||
| 233 | debug-assertions = false | 261 | debug-assertions = false |
| 234 | opt-level = 0 | 262 | opt-level = 0 |
| 235 | overflow-checks = false | 263 | overflow-checks = false |
| 264 | |||
| 265 | [package.metadata.embassy] | ||
| 266 | build = [ | ||
| 267 | { target = "thumbv7m-none-eabi", features = ["stm32f103c8"], artifact-dir = "out/tests/stm32f103c8" }, | ||
| 268 | { target = "thumbv7em-none-eabi", features = ["stm32f429zi"], artifact-dir = "out/tests/stm32f429zi" }, | ||
| 269 | { target = "thumbv7em-none-eabi", features = ["stm32f446re"], artifact-dir = "out/tests/stm32f446re" }, | ||
| 270 | { target = "thumbv7em-none-eabi", features = ["stm32g491re"], artifact-dir = "out/tests/stm32g491re" }, | ||
| 271 | { target = "thumbv6m-none-eabi", features = ["stm32g071rb"], artifact-dir = "out/tests/stm32g071rb" }, | ||
| 272 | { target = "thumbv6m-none-eabi", features = ["stm32c031c6"], artifact-dir = "out/tests/stm32c031c6" }, | ||
| 273 | { target = "thumbv6m-none-eabi", features = ["stm32c071rb"], artifact-dir = "out/tests/stm32c071rb" }, | ||
| 274 | { target = "thumbv7em-none-eabi", features = ["stm32h755zi"], artifact-dir = "out/tests/stm32h755zi" }, | ||
| 275 | { target = "thumbv7em-none-eabi", features = ["stm32h753zi"], artifact-dir = "out/tests/stm32h753zi" }, | ||
| 276 | { target = "thumbv7em-none-eabi", features = ["stm32h7a3zi"], artifact-dir = "out/tests/stm32h7a3zi" }, | ||
| 277 | { target = "thumbv7em-none-eabi", features = ["stm32wb55rg"], artifact-dir = "out/tests/stm32wb55rg" }, | ||
| 278 | { target = "thumbv8m.main-none-eabihf", features = ["stm32h563zi"], artifact-dir = "out/tests/stm32h563zi" }, | ||
| 279 | { target = "thumbv8m.main-none-eabihf", features = ["stm32u585ai"], artifact-dir = "out/tests/stm32u585ai" }, | ||
| 280 | { target = "thumbv8m.main-none-eabihf", features = ["stm32u5a5zj"], artifact-dir = "out/tests/stm32u5a5zj" }, | ||
| 281 | { target = "thumbv8m.main-none-eabihf", features = ["stm32wba52cg"], artifact-dir = "out/tests/stm32wba52cg" }, | ||
| 282 | { target = "thumbv6m-none-eabi", features = ["stm32l073rz"], artifact-dir = "out/tests/stm32l073rz" }, | ||
| 283 | { target = "thumbv7m-none-eabi", features = ["stm32l152re"], artifact-dir = "out/tests/stm32l152re" }, | ||
| 284 | { target = "thumbv7em-none-eabi", features = ["stm32l4a6zg"], artifact-dir = "out/tests/stm32l4a6zg" }, | ||
| 285 | { target = "thumbv7em-none-eabi", features = ["stm32l4r5zi"], artifact-dir = "out/tests/stm32l4r5zi" }, | ||
| 286 | { target = "thumbv8m.main-none-eabihf", features = ["stm32l552ze"], artifact-dir = "out/tests/stm32l552ze" }, | ||
| 287 | { target = "thumbv7em-none-eabi", features = ["stm32f767zi"], artifact-dir = "out/tests/stm32f767zi" }, | ||
| 288 | { target = "thumbv7m-none-eabi", features = ["stm32f207zg"], artifact-dir = "out/tests/stm32f207zg" }, | ||
| 289 | { target = "thumbv7em-none-eabi", features = ["stm32f303ze"], artifact-dir = "out/tests/stm32f303ze" }, | ||
| 290 | { target = "thumbv7em-none-eabi", features = ["stm32l496zg"], artifact-dir = "out/tests/stm32l496zg" }, | ||
| 291 | { target = "thumbv7em-none-eabi", features = ["stm32wl55jc"], artifact-dir = "out/tests/stm32wl55jc" }, | ||
| 292 | { target = "thumbv7em-none-eabi", features = ["stm32h7s3l8"], artifact-dir = "out/tests/stm32h7s3l8" }, | ||
| 293 | { target = "thumbv6m-none-eabi", features = ["stm32f091rc"], artifact-dir = "out/tests/stm32f091rc" }, | ||
| 294 | { target = "thumbv8m.main-none-eabihf", features = ["stm32h503rb"], artifact-dir = "out/tests/stm32h503rb" }, | ||
| 295 | { target = "thumbv6m-none-eabi", features = ["stm32u083rc"], artifact-dir = "out/tests/stm32u083rc" } | ||
| 296 | ] | ||
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index 722671bf1..556d77a20 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs | |||
| @@ -12,6 +12,7 @@ fn main() -> Result<(), Box<dyn Error>> { | |||
| 12 | // too little RAM to run from RAM. | 12 | // too little RAM to run from RAM. |
| 13 | feature = "stm32f103c8", // 20 kb | 13 | feature = "stm32f103c8", // 20 kb |
| 14 | feature = "stm32c031c6", // 6 kb | 14 | feature = "stm32c031c6", // 6 kb |
| 15 | feature = "stm32c071rb", // 24 kb | ||
| 15 | feature = "stm32l073rz", // 20 kb | 16 | feature = "stm32l073rz", // 20 kb |
| 16 | feature = "stm32h503rb", // 32 kb | 17 | feature = "stm32h503rb", // 32 kb |
| 17 | // no VTOR, so interrupts can't work when running from RAM | 18 | // no VTOR, so interrupts can't work when running from RAM |
diff --git a/tests/stm32/src/bin/afio.rs b/tests/stm32/src/bin/afio.rs new file mode 100644 index 000000000..d88765717 --- /dev/null +++ b/tests/stm32/src/bin/afio.rs | |||
| @@ -0,0 +1,1158 @@ | |||
| 1 | // required-features: afio | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 6 | |||
| 7 | use common::*; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_stm32::gpio::{AfioRemap, OutputType, Pull}; | ||
| 10 | use embassy_stm32::pac::AFIO; | ||
| 11 | use embassy_stm32::time::khz; | ||
| 12 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | ||
| 13 | use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; | ||
| 14 | use embassy_stm32::timer::pwm_input::PwmInput; | ||
| 15 | use embassy_stm32::timer::qei::Qei; | ||
| 16 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | ||
| 17 | use embassy_stm32::timer::{Ch1, Ch2}; | ||
| 18 | use embassy_stm32::usart::{Uart, UartRx, UartTx}; | ||
| 19 | use embassy_stm32::{Peripherals, bind_interrupts}; | ||
| 20 | |||
| 21 | #[cfg(not(feature = "afio-connectivity-line"))] | ||
| 22 | bind_interrupts!(struct Irqs { | ||
| 23 | USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>; | ||
| 24 | TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>; | ||
| 25 | }); | ||
| 26 | |||
| 27 | #[cfg(feature = "afio-connectivity-line")] | ||
| 28 | bind_interrupts!(struct Irqs { | ||
| 29 | CAN1_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN1>; | ||
| 30 | CAN1_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN1>; | ||
| 31 | CAN1_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN1>; | ||
| 32 | CAN1_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN1>; | ||
| 33 | |||
| 34 | CAN2_RX0 => embassy_stm32::can::Rx0InterruptHandler<embassy_stm32::peripherals::CAN2>; | ||
| 35 | CAN2_RX1 => embassy_stm32::can::Rx1InterruptHandler<embassy_stm32::peripherals::CAN2>; | ||
| 36 | CAN2_SCE => embassy_stm32::can::SceInterruptHandler<embassy_stm32::peripherals::CAN2>; | ||
| 37 | CAN2_TX => embassy_stm32::can::TxInterruptHandler<embassy_stm32::peripherals::CAN2>; | ||
| 38 | |||
| 39 | ETH => embassy_stm32::eth::InterruptHandler; | ||
| 40 | USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>; | ||
| 41 | TIM1_CC => embassy_stm32::timer::CaptureCompareInterruptHandler<embassy_stm32::peripherals::TIM1>; | ||
| 42 | }); | ||
| 43 | |||
| 44 | #[embassy_executor::main] | ||
| 45 | async fn main(_spawner: Spawner) { | ||
| 46 | let mut p = init(); | ||
| 47 | info!("Hello World!"); | ||
| 48 | |||
| 49 | // USART3 | ||
| 50 | { | ||
| 51 | // no remap RX/TX/RTS/CTS | ||
| 52 | afio_registers_set_remap(); | ||
| 53 | Uart::new_blocking_with_rtscts( | ||
| 54 | p.USART3.reborrow(), | ||
| 55 | p.PB11.reborrow(), | ||
| 56 | p.PB10.reborrow(), | ||
| 57 | p.PB14.reborrow(), | ||
| 58 | p.PB13.reborrow(), | ||
| 59 | Default::default(), | ||
| 60 | ) | ||
| 61 | .unwrap(); | ||
| 62 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 63 | } | ||
| 64 | { | ||
| 65 | // no remap RX/TX | ||
| 66 | afio_registers_set_remap(); | ||
| 67 | Uart::new_blocking( | ||
| 68 | p.USART3.reborrow(), | ||
| 69 | p.PB11.reborrow(), | ||
| 70 | p.PB10.reborrow(), | ||
| 71 | Default::default(), | ||
| 72 | ) | ||
| 73 | .unwrap(); | ||
| 74 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 75 | } | ||
| 76 | { | ||
| 77 | // no remap TX | ||
| 78 | afio_registers_set_remap(); | ||
| 79 | Uart::new_blocking_half_duplex( | ||
| 80 | p.USART3.reborrow(), | ||
| 81 | p.PB10.reborrow(), | ||
| 82 | Default::default(), | ||
| 83 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 84 | ) | ||
| 85 | .unwrap(); | ||
| 86 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 87 | } | ||
| 88 | { | ||
| 89 | // no remap TX async | ||
| 90 | afio_registers_set_remap(); | ||
| 91 | UartTx::new( | ||
| 92 | p.USART3.reborrow(), | ||
| 93 | p.PB10.reborrow(), | ||
| 94 | p.DMA1_CH2.reborrow(), | ||
| 95 | Default::default(), | ||
| 96 | ) | ||
| 97 | .unwrap(); | ||
| 98 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 99 | } | ||
| 100 | { | ||
| 101 | // no remap TX/CTS async | ||
| 102 | afio_registers_set_remap(); | ||
| 103 | UartTx::new_with_cts( | ||
| 104 | p.USART3.reborrow(), | ||
| 105 | p.PB10.reborrow(), | ||
| 106 | p.PB13.reborrow(), | ||
| 107 | p.DMA1_CH2.reborrow(), | ||
| 108 | Default::default(), | ||
| 109 | ) | ||
| 110 | .unwrap(); | ||
| 111 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 112 | } | ||
| 113 | { | ||
| 114 | // no remap RX async | ||
| 115 | afio_registers_set_remap(); | ||
| 116 | UartRx::new( | ||
| 117 | p.USART3.reborrow(), | ||
| 118 | Irqs, | ||
| 119 | p.PB11.reborrow(), | ||
| 120 | p.DMA1_CH3.reborrow(), | ||
| 121 | Default::default(), | ||
| 122 | ) | ||
| 123 | .unwrap(); | ||
| 124 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 125 | } | ||
| 126 | { | ||
| 127 | // no remap RX async | ||
| 128 | afio_registers_set_remap(); | ||
| 129 | UartRx::new_with_rts( | ||
| 130 | p.USART3.reborrow(), | ||
| 131 | Irqs, | ||
| 132 | p.PB11.reborrow(), | ||
| 133 | p.PB14.reborrow(), | ||
| 134 | p.DMA1_CH3.reborrow(), | ||
| 135 | Default::default(), | ||
| 136 | ) | ||
| 137 | .unwrap(); | ||
| 138 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 139 | } | ||
| 140 | { | ||
| 141 | // no remap RX/TX async | ||
| 142 | afio_registers_set_remap(); | ||
| 143 | Uart::new( | ||
| 144 | p.USART3.reborrow(), | ||
| 145 | p.PB11.reborrow(), | ||
| 146 | p.PB10.reborrow(), | ||
| 147 | Irqs, | ||
| 148 | p.DMA1_CH2.reborrow(), | ||
| 149 | p.DMA1_CH3.reborrow(), | ||
| 150 | Default::default(), | ||
| 151 | ) | ||
| 152 | .unwrap(); | ||
| 153 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 154 | } | ||
| 155 | { | ||
| 156 | // no remap RX/TX/RTS/CTS async | ||
| 157 | afio_registers_set_remap(); | ||
| 158 | Uart::new_with_rtscts( | ||
| 159 | p.USART3.reborrow(), | ||
| 160 | p.PB11.reborrow(), | ||
| 161 | p.PB10.reborrow(), | ||
| 162 | Irqs, | ||
| 163 | p.PB14.reborrow(), | ||
| 164 | p.PB13.reborrow(), | ||
| 165 | p.DMA1_CH2.reborrow(), | ||
| 166 | p.DMA1_CH3.reborrow(), | ||
| 167 | Default::default(), | ||
| 168 | ) | ||
| 169 | .unwrap(); | ||
| 170 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 0); | ||
| 171 | } | ||
| 172 | |||
| 173 | // TIM1 | ||
| 174 | { | ||
| 175 | // no remap | ||
| 176 | afio_registers_set_remap(); | ||
| 177 | SimplePwm::new::<AfioRemap<0>>( | ||
| 178 | p.TIM1.reborrow(), | ||
| 179 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | ||
| 180 | Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)), | ||
| 181 | Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)), | ||
| 182 | Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)), | ||
| 183 | khz(10), | ||
| 184 | Default::default(), | ||
| 185 | ); | ||
| 186 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0); | ||
| 187 | } | ||
| 188 | { | ||
| 189 | // no remap | ||
| 190 | afio_registers_set_remap(); | ||
| 191 | SimplePwm::new::<AfioRemap<0>>( | ||
| 192 | p.TIM1.reborrow(), | ||
| 193 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | ||
| 194 | None, | ||
| 195 | None, | ||
| 196 | None, | ||
| 197 | khz(10), | ||
| 198 | Default::default(), | ||
| 199 | ); | ||
| 200 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 0); | ||
| 201 | } | ||
| 202 | { | ||
| 203 | // partial remap | ||
| 204 | reset_afio_registers(); | ||
| 205 | ComplementaryPwm::new::<AfioRemap<1>>( | ||
| 206 | p.TIM1.reborrow(), | ||
| 207 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | ||
| 208 | None, | ||
| 209 | None, | ||
| 210 | None, | ||
| 211 | None, | ||
| 212 | None, | ||
| 213 | None, | ||
| 214 | None, | ||
| 215 | khz(10), | ||
| 216 | Default::default(), | ||
| 217 | ); | ||
| 218 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | ||
| 219 | } | ||
| 220 | { | ||
| 221 | // partial remap | ||
| 222 | reset_afio_registers(); | ||
| 223 | ComplementaryPwm::new::<AfioRemap<1>>( | ||
| 224 | p.TIM1.reborrow(), | ||
| 225 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | ||
| 226 | Some(ComplementaryPwmPin::new(p.PA7.reborrow(), OutputType::PushPull)), | ||
| 227 | Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)), | ||
| 228 | Some(ComplementaryPwmPin::new(p.PB0.reborrow(), OutputType::PushPull)), | ||
| 229 | Some(PwmPin::new(p.PA10.reborrow(), OutputType::PushPull)), | ||
| 230 | None, // pin does not exist on medium-density devices | ||
| 231 | Some(PwmPin::new(p.PA11.reborrow(), OutputType::PushPull)), | ||
| 232 | None, // signal does not exist | ||
| 233 | khz(10), | ||
| 234 | Default::default(), | ||
| 235 | ); | ||
| 236 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | ||
| 237 | } | ||
| 238 | { | ||
| 239 | // partial remap | ||
| 240 | reset_afio_registers(); | ||
| 241 | InputCapture::new::<AfioRemap<1>>( | ||
| 242 | p.TIM1.reborrow(), | ||
| 243 | Some(CapturePin::new(p.PA8.reborrow(), Pull::Down)), | ||
| 244 | None, | ||
| 245 | None, | ||
| 246 | None, | ||
| 247 | Irqs, | ||
| 248 | khz(10), | ||
| 249 | Default::default(), | ||
| 250 | ); | ||
| 251 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | ||
| 252 | } | ||
| 253 | { | ||
| 254 | // partial remap | ||
| 255 | reset_afio_registers(); | ||
| 256 | PwmInput::new_ch1::<AfioRemap<1>>(p.TIM1.reborrow(), p.PA8.reborrow(), Pull::Down, khz(10)); | ||
| 257 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | ||
| 258 | } | ||
| 259 | { | ||
| 260 | // partial remap | ||
| 261 | reset_afio_registers(); | ||
| 262 | Qei::new::<Ch1, Ch2, AfioRemap<1>>( | ||
| 263 | p.TIM1.reborrow(), | ||
| 264 | p.PA8.reborrow(), | ||
| 265 | p.PA9.reborrow(), | ||
| 266 | Default::default(), | ||
| 267 | ); | ||
| 268 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | ||
| 269 | } | ||
| 270 | |||
| 271 | // TIM2 | ||
| 272 | { | ||
| 273 | // no remap | ||
| 274 | afio_registers_set_remap(); | ||
| 275 | SimplePwm::new::<AfioRemap<0>>( | ||
| 276 | p.TIM2.reborrow(), | ||
| 277 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), | ||
| 278 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), | ||
| 279 | Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)), | ||
| 280 | Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)), | ||
| 281 | khz(10), | ||
| 282 | Default::default(), | ||
| 283 | ); | ||
| 284 | defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 0); | ||
| 285 | } | ||
| 286 | { | ||
| 287 | // partial remap 1 | ||
| 288 | reset_afio_registers(); | ||
| 289 | SimplePwm::new::<AfioRemap<1>>( | ||
| 290 | p.TIM2.reborrow(), | ||
| 291 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), | ||
| 292 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), | ||
| 293 | Some(PwmPin::new(p.PA2.reborrow(), OutputType::PushPull)), | ||
| 294 | Some(PwmPin::new(p.PA3.reborrow(), OutputType::PushPull)), | ||
| 295 | khz(10), | ||
| 296 | Default::default(), | ||
| 297 | ); | ||
| 298 | defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 1); | ||
| 299 | } | ||
| 300 | { | ||
| 301 | // partial remap 2 | ||
| 302 | reset_afio_registers(); | ||
| 303 | SimplePwm::new::<AfioRemap<2>>( | ||
| 304 | p.TIM2.reborrow(), | ||
| 305 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), | ||
| 306 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), | ||
| 307 | Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)), | ||
| 308 | Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)), | ||
| 309 | khz(10), | ||
| 310 | Default::default(), | ||
| 311 | ); | ||
| 312 | defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 2); | ||
| 313 | } | ||
| 314 | { | ||
| 315 | // full remap | ||
| 316 | reset_afio_registers(); | ||
| 317 | SimplePwm::new::<AfioRemap<3>>( | ||
| 318 | p.TIM2.reborrow(), | ||
| 319 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), | ||
| 320 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), | ||
| 321 | Some(PwmPin::new(p.PB10.reborrow(), OutputType::PushPull)), | ||
| 322 | Some(PwmPin::new(p.PB11.reborrow(), OutputType::PushPull)), | ||
| 323 | khz(10), | ||
| 324 | Default::default(), | ||
| 325 | ); | ||
| 326 | defmt::assert_eq!(AFIO.mapr().read().tim2_remap(), 3); | ||
| 327 | } | ||
| 328 | |||
| 329 | connectivity_line::run(&mut p); | ||
| 330 | value_line::run(&mut p); | ||
| 331 | |||
| 332 | info!("Test OK"); | ||
| 333 | cortex_m::asm::bkpt(); | ||
| 334 | } | ||
| 335 | |||
| 336 | #[cfg(feature = "afio-connectivity-line")] | ||
| 337 | mod connectivity_line { | ||
| 338 | use embassy_stm32::can::Can; | ||
| 339 | use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue}; | ||
| 340 | use embassy_stm32::i2s::I2S; | ||
| 341 | use embassy_stm32::spi::Spi; | ||
| 342 | |||
| 343 | use super::*; | ||
| 344 | |||
| 345 | pub fn run(p: &mut Peripherals) { | ||
| 346 | // USART3 | ||
| 347 | { | ||
| 348 | // partial remap RX/TX/RTS/CTS | ||
| 349 | reset_afio_registers(); | ||
| 350 | Uart::new_blocking_with_rtscts( | ||
| 351 | p.USART3.reborrow(), | ||
| 352 | p.PC11.reborrow(), | ||
| 353 | p.PC10.reborrow(), | ||
| 354 | p.PB14.reborrow(), | ||
| 355 | p.PB13.reborrow(), | ||
| 356 | Default::default(), | ||
| 357 | ) | ||
| 358 | .unwrap(); | ||
| 359 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 360 | } | ||
| 361 | { | ||
| 362 | // partial remap RX/TX | ||
| 363 | reset_afio_registers(); | ||
| 364 | Uart::new_blocking( | ||
| 365 | p.USART3.reborrow(), | ||
| 366 | p.PC11.reborrow(), | ||
| 367 | p.PC10.reborrow(), | ||
| 368 | Default::default(), | ||
| 369 | ) | ||
| 370 | .unwrap(); | ||
| 371 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 372 | } | ||
| 373 | { | ||
| 374 | // partial remap TX | ||
| 375 | reset_afio_registers(); | ||
| 376 | Uart::new_blocking_half_duplex( | ||
| 377 | p.USART3.reborrow(), | ||
| 378 | p.PC10.reborrow(), | ||
| 379 | Default::default(), | ||
| 380 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 381 | ) | ||
| 382 | .unwrap(); | ||
| 383 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 384 | } | ||
| 385 | { | ||
| 386 | // partial remap TX async | ||
| 387 | reset_afio_registers(); | ||
| 388 | UartTx::new( | ||
| 389 | p.USART3.reborrow(), | ||
| 390 | p.PC10.reborrow(), | ||
| 391 | p.DMA1_CH2.reborrow(), | ||
| 392 | Default::default(), | ||
| 393 | ) | ||
| 394 | .unwrap(); | ||
| 395 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 396 | } | ||
| 397 | { | ||
| 398 | // partial remap TX/CTS async | ||
| 399 | reset_afio_registers(); | ||
| 400 | UartTx::new_with_cts( | ||
| 401 | p.USART3.reborrow(), | ||
| 402 | p.PC10.reborrow(), | ||
| 403 | p.PB13.reborrow(), | ||
| 404 | p.DMA1_CH2.reborrow(), | ||
| 405 | Default::default(), | ||
| 406 | ) | ||
| 407 | .unwrap(); | ||
| 408 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 409 | } | ||
| 410 | { | ||
| 411 | // partial remap RX async | ||
| 412 | reset_afio_registers(); | ||
| 413 | UartRx::new( | ||
| 414 | p.USART3.reborrow(), | ||
| 415 | Irqs, | ||
| 416 | p.PC11.reborrow(), | ||
| 417 | p.DMA1_CH3.reborrow(), | ||
| 418 | Default::default(), | ||
| 419 | ) | ||
| 420 | .unwrap(); | ||
| 421 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 422 | } | ||
| 423 | { | ||
| 424 | // partial remap RX async | ||
| 425 | reset_afio_registers(); | ||
| 426 | UartRx::new_with_rts( | ||
| 427 | p.USART3.reborrow(), | ||
| 428 | Irqs, | ||
| 429 | p.PC11.reborrow(), | ||
| 430 | p.PB14.reborrow(), | ||
| 431 | p.DMA1_CH3.reborrow(), | ||
| 432 | Default::default(), | ||
| 433 | ) | ||
| 434 | .unwrap(); | ||
| 435 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 436 | } | ||
| 437 | { | ||
| 438 | // partial remap RX/TX async | ||
| 439 | reset_afio_registers(); | ||
| 440 | Uart::new( | ||
| 441 | p.USART3.reborrow(), | ||
| 442 | p.PC11.reborrow(), | ||
| 443 | p.PC10.reborrow(), | ||
| 444 | Irqs, | ||
| 445 | p.DMA1_CH2.reborrow(), | ||
| 446 | p.DMA1_CH3.reborrow(), | ||
| 447 | Default::default(), | ||
| 448 | ) | ||
| 449 | .unwrap(); | ||
| 450 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 451 | } | ||
| 452 | { | ||
| 453 | // partial remap RX/TX/RTS/CTS async | ||
| 454 | reset_afio_registers(); | ||
| 455 | Uart::new_with_rtscts( | ||
| 456 | p.USART3.reborrow(), | ||
| 457 | p.PC11.reborrow(), | ||
| 458 | p.PC10.reborrow(), | ||
| 459 | Irqs, | ||
| 460 | p.PB14.reborrow(), | ||
| 461 | p.PB13.reborrow(), | ||
| 462 | p.DMA1_CH2.reborrow(), | ||
| 463 | p.DMA1_CH3.reborrow(), | ||
| 464 | Default::default(), | ||
| 465 | ) | ||
| 466 | .unwrap(); | ||
| 467 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 1); | ||
| 468 | } | ||
| 469 | { | ||
| 470 | // full remap RX/TX/RTS/CTS | ||
| 471 | reset_afio_registers(); | ||
| 472 | Uart::new_blocking_with_rtscts( | ||
| 473 | p.USART3.reborrow(), | ||
| 474 | p.PD9.reborrow(), | ||
| 475 | p.PD8.reborrow(), | ||
| 476 | p.PD12.reborrow(), | ||
| 477 | p.PD11.reborrow(), | ||
| 478 | Default::default(), | ||
| 479 | ) | ||
| 480 | .unwrap(); | ||
| 481 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 482 | } | ||
| 483 | { | ||
| 484 | // full remap RX/TX | ||
| 485 | reset_afio_registers(); | ||
| 486 | Uart::new_blocking( | ||
| 487 | p.USART3.reborrow(), | ||
| 488 | p.PD9.reborrow(), | ||
| 489 | p.PD8.reborrow(), | ||
| 490 | Default::default(), | ||
| 491 | ) | ||
| 492 | .unwrap(); | ||
| 493 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 494 | } | ||
| 495 | { | ||
| 496 | // full remap TX | ||
| 497 | reset_afio_registers(); | ||
| 498 | Uart::new_blocking_half_duplex( | ||
| 499 | p.USART3.reborrow(), | ||
| 500 | p.PD8.reborrow(), | ||
| 501 | Default::default(), | ||
| 502 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 503 | ) | ||
| 504 | .unwrap(); | ||
| 505 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 506 | } | ||
| 507 | { | ||
| 508 | // full remap TX async | ||
| 509 | reset_afio_registers(); | ||
| 510 | UartTx::new( | ||
| 511 | p.USART3.reborrow(), | ||
| 512 | p.PD8.reborrow(), | ||
| 513 | p.DMA1_CH2.reborrow(), | ||
| 514 | Default::default(), | ||
| 515 | ) | ||
| 516 | .unwrap(); | ||
| 517 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 518 | } | ||
| 519 | { | ||
| 520 | // full remap TX/CTS async | ||
| 521 | reset_afio_registers(); | ||
| 522 | UartTx::new_with_cts( | ||
| 523 | p.USART3.reborrow(), | ||
| 524 | p.PD8.reborrow(), | ||
| 525 | p.PD11.reborrow(), | ||
| 526 | p.DMA1_CH2.reborrow(), | ||
| 527 | Default::default(), | ||
| 528 | ) | ||
| 529 | .unwrap(); | ||
| 530 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 531 | } | ||
| 532 | { | ||
| 533 | // full remap RX async | ||
| 534 | reset_afio_registers(); | ||
| 535 | UartRx::new( | ||
| 536 | p.USART3.reborrow(), | ||
| 537 | Irqs, | ||
| 538 | p.PD9.reborrow(), | ||
| 539 | p.DMA1_CH3.reborrow(), | ||
| 540 | Default::default(), | ||
| 541 | ) | ||
| 542 | .unwrap(); | ||
| 543 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 544 | } | ||
| 545 | { | ||
| 546 | // full remap RX async | ||
| 547 | reset_afio_registers(); | ||
| 548 | UartRx::new_with_rts( | ||
| 549 | p.USART3.reborrow(), | ||
| 550 | Irqs, | ||
| 551 | p.PD9.reborrow(), | ||
| 552 | p.PD12.reborrow(), | ||
| 553 | p.DMA1_CH3.reborrow(), | ||
| 554 | Default::default(), | ||
| 555 | ) | ||
| 556 | .unwrap(); | ||
| 557 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 558 | } | ||
| 559 | { | ||
| 560 | // full remap RX/TX async | ||
| 561 | reset_afio_registers(); | ||
| 562 | Uart::new( | ||
| 563 | p.USART3.reborrow(), | ||
| 564 | p.PD9.reborrow(), | ||
| 565 | p.PD8.reborrow(), | ||
| 566 | Irqs, | ||
| 567 | p.DMA1_CH2.reborrow(), | ||
| 568 | p.DMA1_CH3.reborrow(), | ||
| 569 | Default::default(), | ||
| 570 | ) | ||
| 571 | .unwrap(); | ||
| 572 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 573 | } | ||
| 574 | { | ||
| 575 | // full remap RX/TX/RTS/CTS async | ||
| 576 | reset_afio_registers(); | ||
| 577 | Uart::new_with_rtscts( | ||
| 578 | p.USART3.reborrow(), | ||
| 579 | p.PD9.reborrow(), | ||
| 580 | p.PD8.reborrow(), | ||
| 581 | Irqs, | ||
| 582 | p.PD12.reborrow(), | ||
| 583 | p.PD11.reborrow(), | ||
| 584 | p.DMA1_CH2.reborrow(), | ||
| 585 | p.DMA1_CH3.reborrow(), | ||
| 586 | Default::default(), | ||
| 587 | ) | ||
| 588 | .unwrap(); | ||
| 589 | defmt::assert_eq!(AFIO.mapr().read().usart3_remap(), 3); | ||
| 590 | } | ||
| 591 | |||
| 592 | // SPI3 | ||
| 593 | { | ||
| 594 | // no remap SCK/MISO/MOSI | ||
| 595 | afio_registers_set_remap(); | ||
| 596 | Spi::new_blocking( | ||
| 597 | p.SPI3.reborrow(), | ||
| 598 | p.PB3.reborrow(), | ||
| 599 | p.PB5.reborrow(), | ||
| 600 | p.PB4.reborrow(), | ||
| 601 | Default::default(), | ||
| 602 | ); | ||
| 603 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 604 | } | ||
| 605 | { | ||
| 606 | // no remap SCK/MOSI | ||
| 607 | afio_registers_set_remap(); | ||
| 608 | Spi::new_blocking_txonly( | ||
| 609 | p.SPI3.reborrow(), | ||
| 610 | p.PB3.reborrow(), | ||
| 611 | p.PB5.reborrow(), | ||
| 612 | Default::default(), | ||
| 613 | ); | ||
| 614 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 615 | } | ||
| 616 | { | ||
| 617 | // no remap MOSI | ||
| 618 | afio_registers_set_remap(); | ||
| 619 | Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default()); | ||
| 620 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 621 | } | ||
| 622 | { | ||
| 623 | // no remap SCK/MISO | ||
| 624 | afio_registers_set_remap(); | ||
| 625 | Spi::new_blocking_rxonly( | ||
| 626 | p.SPI3.reborrow(), | ||
| 627 | p.PB3.reborrow(), | ||
| 628 | p.PB4.reborrow(), | ||
| 629 | Default::default(), | ||
| 630 | ); | ||
| 631 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 632 | } | ||
| 633 | { | ||
| 634 | // remap SCK/MISO/MOSI | ||
| 635 | reset_afio_registers(); | ||
| 636 | Spi::new_blocking( | ||
| 637 | p.SPI3.reborrow(), | ||
| 638 | p.PC10.reborrow(), | ||
| 639 | p.PC12.reborrow(), | ||
| 640 | p.PC11.reborrow(), | ||
| 641 | Default::default(), | ||
| 642 | ); | ||
| 643 | |||
| 644 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 645 | } | ||
| 646 | { | ||
| 647 | // remap SCK/MOSI | ||
| 648 | reset_afio_registers(); | ||
| 649 | Spi::new_blocking_txonly( | ||
| 650 | p.SPI3.reborrow(), | ||
| 651 | p.PC10.reborrow(), | ||
| 652 | p.PC12.reborrow(), | ||
| 653 | Default::default(), | ||
| 654 | ); | ||
| 655 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 656 | } | ||
| 657 | { | ||
| 658 | // remap MOSI | ||
| 659 | reset_afio_registers(); | ||
| 660 | Spi::new_blocking_txonly_nosck(p.SPI3.reborrow(), p.PB5.reborrow(), Default::default()); | ||
| 661 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 662 | } | ||
| 663 | { | ||
| 664 | // remap SCK/MISO | ||
| 665 | reset_afio_registers(); | ||
| 666 | Spi::new_blocking_rxonly( | ||
| 667 | p.SPI3.reborrow(), | ||
| 668 | p.PC10.reborrow(), | ||
| 669 | p.PC11.reborrow(), | ||
| 670 | Default::default(), | ||
| 671 | ); | ||
| 672 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 673 | } | ||
| 674 | |||
| 675 | // I2S3 | ||
| 676 | { | ||
| 677 | // no remap SD/WS/CK/MCK | ||
| 678 | afio_registers_set_remap(); | ||
| 679 | I2S::new_txonly( | ||
| 680 | p.SPI3.reborrow(), | ||
| 681 | p.PB5.reborrow(), | ||
| 682 | p.PA15.reborrow(), | ||
| 683 | p.PB3.reborrow(), | ||
| 684 | p.PC7.reborrow(), | ||
| 685 | p.DMA2_CH2.reborrow(), | ||
| 686 | &mut [0u16; 0], | ||
| 687 | Default::default(), | ||
| 688 | ); | ||
| 689 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 690 | } | ||
| 691 | { | ||
| 692 | // no remap SD/WS/CK | ||
| 693 | afio_registers_set_remap(); | ||
| 694 | I2S::new_txonly_nomck( | ||
| 695 | p.SPI3.reborrow(), | ||
| 696 | p.PB5.reborrow(), | ||
| 697 | p.PA15.reborrow(), | ||
| 698 | p.PB3.reborrow(), | ||
| 699 | p.DMA2_CH2.reborrow(), | ||
| 700 | &mut [0u16; 0], | ||
| 701 | Default::default(), | ||
| 702 | ); | ||
| 703 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), false); | ||
| 704 | } | ||
| 705 | { | ||
| 706 | // no remap SD/WS/CK/MCK | ||
| 707 | afio_registers_set_remap(); | ||
| 708 | I2S::new_rxonly( | ||
| 709 | p.SPI3.reborrow(), | ||
| 710 | p.PB4.reborrow(), | ||
| 711 | p.PA15.reborrow(), | ||
| 712 | p.PB3.reborrow(), | ||
| 713 | p.PC7.reborrow(), | ||
| 714 | p.DMA2_CH1.reborrow(), | ||
| 715 | &mut [0u16; 0], | ||
| 716 | Default::default(), | ||
| 717 | ); | ||
| 718 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 719 | } | ||
| 720 | { | ||
| 721 | // remap SD/WS/CK/MCK | ||
| 722 | reset_afio_registers(); | ||
| 723 | I2S::new_txonly( | ||
| 724 | p.SPI3.reborrow(), | ||
| 725 | p.PC12.reborrow(), | ||
| 726 | p.PA4.reborrow(), | ||
| 727 | p.PC10.reborrow(), | ||
| 728 | p.PC7.reborrow(), | ||
| 729 | p.DMA2_CH2.reborrow(), | ||
| 730 | &mut [0u16; 0], | ||
| 731 | Default::default(), | ||
| 732 | ); | ||
| 733 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 734 | } | ||
| 735 | { | ||
| 736 | // remap SD/WS/CK | ||
| 737 | reset_afio_registers(); | ||
| 738 | I2S::new_txonly_nomck( | ||
| 739 | p.SPI3.reborrow(), | ||
| 740 | p.PC12.reborrow(), | ||
| 741 | p.PA4.reborrow(), | ||
| 742 | p.PC10.reborrow(), | ||
| 743 | p.DMA2_CH2.reborrow(), | ||
| 744 | &mut [0u16; 0], | ||
| 745 | Default::default(), | ||
| 746 | ); | ||
| 747 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 748 | } | ||
| 749 | { | ||
| 750 | // remap SD/WS/CK/MCK | ||
| 751 | reset_afio_registers(); | ||
| 752 | I2S::new_rxonly( | ||
| 753 | p.SPI3.reborrow(), | ||
| 754 | p.PC11.reborrow(), | ||
| 755 | p.PA4.reborrow(), | ||
| 756 | p.PC10.reborrow(), | ||
| 757 | p.PC7.reborrow(), | ||
| 758 | p.DMA2_CH1.reborrow(), | ||
| 759 | &mut [0u16; 0], | ||
| 760 | Default::default(), | ||
| 761 | ); | ||
| 762 | defmt::assert_eq!(AFIO.mapr().read().spi3_remap(), true); | ||
| 763 | } | ||
| 764 | |||
| 765 | // CAN2 | ||
| 766 | { | ||
| 767 | // no remap | ||
| 768 | afio_registers_set_remap(); | ||
| 769 | Can::new(p.CAN2.reborrow(), p.PB12.reborrow(), p.PB13.reborrow(), Irqs); | ||
| 770 | defmt::assert_eq!(AFIO.mapr().read().can2_remap(), false); | ||
| 771 | } | ||
| 772 | { | ||
| 773 | // remap | ||
| 774 | reset_afio_registers(); | ||
| 775 | Can::new(p.CAN2.reborrow(), p.PB5.reborrow(), p.PB6.reborrow(), Irqs); | ||
| 776 | defmt::assert_eq!(AFIO.mapr().read().can2_remap(), true); | ||
| 777 | } | ||
| 778 | |||
| 779 | // Ethernet | ||
| 780 | { | ||
| 781 | // no remap RMII | ||
| 782 | afio_registers_set_remap(); | ||
| 783 | Ethernet::new( | ||
| 784 | &mut PacketQueue::<1, 1>::new(), | ||
| 785 | p.ETH.reborrow(), | ||
| 786 | Irqs, | ||
| 787 | p.PA1.reborrow(), | ||
| 788 | p.PA2.reborrow(), | ||
| 789 | p.PC1.reborrow(), | ||
| 790 | p.PA7.reborrow(), | ||
| 791 | p.PC4.reborrow(), | ||
| 792 | p.PC5.reborrow(), | ||
| 793 | p.PB12.reborrow(), | ||
| 794 | p.PB13.reborrow(), | ||
| 795 | p.PB11.reborrow(), | ||
| 796 | GenericPhy::new_auto(), | ||
| 797 | Default::default(), | ||
| 798 | ); | ||
| 799 | defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false); | ||
| 800 | } | ||
| 801 | { | ||
| 802 | // no remap MII | ||
| 803 | afio_registers_set_remap(); | ||
| 804 | Ethernet::new_mii( | ||
| 805 | &mut PacketQueue::<1, 1>::new(), | ||
| 806 | p.ETH.reborrow(), | ||
| 807 | Irqs, | ||
| 808 | p.PA1.reborrow(), | ||
| 809 | p.PC3.reborrow(), | ||
| 810 | p.PA2.reborrow(), | ||
| 811 | p.PC1.reborrow(), | ||
| 812 | p.PA7.reborrow(), | ||
| 813 | p.PC4.reborrow(), | ||
| 814 | p.PC5.reborrow(), | ||
| 815 | p.PB0.reborrow(), | ||
| 816 | p.PB1.reborrow(), | ||
| 817 | p.PB12.reborrow(), | ||
| 818 | p.PB13.reborrow(), | ||
| 819 | p.PC2.reborrow(), | ||
| 820 | p.PB8.reborrow(), | ||
| 821 | p.PB11.reborrow(), | ||
| 822 | GenericPhy::new_auto(), | ||
| 823 | Default::default(), | ||
| 824 | ); | ||
| 825 | defmt::assert_eq!(AFIO.mapr().read().eth_remap(), false); | ||
| 826 | } | ||
| 827 | { | ||
| 828 | // remap RMII | ||
| 829 | reset_afio_registers(); | ||
| 830 | Ethernet::new( | ||
| 831 | &mut PacketQueue::<1, 1>::new(), | ||
| 832 | p.ETH.reborrow(), | ||
| 833 | Irqs, | ||
| 834 | p.PA1.reborrow(), | ||
| 835 | p.PA2.reborrow(), | ||
| 836 | p.PC1.reborrow(), | ||
| 837 | p.PD8.reborrow(), | ||
| 838 | p.PD9.reborrow(), | ||
| 839 | p.PD10.reborrow(), | ||
| 840 | p.PB12.reborrow(), | ||
| 841 | p.PB13.reborrow(), | ||
| 842 | p.PB11.reborrow(), | ||
| 843 | GenericPhy::new_auto(), | ||
| 844 | Default::default(), | ||
| 845 | ); | ||
| 846 | defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true); | ||
| 847 | } | ||
| 848 | { | ||
| 849 | // remap MII | ||
| 850 | reset_afio_registers(); | ||
| 851 | Ethernet::new_mii( | ||
| 852 | &mut PacketQueue::<1, 1>::new(), | ||
| 853 | p.ETH.reborrow(), | ||
| 854 | Irqs, | ||
| 855 | p.PA1.reborrow(), | ||
| 856 | p.PC3.reborrow(), | ||
| 857 | p.PA2.reborrow(), | ||
| 858 | p.PC1.reborrow(), | ||
| 859 | p.PD8.reborrow(), | ||
| 860 | p.PD9.reborrow(), | ||
| 861 | p.PD10.reborrow(), | ||
| 862 | p.PD11.reborrow(), | ||
| 863 | p.PD12.reborrow(), | ||
| 864 | p.PB12.reborrow(), | ||
| 865 | p.PB13.reborrow(), | ||
| 866 | p.PC2.reborrow(), | ||
| 867 | p.PB8.reborrow(), | ||
| 868 | p.PB11.reborrow(), | ||
| 869 | GenericPhy::new_auto(), | ||
| 870 | Default::default(), | ||
| 871 | ); | ||
| 872 | defmt::assert_eq!(AFIO.mapr().read().eth_remap(), true); | ||
| 873 | } | ||
| 874 | |||
| 875 | // CAN1 | ||
| 876 | { | ||
| 877 | // no remap | ||
| 878 | afio_registers_set_remap(); | ||
| 879 | Can::new(p.CAN1.reborrow(), p.PA11.reborrow(), p.PA12.reborrow(), Irqs); | ||
| 880 | defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 0); | ||
| 881 | } | ||
| 882 | { | ||
| 883 | // partial remap | ||
| 884 | reset_afio_registers(); | ||
| 885 | Can::new(p.CAN1.reborrow(), p.PB8.reborrow(), p.PB9.reborrow(), Irqs); | ||
| 886 | defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 2); | ||
| 887 | } | ||
| 888 | { | ||
| 889 | // full remap | ||
| 890 | reset_afio_registers(); | ||
| 891 | Can::new(p.CAN1.reborrow(), p.PD0.reborrow(), p.PD1.reborrow(), Irqs); | ||
| 892 | defmt::assert_eq!(AFIO.mapr().read().can1_remap(), 3); | ||
| 893 | } | ||
| 894 | |||
| 895 | // USART2 | ||
| 896 | { | ||
| 897 | // no remap RX/TX/RTS/CTS | ||
| 898 | afio_registers_set_remap(); | ||
| 899 | Uart::new_blocking_with_rtscts( | ||
| 900 | p.USART2.reborrow(), | ||
| 901 | p.PA3.reborrow(), | ||
| 902 | p.PA2.reborrow(), | ||
| 903 | p.PA1.reborrow(), | ||
| 904 | p.PA0.reborrow(), | ||
| 905 | Default::default(), | ||
| 906 | ) | ||
| 907 | .unwrap(); | ||
| 908 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false); | ||
| 909 | } | ||
| 910 | { | ||
| 911 | // no remap RX/TX | ||
| 912 | afio_registers_set_remap(); | ||
| 913 | Uart::new_blocking( | ||
| 914 | p.USART2.reborrow(), | ||
| 915 | p.PA3.reborrow(), | ||
| 916 | p.PA2.reborrow(), | ||
| 917 | Default::default(), | ||
| 918 | ) | ||
| 919 | .unwrap(); | ||
| 920 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false); | ||
| 921 | } | ||
| 922 | { | ||
| 923 | // no remap TX | ||
| 924 | afio_registers_set_remap(); | ||
| 925 | Uart::new_blocking_half_duplex( | ||
| 926 | p.USART2.reborrow(), | ||
| 927 | p.PA2.reborrow(), | ||
| 928 | Default::default(), | ||
| 929 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 930 | ) | ||
| 931 | .unwrap(); | ||
| 932 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false); | ||
| 933 | } | ||
| 934 | { | ||
| 935 | // full remap RX/TX/RTS/CTS | ||
| 936 | reset_afio_registers(); | ||
| 937 | Uart::new_blocking_with_rtscts( | ||
| 938 | p.USART2.reborrow(), | ||
| 939 | p.PD6.reborrow(), | ||
| 940 | p.PD5.reborrow(), | ||
| 941 | p.PD4.reborrow(), | ||
| 942 | p.PD3.reborrow(), | ||
| 943 | Default::default(), | ||
| 944 | ) | ||
| 945 | .unwrap(); | ||
| 946 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false); | ||
| 947 | } | ||
| 948 | { | ||
| 949 | // full remap RX/TX | ||
| 950 | reset_afio_registers(); | ||
| 951 | Uart::new_blocking( | ||
| 952 | p.USART2.reborrow(), | ||
| 953 | p.PD6.reborrow(), | ||
| 954 | p.PD5.reborrow(), | ||
| 955 | Default::default(), | ||
| 956 | ) | ||
| 957 | .unwrap(); | ||
| 958 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), false); | ||
| 959 | } | ||
| 960 | { | ||
| 961 | // full remap TX | ||
| 962 | reset_afio_registers(); | ||
| 963 | Uart::new_blocking_half_duplex( | ||
| 964 | p.USART2.reborrow(), | ||
| 965 | p.PD5.reborrow(), | ||
| 966 | Default::default(), | ||
| 967 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 968 | ) | ||
| 969 | .unwrap(); | ||
| 970 | defmt::assert_eq!(AFIO.mapr().read().usart2_remap(), true); | ||
| 971 | } | ||
| 972 | |||
| 973 | // USART1 | ||
| 974 | { | ||
| 975 | // no remap RX/TX/RTS/CTS | ||
| 976 | afio_registers_set_remap(); | ||
| 977 | Uart::new_blocking_with_rtscts( | ||
| 978 | p.USART1.reborrow(), | ||
| 979 | p.PA10.reborrow(), | ||
| 980 | p.PA9.reborrow(), | ||
| 981 | p.PA12.reborrow(), | ||
| 982 | p.PA11.reborrow(), | ||
| 983 | Default::default(), | ||
| 984 | ) | ||
| 985 | .unwrap(); | ||
| 986 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false); | ||
| 987 | } | ||
| 988 | { | ||
| 989 | // no remap RX/TX | ||
| 990 | afio_registers_set_remap(); | ||
| 991 | Uart::new_blocking( | ||
| 992 | p.USART1.reborrow(), | ||
| 993 | p.PA10.reborrow(), | ||
| 994 | p.PA9.reborrow(), | ||
| 995 | Default::default(), | ||
| 996 | ) | ||
| 997 | .unwrap(); | ||
| 998 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false); | ||
| 999 | } | ||
| 1000 | { | ||
| 1001 | // no remap TX | ||
| 1002 | afio_registers_set_remap(); | ||
| 1003 | Uart::new_blocking_half_duplex( | ||
| 1004 | p.USART1.reborrow(), | ||
| 1005 | p.PA9.reborrow(), | ||
| 1006 | Default::default(), | ||
| 1007 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 1008 | ) | ||
| 1009 | .unwrap(); | ||
| 1010 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), false); | ||
| 1011 | } | ||
| 1012 | { | ||
| 1013 | // remap RX/TX/RTS/CTS | ||
| 1014 | reset_afio_registers(); | ||
| 1015 | Uart::new_blocking_with_rtscts( | ||
| 1016 | p.USART1.reborrow(), | ||
| 1017 | p.PB7.reborrow(), | ||
| 1018 | p.PB6.reborrow(), | ||
| 1019 | p.PA12.reborrow(), | ||
| 1020 | p.PA11.reborrow(), | ||
| 1021 | Default::default(), | ||
| 1022 | ) | ||
| 1023 | .unwrap(); | ||
| 1024 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true); | ||
| 1025 | } | ||
| 1026 | { | ||
| 1027 | // remap RX/TX | ||
| 1028 | reset_afio_registers(); | ||
| 1029 | Uart::new_blocking( | ||
| 1030 | p.USART1.reborrow(), | ||
| 1031 | p.PB7.reborrow(), | ||
| 1032 | p.PB6.reborrow(), | ||
| 1033 | Default::default(), | ||
| 1034 | ) | ||
| 1035 | .unwrap(); | ||
| 1036 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true); | ||
| 1037 | } | ||
| 1038 | { | ||
| 1039 | // remap TX | ||
| 1040 | reset_afio_registers(); | ||
| 1041 | Uart::new_blocking_half_duplex( | ||
| 1042 | p.USART1.reborrow(), | ||
| 1043 | p.PB6.reborrow(), | ||
| 1044 | Default::default(), | ||
| 1045 | embassy_stm32::usart::HalfDuplexReadback::NoReadback, | ||
| 1046 | ) | ||
| 1047 | .unwrap(); | ||
| 1048 | defmt::assert_eq!(AFIO.mapr().read().usart1_remap(), true); | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | // TIM1 | ||
| 1052 | { | ||
| 1053 | // full remap | ||
| 1054 | reset_afio_registers(); | ||
| 1055 | SimplePwm::new( | ||
| 1056 | p.TIM1.reborrow(), | ||
| 1057 | Some(PwmPin::new(p.PE9.reborrow(), OutputType::PushPull)), | ||
| 1058 | Some(PwmPin::new(p.PE11.reborrow(), OutputType::PushPull)), | ||
| 1059 | None, | ||
| 1060 | None, | ||
| 1061 | khz(10), | ||
| 1062 | Default::default(), | ||
| 1063 | ); | ||
| 1064 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 3); | ||
| 1065 | } | ||
| 1066 | } | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | #[cfg(feature = "afio-value-line")] | ||
| 1070 | mod value_line { | ||
| 1071 | use super::*; | ||
| 1072 | |||
| 1073 | pub fn run(p: &mut Peripherals) { | ||
| 1074 | // TIM13 | ||
| 1075 | { | ||
| 1076 | // no remap | ||
| 1077 | reset_afio_registers(); | ||
| 1078 | SimplePwm::new( | ||
| 1079 | p.TIM13.reborrow(), | ||
| 1080 | Some(PwmPin::new(p.PC8.reborrow(), OutputType::PushPull)), | ||
| 1081 | None, | ||
| 1082 | None, | ||
| 1083 | None, | ||
| 1084 | khz(10), | ||
| 1085 | Default::default(), | ||
| 1086 | ); | ||
| 1087 | defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), false); | ||
| 1088 | } | ||
| 1089 | { | ||
| 1090 | // remap | ||
| 1091 | reset_afio_registers(); | ||
| 1092 | SimplePwm::new( | ||
| 1093 | p.TIM13.reborrow(), | ||
| 1094 | Some(PwmPin::new(p.PB0.reborrow(), OutputType::PushPull)), | ||
| 1095 | None, | ||
| 1096 | None, | ||
| 1097 | None, | ||
| 1098 | khz(10), | ||
| 1099 | Default::default(), | ||
| 1100 | ); | ||
| 1101 | defmt::assert_eq!(AFIO.mapr2().read().tim13_remap(), true); | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | #[cfg(not(feature = "afio-connectivity-line"))] | ||
| 1107 | mod connectivity_line { | ||
| 1108 | use super::*; | ||
| 1109 | |||
| 1110 | pub fn run(_: &mut Peripherals) {} | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | #[cfg(not(feature = "afio-value-line"))] | ||
| 1114 | mod value_line { | ||
| 1115 | use super::*; | ||
| 1116 | |||
| 1117 | pub fn run(_: &mut Peripherals) {} | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | fn reset_afio_registers() { | ||
| 1121 | set_afio_registers(false, 0); | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | fn afio_registers_set_remap() { | ||
| 1125 | set_afio_registers(true, 1); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | fn set_afio_registers(bool_val: bool, num_val: u8) { | ||
| 1129 | AFIO.mapr().modify(|w| { | ||
| 1130 | w.set_swj_cfg(embassy_stm32::pac::afio::vals::SwjCfg::NO_OP); | ||
| 1131 | w.set_can1_remap(num_val); | ||
| 1132 | w.set_can2_remap(bool_val); | ||
| 1133 | w.set_eth_remap(bool_val); | ||
| 1134 | w.set_i2c1_remap(bool_val); | ||
| 1135 | w.set_spi1_remap(bool_val); | ||
| 1136 | w.set_spi3_remap(bool_val); | ||
| 1137 | w.set_tim1_remap(num_val); | ||
| 1138 | w.set_tim2_remap(num_val); | ||
| 1139 | w.set_tim3_remap(num_val); | ||
| 1140 | w.set_tim4_remap(bool_val); | ||
| 1141 | w.set_usart1_remap(bool_val); | ||
| 1142 | w.set_usart2_remap(bool_val); | ||
| 1143 | w.set_usart3_remap(num_val); | ||
| 1144 | }); | ||
| 1145 | |||
| 1146 | AFIO.mapr2().modify(|w| { | ||
| 1147 | w.set_cec_remap(bool_val); | ||
| 1148 | w.set_tim9_remap(bool_val); | ||
| 1149 | w.set_tim10_remap(bool_val); | ||
| 1150 | w.set_tim11_remap(bool_val); | ||
| 1151 | w.set_tim12_remap(bool_val); | ||
| 1152 | w.set_tim13_remap(bool_val); | ||
| 1153 | w.set_tim14_remap(bool_val); | ||
| 1154 | w.set_tim15_remap(bool_val); | ||
| 1155 | w.set_tim16_remap(bool_val); | ||
| 1156 | w.set_tim17_remap(bool_val); | ||
| 1157 | }); | ||
| 1158 | } | ||
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs index ba8a33e34..348cd049d 100644 --- a/tests/stm32/src/bin/can.rs +++ b/tests/stm32/src/bin/can.rs | |||
| @@ -15,6 +15,7 @@ use embassy_stm32::peripherals::CAN1; | |||
| 15 | use embassy_time::Duration; | 15 | use embassy_time::Duration; |
| 16 | use {defmt_rtt as _, panic_probe as _}; | 16 | use {defmt_rtt as _, panic_probe as _}; |
| 17 | 17 | ||
| 18 | #[path = "../can_common.rs"] | ||
| 18 | mod can_common; | 19 | mod can_common; |
| 19 | use can_common::*; | 20 | use can_common::*; |
| 20 | 21 | ||
| @@ -27,7 +28,7 @@ bind_interrupts!(struct Irqs { | |||
| 27 | 28 | ||
| 28 | #[embassy_executor::main] | 29 | #[embassy_executor::main] |
| 29 | async fn main(_spawner: Spawner) { | 30 | async fn main(_spawner: Spawner) { |
| 30 | let p = embassy_stm32::init(config()); | 31 | let p = init(); |
| 31 | info!("Hello World!"); | 32 | info!("Hello World!"); |
| 32 | 33 | ||
| 33 | let options = TestOptions { | 34 | let options = TestOptions { |
| @@ -43,7 +44,7 @@ async fn main(_spawner: Spawner) { | |||
| 43 | // To synchronise to the bus the RX input needs to see a high level. | 44 | // To synchronise to the bus the RX input needs to see a high level. |
| 44 | // Use `mem::forget()` to release the borrow on the pin but keep the | 45 | // Use `mem::forget()` to release the borrow on the pin but keep the |
| 45 | // pull-up resistor enabled. | 46 | // pull-up resistor enabled. |
| 46 | let rx_pin = Input::new(&mut rx, Pull::Up); | 47 | let rx_pin = Input::new(rx.reborrow(), Pull::Up); |
| 47 | core::mem::forget(rx_pin); | 48 | core::mem::forget(rx_pin); |
| 48 | 49 | ||
| 49 | let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); | 50 | let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); |
diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs index e09226de8..e86eea58b 100644 --- a/tests/stm32/src/bin/cordic.rs +++ b/tests/stm32/src/bin/cordic.rs | |||
| @@ -29,7 +29,7 @@ const OUTPUT_LENGTH: usize = (INPUT_U32_COUNT - 1) * 2; | |||
| 29 | 29 | ||
| 30 | #[embassy_executor::main] | 30 | #[embassy_executor::main] |
| 31 | async fn main(_spawner: Spawner) { | 31 | async fn main(_spawner: Spawner) { |
| 32 | let dp = embassy_stm32::init(config()); | 32 | let dp = init(); |
| 33 | 33 | ||
| 34 | // | 34 | // |
| 35 | // use RNG generate random Q1.31 value | 35 | // use RNG generate random Q1.31 value |
| @@ -82,8 +82,8 @@ async fn main(_spawner: Spawner) { | |||
| 82 | let cnt1 = defmt::unwrap!( | 82 | let cnt1 = defmt::unwrap!( |
| 83 | cordic | 83 | cordic |
| 84 | .async_calc_32bit( | 84 | .async_calc_32bit( |
| 85 | &mut write_dma, | 85 | write_dma.reborrow(), |
| 86 | &mut read_dma, | 86 | read_dma.reborrow(), |
| 87 | &input_q1_31[2..], | 87 | &input_q1_31[2..], |
| 88 | &mut output_q1_31[cnt0..], | 88 | &mut output_q1_31[cnt0..], |
| 89 | true, | 89 | true, |
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs index 60778bdaa..640de50e3 100644 --- a/tests/stm32/src/bin/cryp.rs +++ b/tests/stm32/src/bin/cryp.rs | |||
| @@ -5,9 +5,9 @@ | |||
| 5 | #[path = "../common.rs"] | 5 | #[path = "../common.rs"] |
| 6 | mod common; | 6 | mod common; |
| 7 | 7 | ||
| 8 | use aes_gcm::Aes128Gcm; | ||
| 8 | use aes_gcm::aead::heapless::Vec; | 9 | use aes_gcm::aead::heapless::Vec; |
| 9 | use aes_gcm::aead::{AeadInPlace, KeyInit}; | 10 | use aes_gcm::aead::{AeadInPlace, KeyInit}; |
| 10 | use aes_gcm::Aes128Gcm; | ||
| 11 | use common::*; | 11 | use common::*; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::cryp::{self, *}; | 13 | use embassy_stm32::cryp::{self, *}; |
| @@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs { | |||
| 20 | 20 | ||
| 21 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 23 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 23 | let p: embassy_stm32::Peripherals = init(); |
| 24 | 24 | ||
| 25 | const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567"; | 25 | const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567"; |
| 26 | const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh"; | 26 | const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh"; |
| @@ -72,7 +72,7 @@ async fn main(_spawner: Spawner) { | |||
| 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); | 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); |
| 73 | 73 | ||
| 74 | // Decrypt in software using AES-GCM 128-bit | 74 | // Decrypt in software using AES-GCM 128-bit |
| 75 | let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec); | 75 | cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec).unwrap(); |
| 76 | 76 | ||
| 77 | info!("Test OK"); | 77 | info!("Test OK"); |
| 78 | cortex_m::asm::bkpt(); | 78 | cortex_m::asm::bkpt(); |
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 06501ab14..747b11e7f 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs | |||
| @@ -10,9 +10,8 @@ use core::f32::consts::PI; | |||
| 10 | use common::*; | 10 | use common::*; |
| 11 | use defmt::assert; | 11 | use defmt::assert; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::adc::Adc; | 13 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 14 | use embassy_stm32::dac::{DacCh1, Value}; | 14 | use embassy_stm32::dac::{DacCh1, Value}; |
| 15 | use embassy_stm32::dma::NoDma; | ||
| 16 | use embassy_time::Timer; | 15 | use embassy_time::Timer; |
| 17 | use micromath::F32Ext; | 16 | use micromath::F32Ext; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -20,14 +19,14 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 20 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
| 22 | // Initialize the board and obtain a Peripherals instance | 21 | // Initialize the board and obtain a Peripherals instance |
| 23 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 22 | let p: embassy_stm32::Peripherals = init(); |
| 24 | 23 | ||
| 25 | let adc = peri!(p, ADC); | 24 | let adc = peri!(p, ADC); |
| 26 | let dac = peri!(p, DAC); | 25 | let dac = peri!(p, DAC); |
| 27 | let dac_pin = peri!(p, DAC_PIN); | 26 | let dac_pin = peri!(p, DAC_PIN); |
| 28 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; | 27 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; |
| 29 | 28 | ||
| 30 | let mut dac = DacCh1::new(dac, NoDma, dac_pin); | 29 | let mut dac = DacCh1::new_blocking(dac, dac_pin); |
| 31 | let mut adc = Adc::new(adc); | 30 | let mut adc = Adc::new(adc); |
| 32 | 31 | ||
| 33 | #[cfg(feature = "stm32h755zi")] | 32 | #[cfg(feature = "stm32h755zi")] |
| @@ -38,7 +37,7 @@ async fn main(_spawner: Spawner) { | |||
| 38 | dac.set(Value::Bit8(0)); | 37 | dac.set(Value::Bit8(0)); |
| 39 | // Now wait a little to obtain a stable value | 38 | // Now wait a little to obtain a stable value |
| 40 | Timer::after_millis(30).await; | 39 | Timer::after_millis(30).await; |
| 41 | let offset = adc.read(&mut adc_pin); | 40 | let offset = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0)); |
| 42 | 41 | ||
| 43 | for v in 0..=255 { | 42 | for v in 0..=255 { |
| 44 | // First set the DAC output value | 43 | // First set the DAC output value |
| @@ -49,7 +48,10 @@ async fn main(_spawner: Spawner) { | |||
| 49 | Timer::after_millis(30).await; | 48 | Timer::after_millis(30).await; |
| 50 | 49 | ||
| 51 | // Need to steal the peripherals here because PA4 is obviously in use already | 50 | // Need to steal the peripherals here because PA4 is obviously in use already |
| 52 | let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); | 51 | let measured = adc.blocking_read( |
| 52 | &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4, | ||
| 53 | SampleTime::from_bits(0), | ||
| 54 | ); | ||
| 53 | // Calibrate and normalize the measurement to get close to the dac_output_val | 55 | // Calibrate and normalize the measurement to get close to the dac_output_val |
| 54 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; | 56 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; |
| 55 | 57 | ||
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs index d5e9c9722..2fe0cf1f1 100644 --- a/tests/stm32/src/bin/dac_l1.rs +++ b/tests/stm32/src/bin/dac_l1.rs | |||
| @@ -10,9 +10,8 @@ use core::f32::consts::PI; | |||
| 10 | use common::*; | 10 | use common::*; |
| 11 | use defmt::assert; | 11 | use defmt::assert; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::adc::Adc; | 13 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 14 | use embassy_stm32::dac::{DacCh1, Value}; | 14 | use embassy_stm32::dac::{DacCh1, Value}; |
| 15 | use embassy_stm32::dma::NoDma; | ||
| 16 | use embassy_stm32::{bind_interrupts, peripherals}; | 15 | use embassy_stm32::{bind_interrupts, peripherals}; |
| 17 | use embassy_time::Timer; | 16 | use embassy_time::Timer; |
| 18 | use micromath::F32Ext; | 17 | use micromath::F32Ext; |
| @@ -25,14 +24,14 @@ bind_interrupts!(struct Irqs { | |||
| 25 | #[embassy_executor::main] | 24 | #[embassy_executor::main] |
| 26 | async fn main(_spawner: Spawner) { | 25 | async fn main(_spawner: Spawner) { |
| 27 | // Initialize the board and obtain a Peripherals instance | 26 | // Initialize the board and obtain a Peripherals instance |
| 28 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 27 | let p: embassy_stm32::Peripherals = init(); |
| 29 | 28 | ||
| 30 | let adc = peri!(p, ADC); | 29 | let adc = peri!(p, ADC); |
| 31 | let dac = peri!(p, DAC); | 30 | let dac = peri!(p, DAC); |
| 32 | let dac_pin = peri!(p, DAC_PIN); | 31 | let dac_pin = peri!(p, DAC_PIN); |
| 33 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; | 32 | let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; |
| 34 | 33 | ||
| 35 | let mut dac = DacCh1::new(dac, NoDma, dac_pin); | 34 | let mut dac = DacCh1::new_blocking(dac, dac_pin); |
| 36 | let mut adc = Adc::new(adc, Irqs); | 35 | let mut adc = Adc::new(adc, Irqs); |
| 37 | 36 | ||
| 38 | #[cfg(feature = "stm32h755zi")] | 37 | #[cfg(feature = "stm32h755zi")] |
| @@ -48,7 +47,7 @@ async fn main(_spawner: Spawner) { | |||
| 48 | dac.set(Value::Bit8(0)); | 47 | dac.set(Value::Bit8(0)); |
| 49 | // Now wait a little to obtain a stable value | 48 | // Now wait a little to obtain a stable value |
| 50 | Timer::after_millis(30).await; | 49 | Timer::after_millis(30).await; |
| 51 | let offset = adc.read(&mut adc_pin).await; | 50 | let offset = adc.read(&mut adc_pin, SampleTime::from_bits(0)).await; |
| 52 | 51 | ||
| 53 | for v in 0..=255 { | 52 | for v in 0..=255 { |
| 54 | // First set the DAC output value | 53 | // First set the DAC output value |
| @@ -59,7 +58,12 @@ async fn main(_spawner: Spawner) { | |||
| 59 | Timer::after_millis(30).await; | 58 | Timer::after_millis(30).await; |
| 60 | 59 | ||
| 61 | // Need to steal the peripherals here because PA4 is obviously in use already | 60 | // Need to steal the peripherals here because PA4 is obviously in use already |
| 62 | let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4).await; | 61 | let measured = adc |
| 62 | .read( | ||
| 63 | &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4, | ||
| 64 | SampleTime::from_bits(0), | ||
| 65 | ) | ||
| 66 | .await; | ||
| 63 | // Calibrate and normalize the measurement to get close to the dac_output_val | 67 | // Calibrate and normalize the measurement to get close to the dac_output_val |
| 64 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; | 68 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; |
| 65 | 69 | ||
diff --git a/tests/stm32/src/bin/eeprom.rs b/tests/stm32/src/bin/eeprom.rs new file mode 100644 index 000000000..61d249fd7 --- /dev/null +++ b/tests/stm32/src/bin/eeprom.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | // required-features: eeprom | ||
| 5 | |||
| 6 | #[path = "../common.rs"] | ||
| 7 | mod common; | ||
| 8 | |||
| 9 | use common::*; | ||
| 10 | use defmt::assert_eq; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::flash::Flash; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | // Initialize the board and obtain a Peripherals instance | ||
| 18 | let p: embassy_stm32::Peripherals = init(); | ||
| 19 | |||
| 20 | let mut f = Flash::new_blocking(p.FLASH); | ||
| 21 | const ADDR: u32 = 0x0; | ||
| 22 | |||
| 23 | unwrap!(f.eeprom_write_slice(ADDR, &[1, 2, 3, 4, 5, 6, 7, 8])); | ||
| 24 | let mut buf = [0u8; 8]; | ||
| 25 | unwrap!(f.eeprom_read_slice(ADDR, &mut buf)); | ||
| 26 | assert_eq!(&buf[..], &[1, 2, 3, 4, 5, 6, 7, 8]); | ||
| 27 | |||
| 28 | info!("Test OK"); | ||
| 29 | cortex_m::asm::bkpt(); | ||
| 30 | } | ||
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 7c02f0354..ffc76b96f 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs | |||
| @@ -6,13 +6,11 @@ | |||
| 6 | mod common; | 6 | mod common; |
| 7 | use common::*; | 7 | use common::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_net::{Stack, StackResources}; | 9 | use embassy_net::StackResources; |
| 10 | use embassy_stm32::eth::generic_smi::GenericSMI; | 10 | use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue, Sma}; |
| 11 | use embassy_stm32::eth::{Ethernet, PacketQueue}; | 11 | use embassy_stm32::peripherals::{ETH, ETH_SMA}; |
| 12 | use embassy_stm32::peripherals::ETH; | ||
| 13 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; | 13 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; |
| 15 | use rand_core::RngCore; | ||
| 16 | use static_cell::StaticCell; | 14 | use static_cell::StaticCell; |
| 17 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 18 | 16 | ||
| @@ -29,16 +27,16 @@ bind_interrupts!(struct Irqs { | |||
| 29 | RNG => rng::InterruptHandler<peripherals::RNG>; | 27 | RNG => rng::InterruptHandler<peripherals::RNG>; |
| 30 | }); | 28 | }); |
| 31 | 29 | ||
| 32 | type Device = Ethernet<'static, ETH, GenericSMI>; | 30 | type Device = Ethernet<'static, ETH, GenericPhy<Sma<'static, ETH_SMA>>>; |
| 33 | 31 | ||
| 34 | #[embassy_executor::task] | 32 | #[embassy_executor::task] |
| 35 | async fn net_task(stack: &'static Stack<Device>) -> ! { | 33 | async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! { |
| 36 | stack.run().await | 34 | runner.run().await |
| 37 | } | 35 | } |
| 38 | 36 | ||
| 39 | #[embassy_executor::main] | 37 | #[embassy_executor::main] |
| 40 | async fn main(spawner: Spawner) { | 38 | async fn main(spawner: Spawner) { |
| 41 | let p = embassy_stm32::init(config()); | 39 | let p = init(); |
| 42 | info!("Hello World!"); | 40 | info!("Hello World!"); |
| 43 | 41 | ||
| 44 | // Generate random seed. | 42 | // Generate random seed. |
| @@ -71,13 +69,12 @@ async fn main(spawner: Spawner) { | |||
| 71 | const PACKET_QUEUE_SIZE: usize = 4; | 69 | const PACKET_QUEUE_SIZE: usize = 4; |
| 72 | 70 | ||
| 73 | static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); | 71 | static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); |
| 72 | |||
| 74 | let device = Ethernet::new( | 73 | let device = Ethernet::new( |
| 75 | PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), | 74 | PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), |
| 76 | p.ETH, | 75 | p.ETH, |
| 77 | Irqs, | 76 | Irqs, |
| 78 | p.PA1, | 77 | p.PA1, |
| 79 | p.PA2, | ||
| 80 | p.PC1, | ||
| 81 | p.PA7, | 78 | p.PA7, |
| 82 | p.PC4, | 79 | p.PC4, |
| 83 | p.PC5, | 80 | p.PC5, |
| @@ -87,8 +84,10 @@ async fn main(spawner: Spawner) { | |||
| 87 | #[cfg(feature = "stm32h563zi")] | 84 | #[cfg(feature = "stm32h563zi")] |
| 88 | p.PB15, | 85 | p.PB15, |
| 89 | p.PG11, | 86 | p.PG11, |
| 90 | GenericSMI::new(0), | ||
| 91 | mac_addr, | 87 | mac_addr, |
| 88 | p.ETH_SMA, | ||
| 89 | p.PA2, | ||
| 90 | p.PC1, | ||
| 92 | ); | 91 | ); |
| 93 | 92 | ||
| 94 | let config = embassy_net::Config::dhcpv4(Default::default()); | 93 | let config = embassy_net::Config::dhcpv4(Default::default()); |
| @@ -99,17 +98,11 @@ async fn main(spawner: Spawner) { | |||
| 99 | //}); | 98 | //}); |
| 100 | 99 | ||
| 101 | // Init network stack | 100 | // Init network stack |
| 102 | static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||
| 103 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 101 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 104 | let stack = &*STACK.init(Stack::new( | 102 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 105 | device, | ||
| 106 | config, | ||
| 107 | RESOURCES.init(StackResources::<2>::new()), | ||
| 108 | seed, | ||
| 109 | )); | ||
| 110 | 103 | ||
| 111 | // Launch network task | 104 | // Launch network task |
| 112 | unwrap!(spawner.spawn(net_task(&stack))); | 105 | spawner.spawn(unwrap!(net_task(runner))); |
| 113 | 106 | ||
| 114 | perf_client::run( | 107 | perf_client::run( |
| 115 | stack, | 108 | stack, |
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs index bc2b7edd4..d97f493df 100644 --- a/tests/stm32/src/bin/fdcan.rs +++ b/tests/stm32/src/bin/fdcan.rs | |||
| @@ -8,10 +8,11 @@ mod common; | |||
| 8 | use common::*; | 8 | use common::*; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_stm32::peripherals::*; | 10 | use embassy_stm32::peripherals::*; |
| 11 | use embassy_stm32::{bind_interrupts, can, Config}; | 11 | use embassy_stm32::{Config, bind_interrupts, can}; |
| 12 | use embassy_time::Duration; | 12 | use embassy_time::Duration; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | #[path = "../can_common.rs"] | ||
| 15 | mod can_common; | 16 | mod can_common; |
| 16 | use can_common::*; | 17 | use can_common::*; |
| 17 | 18 | ||
| @@ -102,10 +103,10 @@ fn options() -> (Config, TestOptions) { | |||
| 102 | 103 | ||
| 103 | #[embassy_executor::main] | 104 | #[embassy_executor::main] |
| 104 | async fn main(_spawner: Spawner) { | 105 | async fn main(_spawner: Spawner) { |
| 105 | //let peripherals = embassy_stm32::init(config()); | 106 | //let peripherals = init(); |
| 106 | 107 | ||
| 107 | let (config, options) = options(); | 108 | let (config, options) = options(); |
| 108 | let peripherals = embassy_stm32::init(config); | 109 | let peripherals = init_with_config(config); |
| 109 | 110 | ||
| 110 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); | 111 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); |
| 111 | let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); | 112 | let mut can2 = can::CanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); |
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index dfa299ab5..40b03201c 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs | |||
| @@ -10,7 +10,7 @@ use embassy_stm32::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull, Spe | |||
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 13 | let p = embassy_stm32::init(config()); | 13 | let p = init(); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | // Arduino pins D0 and D1 | 16 | // Arduino pins D0 and D1 |
| @@ -20,10 +20,10 @@ async fn main(_spawner: Spawner) { | |||
| 20 | 20 | ||
| 21 | // Test initial output | 21 | // Test initial output |
| 22 | { | 22 | { |
| 23 | let b = Input::new(&mut b, Pull::None); | 23 | let b = Input::new(b.reborrow(), Pull::None); |
| 24 | 24 | ||
| 25 | { | 25 | { |
| 26 | let a = Output::new(&mut a, Level::Low, Speed::Low); | 26 | let a = Output::new(a.reborrow(), Level::Low, Speed::Low); |
| 27 | delay(); | 27 | delay(); |
| 28 | assert!(b.is_low()); | 28 | assert!(b.is_low()); |
| 29 | assert!(!b.is_high()); | 29 | assert!(!b.is_high()); |
| @@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) { | |||
| 31 | assert!(!a.is_set_high()); | 31 | assert!(!a.is_set_high()); |
| 32 | } | 32 | } |
| 33 | { | 33 | { |
| 34 | let mut a = Output::new(&mut a, Level::High, Speed::Low); | 34 | let mut a = Output::new(a.reborrow(), Level::High, Speed::Low); |
| 35 | delay(); | 35 | delay(); |
| 36 | assert!(!b.is_low()); | 36 | assert!(!b.is_low()); |
| 37 | assert!(b.is_high()); | 37 | assert!(b.is_high()); |
| @@ -68,10 +68,10 @@ async fn main(_spawner: Spawner) { | |||
| 68 | 68 | ||
| 69 | // Test input no pull | 69 | // Test input no pull |
| 70 | { | 70 | { |
| 71 | let b = Input::new(&mut b, Pull::None); | 71 | let b = Input::new(b.reborrow(), Pull::None); |
| 72 | // no pull, the status is undefined | 72 | // no pull, the status is undefined |
| 73 | 73 | ||
| 74 | let mut a = Output::new(&mut a, Level::Low, Speed::Low); | 74 | let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); |
| 75 | delay(); | 75 | delay(); |
| 76 | assert!(b.is_low()); | 76 | assert!(b.is_low()); |
| 77 | a.set_high(); | 77 | a.set_high(); |
| @@ -81,11 +81,11 @@ async fn main(_spawner: Spawner) { | |||
| 81 | 81 | ||
| 82 | // Test input pulldown | 82 | // Test input pulldown |
| 83 | { | 83 | { |
| 84 | let b = Input::new(&mut b, Pull::Down); | 84 | let b = Input::new(b.reborrow(), Pull::Down); |
| 85 | delay(); | 85 | delay(); |
| 86 | assert!(b.is_low()); | 86 | assert!(b.is_low()); |
| 87 | 87 | ||
| 88 | let mut a = Output::new(&mut a, Level::Low, Speed::Low); | 88 | let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); |
| 89 | delay(); | 89 | delay(); |
| 90 | assert!(b.is_low()); | 90 | assert!(b.is_low()); |
| 91 | a.set_high(); | 91 | a.set_high(); |
| @@ -95,11 +95,11 @@ async fn main(_spawner: Spawner) { | |||
| 95 | 95 | ||
| 96 | // Test input pullup | 96 | // Test input pullup |
| 97 | { | 97 | { |
| 98 | let b = Input::new(&mut b, Pull::Up); | 98 | let b = Input::new(b.reborrow(), Pull::Up); |
| 99 | delay(); | 99 | delay(); |
| 100 | assert!(b.is_high()); | 100 | assert!(b.is_high()); |
| 101 | 101 | ||
| 102 | let mut a = Output::new(&mut a, Level::Low, Speed::Low); | 102 | let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); |
| 103 | delay(); | 103 | delay(); |
| 104 | assert!(b.is_low()); | 104 | assert!(b.is_low()); |
| 105 | a.set_high(); | 105 | a.set_high(); |
| @@ -109,10 +109,10 @@ async fn main(_spawner: Spawner) { | |||
| 109 | 109 | ||
| 110 | // Test output open drain | 110 | // Test output open drain |
| 111 | { | 111 | { |
| 112 | let b = Input::new(&mut b, Pull::Down); | 112 | let b = Input::new(b.reborrow(), Pull::Down); |
| 113 | // no pull, the status is undefined | 113 | // no pull, the status is undefined |
| 114 | 114 | ||
| 115 | let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low, Pull::None); | 115 | let mut a = OutputOpenDrain::new(a.reborrow(), Level::Low, Speed::Low); |
| 116 | delay(); | 116 | delay(); |
| 117 | assert!(b.is_low()); | 117 | assert!(b.is_low()); |
| 118 | a.set_high(); // High-Z output | 118 | a.set_high(); // High-Z output |
| @@ -124,12 +124,12 @@ async fn main(_spawner: Spawner) { | |||
| 124 | // Test initial output | 124 | // Test initial output |
| 125 | { | 125 | { |
| 126 | //Flex pin configured as input | 126 | //Flex pin configured as input |
| 127 | let mut b = Flex::new(&mut b); | 127 | let mut b = Flex::new(b.reborrow()); |
| 128 | b.set_as_input(Pull::None); | 128 | b.set_as_input(Pull::None); |
| 129 | 129 | ||
| 130 | { | 130 | { |
| 131 | //Flex pin configured as output | 131 | //Flex pin configured as output |
| 132 | let mut a = Flex::new(&mut a); //Flex pin configured as output | 132 | let mut a = Flex::new(a.reborrow()); //Flex pin configured as output |
| 133 | a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state | 133 | a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state |
| 134 | a.set_as_output(Speed::Low); | 134 | a.set_as_output(Speed::Low); |
| 135 | delay(); | 135 | delay(); |
| @@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) { | |||
| 137 | } | 137 | } |
| 138 | { | 138 | { |
| 139 | //Flex pin configured as output | 139 | //Flex pin configured as output |
| 140 | let mut a = Flex::new(&mut a); | 140 | let mut a = Flex::new(a.reborrow()); |
| 141 | a.set_high(); | 141 | a.set_high(); |
| 142 | a.set_as_output(Speed::Low); | 142 | a.set_as_output(Speed::Low); |
| 143 | 143 | ||
| @@ -148,10 +148,10 @@ async fn main(_spawner: Spawner) { | |||
| 148 | 148 | ||
| 149 | // Test input no pull | 149 | // Test input no pull |
| 150 | { | 150 | { |
| 151 | let mut b = Flex::new(&mut b); | 151 | let mut b = Flex::new(b.reborrow()); |
| 152 | b.set_as_input(Pull::None); // no pull, the status is undefined | 152 | b.set_as_input(Pull::None); // no pull, the status is undefined |
| 153 | 153 | ||
| 154 | let mut a = Flex::new(&mut a); | 154 | let mut a = Flex::new(a.reborrow()); |
| 155 | a.set_low(); | 155 | a.set_low(); |
| 156 | a.set_as_output(Speed::Low); | 156 | a.set_as_output(Speed::Low); |
| 157 | 157 | ||
| @@ -164,12 +164,12 @@ async fn main(_spawner: Spawner) { | |||
| 164 | 164 | ||
| 165 | // Test input pulldown | 165 | // Test input pulldown |
| 166 | { | 166 | { |
| 167 | let mut b = Flex::new(&mut b); | 167 | let mut b = Flex::new(b.reborrow()); |
| 168 | b.set_as_input(Pull::Down); | 168 | b.set_as_input(Pull::Down); |
| 169 | delay(); | 169 | delay(); |
| 170 | assert!(b.is_low()); | 170 | assert!(b.is_low()); |
| 171 | 171 | ||
| 172 | let mut a = Flex::new(&mut a); | 172 | let mut a = Flex::new(a.reborrow()); |
| 173 | a.set_low(); | 173 | a.set_low(); |
| 174 | a.set_as_output(Speed::Low); | 174 | a.set_as_output(Speed::Low); |
| 175 | delay(); | 175 | delay(); |
| @@ -181,12 +181,12 @@ async fn main(_spawner: Spawner) { | |||
| 181 | 181 | ||
| 182 | // Test input pullup | 182 | // Test input pullup |
| 183 | { | 183 | { |
| 184 | let mut b = Flex::new(&mut b); | 184 | let mut b = Flex::new(b.reborrow()); |
| 185 | b.set_as_input(Pull::Up); | 185 | b.set_as_input(Pull::Up); |
| 186 | delay(); | 186 | delay(); |
| 187 | assert!(b.is_high()); | 187 | assert!(b.is_high()); |
| 188 | 188 | ||
| 189 | let mut a = Flex::new(&mut a); | 189 | let mut a = Flex::new(a.reborrow()); |
| 190 | a.set_high(); | 190 | a.set_high(); |
| 191 | a.set_as_output(Speed::Low); | 191 | a.set_as_output(Speed::Low); |
| 192 | delay(); | 192 | delay(); |
| @@ -198,12 +198,12 @@ async fn main(_spawner: Spawner) { | |||
| 198 | 198 | ||
| 199 | // Test output open drain | 199 | // Test output open drain |
| 200 | { | 200 | { |
| 201 | let mut b = Flex::new(&mut b); | 201 | let mut b = Flex::new(b.reborrow()); |
| 202 | b.set_as_input(Pull::Down); | 202 | b.set_as_input(Pull::Down); |
| 203 | 203 | ||
| 204 | let mut a = Flex::new(&mut a); | 204 | let mut a = Flex::new(a.reborrow()); |
| 205 | a.set_low(); | 205 | a.set_low(); |
| 206 | a.set_as_input_output(Speed::Low, Pull::None); | 206 | a.set_as_input_output(Speed::Low); |
| 207 | delay(); | 207 | delay(); |
| 208 | assert!(b.is_low()); | 208 | assert!(b.is_low()); |
| 209 | a.set_high(); // High-Z output | 209 | a.set_high(); // High-Z output |
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs index 5f54ea435..bb08d0cf1 100644 --- a/tests/stm32/src/bin/hash.rs +++ b/tests/stm32/src/bin/hash.rs | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | mod common; | 6 | mod common; |
| 7 | use common::*; | 7 | use common::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::dma::NoDma; | ||
| 10 | use embassy_stm32::hash::*; | 9 | use embassy_stm32::hash::*; |
| 10 | use embassy_stm32::mode::Blocking; | ||
| 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; | 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; |
| 12 | use hmac::{Hmac, Mac}; | 12 | use hmac::{Hmac, Mac}; |
| 13 | use sha2::{Digest, Sha224, Sha256}; | 13 | use sha2::{Digest, Sha224, Sha256}; |
| @@ -33,11 +33,7 @@ bind_interrupts!(struct Irqs { | |||
| 33 | HASH => hash::InterruptHandler<peripherals::HASH>; | 33 | HASH => hash::InterruptHandler<peripherals::HASH>; |
| 34 | }); | 34 | }); |
| 35 | 35 | ||
| 36 | #[embassy_executor::main] | 36 | fn test_interrupt(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) { |
| 37 | async fn main(_spawner: Spawner) { | ||
| 38 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | ||
| 39 | let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); | ||
| 40 | |||
| 41 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; | 37 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; |
| 42 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; | 38 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; |
| 43 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; | 39 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; |
| @@ -96,6 +92,47 @@ async fn main(_spawner: Spawner) { | |||
| 96 | info!("Hardware HMAC: {:?}", hw_hmac); | 92 | info!("Hardware HMAC: {:?}", hw_hmac); |
| 97 | info!("Software HMAC: {:?}", sw_hmac[..]); | 93 | info!("Software HMAC: {:?}", sw_hmac[..]); |
| 98 | defmt::assert!(hw_hmac == sw_hmac[..]); | 94 | defmt::assert!(hw_hmac == sw_hmac[..]); |
| 95 | } | ||
| 96 | |||
| 97 | // This uses sha512, so only supported on hash_v3 and up | ||
| 98 | #[cfg(feature = "hash-v34")] | ||
| 99 | fn 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] | ||
| 126 | async fn main(_spawner: Spawner) { | ||
| 127 | let p: embassy_stm32::Peripherals = init(); | ||
| 128 | let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs); | ||
| 129 | |||
| 130 | test_interrupt(&mut hw_hasher); | ||
| 131 | // Run it a second time to check hash-after-hmac | ||
| 132 | test_interrupt(&mut hw_hasher); | ||
| 133 | |||
| 134 | #[cfg(feature = "hash-v34")] | ||
| 135 | test_sizes(&mut hw_hasher); | ||
| 99 | 136 | ||
| 100 | info!("Test OK"); | 137 | info!("Test OK"); |
| 101 | cortex_m::asm::bkpt(); | 138 | cortex_m::asm::bkpt(); |
diff --git a/tests/stm32/src/bin/hsem.rs b/tests/stm32/src/bin/hsem.rs new file mode 100644 index 000000000..fa69f22b2 --- /dev/null +++ b/tests/stm32/src/bin/hsem.rs | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | // required-features: hsem | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use common::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_stm32::bind_interrupts; | ||
| 11 | use embassy_stm32::hsem::{HardwareSemaphore, HardwareSemaphoreInterruptHandler}; | ||
| 12 | use embassy_stm32::peripherals::HSEM; | ||
| 13 | |||
| 14 | bind_interrupts!(struct Irqs{ | ||
| 15 | HSEM => HardwareSemaphoreInterruptHandler<HSEM>; | ||
| 16 | }); | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async fn main(_spawner: Spawner) { | ||
| 20 | let p: embassy_stm32::Peripherals = init(); | ||
| 21 | |||
| 22 | let hsem = HardwareSemaphore::new(p.HSEM, Irqs); | ||
| 23 | |||
| 24 | // if hsem.channel_for(SemaphoreNumber::Channel5).is_semaphore_locked() { | ||
| 25 | // defmt::panic!("Semaphore 5 already locked!") | ||
| 26 | // } | ||
| 27 | // | ||
| 28 | // hsem.channel_for(SemaphoreNumber::Channel5).one_step_lock().unwrap(); | ||
| 29 | // hsem.channel_for(SemaphoreNumber::Channel1).two_step_lock(0).unwrap(); | ||
| 30 | // | ||
| 31 | // hsem.channel_for(SemaphoreNumber::Channel5).unlock(0); | ||
| 32 | |||
| 33 | #[cfg(feature = "stm32wb55rg")] | ||
| 34 | let [_channel1, _channel2, mut channel5, _channel6] = hsem.split(); | ||
| 35 | #[cfg(not(feature = "stm32wb55rg"))] | ||
| 36 | let [_channel1, _channel2, _channel3, _channel4, mut channel5, _channel6] = hsem.split(); | ||
| 37 | |||
| 38 | info!("Locking channel 5"); | ||
| 39 | |||
| 40 | let mutex = channel5.lock(0).await; | ||
| 41 | |||
| 42 | info!("Locked channel 5"); | ||
| 43 | |||
| 44 | drop(mutex); | ||
| 45 | |||
| 46 | info!("Unlocked channel 5"); | ||
| 47 | |||
| 48 | info!("Test OK"); | ||
| 49 | cortex_m::asm::bkpt(); | ||
| 50 | } | ||
diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs index 15ef4fb60..8438353a8 100644 --- a/tests/stm32/src/bin/rng.rs +++ b/tests/stm32/src/bin/rng.rs | |||
| @@ -41,7 +41,7 @@ bind_interrupts!(struct Irqs { | |||
| 41 | 41 | ||
| 42 | #[embassy_executor::main] | 42 | #[embassy_executor::main] |
| 43 | async fn main(_spawner: Spawner) { | 43 | async fn main(_spawner: Spawner) { |
| 44 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | 44 | let p: embassy_stm32::Peripherals = init(); |
| 45 | 45 | ||
| 46 | let mut rng = Rng::new(p.RNG, Irqs); | 46 | let mut rng = Rng::new(p.RNG, Irqs); |
| 47 | 47 | ||
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index c04d616ac..eb27af4ca 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs | |||
| @@ -10,15 +10,21 @@ use common::*; | |||
| 10 | use defmt::assert; | 10 | use defmt::assert; |
| 11 | use embassy_executor::Spawner; | 11 | use embassy_executor::Spawner; |
| 12 | use embassy_stm32::rcc::LsConfig; | 12 | use embassy_stm32::rcc::LsConfig; |
| 13 | #[cfg(feature = "stop")] | ||
| 14 | use embassy_stm32::rtc::Rtc; | ||
| 15 | #[cfg(not(feature = "stop"))] | ||
| 13 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 16 | use embassy_stm32::rtc::{Rtc, RtcConfig}; |
| 14 | use embassy_time::Timer; | 17 | use embassy_time::Timer; |
| 15 | |||
| 16 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 18 | let mut config = config(); | 20 | let mut config = config(); |
| 19 | config.rcc.ls = LsConfig::default_lse(); | 21 | config.rcc.ls = LsConfig::default_lse(); |
| 22 | #[cfg(feature = "stop")] | ||
| 23 | { | ||
| 24 | config.rtc._disable_rtc = false; | ||
| 25 | } | ||
| 20 | 26 | ||
| 21 | let p = embassy_stm32::init(config); | 27 | let p = init_with_config(config); |
| 22 | info!("Hello World!"); | 28 | info!("Hello World!"); |
| 23 | 29 | ||
| 24 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | 30 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) |
| @@ -26,14 +32,25 @@ async fn main(_spawner: Spawner) { | |||
| 26 | .and_hms_opt(10, 30, 15) | 32 | .and_hms_opt(10, 30, 15) |
| 27 | .unwrap(); | 33 | .unwrap(); |
| 28 | 34 | ||
| 29 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 35 | #[cfg(not(feature = "stop"))] |
| 36 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 37 | |||
| 38 | #[cfg(feature = "stop")] | ||
| 39 | let (rtc, time_provider) = Rtc::new(p.RTC); | ||
| 30 | 40 | ||
| 41 | #[cfg(not(feature = "stop"))] | ||
| 31 | rtc.set_datetime(now.into()).expect("datetime not set"); | 42 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 32 | 43 | ||
| 44 | #[cfg(feature = "stop")] | ||
| 45 | critical_section::with(|cs| { | ||
| 46 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); | ||
| 47 | }); | ||
| 48 | |||
| 33 | info!("Waiting 5 seconds"); | 49 | info!("Waiting 5 seconds"); |
| 34 | Timer::after_millis(5000).await; | 50 | Timer::after_millis(5000).await; |
| 35 | 51 | ||
| 36 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 52 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 53 | |||
| 37 | let seconds = (then - now).num_seconds(); | 54 | let seconds = (then - now).num_seconds(); |
| 38 | 55 | ||
| 39 | info!("measured = {}", seconds); | 56 | info!("measured = {}", seconds); |
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs index 54f55d2d6..9f9c526e1 100644 --- a/tests/stm32/src/bin/sdmmc.rs +++ b/tests/stm32/src/bin/sdmmc.rs | |||
| @@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs { | |||
| 20 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
| 21 | info!("Hello World!"); | 21 | info!("Hello World!"); |
| 22 | 22 | ||
| 23 | let p = embassy_stm32::init(config()); | 23 | let p = init(); |
| 24 | 24 | ||
| 25 | let (mut sdmmc, mut dma, mut clk, mut cmd, mut d0, mut d1, mut d2, mut d3) = | 25 | let (mut sdmmc, mut dma, mut clk, mut cmd, mut d0, mut d1, mut d2, mut d3) = |
| 26 | (p.SDIO, p.DMA2_CH3, p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11); | 26 | (p.SDIO, p.DMA2_CH3, p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11); |
| @@ -34,27 +34,29 @@ async fn main(_spawner: Spawner) { | |||
| 34 | pattern1[i] = i as u8; | 34 | pattern1[i] = i as u8; |
| 35 | pattern2[i] = !i as u8; | 35 | pattern2[i] = !i as u8; |
| 36 | } | 36 | } |
| 37 | let patterns = [pattern1.clone(), pattern2.clone()]; | ||
| 37 | 38 | ||
| 38 | let mut block = DataBlock([0u8; 512]); | 39 | let mut block = DataBlock([0u8; 512]); |
| 40 | let mut blocks = [DataBlock([0u8; 512]), DataBlock([0u8; 512])]; | ||
| 39 | 41 | ||
| 40 | // ======== Try 4bit. ============== | 42 | // ======== Try 4bit. ============== |
| 41 | info!("initializing in 4-bit mode..."); | 43 | info!("initializing in 4-bit mode..."); |
| 42 | let mut s = Sdmmc::new_4bit( | 44 | let mut s = Sdmmc::new_4bit( |
| 43 | &mut sdmmc, | 45 | sdmmc.reborrow(), |
| 44 | Irqs, | 46 | Irqs, |
| 45 | &mut dma, | 47 | dma.reborrow(), |
| 46 | &mut clk, | 48 | clk.reborrow(), |
| 47 | &mut cmd, | 49 | cmd.reborrow(), |
| 48 | &mut d0, | 50 | d0.reborrow(), |
| 49 | &mut d1, | 51 | d1.reborrow(), |
| 50 | &mut d2, | 52 | d2.reborrow(), |
| 51 | &mut d3, | 53 | d3.reborrow(), |
| 52 | Default::default(), | 54 | Default::default(), |
| 53 | ); | 55 | ); |
| 54 | 56 | ||
| 55 | let mut err = None; | 57 | let mut err = None; |
| 56 | loop { | 58 | loop { |
| 57 | match s.init_card(mhz(24)).await { | 59 | match s.init_sd_card(mhz(24)).await { |
| 58 | Ok(_) => break, | 60 | Ok(_) => break, |
| 59 | Err(e) => { | 61 | Err(e) => { |
| 60 | if err != Some(e) { | 62 | if err != Some(e) { |
| @@ -84,23 +86,33 @@ async fn main(_spawner: Spawner) { | |||
| 84 | s.read_block(block_idx, &mut block).await.unwrap(); | 86 | s.read_block(block_idx, &mut block).await.unwrap(); |
| 85 | assert_eq!(block, pattern2); | 87 | assert_eq!(block, pattern2); |
| 86 | 88 | ||
| 89 | info!("writing blocks [pattern1, pattern2]..."); | ||
| 90 | s.write_blocks(block_idx, &patterns).await.unwrap(); | ||
| 91 | |||
| 92 | info!("reading blocks..."); | ||
| 93 | s.read_blocks(block_idx, &mut blocks).await.unwrap(); | ||
| 94 | assert_eq!(&blocks, &patterns); | ||
| 95 | |||
| 87 | drop(s); | 96 | drop(s); |
| 88 | 97 | ||
| 98 | // FIXME: this hangs on Rust 1.86 and higher. | ||
| 99 | // I haven't been able to figure out why. | ||
| 100 | /* | ||
| 89 | // ======== Try 1bit. ============== | 101 | // ======== Try 1bit. ============== |
| 90 | info!("initializing in 1-bit mode..."); | 102 | info!("initializing in 1-bit mode..."); |
| 91 | let mut s = Sdmmc::new_1bit( | 103 | let mut s = Sdmmc::new_1bit( |
| 92 | &mut sdmmc, | 104 | sdmmc.reborrow(), |
| 93 | Irqs, | 105 | Irqs, |
| 94 | &mut dma, | 106 | dma.reborrow(), |
| 95 | &mut clk, | 107 | clk.reborrow(), |
| 96 | &mut cmd, | 108 | cmd.reborrow(), |
| 97 | &mut d0, | 109 | d0.reborrow(), |
| 98 | Default::default(), | 110 | Default::default(), |
| 99 | ); | 111 | ); |
| 100 | 112 | ||
| 101 | let mut err = None; | 113 | let mut err = None; |
| 102 | loop { | 114 | loop { |
| 103 | match s.init_card(mhz(24)).await { | 115 | match s.init_sd_card(mhz(24)).await { |
| 104 | Ok(_) => break, | 116 | Ok(_) => break, |
| 105 | Err(e) => { | 117 | Err(e) => { |
| 106 | if err != Some(e) { | 118 | if err != Some(e) { |
| @@ -116,9 +128,9 @@ async fn main(_spawner: Spawner) { | |||
| 116 | info!("Card: {:#?}", Debug2Format(card)); | 128 | info!("Card: {:#?}", Debug2Format(card)); |
| 117 | info!("Clock: {}", s.clock()); | 129 | info!("Clock: {}", s.clock()); |
| 118 | 130 | ||
| 119 | info!("reading pattern2 written in 4bit mode..."); | 131 | info!("reading pattern1 written in 4bit mode..."); |
| 120 | s.read_block(block_idx, &mut block).await.unwrap(); | 132 | s.read_block(block_idx, &mut block).await.unwrap(); |
| 121 | assert_eq!(block, pattern2); | 133 | assert_eq!(block, pattern1); |
| 122 | 134 | ||
| 123 | info!("writing pattern1..."); | 135 | info!("writing pattern1..."); |
| 124 | s.write_block(block_idx, &pattern1).await.unwrap(); | 136 | s.write_block(block_idx, &pattern1).await.unwrap(); |
| @@ -134,7 +146,15 @@ async fn main(_spawner: Spawner) { | |||
| 134 | s.read_block(block_idx, &mut block).await.unwrap(); | 146 | s.read_block(block_idx, &mut block).await.unwrap(); |
| 135 | assert_eq!(block, pattern2); | 147 | assert_eq!(block, pattern2); |
| 136 | 148 | ||
| 149 | info!("writing blocks [pattern1, pattern2]..."); | ||
| 150 | s.write_blocks(block_idx, &patterns).await.unwrap(); | ||
| 151 | |||
| 152 | info!("reading blocks..."); | ||
| 153 | s.read_blocks(block_idx, &mut blocks).await.unwrap(); | ||
| 154 | assert_eq!(&blocks, &patterns); | ||
| 155 | |||
| 137 | drop(s); | 156 | drop(s); |
| 157 | */ | ||
| 138 | 158 | ||
| 139 | info!("Test OK"); | 159 | info!("Test OK"); |
| 140 | cortex_m::asm::bkpt(); | 160 | cortex_m::asm::bkpt(); |
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index 0ffd0f653..cedff772c 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs | |||
| @@ -7,12 +7,14 @@ use common::*; | |||
| 7 | use defmt::assert_eq; | 7 | use defmt::assert_eq; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::spi::{self, Spi}; | 10 | use embassy_stm32::mode::Blocking; |
| 11 | use embassy_stm32::spi::mode::Master; | ||
| 12 | use embassy_stm32::spi::{self, Spi, Word}; | ||
| 11 | use embassy_stm32::time::Hertz; | 13 | use embassy_stm32::time::Hertz; |
| 12 | 14 | ||
| 13 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 15 | let p = embassy_stm32::init(config()); | 17 | let p = init(); |
| 16 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 17 | 19 | ||
| 18 | let mut spi_peri = peri!(p, SPI); | 20 | let mut spi_peri = peri!(p, SPI); |
| @@ -24,18 +26,65 @@ async fn main(_spawner: Spawner) { | |||
| 24 | spi_config.frequency = Hertz(1_000_000); | 26 | spi_config.frequency = Hertz(1_000_000); |
| 25 | 27 | ||
| 26 | let mut spi = Spi::new_blocking( | 28 | let mut spi = Spi::new_blocking( |
| 27 | &mut spi_peri, | 29 | spi_peri.reborrow(), |
| 28 | &mut sck, // Arduino D13 | 30 | sck.reborrow(), // Arduino D13 |
| 29 | &mut mosi, // Arduino D11 | 31 | mosi.reborrow(), // Arduino D11 |
| 30 | &mut miso, // Arduino D12 | 32 | miso.reborrow(), // Arduino D12 |
| 31 | spi_config, | 33 | spi_config, |
| 32 | ); | 34 | ); |
| 33 | 35 | ||
| 34 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 36 | test_txrx::<u8>(&mut spi); |
| 37 | test_txrx::<u16>(&mut spi); | ||
| 38 | |||
| 39 | // Assert the RCC bit gets disabled on drop. | ||
| 40 | #[cfg(feature = "stm32f429zi")] | ||
| 41 | defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | ||
| 42 | drop(spi); | ||
| 43 | #[cfg(feature = "stm32f429zi")] | ||
| 44 | defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | ||
| 45 | |||
| 46 | // test rx-only configuration | ||
| 47 | let mut spi = Spi::new_blocking_rxonly(spi_peri.reborrow(), sck.reborrow(), miso.reborrow(), spi_config); | ||
| 48 | let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh); | ||
| 49 | |||
| 50 | test_rx::<u8>(&mut spi, &mut mosi_out); | ||
| 51 | test_rx::<u16>(&mut spi, &mut mosi_out); | ||
| 52 | drop(spi); | ||
| 53 | drop(mosi_out); | ||
| 54 | |||
| 55 | let mut spi = Spi::new_blocking_txonly(spi_peri.reborrow(), sck.reborrow(), mosi.reborrow(), spi_config); | ||
| 56 | test_tx::<u8>(&mut spi); | ||
| 57 | test_tx::<u16>(&mut spi); | ||
| 58 | drop(spi); | ||
| 59 | |||
| 60 | let mut spi = Spi::new_blocking_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), spi_config); | ||
| 61 | test_tx::<u8>(&mut spi); | ||
| 62 | test_tx::<u16>(&mut spi); | ||
| 63 | drop(spi); | ||
| 64 | |||
| 65 | info!("Test OK"); | ||
| 66 | cortex_m::asm::bkpt(); | ||
| 67 | } | ||
| 68 | |||
| 69 | fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) | ||
| 70 | where | ||
| 71 | W: core::ops::Not<Output = W>, | ||
| 72 | { | ||
| 73 | let data: [W; 9] = [ | ||
| 74 | 0x00u8.into(), | ||
| 75 | 0xFFu8.into(), | ||
| 76 | 0xAAu8.into(), | ||
| 77 | 0x55u8.into(), | ||
| 78 | 0xC0u8.into(), | ||
| 79 | 0xFFu8.into(), | ||
| 80 | 0xEEu8.into(), | ||
| 81 | 0xC0u8.into(), | ||
| 82 | 0xDEu8.into(), | ||
| 83 | ]; | ||
| 35 | 84 | ||
| 36 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. | 85 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. |
| 37 | // so we should get the data we sent back. | 86 | // so we should get the data we sent back. |
| 38 | let mut buf = [0; 9]; | 87 | let mut buf = [W::default(); 9]; |
| 39 | spi.blocking_transfer(&mut buf, &data).unwrap(); | 88 | spi.blocking_transfer(&mut buf, &data).unwrap(); |
| 40 | assert_eq!(buf, data); | 89 | assert_eq!(buf, data); |
| 41 | 90 | ||
| @@ -59,47 +108,33 @@ async fn main(_spawner: Spawner) { | |||
| 59 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); | 108 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); |
| 60 | spi.blocking_read::<u8>(&mut []).unwrap(); | 109 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 61 | spi.blocking_write::<u8>(&[]).unwrap(); | 110 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 111 | } | ||
| 62 | 112 | ||
| 63 | // Assert the RCC bit gets disabled on drop. | 113 | fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>, mosi_out: &mut Output<'_>) |
| 64 | #[cfg(feature = "stm32f429zi")] | 114 | where |
| 65 | defmt::assert!(embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | 115 | W: core::ops::Not<Output = W>, |
| 66 | drop(spi); | 116 | { |
| 67 | #[cfg(feature = "stm32f429zi")] | 117 | let mut buf = [W::default(); 9]; |
| 68 | defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); | ||
| 69 | 118 | ||
| 70 | // test rx-only configuration | ||
| 71 | let mut spi = Spi::new_blocking_rxonly(&mut spi_peri, &mut sck, &mut miso, spi_config); | ||
| 72 | let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); | ||
| 73 | mosi_out.set_high(); | 119 | mosi_out.set_high(); |
| 74 | spi.blocking_read(&mut buf).unwrap(); | 120 | spi.blocking_read(&mut buf).unwrap(); |
| 75 | assert_eq!(buf, [0xff; 9]); | 121 | assert_eq!(buf, [!W::default(); 9]); |
| 76 | mosi_out.set_low(); | 122 | mosi_out.set_low(); |
| 77 | spi.blocking_read(&mut buf).unwrap(); | 123 | spi.blocking_read(&mut buf).unwrap(); |
| 78 | assert_eq!(buf, [0x00; 9]); | 124 | assert_eq!(buf, [W::default(); 9]); |
| 79 | spi.blocking_read::<u8>(&mut []).unwrap(); | 125 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 80 | spi.blocking_read::<u8>(&mut []).unwrap(); | 126 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 81 | drop(mosi_out); | 127 | } |
| 82 | drop(spi); | 128 | |
| 129 | fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) | ||
| 130 | where | ||
| 131 | W: core::ops::Not<Output = W>, | ||
| 132 | { | ||
| 133 | let buf = [W::default(); 9]; | ||
| 83 | 134 | ||
| 84 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. | 135 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. |
| 85 | let mut spi = Spi::new_blocking_txonly(&mut spi_peri, &mut sck, &mut mosi, spi_config); | ||
| 86 | spi.blocking_transfer(&mut buf, &data).unwrap(); | ||
| 87 | spi.blocking_transfer_in_place(&mut buf).unwrap(); | ||
| 88 | spi.blocking_write(&buf).unwrap(); | 136 | spi.blocking_write(&buf).unwrap(); |
| 89 | spi.blocking_read(&mut buf).unwrap(); | ||
| 90 | spi.blocking_transfer::<u8>(&mut [], &[]).unwrap(); | ||
| 91 | spi.blocking_transfer_in_place::<u8>(&mut []).unwrap(); | ||
| 92 | spi.blocking_read::<u8>(&mut []).unwrap(); | ||
| 93 | spi.blocking_write::<u8>(&[]).unwrap(); | 137 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 94 | drop(spi); | ||
| 95 | |||
| 96 | // Test tx-only nosck. | ||
| 97 | let mut spi = Spi::new_blocking_txonly_nosck(&mut spi_peri, &mut mosi, spi_config); | ||
| 98 | spi.blocking_write(&buf).unwrap(); | 138 | spi.blocking_write(&buf).unwrap(); |
| 99 | spi.blocking_write::<u8>(&[]).unwrap(); | 139 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 100 | spi.blocking_write(&buf).unwrap(); | ||
| 101 | drop(spi); | ||
| 102 | |||
| 103 | info!("Test OK"); | ||
| 104 | cortex_m::asm::bkpt(); | ||
| 105 | } | 140 | } |
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index fd26d3f71..c8cd92401 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs | |||
| @@ -7,12 +7,14 @@ use common::*; | |||
| 7 | use defmt::assert_eq; | 7 | use defmt::assert_eq; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::spi::{self, Spi}; | 10 | use embassy_stm32::mode::Async; |
| 11 | use embassy_stm32::spi::mode::Master; | ||
| 12 | use embassy_stm32::spi::{self, Spi, Word}; | ||
| 11 | use embassy_stm32::time::Hertz; | 13 | use embassy_stm32::time::Hertz; |
| 12 | 14 | ||
| 13 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 15 | let p = embassy_stm32::init(config()); | 17 | let p = init(); |
| 16 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 17 | 19 | ||
| 18 | let mut spi_peri = peri!(p, SPI); | 20 | let mut spi_peri = peri!(p, SPI); |
| @@ -26,20 +28,76 @@ async fn main(_spawner: Spawner) { | |||
| 26 | spi_config.frequency = Hertz(1_000_000); | 28 | spi_config.frequency = Hertz(1_000_000); |
| 27 | 29 | ||
| 28 | let mut spi = Spi::new( | 30 | let mut spi = Spi::new( |
| 29 | &mut spi_peri, | 31 | spi_peri.reborrow(), |
| 30 | &mut sck, // Arduino D13 | 32 | sck.reborrow(), // Arduino D13 |
| 31 | &mut mosi, // Arduino D11 | 33 | mosi.reborrow(), // Arduino D11 |
| 32 | &mut miso, // Arduino D12 | 34 | miso.reborrow(), // Arduino D12 |
| 33 | &mut tx_dma, | 35 | tx_dma.reborrow(), |
| 34 | &mut rx_dma, | 36 | rx_dma.reborrow(), |
| 35 | spi_config, | 37 | spi_config, |
| 36 | ); | 38 | ); |
| 37 | 39 | ||
| 38 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 40 | test_txrx::<u8>(&mut spi).await; |
| 41 | test_txrx::<u16>(&mut spi).await; | ||
| 42 | drop(spi); | ||
| 43 | |||
| 44 | // test rx-only configuration | ||
| 45 | let mut spi = Spi::new_rxonly( | ||
| 46 | spi_peri.reborrow(), | ||
| 47 | sck.reborrow(), | ||
| 48 | miso.reborrow(), | ||
| 49 | // SPIv1/f1 requires txdma even if rxonly. | ||
| 50 | #[cfg(not(feature = "spi-v345"))] | ||
| 51 | tx_dma.reborrow(), | ||
| 52 | rx_dma.reborrow(), | ||
| 53 | spi_config, | ||
| 54 | ); | ||
| 55 | let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh); | ||
| 56 | |||
| 57 | test_rx::<u8>(&mut spi, &mut mosi_out).await; | ||
| 58 | test_rx::<u16>(&mut spi, &mut mosi_out).await; | ||
| 59 | drop(spi); | ||
| 60 | drop(mosi_out); | ||
| 61 | |||
| 62 | let mut spi = Spi::new_txonly( | ||
| 63 | spi_peri.reborrow(), | ||
| 64 | sck.reborrow(), | ||
| 65 | mosi.reborrow(), | ||
| 66 | tx_dma.reborrow(), | ||
| 67 | spi_config, | ||
| 68 | ); | ||
| 69 | test_tx::<u8>(&mut spi).await; | ||
| 70 | test_tx::<u16>(&mut spi).await; | ||
| 71 | drop(spi); | ||
| 72 | |||
| 73 | let mut spi = Spi::new_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), tx_dma.reborrow(), spi_config); | ||
| 74 | test_tx::<u8>(&mut spi).await; | ||
| 75 | test_tx::<u16>(&mut spi).await; | ||
| 76 | drop(spi); | ||
| 77 | |||
| 78 | info!("Test OK"); | ||
| 79 | cortex_m::asm::bkpt(); | ||
| 80 | } | ||
| 81 | |||
| 82 | async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) | ||
| 83 | where | ||
| 84 | W: core::ops::Not<Output = W>, | ||
| 85 | { | ||
| 86 | let data: [W; 9] = [ | ||
| 87 | 0x00u8.into(), | ||
| 88 | 0xFFu8.into(), | ||
| 89 | 0xAAu8.into(), | ||
| 90 | 0x55u8.into(), | ||
| 91 | 0xC0u8.into(), | ||
| 92 | 0xFFu8.into(), | ||
| 93 | 0xEEu8.into(), | ||
| 94 | 0xC0u8.into(), | ||
| 95 | 0xDEu8.into(), | ||
| 96 | ]; | ||
| 39 | 97 | ||
| 40 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. | 98 | // Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor. |
| 41 | // so we should get the data we sent back. | 99 | // so we should get the data we sent back. |
| 42 | let mut buf = [0; 9]; | 100 | let mut buf = [W::default(); 9]; |
| 43 | spi.transfer(&mut buf, &data).await.unwrap(); | 101 | spi.transfer(&mut buf, &data).await.unwrap(); |
| 44 | assert_eq!(buf, data); | 102 | assert_eq!(buf, data); |
| 45 | 103 | ||
| @@ -83,56 +141,41 @@ async fn main(_spawner: Spawner) { | |||
| 83 | spi.blocking_write(&buf).unwrap(); | 141 | spi.blocking_write(&buf).unwrap(); |
| 84 | spi.blocking_read(&mut buf).unwrap(); | 142 | spi.blocking_read(&mut buf).unwrap(); |
| 85 | spi.write(&buf).await.unwrap(); | 143 | spi.write(&buf).await.unwrap(); |
| 144 | } | ||
| 86 | 145 | ||
| 87 | core::mem::drop(spi); | 146 | async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>, mosi_out: &mut Output<'_>) |
| 147 | where | ||
| 148 | W: core::ops::Not<Output = W>, | ||
| 149 | { | ||
| 150 | let mut buf = [W::default(); 9]; | ||
| 88 | 151 | ||
| 89 | // test rx-only configuration | ||
| 90 | let mut spi = Spi::new_rxonly( | ||
| 91 | &mut spi_peri, | ||
| 92 | &mut sck, | ||
| 93 | &mut miso, | ||
| 94 | // SPIv1/f1 requires txdma even if rxonly. | ||
| 95 | #[cfg(not(feature = "spi-v345"))] | ||
| 96 | &mut tx_dma, | ||
| 97 | &mut rx_dma, | ||
| 98 | spi_config, | ||
| 99 | ); | ||
| 100 | let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); | ||
| 101 | mosi_out.set_high(); | 152 | mosi_out.set_high(); |
| 102 | spi.read(&mut buf).await.unwrap(); | 153 | spi.read(&mut buf).await.unwrap(); |
| 103 | assert_eq!(buf, [0xff; 9]); | 154 | assert_eq!(buf, [!W::default(); 9]); |
| 104 | spi.blocking_read(&mut buf).unwrap(); | 155 | spi.blocking_read(&mut buf).unwrap(); |
| 105 | assert_eq!(buf, [0xff; 9]); | 156 | assert_eq!(buf, [!W::default(); 9]); |
| 106 | spi.read(&mut buf).await.unwrap(); | 157 | spi.read(&mut buf).await.unwrap(); |
| 107 | assert_eq!(buf, [0xff; 9]); | 158 | assert_eq!(buf, [!W::default(); 9]); |
| 108 | spi.read(&mut buf).await.unwrap(); | 159 | spi.read(&mut buf).await.unwrap(); |
| 109 | assert_eq!(buf, [0xff; 9]); | 160 | assert_eq!(buf, [!W::default(); 9]); |
| 110 | spi.blocking_read(&mut buf).unwrap(); | 161 | spi.blocking_read(&mut buf).unwrap(); |
| 111 | assert_eq!(buf, [0xff; 9]); | 162 | assert_eq!(buf, [!W::default(); 9]); |
| 112 | spi.blocking_read(&mut buf).unwrap(); | 163 | spi.blocking_read(&mut buf).unwrap(); |
| 113 | assert_eq!(buf, [0xff; 9]); | 164 | assert_eq!(buf, [!W::default(); 9]); |
| 114 | mosi_out.set_low(); | 165 | mosi_out.set_low(); |
| 115 | spi.read(&mut buf).await.unwrap(); | 166 | spi.read(&mut buf).await.unwrap(); |
| 116 | assert_eq!(buf, [0x00; 9]); | 167 | assert_eq!(buf, [W::default(); 9]); |
| 117 | spi.read::<u8>(&mut []).await.unwrap(); | 168 | spi.read::<u8>(&mut []).await.unwrap(); |
| 118 | spi.blocking_read::<u8>(&mut []).unwrap(); | 169 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 119 | drop(mosi_out); | 170 | } |
| 120 | drop(spi); | ||
| 121 | 171 | ||
| 122 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. | 172 | async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) |
| 123 | let mut spi = Spi::new_txonly(&mut spi_peri, &mut sck, &mut mosi, &mut tx_dma, spi_config); | 173 | where |
| 124 | spi.blocking_write(&buf).unwrap(); | 174 | W: core::ops::Not<Output = W>, |
| 125 | spi.write(&buf).await.unwrap(); | 175 | { |
| 126 | spi.blocking_write(&buf).unwrap(); | 176 | let buf = [W::default(); 9]; |
| 127 | spi.blocking_write(&buf).unwrap(); | ||
| 128 | spi.write(&buf).await.unwrap(); | ||
| 129 | spi.write(&buf).await.unwrap(); | ||
| 130 | spi.write::<u8>(&[]).await.unwrap(); | ||
| 131 | spi.blocking_write::<u8>(&[]).unwrap(); | ||
| 132 | drop(spi); | ||
| 133 | 177 | ||
| 134 | // Test tx-only nosck. | 178 | // Test tx-only. Just check it doesn't hang, not much else we can do without using SPI slave. |
| 135 | let mut spi = Spi::new_txonly_nosck(&mut spi_peri, &mut mosi, &mut tx_dma, spi_config); | ||
| 136 | spi.blocking_write(&buf).unwrap(); | 179 | spi.blocking_write(&buf).unwrap(); |
| 137 | spi.write(&buf).await.unwrap(); | 180 | spi.write(&buf).await.unwrap(); |
| 138 | spi.blocking_write(&buf).unwrap(); | 181 | spi.blocking_write(&buf).unwrap(); |
| @@ -141,8 +184,4 @@ async fn main(_spawner: Spawner) { | |||
| 141 | spi.write(&buf).await.unwrap(); | 184 | spi.write(&buf).await.unwrap(); |
| 142 | spi.write::<u8>(&[]).await.unwrap(); | 185 | spi.write::<u8>(&[]).await.unwrap(); |
| 143 | spi.blocking_write::<u8>(&[]).unwrap(); | 186 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 144 | drop(spi); | ||
| 145 | |||
| 146 | info!("Test OK"); | ||
| 147 | cortex_m::asm::bkpt(); | ||
| 148 | } | 187 | } |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index c1106bb2f..83c375bc5 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -7,21 +7,12 @@ mod common; | |||
| 7 | 7 | ||
| 8 | use chrono::NaiveDate; | 8 | use chrono::NaiveDate; |
| 9 | use common::*; | 9 | use common::*; |
| 10 | use cortex_m_rt::entry; | ||
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 12 | use embassy_stm32::low_power::{stop_ready, stop_with_rtc, Executor, StopMode}; | 11 | use embassy_stm32::low_power::{StopMode, stop_ready}; |
| 13 | use embassy_stm32::rcc::LsConfig; | 12 | use embassy_stm32::rcc::LsConfig; |
| 14 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 13 | use embassy_stm32::rtc::Rtc; |
| 15 | use embassy_stm32::Config; | 14 | use embassy_stm32::{Config, low_power}; |
| 16 | use embassy_time::Timer; | 15 | use embassy_time::Timer; |
| 17 | use static_cell::StaticCell; | ||
| 18 | |||
| 19 | #[entry] | ||
| 20 | fn main() -> ! { | ||
| 21 | Executor::take().run(|spawner| { | ||
| 22 | unwrap!(spawner.spawn(async_main(spawner))); | ||
| 23 | }); | ||
| 24 | } | ||
| 25 | 16 | ||
| 26 | #[embassy_executor::task] | 17 | #[embassy_executor::task] |
| 27 | async fn task_1() { | 18 | async fn task_1() { |
| @@ -44,12 +35,13 @@ async fn task_2() { | |||
| 44 | cortex_m::asm::bkpt(); | 35 | cortex_m::asm::bkpt(); |
| 45 | } | 36 | } |
| 46 | 37 | ||
| 47 | #[embassy_executor::task] | 38 | #[embassy_executor::main(executor = "low_power::Executor")] |
| 48 | async fn async_main(spawner: Spawner) { | 39 | async fn async_main(spawner: Spawner) { |
| 49 | let _ = config(); | 40 | let _ = config(); |
| 50 | 41 | ||
| 51 | let mut config = Config::default(); | 42 | let mut config = Config::default(); |
| 52 | config.rcc.ls = LsConfig::default_lse(); | 43 | config.rcc.ls = LsConfig::default_lse(); |
| 44 | config.rtc._disable_rtc = false; | ||
| 53 | 45 | ||
| 54 | // System Clock seems cannot be greater than 16 MHz | 46 | // System Clock seems cannot be greater than 16 MHz |
| 55 | #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] | 47 | #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] |
| @@ -58,7 +50,7 @@ async fn async_main(spawner: Spawner) { | |||
| 58 | config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4 | 50 | config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4 |
| 59 | } | 51 | } |
| 60 | 52 | ||
| 61 | let p = embassy_stm32::init(config); | 53 | let p = init_with_config(config); |
| 62 | info!("Hello World!"); | 54 | info!("Hello World!"); |
| 63 | 55 | ||
| 64 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | 56 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) |
| @@ -66,15 +58,12 @@ async fn async_main(spawner: Spawner) { | |||
| 66 | .and_hms_opt(10, 30, 15) | 58 | .and_hms_opt(10, 30, 15) |
| 67 | .unwrap(); | 59 | .unwrap(); |
| 68 | 60 | ||
| 69 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 61 | let (rtc, _time_provider) = Rtc::new(p.RTC); |
| 70 | 62 | ||
| 71 | rtc.set_datetime(now.into()).expect("datetime not set"); | 63 | critical_section::with(|cs| { |
| 72 | 64 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); | |
| 73 | static RTC: StaticCell<Rtc> = StaticCell::new(); | 65 | }); |
| 74 | let rtc = RTC.init(rtc); | ||
| 75 | |||
| 76 | stop_with_rtc(rtc); | ||
| 77 | 66 | ||
| 78 | spawner.spawn(task_1()).unwrap(); | 67 | spawner.spawn(task_1().unwrap()); |
| 79 | spawner.spawn(task_2()).unwrap(); | 68 | spawner.spawn(task_2().unwrap()); |
| 80 | } | 69 | } |
diff --git a/tests/stm32/src/bin/timer.rs b/tests/stm32/src/bin/timer.rs index d86f54ad2..8719e7670 100644 --- a/tests/stm32/src/bin/timer.rs +++ b/tests/stm32/src/bin/timer.rs | |||
| @@ -10,7 +10,7 @@ use embassy_time::{Instant, Timer}; | |||
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 13 | let _p = embassy_stm32::init(config()); | 13 | let _p = init(); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | let start = Instant::now(); | 16 | let start = Instant::now(); |
diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs index c09334ec8..c794afff8 100644 --- a/tests/stm32/src/bin/ucpd.rs +++ b/tests/stm32/src/bin/ucpd.rs | |||
| @@ -9,7 +9,7 @@ use defmt::{assert, assert_eq}; | |||
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_futures::join::join; | 10 | use embassy_futures::join::join; |
| 11 | use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; | 11 | use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals}; | 12 | use embassy_stm32::{Peri, bind_interrupts, peripherals}; |
| 13 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| @@ -28,8 +28,8 @@ async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: C | |||
| 28 | 28 | ||
| 29 | async fn source( | 29 | async fn source( |
| 30 | mut ucpd: Ucpd<'static, peripherals::UCPD1>, | 30 | mut ucpd: Ucpd<'static, peripherals::UCPD1>, |
| 31 | rx_dma: peripherals::DMA1_CH1, | 31 | rx_dma: Peri<'static, peripherals::DMA1_CH1>, |
| 32 | tx_dma: peripherals::DMA1_CH2, | 32 | tx_dma: Peri<'static, peripherals::DMA1_CH2>, |
| 33 | ) { | 33 | ) { |
| 34 | debug!("source: setting default current pull-up"); | 34 | debug!("source: setting default current pull-up"); |
| 35 | ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); | 35 | ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); |
| @@ -65,8 +65,8 @@ async fn source( | |||
| 65 | 65 | ||
| 66 | async fn sink( | 66 | async fn sink( |
| 67 | mut ucpd: Ucpd<'static, peripherals::UCPD2>, | 67 | mut ucpd: Ucpd<'static, peripherals::UCPD2>, |
| 68 | rx_dma: peripherals::DMA1_CH3, | 68 | rx_dma: Peri<'static, peripherals::DMA1_CH3>, |
| 69 | tx_dma: peripherals::DMA1_CH4, | 69 | tx_dma: Peri<'static, peripherals::DMA1_CH4>, |
| 70 | ) { | 70 | ) { |
| 71 | debug!("sink: setting pull down"); | 71 | debug!("sink: setting pull down"); |
| 72 | ucpd.cc_phy().set_pull(CcPull::Sink); | 72 | ucpd.cc_phy().set_pull(CcPull::Sink); |
| @@ -102,12 +102,12 @@ async fn sink( | |||
| 102 | 102 | ||
| 103 | #[embassy_executor::main] | 103 | #[embassy_executor::main] |
| 104 | async fn main(_spawner: Spawner) { | 104 | async fn main(_spawner: Spawner) { |
| 105 | let p = embassy_stm32::init(config()); | 105 | let p = init(); |
| 106 | info!("Hello World!"); | 106 | info!("Hello World!"); |
| 107 | 107 | ||
| 108 | // Wire between PD0 and PA8 | 108 | // Wire between PD0 and PA8 |
| 109 | let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15); | 109 | let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15, Default::default()); |
| 110 | let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2); | 110 | let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2, Default::default()); |
| 111 | 111 | ||
| 112 | join( | 112 | join( |
| 113 | source(ucpd1, p.DMA1_CH1, p.DMA1_CH2), | 113 | source(ucpd1, p.DMA1_CH1, p.DMA1_CH2), |
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs index a6e34674d..0b98d3eeb 100644 --- a/tests/stm32/src/bin/usart.rs +++ b/tests/stm32/src/bin/usart.rs | |||
| @@ -7,11 +7,11 @@ use common::*; | |||
| 7 | use defmt::{assert, assert_eq, unreachable}; | 7 | use defmt::{assert, assert_eq, unreachable}; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; | 9 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; |
| 10 | use embassy_time::{block_for, Duration, Instant}; | 10 | use embassy_time::{Duration, Instant, block_for}; |
| 11 | 11 | ||
| 12 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_stm32::init(config()); | 14 | let p = init(); |
| 15 | info!("Hello World!"); | 15 | info!("Hello World!"); |
| 16 | 16 | ||
| 17 | // Arduino pins D0 and D1 | 17 | // Arduino pins D0 and D1 |
| @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { | |||
| 22 | 22 | ||
| 23 | { | 23 | { |
| 24 | let config = Config::default(); | 24 | let config = Config::default(); |
| 25 | let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); | 25 | let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); |
| 26 | 26 | ||
| 27 | // We can't send too many bytes, they have to fit in the FIFO. | 27 | // We can't send too many bytes, they have to fit in the FIFO. |
| 28 | // This is because we aren't sending+receiving at the same time. | 28 | // This is because we aren't sending+receiving at the same time. |
| @@ -33,12 +33,19 @@ async fn main(_spawner: Spawner) { | |||
| 33 | let mut buf = [0; 2]; | 33 | let mut buf = [0; 2]; |
| 34 | usart.blocking_read(&mut buf).unwrap(); | 34 | usart.blocking_read(&mut buf).unwrap(); |
| 35 | assert_eq!(buf, data); | 35 | assert_eq!(buf, data); |
| 36 | |||
| 37 | // Test flush doesn't hang. | ||
| 38 | usart.blocking_write(&data).unwrap(); | ||
| 39 | usart.blocking_flush().unwrap(); | ||
| 40 | |||
| 41 | // Test flush doesn't hang if there's nothing to flush | ||
| 42 | usart.blocking_flush().unwrap(); | ||
| 36 | } | 43 | } |
| 37 | 44 | ||
| 38 | // Test error handling with with an overflow error | 45 | // Test error handling with with an overflow error |
| 39 | { | 46 | { |
| 40 | let config = Config::default(); | 47 | let config = Config::default(); |
| 41 | let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); | 48 | let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); |
| 42 | 49 | ||
| 43 | // Send enough bytes to fill the RX FIFOs off all USART versions. | 50 | // Send enough bytes to fill the RX FIFOs off all USART versions. |
| 44 | let data = [0; 64]; | 51 | let data = [0; 64]; |
| @@ -68,7 +75,7 @@ async fn main(_spawner: Spawner) { | |||
| 68 | 75 | ||
| 69 | let mut config = Config::default(); | 76 | let mut config = Config::default(); |
| 70 | config.baudrate = baudrate; | 77 | config.baudrate = baudrate; |
| 71 | let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { | 78 | let mut usart = match Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config) { |
| 72 | Ok(x) => x, | 79 | Ok(x) => x, |
| 73 | Err(ConfigError::BaudrateTooHigh) => { | 80 | Err(ConfigError::BaudrateTooHigh) => { |
| 74 | info!("baudrate too high"); | 81 | info!("baudrate too high"); |
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs index 24e2b2896..a34498376 100644 --- a/tests/stm32/src/bin/usart_dma.rs +++ b/tests/stm32/src/bin/usart_dma.rs | |||
| @@ -11,7 +11,7 @@ use embassy_stm32::usart::{Config, Uart}; | |||
| 11 | 11 | ||
| 12 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_stm32::init(config()); | 14 | let p = init(); |
| 15 | info!("Hello World!"); | 15 | info!("Hello World!"); |
| 16 | 16 | ||
| 17 | // Arduino pins D0 and D1 | 17 | // Arduino pins D0 and D1 |
| @@ -51,6 +51,23 @@ async fn main(_spawner: Spawner) { | |||
| 51 | assert_eq!(tx_buf, rx_buf); | 51 | assert_eq!(tx_buf, rx_buf); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | // Test flush doesn't hang. Check multiple combinations of async+blocking. | ||
| 55 | tx.write(&tx_buf).await.unwrap(); | ||
| 56 | tx.flush().await.unwrap(); | ||
| 57 | tx.flush().await.unwrap(); | ||
| 58 | |||
| 59 | tx.write(&tx_buf).await.unwrap(); | ||
| 60 | tx.blocking_flush().unwrap(); | ||
| 61 | tx.flush().await.unwrap(); | ||
| 62 | |||
| 63 | tx.blocking_write(&tx_buf).unwrap(); | ||
| 64 | tx.blocking_flush().unwrap(); | ||
| 65 | tx.flush().await.unwrap(); | ||
| 66 | |||
| 67 | tx.blocking_write(&tx_buf).unwrap(); | ||
| 68 | tx.flush().await.unwrap(); | ||
| 69 | tx.blocking_flush().unwrap(); | ||
| 70 | |||
| 54 | info!("Test OK"); | 71 | info!("Test OK"); |
| 55 | cortex_m::asm::bkpt(); | 72 | cortex_m::asm::bkpt(); |
| 56 | } | 73 | } |
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index ea1e52358..15a0b0d60 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs | |||
| @@ -18,7 +18,7 @@ const DMA_BUF_SIZE: usize = 256; | |||
| 18 | 18 | ||
| 19 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async fn main(spawner: Spawner) { |
| 21 | let p = embassy_stm32::init(config()); | 21 | let p = init(); |
| 22 | info!("Hello World!"); | 22 | info!("Hello World!"); |
| 23 | 23 | ||
| 24 | // Arduino pins D0 and D1 | 24 | // Arduino pins D0 and D1 |
| @@ -43,12 +43,11 @@ async fn main(spawner: Spawner) { | |||
| 43 | let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap(); | 43 | let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap(); |
| 44 | let (tx, rx) = usart.split(); | 44 | let (tx, rx) = usart.split(); |
| 45 | static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE]; | 45 | static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE]; |
| 46 | let dma_buf = unsafe { DMA_BUF.as_mut() }; | 46 | let rx = rx.into_ring_buffered(unsafe { &mut *core::ptr::addr_of_mut!(DMA_BUF) }); |
| 47 | let rx = rx.into_ring_buffered(dma_buf); | ||
| 48 | 47 | ||
| 49 | info!("Spawning tasks"); | 48 | info!("Spawning tasks"); |
| 50 | spawner.spawn(transmit_task(tx)).unwrap(); | 49 | spawner.spawn(transmit_task(tx).unwrap()); |
| 51 | spawner.spawn(receive_task(rx)).unwrap(); | 50 | spawner.spawn(receive_task(rx).unwrap()); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | #[embassy_executor::task] | 53 | #[embassy_executor::task] |
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs index 82a540d45..0f396b848 100644 --- a/tests/stm32/src/bin/wpan_ble.rs +++ b/tests/stm32/src/bin/wpan_ble.rs | |||
| @@ -12,16 +12,16 @@ use embassy_executor::Spawner; | |||
| 12 | use embassy_stm32::bind_interrupts; | 12 | use embassy_stm32::bind_interrupts; |
| 13 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 13 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 14 | use embassy_stm32::rcc::WPAN_DEFAULT; | 14 | use embassy_stm32::rcc::WPAN_DEFAULT; |
| 15 | use embassy_stm32_wpan::TlMbox; | ||
| 16 | use embassy_stm32_wpan::hci::BdAddr; | ||
| 15 | use embassy_stm32_wpan::hci::host::uart::UartHci; | 17 | use embassy_stm32_wpan::hci::host::uart::UartHci; |
| 16 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; | 18 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; |
| 17 | use embassy_stm32_wpan::hci::types::AdvertisingType; | 19 | use embassy_stm32_wpan::hci::types::AdvertisingType; |
| 18 | use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role}; | 20 | use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role}; |
| 19 | use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands; | 21 | use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands; |
| 20 | use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel}; | 22 | use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel}; |
| 21 | use embassy_stm32_wpan::hci::BdAddr; | ||
| 22 | use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; | 23 | use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; |
| 23 | use embassy_stm32_wpan::sub::mm; | 24 | use embassy_stm32_wpan::sub::mm; |
| 24 | use embassy_stm32_wpan::TlMbox; | ||
| 25 | use {defmt_rtt as _, panic_probe as _}; | 25 | use {defmt_rtt as _, panic_probe as _}; |
| 26 | 26 | ||
| 27 | bind_interrupts!(struct Irqs{ | 27 | bind_interrupts!(struct Irqs{ |
| @@ -41,13 +41,13 @@ async fn main(spawner: Spawner) { | |||
| 41 | let mut config = config(); | 41 | let mut config = config(); |
| 42 | config.rcc = WPAN_DEFAULT; | 42 | config.rcc = WPAN_DEFAULT; |
| 43 | 43 | ||
| 44 | let p = embassy_stm32::init(config); | 44 | let p = init_with_config(config); |
| 45 | info!("Hello World!"); | 45 | info!("Hello World!"); |
| 46 | 46 | ||
| 47 | let config = Config::default(); | 47 | let config = Config::default(); |
| 48 | let mut mbox = TlMbox::init(p.IPCC, Irqs, config); | 48 | let mut mbox = TlMbox::init(p.IPCC, Irqs, config); |
| 49 | 49 | ||
| 50 | spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); | 50 | spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); |
| 51 | 51 | ||
| 52 | let sys_event = mbox.sys_subsystem.read().await; | 52 | let sys_event = mbox.sys_subsystem.read().await; |
| 53 | info!("sys event: {}", sys_event.payload()); | 53 | info!("sys event: {}", sys_event.payload()); |
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index fe53b8786..f27146c44 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs | |||
| @@ -10,13 +10,13 @@ use embassy_executor::Spawner; | |||
| 10 | use embassy_stm32::bind_interrupts; | 10 | use embassy_stm32::bind_interrupts; |
| 11 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 11 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 12 | use embassy_stm32::rcc::WPAN_DEFAULT; | 12 | use embassy_stm32::rcc::WPAN_DEFAULT; |
| 13 | use embassy_stm32_wpan::TlMbox; | ||
| 13 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; | 14 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; |
| 14 | use embassy_stm32_wpan::mac::event::MacEvent; | 15 | use embassy_stm32_wpan::mac::event::MacEvent; |
| 15 | use embassy_stm32_wpan::mac::typedefs::{ | 16 | use embassy_stm32_wpan::mac::typedefs::{ |
| 16 | AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PanId, PibId, SecurityLevel, | 17 | AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PanId, PibId, SecurityLevel, |
| 17 | }; | 18 | }; |
| 18 | use embassy_stm32_wpan::sub::mm; | 19 | use embassy_stm32_wpan::sub::mm; |
| 19 | use embassy_stm32_wpan::TlMbox; | ||
| 20 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | 21 | ||
| 22 | bind_interrupts!(struct Irqs{ | 22 | bind_interrupts!(struct Irqs{ |
| @@ -34,13 +34,13 @@ async fn main(spawner: Spawner) { | |||
| 34 | let mut config = config(); | 34 | let mut config = config(); |
| 35 | config.rcc = WPAN_DEFAULT; | 35 | config.rcc = WPAN_DEFAULT; |
| 36 | 36 | ||
| 37 | let p = embassy_stm32::init(config); | 37 | let p = init_with_config(config); |
| 38 | info!("Hello World!"); | 38 | info!("Hello World!"); |
| 39 | 39 | ||
| 40 | let config = Config::default(); | 40 | let config = Config::default(); |
| 41 | let mbox = TlMbox::init(p.IPCC, Irqs, config); | 41 | let mbox = TlMbox::init(p.IPCC, Irqs, config); |
| 42 | 42 | ||
| 43 | spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); | 43 | spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); |
| 44 | 44 | ||
| 45 | let sys_event = mbox.sys_subsystem.read().await; | 45 | let sys_event = mbox.sys_subsystem.read().await; |
| 46 | info!("sys event: {}", sys_event.payload()); | 46 | info!("sys event: {}", sys_event.payload()); |
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/can_common.rs index 4e1740ad5..4e1740ad5 100644 --- a/tests/stm32/src/bin/can_common.rs +++ b/tests/stm32/src/can_common.rs | |||
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 4e0231858..096cce947 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | pub use defmt::*; | 3 | pub use defmt::*; |
| 4 | use embassy_stm32::Config; | ||
| 4 | #[allow(unused)] | 5 | #[allow(unused)] |
| 5 | use embassy_stm32::rcc::*; | 6 | use embassy_stm32::rcc::*; |
| 6 | #[allow(unused)] | 7 | #[allow(unused)] |
| 7 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| 8 | use embassy_stm32::Config; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | #[cfg(feature = "stm32f103c8")] | 11 | #[cfg(feature = "stm32f103c8")] |
| @@ -34,6 +34,8 @@ teleprobe_meta::target!(b"nucleo-stm32u5a5zj"); | |||
| 34 | teleprobe_meta::target!(b"nucleo-stm32h563zi"); | 34 | teleprobe_meta::target!(b"nucleo-stm32h563zi"); |
| 35 | #[cfg(feature = "stm32c031c6")] | 35 | #[cfg(feature = "stm32c031c6")] |
| 36 | teleprobe_meta::target!(b"nucleo-stm32c031c6"); | 36 | teleprobe_meta::target!(b"nucleo-stm32c031c6"); |
| 37 | #[cfg(feature = "stm32c071rb")] | ||
| 38 | teleprobe_meta::target!(b"nucleo-stm32c071rb"); | ||
| 37 | #[cfg(feature = "stm32l073rz")] | 39 | #[cfg(feature = "stm32l073rz")] |
| 38 | teleprobe_meta::target!(b"nucleo-stm32l073rz"); | 40 | teleprobe_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"))] |
| 105 | define_peris!( | 107 | define_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")] | ||
| 192 | define_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")] |
| 190 | define_peris!( | 198 | define_peris!( |
| 191 | UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, | 199 | UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, |
| @@ -271,7 +279,7 @@ pub fn config() -> Config { | |||
| 271 | #[allow(unused_mut)] | 279 | #[allow(unused_mut)] |
| 272 | let mut config = Config::default(); | 280 | let mut config = Config::default(); |
| 273 | 281 | ||
| 274 | #[cfg(feature = "stm32c031c6")] | 282 | #[cfg(any(feature = "stm32c031c6", feature = "stm32c071rb"))] |
| 275 | { | 283 | { |
| 276 | config.rcc.hsi = Some(Hsi { | 284 | config.rcc.hsi = Some(Hsi { |
| 277 | sys_div: HsiSysDiv::DIV1, // 48Mhz | 285 | sys_div: HsiSysDiv::DIV1, // 48Mhz |
| @@ -284,7 +292,9 @@ pub fn config() -> Config { | |||
| 284 | 292 | ||
| 285 | #[cfg(feature = "stm32g071rb")] | 293 | #[cfg(feature = "stm32g071rb")] |
| 286 | { | 294 | { |
| 287 | config.rcc.hsi = true; | 295 | config.rcc.hsi = Some(Hsi { |
| 296 | sys_div: HsiSysDiv::DIV1, | ||
| 297 | }); | ||
| 288 | config.rcc.pll = Some(Pll { | 298 | config.rcc.pll = Some(Pll { |
| 289 | source: PllSource::HSI, | 299 | source: PllSource::HSI, |
| 290 | prediv: PllPreDiv::DIV1, | 300 | prediv: PllPreDiv::DIV1, |
| @@ -458,6 +468,8 @@ pub fn config() -> Config { | |||
| 458 | config.rcc.apb3_pre = APBPrescaler::DIV1; | 468 | config.rcc.apb3_pre = APBPrescaler::DIV1; |
| 459 | config.rcc.sys = Sysclk::PLL1_P; | 469 | config.rcc.sys = Sysclk::PLL1_P; |
| 460 | config.rcc.voltage_scale = VoltageScale::Scale0; | 470 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 471 | |||
| 472 | config.rtc._disable_rtc = true; | ||
| 461 | } | 473 | } |
| 462 | 474 | ||
| 463 | #[cfg(feature = "stm32h503rb")] | 475 | #[cfg(feature = "stm32h503rb")] |
| @@ -671,6 +683,8 @@ pub fn config() -> Config { | |||
| 671 | divp: Some(PllDiv::DIV2), // 600Mhz | 683 | divp: Some(PllDiv::DIV2), // 600Mhz |
| 672 | divq: Some(PllDiv::DIV25), // 48Mhz | 684 | divq: Some(PllDiv::DIV25), // 48Mhz |
| 673 | divr: None, | 685 | divr: None, |
| 686 | divs: None, | ||
| 687 | divt: None, | ||
| 674 | }); | 688 | }); |
| 675 | config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz | 689 | config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz |
| 676 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz | 690 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz |
| @@ -699,3 +713,21 @@ pub fn config() -> Config { | |||
| 699 | 713 | ||
| 700 | config | 714 | config |
| 701 | } | 715 | } |
| 716 | |||
| 717 | #[allow(unused)] | ||
| 718 | pub fn init() -> embassy_stm32::Peripherals { | ||
| 719 | init_with_config(config()) | ||
| 720 | } | ||
| 721 | |||
| 722 | #[allow(unused)] | ||
| 723 | pub fn init_with_config(config: Config) -> embassy_stm32::Peripherals { | ||
| 724 | #[cfg(any(feature = "stm32wl55jc", feature = "stm32h755zi"))] | ||
| 725 | { | ||
| 726 | // Not in shared memory, but we're not running the second core, so it's fine | ||
| 727 | static SHARED_DATA: core::mem::MaybeUninit<embassy_stm32::SharedData> = core::mem::MaybeUninit::uninit(); | ||
| 728 | embassy_stm32::init_primary(config, &SHARED_DATA) | ||
| 729 | } | ||
| 730 | |||
| 731 | #[cfg(not(any(feature = "stm32wl55jc", feature = "stm32h755zi")))] | ||
| 732 | embassy_stm32::init(config) | ||
| 733 | } | ||
diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml index 7b54a4f52..da04a1f5d 100644 --- a/tests/utils/Cargo.toml +++ b/tests/utils/Cargo.toml | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "test-utils" | 2 | name = "test-utils" |
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2024" |
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 5 | 7 | ||
| 6 | [dependencies] | 8 | [dependencies] |
| 7 | rand = "0.8" | 9 | rand = "0.9" |
| 8 | serial = "0.4" | 10 | serial = "0.4" |
diff --git a/tests/utils/src/bin/saturate_serial.rs b/tests/utils/src/bin/saturate_serial.rs index 18ca12fb7..1c8a8b322 100644 --- a/tests/utils/src/bin/saturate_serial.rs +++ b/tests/utils/src/bin/saturate_serial.rs | |||
| @@ -2,7 +2,7 @@ use std::path::Path; | |||
| 2 | use std::time::Duration; | 2 | use std::time::Duration; |
| 3 | use std::{env, io, process, thread}; | 3 | use std::{env, io, process, thread}; |
| 4 | 4 | ||
| 5 | use rand::random; | 5 | use rand::{Rng, rng}; |
| 6 | use serial::SerialPort; | 6 | use serial::SerialPort; |
| 7 | 7 | ||
| 8 | pub fn main() { | 8 | pub 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)); |
