From 24c4ea71b11ce6c07d92dd6876fec6a9b0f6ed10 Mon Sep 17 00:00:00 2001 From: ZhangYong Date: Sat, 3 Jun 2023 17:44:25 +0800 Subject: [PATCH 01/28] sync/pipe: write all user data to pipe sync/pipe: add write_all function --- embassy-sync/src/pipe.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/embassy-sync/src/pipe.rs b/embassy-sync/src/pipe.rs index ee27cdec..db6ebb08 100644 --- a/embassy-sync/src/pipe.rs +++ b/embassy-sync/src/pipe.rs @@ -294,6 +294,16 @@ where WriteFuture { pipe: self, buf } } + /// Write all bytes to the pipe. + /// + /// This method writes all bytes from `buf` into the pipe + pub async fn write_all(&self, mut buf: &[u8]) { + while !buf.is_empty() { + let n = self.write(buf).await; + buf = &buf[n..]; + } + } + /// Attempt to immediately write some bytes to the pipe. /// /// This method will either write a nonzero amount of bytes to the pipe immediately, From a4b8fc420a377bd231d413dbdb2543550e3726ef Mon Sep 17 00:00:00 2001 From: ExplodingWaffle Date: Mon, 5 Jun 2023 01:30:34 +0100 Subject: [PATCH 02/28] Replace Into for Level with From for bool --- embassy-rp/src/gpio.rs | 6 +++--- embassy-stm32/src/gpio.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index f213bfea..91cef860 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -31,9 +31,9 @@ impl From for Level { } } -impl Into for Level { - fn into(self) -> bool { - match self { +impl From for bool { + fn from(level: Level) -> bool { + match level { Level::Low => false, Level::High => true, } diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 4895684e..7a066a4c 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -341,9 +341,9 @@ impl From for Level { } } -impl Into for Level { - fn into(self) -> bool { - match self { +impl From for bool { + fn from(level: Level) -> bool { + match level { Level::Low => false, Level::High => true, } From 44624b2d7a15ccc94971fc8d2091800f67821c58 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Thu, 1 Jun 2023 17:10:18 +0200 Subject: [PATCH 03/28] Put proto-ipv4 behind a feature flag --- embassy-net/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 0a47c5d9..4ac57257 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -26,7 +26,8 @@ unstable-traits = [] udp = ["smoltcp/socket-udp"] tcp = ["smoltcp/socket-tcp"] dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] -dhcpv4 = ["medium-ethernet", "smoltcp/socket-dhcpv4"] +dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"] +proto-ipv4 = ["smoltcp/proto-ipv4"] proto-ipv6 = ["smoltcp/proto-ipv6"] medium-ethernet = ["smoltcp/medium-ethernet"] medium-ip = ["smoltcp/medium-ip"] @@ -38,7 +39,6 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } smoltcp = { version = "0.9.0", default-features = false, features = [ - "proto-ipv4", "socket", "async", ]} From 5ee26a5dd1af3e172610b94b2657af709b319dad Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 5 Jun 2023 22:28:14 +0200 Subject: [PATCH 04/28] rp/dma: fix use-after-free read. --- embassy-rp/src/dma.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 74f4e699..1cbb4651 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -75,16 +75,17 @@ pub unsafe fn write<'a, C: Channel, W: Word>( ) } +static DUMMY: u32 = 0; + pub unsafe fn write_repeated<'a, C: Channel, W: Word>( ch: impl Peripheral

+ 'a, to: *mut W, len: usize, dreq: u8, ) -> Transfer<'a, C> { - let dummy: u32 = 0; copy_inner( ch, - &dummy as *const u32, + &DUMMY as *const u32, to as *mut u32, len, W::size(), From adf053a935d03711b48859e3243e86d3038fa7c4 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 5 Jun 2023 22:54:25 +0200 Subject: [PATCH 05/28] rp/flash: unify FLASH_BASE const. --- embassy-rp/src/flash.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 0410429e..838b987d 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -9,7 +9,7 @@ use embedded_storage::nor_flash::{ use crate::pac; use crate::peripherals::FLASH; -pub const FLASH_BASE: usize = 0x10000000; +pub const FLASH_BASE: *const u32 = 0x10000000 as _; // **NOTE**: // @@ -63,8 +63,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { trace!( "Reading from 0x{:x} to 0x{:x}", - FLASH_BASE + offset as usize, - FLASH_BASE + offset as usize + bytes.len() + FLASH_BASE as u32 + offset, + FLASH_BASE as u32 + offset + bytes.len() as u32 ); check_read(self, offset, bytes.len())?; @@ -242,6 +242,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S mod ram_helpers { use core::marker::PhantomData; + use super::*; use crate::rom_data; #[repr(C)] @@ -321,7 +322,7 @@ mod ram_helpers { pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) { let mut boot2 = [0u32; 256 / 4]; let ptrs = if use_boot2 { - rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); + rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(true, false, &boot2) } else { flash_function_pointers(true, false) @@ -351,7 +352,7 @@ mod ram_helpers { pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) { let mut boot2 = [0u32; 256 / 4]; let ptrs = if use_boot2 { - rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); + rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(true, true, &boot2) } else { flash_function_pointers(true, true) @@ -386,7 +387,7 @@ mod ram_helpers { pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) { let mut boot2 = [0u32; 256 / 4]; let ptrs = if use_boot2 { - rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); + rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, true, &boot2) } else { flash_function_pointers(false, true) @@ -511,7 +512,7 @@ mod ram_helpers { pub unsafe fn flash_unique_id(out: &mut [u8], use_boot2: bool) { let mut boot2 = [0u32; 256 / 4]; let ptrs = if use_boot2 { - rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); + rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, false, &boot2) } else { flash_function_pointers(false, false) @@ -539,7 +540,7 @@ mod ram_helpers { pub unsafe fn flash_jedec_id(use_boot2: bool) -> u32 { let mut boot2 = [0u32; 256 / 4]; let ptrs = if use_boot2 { - rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); + rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, false, &boot2) } else { flash_function_pointers(false, false) From 70e1b976d87c5bde4b07e7e0b0fcf1499e4d98ef Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 5 Jun 2023 23:40:34 +0200 Subject: [PATCH 06/28] rp/flash: fix missing clobbers, do not clobber frame pointer (r7). --- embassy-rp/src/flash.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 838b987d..cd34e605 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -587,7 +587,6 @@ mod ram_helpers { "ldr r4, [r5, #4]", "blx r4", // flash_exit_xip() - "mov r7, r10", // cmd "movs r4, #0x18", "lsls r4, r4, #24", // 0x18000000, SSI, RP2040 datasheet 4.10.13 @@ -604,8 +603,9 @@ mod ram_helpers { "str r1, [r4, #0]", // Write ctrlr1 with len-1 - "ldr r0, [r7, #8]", // dummy_len - "ldr r1, [r7, #16]", // data_len + "mov r3, r10", // cmd + "ldr r0, [r3, #8]", // dummy_len + "ldr r1, [r3, #16]", // data_len "add r0, r1", "subs r0, #1", "str r0, [r4, #0x04]", // CTRLR1 @@ -617,8 +617,8 @@ mod ram_helpers { // Write cmd/addr phase to DR "mov r2, r4", "adds r2, 0x60", // &DR - "ldr r0, [r7, #0]", // cmd_addr - "ldr r1, [r7, #4]", // cmd_addr_len + "ldr r0, [r3, #0]", // cmd_addr + "ldr r1, [r3, #4]", // cmd_addr_len "10:", "ldrb r3, [r0]", "strb r3, [r2]", // DR @@ -627,7 +627,8 @@ mod ram_helpers { "bne 10b", // Skip any dummy cycles - "ldr r1, [r7, #8]", // dummy_len + "mov r3, r10", // cmd + "ldr r1, [r3, #8]", // dummy_len "cmp r1, #0", "beq 9f", "4:", @@ -644,8 +645,9 @@ mod ram_helpers { // Read RX fifo "9:", - "ldr r0, [r7, #12]", // data - "ldr r1, [r7, #16]", // data_len + "mov r2, r10", // cmd + "ldr r0, [r2, #12]", // data + "ldr r1, [r2, #16]", // data_len "2:", "ldr r3, [r4, #0x28]", // SR @@ -679,13 +681,12 @@ mod ram_helpers { out("r2") _, out("r3") _, out("r4") _, + out("r5") _, // Registers r8-r10 are used to store values // from r0-r2 in registers not clobbered by // function calls. // The values can't be passed in using r8-r10 directly // due to https://github.com/rust-lang/rust/issues/99071 - out("r8") _, - out("r9") _, out("r10") _, clobber_abi("C"), ); From 162d48530436be9cfa6a0d4aba88d97f52a5ad4a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 5 Jun 2023 23:41:26 +0200 Subject: [PATCH 07/28] rp/flash: centralize `USE_BOOT2` in a single const. --- embassy-rp/src/flash.rs | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index cd34e605..0372afb1 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -10,6 +10,7 @@ use crate::pac; use crate::peripherals::FLASH; pub const FLASH_BASE: *const u32 = 0x10000000 as _; +pub const USE_BOOT2: bool = true; // **NOTE**: // @@ -89,7 +90,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { let len = to - from; - unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len, true))? }; + unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? }; Ok(()) } @@ -114,7 +115,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { let unaligned_offset = offset as usize - start; - unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? } + unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } } let remaining_len = bytes.len() - start_padding; @@ -132,12 +133,12 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { if bytes.as_ptr() as usize >= 0x2000_0000 { let aligned_data = &bytes[start_padding..end_padding]; - unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true))? } + unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } } else { for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { let mut ram_buf = [0xFF_u8; PAGE_SIZE]; ram_buf.copy_from_slice(chunk); - unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf, true))? } + unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } aligned_offset += PAGE_SIZE; } } @@ -152,7 +153,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); - unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? } + unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } } Ok(()) @@ -190,7 +191,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { /// Read SPI flash unique ID pub fn unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { - unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid, true))? }; + unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? }; Ok(()) } @@ -199,7 +200,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { let mut jedec = None; unsafe { self.in_ram(|| { - jedec.replace(ram_helpers::flash_jedec_id(true)); + jedec.replace(ram_helpers::flash_jedec_id()); })?; }; Ok(jedec.unwrap()) @@ -307,7 +308,7 @@ mod ram_helpers { /// /// `addr` and `len` must be multiples of 4096 /// - /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader + /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader /// is used to re-initialize the XIP engine after flashing. /// /// # Safety @@ -319,9 +320,9 @@ mod ram_helpers { /// - DMA must not access flash memory /// /// `addr` and `len` parameters must be valid and are not checked. - pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) { + pub unsafe fn flash_range_erase(addr: u32, len: u32) { let mut boot2 = [0u32; 256 / 4]; - let ptrs = if use_boot2 { + let ptrs = if USE_BOOT2 { rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(true, false, &boot2) } else { @@ -337,7 +338,7 @@ mod ram_helpers { /// /// `addr` and `data.len()` must be multiples of 4096 /// - /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader + /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader /// is used to re-initialize the XIP engine after flashing. /// /// # Safety @@ -349,9 +350,9 @@ mod ram_helpers { /// - DMA must not access flash memory /// /// `addr` and `len` parameters must be valid and are not checked. - pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) { + pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8]) { let mut boot2 = [0u32; 256 / 4]; - let ptrs = if use_boot2 { + let ptrs = if USE_BOOT2 { rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(true, true, &boot2) } else { @@ -372,7 +373,7 @@ mod ram_helpers { /// /// `addr` and `data.len()` must be multiples of 256 /// - /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader + /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader /// is used to re-initialize the XIP engine after flashing. /// /// # Safety @@ -384,9 +385,9 @@ mod ram_helpers { /// - DMA must not access flash memory /// /// `addr` and `len` parameters must be valid and are not checked. - pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) { + pub unsafe fn flash_range_program(addr: u32, data: &[u8]) { let mut boot2 = [0u32; 256 / 4]; - let ptrs = if use_boot2 { + let ptrs = if USE_BOOT2 { rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, true, &boot2) } else { @@ -509,9 +510,9 @@ mod ram_helpers { /// - DMA must not access flash memory /// /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) - pub unsafe fn flash_unique_id(out: &mut [u8], use_boot2: bool) { + pub unsafe fn flash_unique_id(out: &mut [u8]) { let mut boot2 = [0u32; 256 / 4]; - let ptrs = if use_boot2 { + let ptrs = if USE_BOOT2 { rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, false, &boot2) } else { @@ -537,9 +538,9 @@ mod ram_helpers { /// - DMA must not access flash memory /// /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) - pub unsafe fn flash_jedec_id(use_boot2: bool) -> u32 { + pub unsafe fn flash_jedec_id() -> u32 { let mut boot2 = [0u32; 256 / 4]; - let ptrs = if use_boot2 { + let ptrs = if USE_BOOT2 { rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); flash_function_pointers_with_boot2(false, false, &boot2) } else { From 4f03dff577f08bb9af1ea3fc118857973baa686e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 6 Jun 2023 00:06:32 +0200 Subject: [PATCH 08/28] rp: add run-from-ram feature. --- embassy-rp/Cargo.toml | 5 +++++ embassy-rp/src/flash.rs | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 5f08c7f3..ddada655 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -41,6 +41,11 @@ boot2-ram-memcpy = [] boot2-w25q080 = [] boot2-w25x10cl = [] +# Indicate code is running from RAM. +# Set this if all code is in RAM, and the cores never access memory-mapped flash memory through XIP. +# This allows the flash driver to not force pausing execution on both cores when doing flash operations. +run-from-ram = [] + # Enable nightly-only features nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 0372afb1..5d928aba 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -10,7 +10,10 @@ use crate::pac; use crate::peripherals::FLASH; pub const FLASH_BASE: *const u32 = 0x10000000 as _; -pub const USE_BOOT2: bool = true; + +// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead. +// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance. +pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram"); // **NOTE**: // From 593fc78dd892338386a2a81400e0621372264053 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 6 Jun 2023 00:07:03 +0200 Subject: [PATCH 09/28] tests/rp: enable run-from-ram. Otherwise the flash test is flaky because it attempts to use boot2. --- tests/rp/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 1786baee..6bcac373 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -10,7 +10,7 @@ teleprobe-meta = "1" embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } -embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics"] } +embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3.0" From 6701606e4c7811082808271b67caa1cdc9387163 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 6 Jun 2023 02:28:00 +0200 Subject: [PATCH 10/28] cyw43: add perf HIL test. --- ci.sh | 2 +- tests/perf-server/Cargo.toml | 8 + tests/perf-server/deploy.sh | 11 ++ tests/perf-server/perf-server.service | 16 ++ tests/perf-server/src/main.rs | 90 +++++++++ tests/rp/Cargo.toml | 6 +- tests/rp/src/bin/cyw43-perf.rs | 267 ++++++++++++++++++++++++++ 7 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 tests/perf-server/Cargo.toml create mode 100755 tests/perf-server/deploy.sh create mode 100644 tests/perf-server/perf-server.service create mode 100644 tests/perf-server/src/main.rs create mode 100644 tests/rp/src/bin/cyw43-perf.rs diff --git a/ci.sh b/ci.sh index 3d6e2879..08558a18 100755 --- a/ci.sh +++ b/ci.sh @@ -3,7 +3,7 @@ set -euo pipefail export RUSTFLAGS=-Dwarnings -export DEFMT_LOG=trace +export DEFMT_LOG=trace,cyw43=info,cyw43_pio=info,smoltcp=info # needed by wifi examples export WIFI_NETWORK=x diff --git a/tests/perf-server/Cargo.toml b/tests/perf-server/Cargo.toml new file mode 100644 index 00000000..53203905 --- /dev/null +++ b/tests/perf-server/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "perf-server" +version = "0.1.0" +edition = "2021" + +[dependencies] +log = "0.4.17" +pretty_env_logger = "0.4.0" diff --git a/tests/perf-server/deploy.sh b/tests/perf-server/deploy.sh new file mode 100755 index 00000000..032e99c3 --- /dev/null +++ b/tests/perf-server/deploy.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +HOST=root@192.168.1.3 + +cargo build --release +ssh $HOST -- systemctl stop perf-server +scp target/release/perf-server $HOST:/root +scp perf-server.service $HOST:/etc/systemd/system/ +ssh $HOST -- 'systemctl daemon-reload; systemctl restart perf-server' \ No newline at end of file diff --git a/tests/perf-server/perf-server.service b/tests/perf-server/perf-server.service new file mode 100644 index 00000000..c14c5d16 --- /dev/null +++ b/tests/perf-server/perf-server.service @@ -0,0 +1,16 @@ +[Unit] +Description=perf-server +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +ExecStart=/root/perf-server +Environment=RUST_BACKTRACE=1 +Environment=RUST_LOG=info + +[Install] +WantedBy=multi-user.target diff --git a/tests/perf-server/src/main.rs b/tests/perf-server/src/main.rs new file mode 100644 index 00000000..f6e7efc5 --- /dev/null +++ b/tests/perf-server/src/main.rs @@ -0,0 +1,90 @@ +use std::io::{Read, Write}; +use std::net::{TcpListener, TcpStream}; +use std::thread::spawn; +use std::time::Duration; + +use log::info; + +fn main() { + pretty_env_logger::init(); + spawn(|| rx_listen()); + spawn(|| rxtx_listen()); + tx_listen(); +} + +fn tx_listen() { + info!("tx: listening on 0.0.0.0:4321"); + let listener = TcpListener::bind("0.0.0.0:4321").unwrap(); + loop { + let (socket, addr) = listener.accept().unwrap(); + info!("tx: received connection from: {}", addr); + spawn(|| tx_conn(socket)); + } +} + +fn tx_conn(mut socket: TcpStream) { + socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); + socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); + + let buf = [0; 1024]; + loop { + if let Err(e) = socket.write_all(&buf) { + info!("tx: failed to write to socket; err = {:?}", e); + return; + } + } +} + +fn rx_listen() { + info!("rx: listening on 0.0.0.0:4322"); + let listener = TcpListener::bind("0.0.0.0:4322").unwrap(); + loop { + let (socket, addr) = listener.accept().unwrap(); + info!("rx: received connection from: {}", addr); + spawn(|| rx_conn(socket)); + } +} + +fn rx_conn(mut socket: TcpStream) { + socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); + socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); + + let mut buf = [0; 1024]; + loop { + if let Err(e) = socket.read_exact(&mut buf) { + info!("rx: failed to read from socket; err = {:?}", e); + return; + } + } +} + +fn rxtx_listen() { + info!("rxtx: listening on 0.0.0.0:4323"); + let listener = TcpListener::bind("0.0.0.0:4323").unwrap(); + loop { + let (socket, addr) = listener.accept().unwrap(); + info!("rxtx: received connection from: {}", addr); + spawn(|| rxtx_conn(socket)); + } +} + +fn rxtx_conn(mut socket: TcpStream) { + socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); + socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); + + let mut buf = [0; 1024]; + loop { + match socket.read(&mut buf) { + Ok(n) => { + if let Err(e) = socket.write_all(&buf[..n]) { + info!("rxtx: failed to write to socket; err = {:?}", e); + return; + } + } + Err(e) => { + info!("rxtx: failed to read from socket; err = {:?}", e); + return; + } + } + } +} diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 6bcac373..fa97fdcc 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -5,13 +5,16 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -teleprobe-meta = "1" +teleprobe-meta = "1.1" embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } +embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } +cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } defmt = "0.3.0" defmt-rtt = "0.4" @@ -25,6 +28,7 @@ panic-probe = { version = "0.3.0", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } embedded-io = { version = "0.4.0", features = ["async"] } embedded-storage = { version = "0.3" } +static_cell = { version = "1.1", features = ["nightly"]} [profile.dev] debug = 2 diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs new file mode 100644 index 00000000..568f1b82 --- /dev/null +++ b/tests/rp/src/bin/cyw43-perf.rs @@ -0,0 +1,267 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +#[path = "../common.rs"] +mod common; + +use cyw43_pio::PioSpi; +use defmt::{assert, panic, *}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_net::tcp::TcpSocket; +use embassy_net::{Config, Ipv4Address, Stack, StackResources}; +use embassy_rp::gpio::{Level, Output}; +use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; +use embassy_rp::pio::Pio; +use embassy_rp::rom_data; +use embassy_time::{with_timeout, Duration, Timer}; +use static_cell::make_static; +use {defmt_rtt as _, panic_probe as _}; + +teleprobe_meta::timeout!(120); + +#[embassy_executor::task] +async fn wifi_task( + runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, +) -> ! { + runner.run().await +} + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack>) -> ! { + stack.run().await +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + info!("Hello World!"); + let p = embassy_rp::init(Default::default()); + + // needed for reading the firmware from flash via XIP. + unsafe { + rom_data::flash_exit_xip(); + rom_data::flash_enter_cmd_xip(); + } + + // cyw43 firmware needs to be flashed manually: + // probe-rs-cli download 43439A0.bin --format bin --chip RP2040 --base-address 0x101c0000 + // probe-rs-cli download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101f8000 + let fw = unsafe { core::slice::from_raw_parts(0x101c0000 as *const u8, 224190) }; + let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; + + let pwr = Output::new(p.PIN_23, Level::Low); + let cs = Output::new(p.PIN_25, Level::High); + let mut pio = Pio::new(p.PIO0); + let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); + + let state = make_static!(cyw43::State::new()); + let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; + unwrap!(spawner.spawn(wifi_task(runner))); + + control.init(clm).await; + control + .set_power_management(cyw43::PowerManagementMode::PowerSave) + .await; + + let config = Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::Config { + // address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), + // dns_servers: Vec::new(), + // gateway: Some(Ipv4Address::new(192, 168, 69, 1)), + //}); + + // Generate random seed + let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. + + // Init network stack + let stack = &*make_static!(Stack::new( + net_device, + config, + make_static!(StackResources::<2>::new()), + seed + )); + + unwrap!(spawner.spawn(net_task(stack))); + + loop { + match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { + Ok(_) => break, + Err(err) => { + panic!("join failed with status={}", err.status); + } + } + } + + info!("Waiting for DHCP up..."); + while stack.config().is_none() { + Timer::after(Duration::from_millis(100)).await; + } + info!("IP addressing up!"); + + let down = test_download(stack).await; + let up = test_upload(stack).await; + let updown = test_upload_download(stack).await; + + assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS); + assert!(up > TEST_EXPECTED_UPLOAD_KBPS); + assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} + +// Test-only wifi network, no internet access! +const WIFI_NETWORK: &str = "EmbassyTest"; +const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; + +const TEST_DURATION: usize = 10; +const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 500; +const TEST_EXPECTED_UPLOAD_KBPS: usize = 500; +const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 400; +const RX_BUFFER_SIZE: usize = 4096; +const TX_BUFFER_SIZE: usize = 4096; +const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); +const DOWNLOAD_PORT: u16 = 4321; +const UPLOAD_PORT: u16 = 4322; +const UPLOAD_DOWNLOAD_PORT: u16 = 4323; + +async fn test_download(stack: &'static Stack>) -> usize { + info!("Testing download..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let mut rx_buf = [0; 4096]; + let mut total: usize = 0; + with_timeout(Duration::from_secs(TEST_DURATION as _), async { + loop { + match socket.read(&mut rx_buf).await { + Ok(0) => { + error!("read EOF"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("read error: {:?}", e); + return 0; + } + } + } + }) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("download: {} kB/s", kbps); + kbps +} + +async fn test_upload(stack: &'static Stack>) -> usize { + info!("Testing upload..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let buf = [0; 4096]; + let mut total: usize = 0; + with_timeout(Duration::from_secs(TEST_DURATION as _), async { + loop { + match socket.write(&buf).await { + Ok(0) => { + error!("write zero?!??!?!"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("write error: {:?}", e); + return 0; + } + } + } + }) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("upload: {} kB/s", kbps); + kbps +} + +async fn test_upload_download(stack: &'static Stack>) -> usize { + info!("Testing upload+download..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let (mut reader, mut writer) = socket.split(); + + let tx_buf = [0; 4096]; + let mut rx_buf = [0; 4096]; + let mut total: usize = 0; + let tx_fut = async { + loop { + match writer.write(&tx_buf).await { + Ok(0) => { + error!("write zero?!??!?!"); + return 0; + } + Ok(_) => {} + Err(e) => { + error!("write error: {:?}", e); + return 0; + } + } + } + }; + + let rx_fut = async { + loop { + match reader.read(&mut rx_buf).await { + Ok(0) => { + error!("read EOF"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("read error: {:?}", e); + return 0; + } + } + } + }; + + with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut)) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("upload+download: {} kB/s", kbps); + kbps +} From 54bab33c7342510be538bc6d8545fe50146557cf Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 14:57:17 +0200 Subject: [PATCH 11/28] Rename StaticConfig to StaticConfigV4 --- embassy-net/src/lib.rs | 12 ++++++------ examples/nrf52840/src/bin/usb_ethernet.rs | 2 +- examples/rp/src/bin/ethernet_w5500_multisocket.rs | 2 +- examples/rp/src/bin/ethernet_w5500_tcp_client.rs | 2 +- examples/rp/src/bin/ethernet_w5500_tcp_server.rs | 2 +- examples/rp/src/bin/ethernet_w5500_udp.rs | 2 +- examples/rp/src/bin/usb_ethernet.rs | 2 +- examples/rp/src/bin/wifi_ap_tcp_server.rs | 2 +- examples/rp/src/bin/wifi_tcp_server.rs | 2 +- examples/std/src/bin/net.rs | 2 +- examples/std/src/bin/net_dns.rs | 2 +- examples/std/src/bin/net_udp.rs | 2 +- examples/std/src/bin/tcp_accept.rs | 2 +- examples/stm32f4/src/bin/usb_ethernet.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32h5/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 2 +- examples/stm32l5/src/bin/usb_ethernet.rs | 2 +- 19 files changed, 24 insertions(+), 24 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index bccbad52..ddb325c6 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -68,7 +68,7 @@ impl StackResources { /// Static IP address configuration. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct StaticConfig { +pub struct StaticConfigV4 { /// IP address and subnet mask. pub address: Ipv4Cidr, /// Default gateway. @@ -114,7 +114,7 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { /// Use a static IP address configuration. - Static(StaticConfig), + Static(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -131,7 +131,7 @@ pub struct Stack { struct Inner { device: D, link_up: bool, - config: Option, + config: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -243,7 +243,7 @@ impl Stack { } /// Get the current IP configuration. - pub fn config(&self) -> Option { + pub fn config(&self) -> Option { self.with(|_s, i| i.config.clone()) } @@ -374,7 +374,7 @@ impl SocketStack { } impl Inner { - fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) { + fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -470,7 +470,7 @@ impl Inner { None => {} Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), Some(dhcpv4::Event::Configured(config)) => { - let config = StaticConfig { + let config = StaticConfigV4 { address: config.address, gateway: config.router, dns_servers: config.dns_servers, diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index 1065f5b5..b4316f5a 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs @@ -98,7 +98,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(usb_ncm_task(runner))); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index 63e142e7..7e9e20b2 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs @@ -120,7 +120,7 @@ async fn listen_task(stack: &'static Stack>, id: u8, port: u16) } } -async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfig { +async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { if let Some(config) = stack.config() { return config.clone(); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index a532de00..c0275be1 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -108,7 +108,7 @@ async fn main(spawner: Spawner) { } } -async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfig { +async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { if let Some(config) = stack.config() { return config.clone(); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index 599f6b1e..da73e41f 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs @@ -116,7 +116,7 @@ async fn main(spawner: Spawner) { } } -async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfig { +async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { if let Some(config) = stack.config() { return config.clone(); diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index ac5a65bb..4c861cbd 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs @@ -95,7 +95,7 @@ async fn main(spawner: Spawner) { } } -async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfig { +async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { if let Some(config) = stack.config() { return config.clone(); diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index 16fbf5e9..d33d9c72 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -87,7 +87,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(usb_ncm_task(runner))); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index b27d3c9f..970cf4b3 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs @@ -62,7 +62,7 @@ async fn main(spawner: Spawner) { .await; // Use a link-local address for communication without DHCP server - let config = Config::Static(embassy_net::StaticConfig { + let config = Config::StaticV4(embassy_net::StaticConfigV4 { address: embassy_net::Ipv4Cidr::new(embassy_net::Ipv4Address::new(169, 254, 1, 1), 16), dns_servers: heapless::Vec::new(), gateway: None, diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 1a00bca9..9f95f8b0 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -62,7 +62,7 @@ async fn main(spawner: Spawner) { .await; let config = Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::Config { + //let config = embassy_net::Config::StaticV4(embassy_net::Config { // address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index b42bfc13..14cf3f25 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -42,7 +42,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index 932ac583..0a479a74 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -40,7 +40,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()]) .unwrap(), diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index d89ec764..0ede5d99 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -38,7 +38,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 01695bae..4379d043 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -53,7 +53,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index d229cc3e..0856b484 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -95,7 +95,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(usb_ncm_task(runner))); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index d8438241..ebdf0d8a 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -63,7 +63,7 @@ async fn main(spawner: Spawner) -> ! { ); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 5d1eadf4..811f74c8 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -82,7 +82,7 @@ async fn main(spawner: Spawner) -> ! { ); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 3aa7b227..5360a213 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! { ); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 575c716b..42781cfd 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -65,7 +65,7 @@ async fn main(spawner: Spawner) -> ! { ); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticConfig(embassy_net::Config { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 6163e070..d96d2f35 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -92,7 +92,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(usb_ncm_task(runner))); let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::Static(embassy_net::StaticConfig { + //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), From e871324bde25bd61241aed83416caf6e49376d5a Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:00:53 +0200 Subject: [PATCH 12/28] net: StaticV4 config behind proto-ipv4 --- embassy-net/src/device.rs | 5 +- embassy-net/src/dns.rs | 1 + embassy-net/src/lib.rs | 46 ++++++++++++++----- embassy-net/src/tcp.rs | 3 ++ .../rp/src/bin/ethernet_w5500_multisocket.rs | 2 +- .../rp/src/bin/ethernet_w5500_tcp_client.rs | 2 +- .../rp/src/bin/ethernet_w5500_tcp_server.rs | 2 +- examples/rp/src/bin/ethernet_w5500_udp.rs | 2 +- 8 files changed, 47 insertions(+), 16 deletions(-) diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs index 5daa0054..583cdc87 100644 --- a/embassy-net/src/device.rs +++ b/embassy-net/src/device.rs @@ -59,7 +59,10 @@ where smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4); smolcaps.checksum.tcp = convert(caps.checksum.tcp); smolcaps.checksum.udp = convert(caps.checksum.udp); - smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4); + #[cfg(feature = "proto-ipv4")] + { + smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4); + } #[cfg(feature = "proto-ipv6")] { smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6); diff --git a/embassy-net/src/dns.rs b/embassy-net/src/dns.rs index 3fd235b2..94f75f10 100644 --- a/embassy-net/src/dns.rs +++ b/embassy-net/src/dns.rs @@ -88,6 +88,7 @@ where let addrs = self.query(host, qtype).await?; if let Some(first) = addrs.get(0) { Ok(match first { + #[cfg(feature = "proto-ipv4")] IpAddress::Ipv4(addr) => IpAddr::V4(addr.0.into()), #[cfg(feature = "proto-ipv6")] IpAddress::Ipv6(addr) => IpAddr::V6(addr.0.into()), diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index ddb325c6..2e713cd1 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -34,7 +34,9 @@ use smoltcp::socket::dhcpv4::{self, RetryConfig}; pub use smoltcp::wire::IpListenEndpoint; #[cfg(feature = "medium-ethernet")] pub use smoltcp::wire::{EthernetAddress, HardwareAddress}; -pub use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr}; +pub use smoltcp::wire::{IpAddress, IpCidr}; +#[cfg(feature = "proto-ipv4")] +pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; #[cfg(feature = "proto-ipv6")] pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr}; @@ -67,6 +69,7 @@ impl StackResources { } /// Static IP address configuration. +#[cfg(feature = "proto-ipv4")] #[derive(Debug, Clone, PartialEq, Eq)] pub struct StaticConfigV4 { /// IP address and subnet mask. @@ -114,7 +117,8 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { /// Use a static IP address configuration. - Static(StaticConfigV4), + #[cfg(feature = "proto-ipv4")] + StaticV4(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -131,7 +135,8 @@ pub struct Stack { struct Inner { device: D, link_up: bool, - config: Option, + #[cfg(feature = "proto-ipv4")] + static_v4: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -187,7 +192,8 @@ impl Stack { let mut inner = Inner { device, link_up: false, - config: None, + #[cfg(feature = "proto-ipv4")] + static_v4: None, #[cfg(feature = "dhcpv4")] dhcp_socket: None, #[cfg(feature = "dns")] @@ -200,7 +206,8 @@ impl Stack { }; match config { - Config::Static(config) => { + #[cfg(feature = "proto-ipv4")] + Config::StaticV4(config) => { inner.apply_config(&mut socket, config); } #[cfg(feature = "dhcpv4")] @@ -239,12 +246,21 @@ impl Stack { /// Get whether the network stack has a valid IP configuration. /// This is true if the network stack has a static IP configuration or if DHCP has completed pub fn is_config_up(&self) -> bool { - self.with(|_s, i| i.config.is_some()) + #[cfg(feature = "proto-ipv4")] + { + return self.config_v4().is_some(); + } + + #[cfg(not(any(feature = "proto-ipv4")))] + { + false + } } /// Get the current IP configuration. - pub fn config(&self) -> Option { - self.with(|_s, i| i.config.clone()) + #[cfg(feature = "proto-ipv4")] + pub fn config_v4(&self) -> Option { + self.with(|_s, i| i.static_v4.clone()) } /// Run the network stack. @@ -264,6 +280,7 @@ impl Stack { pub async fn dns_query(&self, name: &str, qtype: dns::DnsQueryType) -> Result, dns::Error> { // For A and AAAA queries we try detect whether `name` is just an IP address match qtype { + #[cfg(feature = "proto-ipv4")] dns::DnsQueryType::A => { if let Ok(ip) = name.parse().map(IpAddress::Ipv4) { return Ok([ip].into_iter().collect()); @@ -374,6 +391,7 @@ impl SocketStack { } impl Inner { + #[cfg(feature = "proto-ipv4")] fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -410,7 +428,7 @@ impl Inner { socket.update_servers(&servers[..]); } - self.config = Some(config) + self.static_v4 = Some(config) } #[cfg(feature = "dhcpv4")] @@ -430,9 +448,15 @@ impl Inner { s.iface.update_ip_addrs(|ip_addrs| ip_addrs.clear()); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { - s.iface.routes_mut().remove_default_ipv4_route(); + #[cfg(feature = "proto-ipv4")] + { + s.iface.routes_mut().remove_default_ipv4_route(); + } + } + #[cfg(feature = "proto-ipv4")] + { + self.static_v4 = None } - self.config = None } fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 7babb529..52fee688 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -472,7 +472,10 @@ pub mod client { Self: 'a, { let addr: crate::IpAddress = match remote.ip() { + #[cfg(feature = "proto-ipv4")] IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())), + #[cfg(not(feature = "proto-ipv4"))] + IpAddr::V4(_) => panic!("ipv4 support not enabled"), #[cfg(feature = "proto-ipv6")] IpAddr::V6(addr) => crate::IpAddress::Ipv6(crate::Ipv6Address::from_bytes(&addr.octets())), #[cfg(not(feature = "proto-ipv6"))] diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index 7e9e20b2..066ecf2b 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs @@ -122,7 +122,7 @@ async fn listen_task(stack: &'static Stack>, id: u8, port: u16) async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { - if let Some(config) = stack.config() { + if let Some(config) = stack.config_v4() { return config.clone(); } yield_now().await; diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index c0275be1..3e0f5d13 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -110,7 +110,7 @@ async fn main(spawner: Spawner) { async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { - if let Some(config) = stack.config() { + if let Some(config) = stack.config_v4() { return config.clone(); } yield_now().await; diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index da73e41f..db178d49 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs @@ -118,7 +118,7 @@ async fn main(spawner: Spawner) { async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { - if let Some(config) = stack.config() { + if let Some(config) = stack.config_v4() { return config.clone(); } yield_now().await; diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 4c861cbd..21943c3c 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs @@ -97,7 +97,7 @@ async fn main(spawner: Spawner) { async fn wait_for_config(stack: &'static Stack>) -> embassy_net::StaticConfigV4 { loop { - if let Some(config) = stack.config() { + if let Some(config) = stack.config_v4() { return config.clone(); } yield_now().await; From d7f674e410a674f06a749859bde4081a99718f58 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:12:24 +0200 Subject: [PATCH 13/28] net: Allow setting an IPv6 in the stack --- embassy-net/src/lib.rs | 72 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 2e713cd1..9f83cb4e 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -80,6 +80,18 @@ pub struct StaticConfigV4 { pub dns_servers: Vec, } +/// Static IPv6 address configuration +#[cfg(feature = "proto-ipv6")] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StaticConfigV6 { + /// IP address and subnet mask. + pub address: Ipv6Cidr, + /// Default gateway. + pub gateway: Option, + /// DNS servers. + pub dns_servers: Vec, +} + /// DHCP configuration. #[cfg(feature = "dhcpv4")] #[derive(Debug, Clone, PartialEq, Eq)] @@ -116,9 +128,12 @@ impl Default for DhcpConfig { /// Network stack configuration. pub enum Config { - /// Use a static IP address configuration. + /// Use a static IPv4 address configuration. #[cfg(feature = "proto-ipv4")] StaticV4(StaticConfigV4), + /// Use a static IPv6 address configuration. + #[cfg(feature = "proto-ipv6")] + StaticV6(StaticConfigV6), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), @@ -137,6 +152,8 @@ struct Inner { link_up: bool, #[cfg(feature = "proto-ipv4")] static_v4: Option, + #[cfg(feature = "proto-ipv6")] + static_v6: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, #[cfg(feature = "dns")] @@ -194,6 +211,8 @@ impl Stack { link_up: false, #[cfg(feature = "proto-ipv4")] static_v4: None, + #[cfg(feature = "proto-ipv6")] + static_v6: None, #[cfg(feature = "dhcpv4")] dhcp_socket: None, #[cfg(feature = "dns")] @@ -208,7 +227,11 @@ impl Stack { match config { #[cfg(feature = "proto-ipv4")] Config::StaticV4(config) => { - inner.apply_config(&mut socket, config); + inner.apply_config_v4(&mut socket, config); + } + #[cfg(feature = "proto-ipv6")] + Config::StaticV6(config) => { + inner.apply_config_v6(&mut socket, config); } #[cfg(feature = "dhcpv4")] Config::Dhcp(config) => { @@ -392,7 +415,7 @@ impl SocketStack { impl Inner { #[cfg(feature = "proto-ipv4")] - fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfigV4) { + fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -431,6 +454,47 @@ impl Inner { self.static_v4 = Some(config) } + /// Replaces the current IPv6 static configuration with a newly supplied config. + #[cfg(feature = "proto-ipv6")] + fn apply_config_v6(&mut self, s: &mut SocketStack, config: StaticConfigV6) { + #[cfg(feature = "medium-ethernet")] + let medium = self.device.capabilities().medium; + + debug!("Acquired IPv6 configuration:"); + + debug!(" IP address: {}", config.address); + s.iface.update_ip_addrs(|addrs| { + if addrs.is_empty() { + addrs.push(IpCidr::Ipv6(config.address)).unwrap(); + } else { + addrs[0] = IpCidr::Ipv6(config.address); + } + }); + + #[cfg(feature = "medium-ethernet")] + if Medium::Ethernet == medium { + if let Some(gateway) = config.gateway { + debug!(" Default gateway: {}", gateway); + s.iface.routes_mut().add_default_ipv6_route(gateway).unwrap(); + } else { + debug!(" Default gateway: None"); + s.iface.routes_mut().remove_default_ipv6_route(); + } + } + for (i, s) in config.dns_servers.iter().enumerate() { + debug!(" DNS server {}: {}", i, s); + } + + #[cfg(feature = "dns")] + { + let socket = s.sockets.get_mut::(self.dns_socket); + let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)).collect(); + socket.update_servers(&servers[..]); + } + + self.static_v6 = Some(config) + } + #[cfg(feature = "dhcpv4")] fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { socket.set_ignore_naks(config.ignore_naks); @@ -499,7 +563,7 @@ impl Inner { gateway: config.router, dns_servers: config.dns_servers, }; - self.apply_config(s, config) + self.apply_config_v4(s, config) } } } else if old_link_up { From 18578fd15f29e92280e4e317ff3148ea498566dd Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:35:31 +0200 Subject: [PATCH 14/28] net: Allow a combined use of IPv4 and IPv6 DNS servers --- embassy-net/src/lib.rs | 49 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 9f83cb4e..23ec3326 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -444,14 +444,12 @@ impl Inner { debug!(" DNS server {}: {}", i, s); } + self.static_v4 = Some(config); + #[cfg(feature = "dns")] { - let socket = s.sockets.get_mut::(self.dns_socket); - let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv4(*c)).collect(); - socket.update_servers(&servers[..]); + self.update_dns_servers(s) } - - self.static_v4 = Some(config) } /// Replaces the current IPv6 static configuration with a newly supplied config. @@ -485,14 +483,47 @@ impl Inner { debug!(" DNS server {}: {}", i, s); } + self.static_v6 = Some(config); + #[cfg(feature = "dns")] { - let socket = s.sockets.get_mut::(self.dns_socket); - let servers: Vec = config.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)).collect(); - socket.update_servers(&servers[..]); + self.update_dns_servers(s) + } + } + + #[cfg(feature = "dns")] + fn update_dns_servers(&mut self, s: &mut SocketStack) { + let socket = s.sockets.get_mut::(self.dns_socket); + + let servers_v4; + #[cfg(feature = "proto-ipv4")] + { + servers_v4 = self + .static_v4 + .iter() + .flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv4(*c))); + }; + #[cfg(not(feature = "proto-ipv4"))] + { + servers_v4 = core::iter::empty(); } - self.static_v6 = Some(config) + let servers_v6; + #[cfg(feature = "proto-ipv6")] + { + servers_v6 = self + .static_v6 + .iter() + .flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv6(*c))); + } + #[cfg(not(feature = "proto-ipv6"))] + { + servers_v6 = core::iter::empty(); + } + + // Prefer the v6 DNS servers over the v4 servers + let servers: Vec = servers_v6.chain(servers_v4).collect(); + socket.update_servers(&servers[..]); } #[cfg(feature = "dhcpv4")] From d2a6c5c6082dbf3c9783b809d89faf9b369ed1c9 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 16:42:46 +0200 Subject: [PATCH 15/28] CI: Add proto-ipv6 tests without ipv4 to CI --- ci.sh | 4 ++++ ci_stable.sh | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ci.sh b/ci.sh index 3d6e2879..91e7abce 100755 --- a/ci.sh +++ b/ci.sh @@ -30,6 +30,10 @@ cargo batch \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \ diff --git a/ci_stable.sh b/ci_stable.sh index a67087ff..72318fc4 100755 --- a/ci_stable.sh +++ b/ci_stable.sh @@ -17,6 +17,8 @@ cargo batch \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \ From ada7ec2289c1d396ab8ddcf90943ea593d334c52 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 17:14:20 +0200 Subject: [PATCH 16/28] CI: add proto-ipv4 to embassy-net test --- ci.sh | 4 ++-- ci_stable.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci.sh b/ci.sh index 91e7abce..852e512c 100755 --- a/ci.sh +++ b/ci.sh @@ -25,7 +25,7 @@ cargo batch \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \ --- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \ --- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \ - --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,medium-ethernet \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \ @@ -163,4 +163,4 @@ if [[ -z "${TELEPROBE_TOKEN-}" ]]; then exit fi -teleprobe client run -r out/tests \ No newline at end of file +teleprobe client run -r out/tests diff --git a/ci_stable.sh b/ci_stable.sh index 72318fc4..daae9896 100755 --- a/ci_stable.sh +++ b/ci_stable.sh @@ -14,7 +14,7 @@ cargo batch \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features log \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features defmt \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features defmt \ - --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,medium-ethernet \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ From ae1dedc0596832f5ec2389d8ff845b10c0a480f1 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 6 Jun 2023 11:17:02 +0200 Subject: [PATCH 17/28] net: proto-ipv6 in is_config_up --- embassy-net/src/lib.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 23ec3326..4cc191d4 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -269,23 +269,42 @@ impl Stack { /// Get whether the network stack has a valid IP configuration. /// This is true if the network stack has a static IP configuration or if DHCP has completed pub fn is_config_up(&self) -> bool { + let v4_up; + let v6_up; + #[cfg(feature = "proto-ipv4")] { - return self.config_v4().is_some(); + v4_up = self.config_v4().is_some(); + } + #[cfg(not(feature = "proto-ipv4"))] + { + v4_up = false; } - #[cfg(not(any(feature = "proto-ipv4")))] + #[cfg(feature = "proto-ipv6")] { - false + v6_up = self.config_v6().is_some(); } + #[cfg(not(feature = "proto-ipv6"))] + { + v6_up = false; + } + + v4_up || v6_up } - /// Get the current IP configuration. + /// Get the current IPv4 configuration. #[cfg(feature = "proto-ipv4")] pub fn config_v4(&self) -> Option { self.with(|_s, i| i.static_v4.clone()) } + /// Get the current IPv6 configuration. + #[cfg(feature = "proto-ipv6")] + pub fn config_v6(&self) -> Option { + self.with(|_s, i| i.static_v6.clone()) + } + /// Run the network stack. /// /// You must call this in a background task, to process network events. From ca47af6978e85012ff70a98726fcb63ed985109d Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 6 Jun 2023 18:21:45 +0200 Subject: [PATCH 18/28] CI: introduce tests for dual stack v4 and v6 --- ci.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci.sh b/ci.sh index 852e512c..f4f59177 100755 --- a/ci.sh +++ b/ci.sh @@ -34,6 +34,10 @@ cargo batch \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits,nightly \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \ From 2eb08b2dc92bc0393dc417de6ccdc039d30f6dd5 Mon Sep 17 00:00:00 2001 From: Russ Hewgill Date: Tue, 6 Jun 2023 09:49:38 -0700 Subject: [PATCH 19/28] updated can_recv and may_recv to match the smoltcp functions. --- embassy-net/src/tcp.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 7babb529..515bbc5b 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -278,10 +278,18 @@ impl<'a> TcpSocket<'a> { self.io.with(|s, _| s.may_send()) } - /// Get whether the socket is ready to receive data, i.e. whether there is some pending data in the receive buffer. + /// return whether the recieve half of the full-duplex connection is open. + /// This function returns true if it’s possible to receive data from the remote endpoint. + /// It will return true while there is data in the receive buffer, and if there isn’t, + /// as long as the remote endpoint has not closed the connection. pub fn may_recv(&self) -> bool { self.io.with(|s, _| s.may_recv()) } + + /// Get whether the socket is ready to receive data, i.e. whether there is some pending data in the receive buffer. + pub fn can_recv(&self) -> bool { + self.io.with(|s, _| s.can_recv()) + } } impl<'a> Drop for TcpSocket<'a> { From 352f0b6c3823797576c36f417d6be40189bca5d5 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 7 Jun 2023 12:04:15 +0200 Subject: [PATCH 20/28] =?UTF-8?q?net:=20Support=20dual=20stack=C2=A0IP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- embassy-net/src/lib.rs | 75 +++++++++++++++---- examples/nrf52840/src/bin/usb_ethernet.rs | 6 +- .../rp/src/bin/ethernet_w5500_multisocket.rs | 2 +- .../rp/src/bin/ethernet_w5500_tcp_client.rs | 2 +- .../rp/src/bin/ethernet_w5500_tcp_server.rs | 2 +- examples/rp/src/bin/ethernet_w5500_udp.rs | 2 +- examples/rp/src/bin/usb_ethernet.rs | 4 +- examples/rp/src/bin/wifi_ap_tcp_server.rs | 2 +- examples/rp/src/bin/wifi_tcp_server.rs | 4 +- examples/std/src/bin/net.rs | 4 +- examples/std/src/bin/net_dns.rs | 4 +- examples/std/src/bin/net_udp.rs | 4 +- examples/std/src/bin/tcp_accept.rs | 4 +- examples/stm32f4/src/bin/usb_ethernet.rs | 4 +- examples/stm32f7/src/bin/eth.rs | 4 +- examples/stm32h5/src/bin/eth.rs | 4 +- examples/stm32h7/src/bin/eth.rs | 4 +- examples/stm32h7/src/bin/eth_client.rs | 4 +- examples/stm32l5/src/bin/usb_ethernet.rs | 4 +- 19 files changed, 94 insertions(+), 45 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 4cc191d4..cf7ebad3 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -127,16 +127,61 @@ impl Default for DhcpConfig { } /// Network stack configuration. -pub enum Config { - /// Use a static IPv4 address configuration. +pub struct Config { #[cfg(feature = "proto-ipv4")] - StaticV4(StaticConfigV4), - /// Use a static IPv6 address configuration. + pub ipv4: ConfigV4, #[cfg(feature = "proto-ipv6")] - StaticV6(StaticConfigV6), + pub ipv6: ConfigV6, +} + +impl Config { + #[cfg(feature = "proto-ipv4")] + pub fn ipv4_static(config: StaticConfigV4) -> Self { + Self { + ipv4: ConfigV4::Static(config), + #[cfg(feature = "proto-ipv6")] + ipv6: ConfigV6::None, + } + } + + #[cfg(feature = "proto-ipv6")] + pub fn ipv6_static(config: StaticConfigV6) -> Self { + Self { + #[cfg(feature = "proto-ipv4")] + ipv4: ConfigV4::None, + ipv6: ConfigV6::Static(config), + } + } + + #[cfg(feature = "dhcpv4")] + pub fn dhcpv4(config: DhcpConfig) -> Self { + Self { + ipv4: ConfigV4::Dhcp(config), + #[cfg(feature = "proto-ipv6")] + ipv6: ConfigV6::None, + } + } +} + +/// Network stack IPv4 configuration. +#[cfg(feature = "proto-ipv4")] +pub enum ConfigV4 { + /// Use a static IPv4 address configuration. + Static(StaticConfigV4), /// Use DHCP to obtain an IP address configuration. #[cfg(feature = "dhcpv4")] Dhcp(DhcpConfig), + /// Do not configure IPv6. + None, +} + +/// Network stack IPv6 configuration. +#[cfg(feature = "proto-ipv6")] +pub enum ConfigV6 { + /// Use a static IPv6 address configuration. + Static(StaticConfigV6), + /// Do not configure IPv6. + None, } /// A network stack. @@ -224,22 +269,26 @@ impl Stack { dns_waker: WakerRegistration::new(), }; - match config { - #[cfg(feature = "proto-ipv4")] - Config::StaticV4(config) => { + #[cfg(feature = "proto-ipv4")] + match config.ipv4 { + ConfigV4::Static(config) => { inner.apply_config_v4(&mut socket, config); } - #[cfg(feature = "proto-ipv6")] - Config::StaticV6(config) => { - inner.apply_config_v6(&mut socket, config); - } #[cfg(feature = "dhcpv4")] - Config::Dhcp(config) => { + ConfigV4::Dhcp(config) => { let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new(); inner.apply_dhcp_config(&mut dhcp_socket, config); let handle = socket.sockets.add(dhcp_socket); inner.dhcp_socket = Some(handle); } + ConfigV4::None => {} + } + #[cfg(feature = "proto-ipv6")] + match config.ipv6 { + ConfigV6::Static(config) => { + inner.apply_config_v6(&mut socket, config); + } + ConfigV6::None => {} } Self { diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index b4316f5a..f527c0d7 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs @@ -97,12 +97,12 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(make_static!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + // let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), - //}); + // }); // Generate random seed let mut rng = Rng::new(p.RNG, Irqs); diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index 066ecf2b..82568254 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) { // Init network stack let stack = &*make_static!(Stack::new( device, - embassy_net::Config::Dhcp(Default::default()), + embassy_net::Config::dhcpv4(Default::default()), make_static!(StackResources::<3>::new()), seed )); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index 3e0f5d13..d562defa 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -67,7 +67,7 @@ async fn main(spawner: Spawner) { // Init network stack let stack = &*make_static!(Stack::new( device, - embassy_net::Config::Dhcp(Default::default()), + embassy_net::Config::dhcpv4(Default::default()), make_static!(StackResources::<2>::new()), seed )); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index db178d49..7f521cdb 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs @@ -65,7 +65,7 @@ async fn main(spawner: Spawner) { // Init network stack let stack = &*make_static!(Stack::new( device, - embassy_net::Config::Dhcp(Default::default()), + embassy_net::Config::dhcpv4(Default::default()), make_static!(StackResources::<2>::new()), seed )); diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 21943c3c..ada86ae5 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs @@ -62,7 +62,7 @@ async fn main(spawner: Spawner) { // Init network stack let stack = &*make_static!(Stack::new( device, - embassy_net::Config::Dhcp(Default::default()), + embassy_net::Config::dhcpv4(Default::default()), make_static!(StackResources::<2>::new()), seed )); diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index d33d9c72..91d1ec8e 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -86,8 +86,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(make_static!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index 970cf4b3..e8197390 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs @@ -62,7 +62,7 @@ async fn main(spawner: Spawner) { .await; // Use a link-local address for communication without DHCP server - let config = Config::StaticV4(embassy_net::StaticConfigV4 { + let config = Config::ipv4_static(embassy_net::StaticConfigV4 { address: embassy_net::Ipv4Cidr::new(embassy_net::Ipv4Address::new(169, 254, 1, 1), 16), dns_servers: heapless::Vec::new(), gateway: None, diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 9f95f8b0..026e056f 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -61,8 +61,8 @@ async fn main(spawner: Spawner) { .set_power_management(cyw43::PowerManagementMode::PowerSave) .await; - let config = Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::Config { + let config = Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 14cf3f25..3aadb029 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -42,13 +42,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index 0a479a74..65b5a2cd 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -40,14 +40,14 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()]) .unwrap(), gateway: Some(Ipv4Address::new(192, 168, 69, 100)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 0ede5d99..3fc46156 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -38,13 +38,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 4379d043..df09986a 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -53,13 +53,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 0856b484..953d99a4 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -94,8 +94,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(make_static!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index ebdf0d8a..fde6a757 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -62,8 +62,8 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 811f74c8..78c8282a 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -81,8 +81,8 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 5360a213..12d37f7a 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -63,8 +63,8 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 42781cfd..6078fc3f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -64,8 +64,8 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index d96d2f35..32eba427 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -91,8 +91,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(make_static!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::Config::Dhcp(Default::default()); - //let config = embassy_net::Config::StaticV4(embassy_net::StaticConfigV4 { + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), From 2455fd4dbe4e874a9a200d3026f66d437449b04d Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 7 Jun 2023 12:08:53 +0200 Subject: [PATCH 21/28] net: Add documentation to new Config system --- embassy-net/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index cf7ebad3..7e8f765f 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -128,13 +128,16 @@ impl Default for DhcpConfig { /// Network stack configuration. pub struct Config { + /// IPv4 configuration #[cfg(feature = "proto-ipv4")] pub ipv4: ConfigV4, + /// IPv6 configuration #[cfg(feature = "proto-ipv6")] pub ipv6: ConfigV6, } impl Config { + /// IPv4 configuration with static addressing. #[cfg(feature = "proto-ipv4")] pub fn ipv4_static(config: StaticConfigV4) -> Self { Self { @@ -144,6 +147,7 @@ impl Config { } } + /// IPv6 configuration with static addressing. #[cfg(feature = "proto-ipv6")] pub fn ipv6_static(config: StaticConfigV6) -> Self { Self { @@ -153,6 +157,12 @@ impl Config { } } + /// IPv6 configuration with dynamic addressing. + /// + /// # Example + /// ```rust + /// let _cfg = Config::dhcpv4(Default::default()); + /// ``` #[cfg(feature = "dhcpv4")] pub fn dhcpv4(config: DhcpConfig) -> Self { Self { From 921780e6bfb9bcb2cd087b8aa8b094d792c99fa2 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 16:08:40 +0200 Subject: [PATCH 22/28] Make interrupt module more standard. - Move typelevel interrupts to a special-purpose mod: `embassy_xx::interrupt::typelevel`. - Reexport the PAC interrupt enum in `embassy_xx::interrupt`. This has a few advantages: - The `embassy_xx::interrupt` module is now more "standard". - It works with `cortex-m` functions for manipulating interrupts, for example. - It works with RTIC. - the interrupt enum allows holding value that can be "any interrupt at runtime", this can't be done with typelevel irqs. - When "const-generics on enums" is stable, we can remove the typelevel interrupts without disruptive changes to `embassy_xx::interrupt`. --- embassy-cortex-m/src/interrupt.rs | 211 +++++++++++++----- embassy-lora/src/iv.rs | 12 +- embassy-macros/src/lib.rs | 13 -- .../src/macros/cortex_m_interrupt.rs | 66 ------ .../src/macros/cortex_m_interrupt_declare.rs | 21 -- embassy-macros/src/macros/mod.rs | 2 - embassy-nrf/src/buffered_uarte.rs | 11 +- embassy-nrf/src/chips/nrf52805.rs | 56 +++-- embassy-nrf/src/chips/nrf52810.rs | 62 +++-- embassy-nrf/src/chips/nrf52811.rs | 62 +++-- embassy-nrf/src/chips/nrf52820.rs | 60 +++-- embassy-nrf/src/chips/nrf52832.rs | 82 ++++--- embassy-nrf/src/chips/nrf52833.rs | 90 ++++---- embassy-nrf/src/chips/nrf52840.rs | 94 ++++---- embassy-nrf/src/chips/nrf5340_app.rs | 90 ++++---- embassy-nrf/src/chips/nrf5340_net.rs | 48 ++-- embassy-nrf/src/chips/nrf9160.rs | 70 +++--- embassy-nrf/src/gpiote.rs | 14 +- embassy-nrf/src/i2s.rs | 14 +- embassy-nrf/src/lib.rs | 29 +-- embassy-nrf/src/pdm.rs | 13 +- embassy-nrf/src/pwm.rs | 7 +- embassy-nrf/src/qdec.rs | 12 +- embassy-nrf/src/qspi.rs | 12 +- embassy-nrf/src/rng.rs | 10 +- embassy-nrf/src/saadc.rs | 10 +- embassy-nrf/src/spim.rs | 16 +- embassy-nrf/src/spis.rs | 16 +- embassy-nrf/src/temp.rs | 10 +- embassy-nrf/src/time_driver.rs | 6 +- embassy-nrf/src/timer.rs | 5 +- embassy-nrf/src/twim.rs | 12 +- embassy-nrf/src/twis.rs | 12 +- embassy-nrf/src/uarte.rs | 22 +- embassy-nrf/src/usb/mod.rs | 12 +- embassy-nrf/src/usb/vbus_detect.rs | 12 +- embassy-rp/src/adc.rs | 16 +- embassy-rp/src/dma.rs | 8 +- embassy-rp/src/gpio.rs | 8 +- embassy-rp/src/i2c.rs | 13 +- embassy-rp/src/interrupt.rs | 65 ------ embassy-rp/src/lib.rs | 64 +++++- embassy-rp/src/multicore.rs | 4 +- embassy-rp/src/pio.rs | 14 +- embassy-rp/src/timer.rs | 10 +- embassy-rp/src/uart/buffered.rs | 6 +- embassy-rp/src/uart/mod.rs | 10 +- embassy-rp/src/usb.rs | 11 +- embassy-stm32/build.rs | 8 +- embassy-stm32/src/dcmi.rs | 24 +- embassy-stm32/src/dma/bdma.rs | 6 +- embassy-stm32/src/dma/dma.rs | 6 +- embassy-stm32/src/dma/gpdma.rs | 4 +- embassy-stm32/src/eth/v1/mod.rs | 10 +- embassy-stm32/src/eth/v2/mod.rs | 10 +- embassy-stm32/src/exti.rs | 4 +- embassy-stm32/src/flash/asynch.rs | 10 +- embassy-stm32/src/i2c/mod.rs | 6 +- embassy-stm32/src/i2c/v1.rs | 4 +- embassy-stm32/src/i2c/v2.rs | 6 +- embassy-stm32/src/lib.rs | 51 ++--- embassy-stm32/src/sdmmc/mod.rs | 16 +- embassy-stm32/src/time_driver.rs | 2 +- embassy-stm32/src/timer/mod.rs | 6 +- embassy-stm32/src/tl_mbox/mod.rs | 18 +- embassy-stm32/src/usart/buffered.rs | 10 +- embassy-stm32/src/usart/mod.rs | 18 +- embassy-stm32/src/usb/mod.rs | 6 +- embassy-stm32/src/usb/usb.rs | 6 +- embassy-stm32/src/usb_otg/mod.rs | 10 +- embassy-stm32/src/usb_otg/usb.rs | 8 +- examples/stm32f7/build.rs | 3 +- 72 files changed, 845 insertions(+), 930 deletions(-) delete mode 100644 embassy-macros/src/macros/cortex_m_interrupt.rs delete mode 100644 embassy-macros/src/macros/cortex_m_interrupt_declare.rs delete mode 100644 embassy-rp/src/interrupt.rs diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs index 0e790eaa..8e45c36c 100644 --- a/embassy-cortex-m/src/interrupt.rs +++ b/embassy-cortex-m/src/interrupt.rs @@ -2,120 +2,207 @@ use core::mem; use core::sync::atomic::{compiler_fence, Ordering}; +use cortex_m::interrupt::InterruptNumber; use cortex_m::peripheral::NVIC; -/// Do not use. Used for macros and HALs only. Not covered by semver guarantees. -#[doc(hidden)] -pub mod _export { - pub use atomic_polyfill as atomic; - pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare}; -} +/// Generate a standard `mod interrupt` for a HAL. +#[macro_export] +macro_rules! interrupt_mod { + ($($irqs:ident),* $(,)?) => { + pub use cortex_m_rt::interrupt; -/// Interrupt handler trait. -/// -/// Drivers that need to handle interrupts implement this trait. -/// The user must ensure `on_interrupt()` is called every time the interrupt fires. -/// Drivers must use use [`Binding`] to assert at compile time that the user has done so. -pub trait Handler { - /// Interrupt handler function. - /// - /// Must be called every time the `I` interrupt fires, synchronously from - /// the interrupt handler context. - /// - /// # Safety - /// - /// This function must ONLY be called from the interrupt handler for `I`. - unsafe fn on_interrupt(); -} + /// Interrupt definitions. + pub mod interrupt { + pub use embassy_cortex_m::interrupt::{InterruptExt, Priority}; + pub use crate::pac::interrupt::*; + pub use crate::pac::Interrupt; -/// Compile-time assertion that an interrupt has been bound to a handler. -/// -/// For the vast majority of cases, you should use the `bind_interrupts!` -/// macro instead of writing `unsafe impl`s of this trait. -/// -/// # Safety -/// -/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()` -/// to be called every time the `I` interrupt fires. -/// -/// This allows drivers to check bindings at compile-time. -pub unsafe trait Binding> {} + /// Type-level interrupt infrastructure. + /// + /// This module contains one *type* per interrupt. This is used for checking at compile time that + /// the interrupts are correctly bound to HAL drivers. + /// + /// As an end user, you shouldn't need to use this module directly. Use the [`crate::bind_interrupts!`] macro + /// to bind interrupts, and the [`crate::interrupt`] module to manually register interrupt handlers and manipulate + /// interrupts directly (pending/unpending, enabling/disabling, setting the priority, etc...) + pub mod typelevel { + use super::InterruptExt; -#[derive(Clone, Copy)] -pub(crate) struct NrWrap(pub(crate) u16); -unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap { - fn number(self) -> u16 { - self.0 - } + mod sealed { + pub trait Interrupt {} + } + + /// Type-level interrupt. + /// + /// This trait is implemented for all typelevel interrupt types in this module. + pub trait Interrupt: sealed::Interrupt { + + /// Interrupt enum variant. + /// + /// This allows going from typelevel interrupts (one type per interrupt) to + /// non-typelevel interrupts (a single `Interrupt` enum type, with one variant per interrupt). + const IRQ: super::Interrupt; + + /// Enable the interrupt. + #[inline] + unsafe fn enable() { + Self::IRQ.enable() + } + + /// Disable the interrupt. + #[inline] + fn disable() { + Self::IRQ.disable() + } + + /// Check if interrupt is enabled. + #[inline] + fn is_enabled() -> bool { + Self::IRQ.is_enabled() + } + + /// Check if interrupt is pending. + #[inline] + fn is_pending() -> bool { + Self::IRQ.is_pending() + } + + /// Set interrupt pending. + #[inline] + fn pend() { + Self::IRQ.pend() + } + + /// Unset interrupt pending. + #[inline] + fn unpend() { + Self::IRQ.unpend() + } + + /// Get the priority of the interrupt. + #[inline] + fn get_priority() -> crate::interrupt::Priority { + Self::IRQ.get_priority() + } + + /// Set the interrupt priority. + #[inline] + fn set_priority(prio: crate::interrupt::Priority) { + Self::IRQ.set_priority(prio) + } + } + + $( + #[allow(non_camel_case_types)] + #[doc=stringify!($irqs)] + #[doc=" typelevel interrupt."] + pub enum $irqs {} + impl sealed::Interrupt for $irqs{} + impl Interrupt for $irqs { + const IRQ: super::Interrupt = super::Interrupt::$irqs; + } + )* + + /// Interrupt handler trait. + /// + /// Drivers that need to handle interrupts implement this trait. + /// The user must ensure `on_interrupt()` is called every time the interrupt fires. + /// Drivers must use use [`Binding`] to assert at compile time that the user has done so. + pub trait Handler { + /// Interrupt handler function. + /// + /// Must be called every time the `I` interrupt fires, synchronously from + /// the interrupt handler context. + /// + /// # Safety + /// + /// This function must ONLY be called from the interrupt handler for `I`. + unsafe fn on_interrupt(); + } + + /// Compile-time assertion that an interrupt has been bound to a handler. + /// + /// For the vast majority of cases, you should use the `bind_interrupts!` + /// macro instead of writing `unsafe impl`s of this trait. + /// + /// # Safety + /// + /// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()` + /// to be called every time the `I` interrupt fires. + /// + /// This allows drivers to check bindings at compile-time. + pub unsafe trait Binding> {} + } + } + }; } /// Represents an interrupt type that can be configured by embassy to handle /// interrupts. -pub unsafe trait Interrupt { - /// Return the NVIC interrupt number for this interrupt. - fn number() -> u16; - +pub unsafe trait InterruptExt: InterruptNumber + Copy { /// Enable the interrupt. #[inline] - unsafe fn enable() { + unsafe fn enable(self) { compiler_fence(Ordering::SeqCst); - NVIC::unmask(NrWrap(Self::number())) + NVIC::unmask(self) } /// Disable the interrupt. #[inline] - fn disable() { - NVIC::mask(NrWrap(Self::number())); + fn disable(self) { + NVIC::mask(self); compiler_fence(Ordering::SeqCst); } /// Check if interrupt is being handled. #[inline] #[cfg(not(armv6m))] - fn is_active() -> bool { - NVIC::is_active(NrWrap(Self::number())) + fn is_active(self) -> bool { + NVIC::is_active(self) } /// Check if interrupt is enabled. #[inline] - fn is_enabled() -> bool { - NVIC::is_enabled(NrWrap(Self::number())) + fn is_enabled(self) -> bool { + NVIC::is_enabled(self) } /// Check if interrupt is pending. #[inline] - fn is_pending() -> bool { - NVIC::is_pending(NrWrap(Self::number())) + fn is_pending(self) -> bool { + NVIC::is_pending(self) } /// Set interrupt pending. #[inline] - fn pend() { - NVIC::pend(NrWrap(Self::number())) + fn pend(self) { + NVIC::pend(self) } /// Unset interrupt pending. #[inline] - fn unpend() { - NVIC::unpend(NrWrap(Self::number())) + fn unpend(self) { + NVIC::unpend(self) } /// Get the priority of the interrupt. #[inline] - fn get_priority() -> Priority { - Priority::from(NVIC::get_priority(NrWrap(Self::number()))) + fn get_priority(self) -> Priority { + Priority::from(NVIC::get_priority(self)) } /// Set the interrupt priority. #[inline] - fn set_priority(prio: Priority) { + fn set_priority(self, prio: Priority) { critical_section::with(|_| unsafe { let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); - nvic.set_priority(NrWrap(Self::number()), prio.into()) + nvic.set_priority(self, prio.into()) }) } } +unsafe impl InterruptExt for T {} + impl From for Priority { fn from(priority: u8) -> Self { unsafe { mem::transmute(priority & PRIO_MASK) } diff --git a/embassy-lora/src/iv.rs b/embassy-lora/src/iv.rs index 8d521040..2e0b68d1 100644 --- a/embassy-lora/src/iv.rs +++ b/embassy-lora/src/iv.rs @@ -1,7 +1,7 @@ #[cfg(feature = "stm32wl")] use embassy_stm32::interrupt; #[cfg(feature = "stm32wl")] -use embassy_stm32::interrupt::*; +use embassy_stm32::interrupt::InterruptExt; #[cfg(feature = "stm32wl")] use embassy_stm32::pac; #[cfg(feature = "stm32wl")] @@ -20,9 +20,9 @@ use lora_phy::mod_traits::InterfaceVariant; pub struct InterruptHandler {} #[cfg(feature = "stm32wl")] -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { - interrupt::SUBGHZ_RADIO::disable(); + interrupt::SUBGHZ_RADIO.disable(); IRQ_SIGNAL.signal(()); } } @@ -45,11 +45,11 @@ where { /// Create an InterfaceVariant instance for an stm32wl/sx1262 combination pub fn new( - _irq: impl interrupt::Binding, + _irq: impl interrupt::typelevel::Binding, rf_switch_rx: Option, rf_switch_tx: Option, ) -> Result { - interrupt::SUBGHZ_RADIO::disable(); + interrupt::SUBGHZ_RADIO.disable(); Ok(Self { board_type: BoardType::Stm32wlSx1262, // updated when associated with a specific LoRa board rf_switch_rx, @@ -95,7 +95,7 @@ where } async fn await_irq(&mut self) -> Result<(), RadioError> { - unsafe { interrupt::SUBGHZ_RADIO::enable() }; + unsafe { interrupt::SUBGHZ_RADIO.enable() }; IRQ_SIGNAL.wait().await; Ok(()) } diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs index d7ca1f69..ba4f13b7 100644 --- a/embassy-macros/src/lib.rs +++ b/embassy-macros/src/lib.rs @@ -156,16 +156,3 @@ pub fn main_wasm(args: TokenStream, item: TokenStream) -> TokenStream { let f = syn::parse_macro_input!(item as syn::ItemFn); main::run(args, f, main::wasm()).unwrap_or_else(|x| x).into() } - -#[proc_macro_attribute] -pub fn cortex_m_interrupt(args: TokenStream, item: TokenStream) -> TokenStream { - let args = syn::parse_macro_input!(args as syn::AttributeArgs); - let f = syn::parse_macro_input!(item as syn::ItemFn); - cortex_m_interrupt::run(args, f).unwrap_or_else(|x| x).into() -} - -#[proc_macro] -pub fn cortex_m_interrupt_declare(item: TokenStream) -> TokenStream { - let name = syn::parse_macro_input!(item as syn::Ident); - cortex_m_interrupt_declare::run(name).unwrap_or_else(|x| x).into() -} diff --git a/embassy-macros/src/macros/cortex_m_interrupt.rs b/embassy-macros/src/macros/cortex_m_interrupt.rs deleted file mode 100644 index 13af8ca0..00000000 --- a/embassy-macros/src/macros/cortex_m_interrupt.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::iter; - -use darling::FromMeta; -use proc_macro2::TokenStream; -use quote::quote; -use syn::{ReturnType, Type, Visibility}; - -use crate::util::ctxt::Ctxt; - -#[derive(Debug, FromMeta)] -struct Args {} - -pub fn run(args: syn::AttributeArgs, mut f: syn::ItemFn) -> Result { - let _args = Args::from_list(&args).map_err(|e| e.write_errors())?; - - let ident = f.sig.ident.clone(); - let ident_s = ident.to_string(); - - // XXX should we blacklist other attributes? - - let valid_signature = f.sig.constness.is_none() - && f.vis == Visibility::Inherited - && f.sig.abi.is_none() - && f.sig.inputs.is_empty() - && f.sig.generics.params.is_empty() - && f.sig.generics.where_clause.is_none() - && f.sig.variadic.is_none() - && match f.sig.output { - ReturnType::Default => true, - ReturnType::Type(_, ref ty) => match **ty { - Type::Tuple(ref tuple) => tuple.elems.is_empty(), - Type::Never(..) => true, - _ => false, - }, - }; - - let ctxt = Ctxt::new(); - - if !valid_signature { - ctxt.error_spanned_by( - &f.sig, - "`#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`", - ); - } - - ctxt.check()?; - - f.block.stmts = iter::once( - syn::parse2(quote! {{ - // Check that this interrupt actually exists - let __irq_exists_check: interrupt::#ident; - }}) - .unwrap(), - ) - .chain(f.block.stmts) - .collect(); - - let result = quote!( - #[doc(hidden)] - #[export_name = #ident_s] - #[allow(non_snake_case)] - #f - ); - - Ok(result) -} diff --git a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs deleted file mode 100644 index b317482f..00000000 --- a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs +++ /dev/null @@ -1,21 +0,0 @@ -use proc_macro2::TokenStream; -use quote::{format_ident, quote}; - -pub fn run(name: syn::Ident) -> Result { - let name = format_ident!("{}", name); - let doc = format!("{} interrupt.", name); - - let result = quote! { - #[doc = #doc] - #[allow(non_camel_case_types)] - pub enum #name{} - unsafe impl ::embassy_cortex_m::interrupt::Interrupt for #name { - fn number() -> u16 { - use cortex_m::interrupt::InterruptNumber; - let irq = InterruptEnum::#name; - irq.number() as u16 - } - } - }; - Ok(result) -} diff --git a/embassy-macros/src/macros/mod.rs b/embassy-macros/src/macros/mod.rs index a5e7a50e..572094ca 100644 --- a/embassy-macros/src/macros/mod.rs +++ b/embassy-macros/src/macros/mod.rs @@ -1,4 +1,2 @@ -pub mod cortex_m_interrupt; -pub mod cortex_m_interrupt_declare; pub mod main; pub mod task; diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index b4fe2d87..9bc1c1e7 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -15,7 +15,6 @@ use core::slice; use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; @@ -24,13 +23,13 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari use crate::gpio::sealed::Pin; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; -use crate::interrupt::{self}; +use crate::interrupt::typelevel::Interrupt; use crate::ppi::{ self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, }; use crate::timer::{Instance as TimerInstance, Timer}; use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance}; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; mod sealed { use super::*; @@ -77,7 +76,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { //trace!("irq: start"); let r = U::regs(); @@ -202,7 +201,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { ppi_ch1: impl Peripheral

+ 'd, ppi_ch2: impl Peripheral

+ 'd, ppi_group: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, txd: impl Peripheral

+ 'd, config: Config, @@ -237,7 +236,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { ppi_ch1: impl Peripheral

+ 'd, ppi_ch2: impl Peripheral

+ 'd, ppi_group: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, txd: impl Peripheral

+ 'd, cts: impl Peripheral

+ 'd, diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index e406c081..8fbd760d 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs @@ -208,33 +208,29 @@ impl_ppi_channel!(PPI_CH31, 31 => static); impl_saadc_input!(P0_04, ANALOG_INPUT2); impl_saadc_input!(P0_05, ANALOG_INPUT3); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(TWIM0_TWIS0_TWI0); - declare!(SPIM0_SPIS0_SPI0); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2); - declare!(SWI3); - declare!(SWI4); - declare!(SWI5); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + TWIM0_TWIS0_TWI0, + SPIM0_SPIS0_SPI0, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + SWI0_EGU0, + SWI1_EGU1, + SWI2, + SWI3, + SWI4, + SWI5, +); diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 153795e5..bbf8f7cc 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs @@ -234,36 +234,32 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5); impl_saadc_input!(P0_30, ANALOG_INPUT6); impl_saadc_input!(P0_31, ANALOG_INPUT7); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(TWIM0_TWIS0_TWI0); - declare!(SPIM0_SPIS0_SPI0); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2); - declare!(SWI3); - declare!(SWI4); - declare!(SWI5); - declare!(PWM0); - declare!(PDM); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + TWIM0_TWIS0_TWI0, + SPIM0_SPIS0_SPI0, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2, + SWI3, + SWI4, + SWI5, + PWM0, + PDM, +); diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index a7a7cf58..31a8dd6a 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs @@ -236,36 +236,32 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5); impl_saadc_input!(P0_30, ANALOG_INPUT6); impl_saadc_input!(P0_31, ANALOG_INPUT7); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); - declare!(SPIM1_SPIS1_SPI1); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2); - declare!(SWI3); - declare!(SWI4); - declare!(SWI5); - declare!(PWM0); - declare!(PDM); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0, + SPIM1_SPIS1_SPI1, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2, + SWI3, + SWI4, + SWI5, + PWM0, + PDM, +); diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 14a1b8cc..6a6f4fcf 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -224,35 +224,31 @@ impl_ppi_channel!(PPI_CH29, 29 => static); impl_ppi_channel!(PPI_CH30, 30 => static); impl_ppi_channel!(PPI_CH31, 31 => static); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); - declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - declare!(GPIOTE); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2_EGU2); - declare!(SWI3_EGU3); - declare!(SWI4_EGU4); - declare!(SWI5_EGU5); - declare!(TIMER3); - declare!(USBD); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1, + GPIOTE, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2_EGU2, + SWI3_EGU3, + SWI4_EGU4, + SWI5_EGU5, + TIMER3, + USBD, +); diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 83ecd0de..e43b3d5b 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs @@ -263,46 +263,42 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7); impl_i2s!(I2S, I2S, I2S); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); - declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - declare!(NFCT); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP_LPCOMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2_EGU2); - declare!(SWI3_EGU3); - declare!(SWI4_EGU4); - declare!(SWI5_EGU5); - declare!(TIMER3); - declare!(TIMER4); - declare!(PWM0); - declare!(PDM); - declare!(MWU); - declare!(PWM1); - declare!(PWM2); - declare!(SPIM2_SPIS2_SPI2); - declare!(RTC2); - declare!(FPU); - declare!(I2S); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1, + NFCT, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP_LPCOMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2_EGU2, + SWI3_EGU3, + SWI4_EGU4, + SWI5_EGU5, + TIMER3, + TIMER4, + PWM0, + PDM, + MWU, + PWM1, + PWM2, + SPIM2_SPIS2_SPI2, + RTC2, + FPU, + I2S, +); diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 5e5db04d..d95e3497 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs @@ -306,50 +306,46 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7); impl_i2s!(I2S, I2S, I2S); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); - declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - declare!(NFCT); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP_LPCOMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2_EGU2); - declare!(SWI3_EGU3); - declare!(SWI4_EGU4); - declare!(SWI5_EGU5); - declare!(TIMER3); - declare!(TIMER4); - declare!(PWM0); - declare!(PDM); - declare!(MWU); - declare!(PWM1); - declare!(PWM2); - declare!(SPIM2_SPIS2_SPI2); - declare!(RTC2); - declare!(FPU); - declare!(USBD); - declare!(UARTE1); - declare!(PWM3); - declare!(SPIM3); - declare!(I2S); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1, + NFCT, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP_LPCOMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2_EGU2, + SWI3_EGU3, + SWI4_EGU4, + SWI5_EGU5, + TIMER3, + TIMER4, + PWM0, + PDM, + MWU, + PWM1, + PWM2, + SPIM2_SPIS2_SPI2, + RTC2, + FPU, + USBD, + UARTE1, + PWM3, + SPIM3, + I2S, +); diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index f6d33f85..0094b122 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -311,52 +311,48 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7); impl_i2s!(I2S, I2S, I2S); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(POWER_CLOCK); - declare!(RADIO); - declare!(UARTE0_UART0); - declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); - declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - declare!(NFCT); - declare!(GPIOTE); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(TEMP); - declare!(RNG); - declare!(ECB); - declare!(CCM_AAR); - declare!(WDT); - declare!(RTC1); - declare!(QDEC); - declare!(COMP_LPCOMP); - declare!(SWI0_EGU0); - declare!(SWI1_EGU1); - declare!(SWI2_EGU2); - declare!(SWI3_EGU3); - declare!(SWI4_EGU4); - declare!(SWI5_EGU5); - declare!(TIMER3); - declare!(TIMER4); - declare!(PWM0); - declare!(PDM); - declare!(MWU); - declare!(PWM1); - declare!(PWM2); - declare!(SPIM2_SPIS2_SPI2); - declare!(RTC2); - declare!(FPU); - declare!(USBD); - declare!(UARTE1); - declare!(QSPI); - declare!(CRYPTOCELL); - declare!(PWM3); - declare!(SPIM3); - declare!(I2S); -} +embassy_cortex_m::interrupt_mod!( + POWER_CLOCK, + RADIO, + UARTE0_UART0, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1, + NFCT, + GPIOTE, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + TEMP, + RNG, + ECB, + CCM_AAR, + WDT, + RTC1, + QDEC, + COMP_LPCOMP, + SWI0_EGU0, + SWI1_EGU1, + SWI2_EGU2, + SWI3_EGU3, + SWI4_EGU4, + SWI5_EGU5, + TIMER3, + TIMER4, + PWM0, + PDM, + MWU, + PWM1, + PWM2, + SPIM2_SPIS2_SPI2, + RTC2, + FPU, + USBD, + UARTE1, + QSPI, + CRYPTOCELL, + PWM3, + SPIM3, + I2S, +); diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 34f96800..c1052005 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -504,50 +504,46 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5); impl_saadc_input!(P0_19, ANALOG_INPUT6); impl_saadc_input!(P0_20, ANALOG_INPUT7); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(FPU); - declare!(CACHE); - declare!(SPU); - declare!(CLOCK_POWER); - declare!(SERIAL0); - declare!(SERIAL1); - declare!(SPIM4); - declare!(SERIAL2); - declare!(SERIAL3); - declare!(GPIOTE0); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(RTC1); - declare!(WDT0); - declare!(WDT1); - declare!(COMP_LPCOMP); - declare!(EGU0); - declare!(EGU1); - declare!(EGU2); - declare!(EGU3); - declare!(EGU4); - declare!(EGU5); - declare!(PWM0); - declare!(PWM1); - declare!(PWM2); - declare!(PWM3); - declare!(PDM0); - declare!(I2S0); - declare!(IPC); - declare!(QSPI); - declare!(NFCT); - declare!(GPIOTE1); - declare!(QDEC0); - declare!(QDEC1); - declare!(USBD); - declare!(USBREGULATOR); - declare!(KMU); - declare!(CRYPTOCELL); -} +embassy_cortex_m::interrupt_mod!( + FPU, + CACHE, + SPU, + CLOCK_POWER, + SERIAL0, + SERIAL1, + SPIM4, + SERIAL2, + SERIAL3, + GPIOTE0, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + RTC1, + WDT0, + WDT1, + COMP_LPCOMP, + EGU0, + EGU1, + EGU2, + EGU3, + EGU4, + EGU5, + PWM0, + PWM1, + PWM2, + PWM3, + PDM0, + I2S0, + IPC, + QSPI, + NFCT, + GPIOTE1, + QDEC0, + QDEC1, + USBD, + USBREGULATOR, + KMU, + CRYPTOCELL, +); diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index 1e59528c..a6fb1d4c 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -340,29 +340,25 @@ impl_ppi_channel!(PPI_CH29, 29 => configurable); impl_ppi_channel!(PPI_CH30, 30 => configurable); impl_ppi_channel!(PPI_CH31, 31 => configurable); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(CLOCK_POWER); - declare!(RADIO); - declare!(RNG); - declare!(GPIOTE); - declare!(WDT); - declare!(TIMER0); - declare!(ECB); - declare!(AAR_CCM); - declare!(TEMP); - declare!(RTC0); - declare!(IPC); - declare!(SERIAL0); - declare!(EGU0); - declare!(RTC1); - declare!(TIMER1); - declare!(TIMER2); - declare!(SWI0); - declare!(SWI1); - declare!(SWI2); - declare!(SWI3); -} +embassy_cortex_m::interrupt_mod!( + CLOCK_POWER, + RADIO, + RNG, + GPIOTE, + WDT, + TIMER0, + ECB, + AAR_CCM, + TEMP, + RTC0, + IPC, + SERIAL0, + EGU0, + RTC1, + TIMER1, + TIMER2, + SWI0, + SWI1, + SWI2, + SWI3, +); diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index d2b45114..b6ae78bb 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -366,40 +366,36 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5); impl_saadc_input!(P0_19, ANALOG_INPUT6); impl_saadc_input!(P0_20, ANALOG_INPUT7); -pub mod irqs { - use embassy_cortex_m::interrupt::_export::declare; - - use crate::pac::Interrupt as InterruptEnum; - - declare!(SPU); - declare!(CLOCK_POWER); - declare!(UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); - declare!(UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); - declare!(UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); - declare!(UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); - declare!(GPIOTE0); - declare!(SAADC); - declare!(TIMER0); - declare!(TIMER1); - declare!(TIMER2); - declare!(RTC0); - declare!(RTC1); - declare!(WDT); - declare!(EGU0); - declare!(EGU1); - declare!(EGU2); - declare!(EGU3); - declare!(EGU4); - declare!(EGU5); - declare!(PWM0); - declare!(PWM1); - declare!(PWM2); - declare!(PDM); - declare!(PWM3); - declare!(I2S); - declare!(IPC); - declare!(FPU); - declare!(GPIOTE1); - declare!(KMU); - declare!(CRYPTOCELL); -} +embassy_cortex_m::interrupt_mod!( + SPU, + CLOCK_POWER, + UARTE0_SPIM0_SPIS0_TWIM0_TWIS0, + UARTE1_SPIM1_SPIS1_TWIM1_TWIS1, + UARTE2_SPIM2_SPIS2_TWIM2_TWIS2, + UARTE3_SPIM3_SPIS3_TWIM3_TWIS3, + GPIOTE0, + SAADC, + TIMER0, + TIMER1, + TIMER2, + RTC0, + RTC1, + WDT, + EGU0, + EGU1, + EGU2, + EGU3, + EGU4, + EGU5, + PWM0, + PWM1, + PWM2, + PDM, + PWM3, + I2S, + IPC, + FPU, + GPIOTE1, + KMU, + CRYPTOCELL, +); diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 2ec5220a..1d7725bd 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin}; -use crate::interrupt::Interrupt; +use crate::interrupt::InterruptExt; use crate::ppi::{Event, Task}; use crate::{interrupt, pac, peripherals}; @@ -75,15 +75,15 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { // Enable interrupts #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))] - type Irq = interrupt::GPIOTE0; + let irq = interrupt::GPIOTE0; #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] - type Irq = interrupt::GPIOTE1; + let irq = interrupt::GPIOTE1; #[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))] - type Irq = interrupt::GPIOTE; + let irq = interrupt::GPIOTE; - Irq::unpend(); - Irq::set_priority(irq_prio); - unsafe { Irq::enable() }; + irq.unpend(); + irq.set_priority(irq_prio); + unsafe { irq.enable() }; let g = regs(); g.events_port.write(|w| w); diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index 13db77d3..fea38c4c 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs @@ -13,10 +13,10 @@ use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; use crate::gpio::{AnyPin, Pin as GpioPin}; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::pac::i2s::RegisterBlock; use crate::util::{slice_in_ram_or, slice_ptr_parts}; -use crate::{Peripheral, EASY_DMA_SIZE}; +use crate::{interrupt, Peripheral, EASY_DMA_SIZE}; /// Type alias for `MultiBuffering` with 2 buffers. pub type DoubleBuffering = MultiBuffering; @@ -367,7 +367,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let device = Device::::new(); let s = T::state(); @@ -408,7 +408,7 @@ impl<'d, T: Instance> I2S<'d, T> { /// Create a new I2S in master mode pub fn new_master( i2s: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, mck: impl Peripheral

+ 'd, sck: impl Peripheral

+ 'd, lrck: impl Peripheral

+ 'd, @@ -431,7 +431,7 @@ impl<'d, T: Instance> I2S<'d, T> { /// Create a new I2S in slave mode pub fn new_slave( i2s: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sck: impl Peripheral

+ 'd, lrck: impl Peripheral

+ 'd, config: Config, @@ -1173,7 +1173,7 @@ pub(crate) mod sealed { /// I2S peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_i2s { @@ -1188,7 +1188,7 @@ macro_rules! impl_i2s { } } impl crate::i2s::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 6b57c254..a73d22a6 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -93,21 +93,16 @@ pub mod wdt; #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] mod chip; -pub mod interrupt { - //! Interrupt definitions and macros to bind them. - pub use cortex_m::interrupt::{CriticalSection, Mutex}; - pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority}; +pub use crate::chip::interrupt; - pub use crate::chip::irqs::*; - - /// Macro to bind interrupts to handlers. - /// - /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) - /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to - /// prove at compile-time that the right interrupts have been bound. - // developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. - #[macro_export] - macro_rules! bind_interrupts { +/// Macro to bind interrupts to handlers. +/// +/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) +/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to +/// prove at compile-time that the right interrupts have been bound. +// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. +#[macro_export] +macro_rules! bind_interrupts { ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { $vis struct $name; @@ -116,17 +111,16 @@ pub mod interrupt { #[no_mangle] unsafe extern "C" fn $irq() { $( - <$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt(); + <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt(); )* } $( - unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {} + unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {} )* )* }; } -} // Reexports @@ -136,7 +130,6 @@ pub use chip::pac; pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; pub use embassy_cortex_m::executor; -pub use embassy_cortex_m::interrupt::_export::interrupt; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; pub mod config { diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index 9df685a2..0e30f700 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs @@ -6,7 +6,6 @@ use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; use futures::future::poll_fn; @@ -14,15 +13,15 @@ use futures::future::poll_fn; use crate::chip::EASY_DMA_SIZE; use crate::gpio::sealed::Pin; use crate::gpio::{AnyPin, Pin as GpioPin}; -use crate::interrupt::{self}; -use crate::Peripheral; +use crate::interrupt::typelevel::Interrupt; +use crate::{interrupt, Peripheral}; /// Interrupt handler. pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { T::regs().intenclr.write(|w| w.end().clear()); T::state().waker.wake(); @@ -53,7 +52,7 @@ impl<'d, T: Instance> Pdm<'d, T> { /// Create PDM driver pub fn new( pdm: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, clk: impl Peripheral

+ 'd, din: impl Peripheral

+ 'd, config: Config, @@ -274,7 +273,7 @@ pub(crate) mod sealed { /// PDM peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_pdm { @@ -289,7 +288,7 @@ macro_rules! impl_pdm { } } impl crate::pdm::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 708f2310..363a255d 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -8,10 +8,9 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; -use crate::interrupt::Interrupt; use crate::ppi::{Event, Task}; use crate::util::slice_in_ram_or; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; /// SimplePwm is the traditional pwm interface you're probably used to, allowing /// to simply set a duty cycle across up to four channels. @@ -843,7 +842,7 @@ pub(crate) mod sealed { /// PWM peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_pwm { @@ -854,7 +853,7 @@ macro_rules! impl_pwm { } } impl crate::pwm::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index 5761d04e..8bac87d3 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs @@ -10,7 +10,7 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin}; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, Peripheral}; /// Quadrature decoder driver. @@ -50,7 +50,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { T::regs().intenclr.write(|w| w.reportrdy().clear()); T::state().waker.wake(); @@ -61,7 +61,7 @@ impl<'d, T: Instance> Qdec<'d, T> { /// Create a new QDEC. pub fn new( qdec: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, a: impl Peripheral

+ 'd, b: impl Peripheral

+ 'd, config: Config, @@ -73,7 +73,7 @@ impl<'d, T: Instance> Qdec<'d, T> { /// Create a new QDEC, with a pin for LED output. pub fn new_with_led( qdec: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, a: impl Peripheral

+ 'd, b: impl Peripheral

+ 'd, led: impl Peripheral

+ 'd, @@ -271,7 +271,7 @@ pub(crate) mod sealed { /// qdec peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_qdec { @@ -286,7 +286,7 @@ macro_rules! impl_qdec { } } impl crate::qdec::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index 3f48568b..baefc796 100644 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs @@ -12,12 +12,12 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; use crate::gpio::{self, Pin as GpioPin}; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; pub use crate::pac::qspi::ifconfig0::{ ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode, }; pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode; -use crate::Peripheral; +use crate::{interrupt, Peripheral}; /// Deep power-down config. pub struct DeepPowerDownConfig { @@ -120,7 +120,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -143,7 +143,7 @@ impl<'d, T: Instance> Qspi<'d, T> { /// Create a new QSPI driver. pub fn new( qspi: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sck: impl Peripheral

+ 'd, csn: impl Peripheral

+ 'd, io0: impl Peripheral

+ 'd, @@ -644,7 +644,7 @@ pub(crate) mod sealed { /// QSPI peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_qspi { @@ -659,7 +659,7 @@ macro_rules! impl_qspi { } } impl crate::qspi::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index 7e9b3548..923b8b46 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs @@ -12,7 +12,7 @@ use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, Peripheral}; /// Interrupt handler. @@ -20,7 +20,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let s = T::state(); let r = T::regs(); @@ -89,7 +89,7 @@ impl<'d, T: Instance> Rng<'d, T> { /// The synchronous API is safe. pub fn new( rng: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { into_ref!(rng); @@ -255,7 +255,7 @@ pub(crate) mod sealed { /// RNG peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_rng { @@ -270,7 +270,7 @@ macro_rules! impl_rng { } } impl crate::rng::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 39764e38..cf3fb999 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -6,7 +6,6 @@ use core::future::poll_fn; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; @@ -18,6 +17,7 @@ use saadc::oversample::OVERSAMPLE_A; use saadc::resolution::VAL_A; use self::sealed::Input as _; +use crate::interrupt::InterruptExt; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::{interrupt, pac, peripherals, Peripheral}; @@ -33,7 +33,7 @@ pub struct InterruptHandler { _private: (), } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = unsafe { &*SAADC::ptr() }; @@ -144,7 +144,7 @@ impl<'d, const N: usize> Saadc<'d, N> { /// Create a new SAADC driver. pub fn new( saadc: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding + 'd, + _irq: impl interrupt::typelevel::Binding + 'd, config: Config, channel_configs: [ChannelConfig; N], ) -> Self { @@ -189,8 +189,8 @@ impl<'d, const N: usize> Saadc<'d, N> { // Disable all events interrupts r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); - interrupt::SAADC::unpend(); - unsafe { interrupt::SAADC::enable() }; + interrupt::SAADC.unpend(); + unsafe { interrupt::SAADC.enable() }; Self { _p: saadc } } diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index bb9cda32..66bbd1a8 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -15,9 +15,9 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency; use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; /// SPIM error #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -63,7 +63,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -84,7 +84,7 @@ impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver. pub fn new( spim: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, @@ -103,7 +103,7 @@ impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver, capable of TX only (MOSI only). pub fn new_txonly( spim: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sck: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, config: Config, @@ -115,7 +115,7 @@ impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver, capable of RX only (MISO only). pub fn new_rxonly( spim: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, config: Config, @@ -408,7 +408,7 @@ pub(crate) mod sealed { /// SPIM peripheral instance pub trait Instance: Peripheral

+ sealed::Instance + 'static { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_spim { @@ -423,7 +423,7 @@ macro_rules! impl_spim { } } impl crate::spim::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index a1d6803e..aa438415 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -13,9 +13,9 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, AnyPin, Pin as GpioPin}; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; /// SPIS error #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -68,7 +68,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -94,7 +94,7 @@ impl<'d, T: Instance> Spis<'d, T> { /// Create a new SPIS driver. pub fn new( spis: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, cs: impl Peripheral

+ 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, @@ -115,7 +115,7 @@ impl<'d, T: Instance> Spis<'d, T> { /// Create a new SPIS driver, capable of TX only (MISO only). pub fn new_txonly( spis: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, cs: impl Peripheral

+ 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, @@ -128,7 +128,7 @@ impl<'d, T: Instance> Spis<'d, T> { /// Create a new SPIS driver, capable of RX only (MOSI only). pub fn new_rxonly( spis: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, cs: impl Peripheral

+ 'd, sck: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, @@ -480,7 +480,7 @@ pub(crate) mod sealed { /// SPIS peripheral instance pub trait Instance: Peripheral

+ sealed::Instance + 'static { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_spis { @@ -495,7 +495,7 @@ macro_rules! impl_spis { } } impl crate::spis::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs index 8a127efc..491e92c0 100644 --- a/embassy-nrf/src/temp.rs +++ b/embassy-nrf/src/temp.rs @@ -8,7 +8,7 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use fixed::types::I30F2; -use crate::interrupt::Interrupt; +use crate::interrupt::InterruptExt; use crate::peripherals::TEMP; use crate::{interrupt, pac, Peripheral}; @@ -17,7 +17,7 @@ pub struct InterruptHandler { _private: (), } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = unsafe { &*pac::TEMP::PTR }; r.intenclr.write(|w| w.datardy().clear()); @@ -36,13 +36,13 @@ impl<'d> Temp<'d> { /// Create a new temperature sensor driver. pub fn new( _peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding + 'd, + _irq: impl interrupt::typelevel::Binding + 'd, ) -> Self { into_ref!(_peri); // Enable interrupt that signals temperature values - interrupt::TEMP::unpend(); - unsafe { interrupt::TEMP::enable() }; + interrupt::TEMP.unpend(); + unsafe { interrupt::TEMP.enable() }; Self { _peri } } diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 4feff8a7..f993d7b2 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs @@ -7,7 +7,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; use embassy_time::driver::{AlarmHandle, Driver}; -use crate::interrupt::Interrupt; +use crate::interrupt::InterruptExt; use crate::{interrupt, pac}; fn rtc() -> &'static pac::rtc0::RegisterBlock { @@ -142,8 +142,8 @@ impl RtcDriver { // Wait for clear while r.counter.read().bits() != 0 {} - interrupt::RTC1::set_priority(irq_prio); - unsafe { interrupt::RTC1::enable() }; + interrupt::RTC1.set_priority(irq_prio); + unsafe { interrupt::RTC1.enable() }; } fn on_interrupt(&self) { diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 2a0e16a5..dc375785 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -8,7 +8,6 @@ use embassy_hal_common::{into_ref, PeripheralRef}; -use crate::interrupt::Interrupt; use crate::ppi::{Event, Task}; use crate::{pac, Peripheral}; @@ -29,7 +28,7 @@ pub(crate) mod sealed { /// Basic Timer instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: crate::interrupt::typelevel::Interrupt; } /// Extended timer instance. @@ -44,7 +43,7 @@ macro_rules! impl_timer { } } impl crate::timer::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; ($type:ident, $pac_type:ident, $irq:ident) => { diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index dea398a6..2ad0d19b 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -16,9 +16,9 @@ use embassy_time::{Duration, Instant}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::gpio::Pin as GpioPin; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::util::{slice_in_ram, slice_in_ram_or}; -use crate::{gpio, pac, Peripheral}; +use crate::{gpio, interrupt, pac, Peripheral}; /// TWI frequency #[derive(Clone, Copy)] @@ -98,7 +98,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -123,7 +123,7 @@ impl<'d, T: Instance> Twim<'d, T> { /// Create a new TWI driver. pub fn new( twim: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, config: Config, @@ -750,7 +750,7 @@ pub(crate) mod sealed { /// TWIM peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_twim { @@ -765,7 +765,7 @@ macro_rules! impl_twim { } } impl crate::twim::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index 752a8c04..a115d561 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs @@ -15,9 +15,9 @@ use embassy_time::{Duration, Instant}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::gpio::Pin as GpioPin; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::util::slice_in_ram_or; -use crate::{gpio, pac, Peripheral}; +use crate::{gpio, interrupt, pac, Peripheral}; /// TWIS config. #[non_exhaustive] @@ -114,7 +114,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -143,7 +143,7 @@ impl<'d, T: Instance> Twis<'d, T> { /// Create a new TWIS driver. pub fn new( twis: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, config: Config, @@ -778,7 +778,7 @@ pub(crate) mod sealed { /// TWIS peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_twis { @@ -793,7 +793,7 @@ macro_rules! impl_twis { } } impl crate::twis::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 6c6941ee..85a951ae 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -27,11 +27,11 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::util::slice_in_ram_or; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; /// UARTE config. #[derive(Clone)] @@ -68,7 +68,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -108,7 +108,7 @@ impl<'d, T: Instance> Uarte<'d, T> { /// Create a new UARTE without hardware flow control pub fn new( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, txd: impl Peripheral

+ 'd, config: Config, @@ -120,7 +120,7 @@ impl<'d, T: Instance> Uarte<'d, T> { /// Create a new UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, txd: impl Peripheral

+ 'd, cts: impl Peripheral

+ 'd, @@ -313,7 +313,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { /// Create a new tx-only UARTE without hardware flow control pub fn new( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, txd: impl Peripheral

+ 'd, config: Config, ) -> Self { @@ -324,7 +324,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, txd: impl Peripheral

+ 'd, cts: impl Peripheral

+ 'd, config: Config, @@ -509,7 +509,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { /// Create a new rx-only UARTE without hardware flow control pub fn new( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, config: Config, ) -> Self { @@ -520,7 +520,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( uarte: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rxd: impl Peripheral

+ 'd, rts: impl Peripheral

+ 'd, config: Config, @@ -889,7 +889,7 @@ pub(crate) mod sealed { /// UARTE peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_uarte { @@ -908,7 +908,7 @@ macro_rules! impl_uarte { } } impl crate::uarte::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index 3c62b445..76cf40ac 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs @@ -18,9 +18,9 @@ use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo use pac::usbd::RegisterBlock; use self::vbus_detect::VbusDetect; -use crate::interrupt::{self, Interrupt}; +use crate::interrupt::typelevel::Interrupt; use crate::util::slice_in_ram; -use crate::{pac, Peripheral}; +use crate::{interrupt, pac, Peripheral}; const NEW_AW: AtomicWaker = AtomicWaker::new(); static BUS_WAKER: AtomicWaker = NEW_AW; @@ -34,7 +34,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let regs = T::regs(); @@ -98,7 +98,7 @@ impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { /// Create a new USB driver. pub fn new( usb: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, vbus_detect: V, ) -> Self { into_ref!(usb); @@ -804,7 +804,7 @@ pub(crate) mod sealed { /// USB peripheral instance. pub trait Instance: Peripheral

+ sealed::Instance + 'static + Send { /// Interrupt for this peripheral. - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } macro_rules! impl_usb { @@ -815,7 +815,7 @@ macro_rules! impl_usb { } } impl crate::usb::Instance for peripherals::$type { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-nrf/src/usb/vbus_detect.rs b/embassy-nrf/src/usb/vbus_detect.rs index a6a95990..a05e5aa5 100644 --- a/embassy-nrf/src/usb/vbus_detect.rs +++ b/embassy-nrf/src/usb/vbus_detect.rs @@ -7,8 +7,8 @@ use core::task::Poll; use embassy_sync::waitqueue::AtomicWaker; use super::BUS_WAKER; -use crate::interrupt::{self, Interrupt}; -use crate::pac; +use crate::interrupt::typelevel::Interrupt; +use crate::{interrupt, pac}; /// Trait for detecting USB VBUS power. /// @@ -29,9 +29,9 @@ pub trait VbusDetect { } #[cfg(not(feature = "_nrf5340"))] -type UsbRegIrq = interrupt::POWER_CLOCK; +type UsbRegIrq = interrupt::typelevel::POWER_CLOCK; #[cfg(feature = "_nrf5340")] -type UsbRegIrq = interrupt::USBREGULATOR; +type UsbRegIrq = interrupt::typelevel::USBREGULATOR; #[cfg(not(feature = "_nrf5340"))] type UsbRegPeri = pac::POWER; @@ -43,7 +43,7 @@ pub struct InterruptHandler { _private: (), } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let regs = unsafe { &*UsbRegPeri::ptr() }; @@ -77,7 +77,7 @@ static POWER_WAKER: AtomicWaker = AtomicWaker::new(); impl HardwareVbusDetect { /// Create a new `VbusDetectNative`. - pub fn new(_irq: impl interrupt::Binding + 'static) -> Self { + pub fn new(_irq: impl interrupt::typelevel::Binding + 'static) -> Self { let regs = unsafe { &*UsbRegPeri::ptr() }; UsbRegIrq::unpend(); diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index 86a35367..f29c4dfe 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -3,14 +3,14 @@ use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::{Binding, Interrupt}; use embassy_sync::waitqueue::AtomicWaker; use embedded_hal_02::adc::{Channel, OneShot}; use crate::gpio::Pin; -use crate::interrupt::{self, ADC_IRQ_FIFO}; +use crate::interrupt::typelevel::Binding; +use crate::interrupt::InterruptExt; use crate::peripherals::ADC; -use crate::{pac, peripherals, Peripheral}; +use crate::{interrupt, pac, peripherals, Peripheral}; static WAKER: AtomicWaker = AtomicWaker::new(); #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -47,7 +47,7 @@ impl<'d> Adc<'d> { pub fn new( _inner: impl Peripheral

+ 'd, - _irq: impl Binding, + _irq: impl Binding, _config: Config, ) -> Self { unsafe { @@ -62,10 +62,8 @@ impl<'d> Adc<'d> { } // Setup IRQ - unsafe { - ADC_IRQ_FIFO::unpend(); - ADC_IRQ_FIFO::enable(); - }; + interrupt::ADC_IRQ_FIFO.unpend(); + unsafe { interrupt::ADC_IRQ_FIFO.enable() }; Self { phantom: PhantomData } } @@ -164,7 +162,7 @@ pub struct InterruptHandler { _empty: (), } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = Adc::regs(); r.inte().write(|w| w.set_fifo(false)); diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 1cbb4651..042ca99a 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -4,11 +4,11 @@ use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::{Context, Poll}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use pac::dma::vals::DataSize; +use crate::interrupt::InterruptExt; use crate::pac::dma::vals; use crate::{interrupt, pac, peripherals}; @@ -29,12 +29,12 @@ unsafe fn DMA_IRQ_0() { } pub(crate) unsafe fn init() { - interrupt::DMA_IRQ_0::disable(); - interrupt::DMA_IRQ_0::set_priority(interrupt::Priority::P3); + interrupt::DMA_IRQ_0.disable(); + interrupt::DMA_IRQ_0.set_priority(interrupt::Priority::P3); pac::DMA.inte0().write(|w| w.set_inte0(0xFFFF)); - interrupt::DMA_IRQ_0::enable(); + interrupt::DMA_IRQ_0.enable(); } pub unsafe fn read<'a, C: Channel, W: Word>( diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 91cef860..ebd932f5 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -3,10 +3,10 @@ use core::future::Future; use core::pin::Pin as FuturePin; use core::task::{Context, Poll}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; +use crate::interrupt::InterruptExt; use crate::pac::common::{Reg, RW}; use crate::pac::SIO; use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; @@ -137,9 +137,9 @@ pub enum InterruptTrigger { } pub(crate) unsafe fn init() { - interrupt::IO_IRQ_BANK0::disable(); - interrupt::IO_IRQ_BANK0::set_priority(interrupt::Priority::P3); - interrupt::IO_IRQ_BANK0::enable(); + interrupt::IO_IRQ_BANK0.disable(); + interrupt::IO_IRQ_BANK0.set_priority(interrupt::Priority::P3); + interrupt::IO_IRQ_BANK0.enable(); } #[interrupt] diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 124f1c00..ce9a082a 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -2,14 +2,14 @@ use core::future; use core::marker::PhantomData; use core::task::Poll; -use embassy_cortex_m::interrupt::{self, Binding, Interrupt}; use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use pac::i2c; use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; -use crate::{pac, peripherals, Peripheral}; +use crate::interrupt::typelevel::{Binding, Interrupt}; +use crate::{interrupt, pac, peripherals, Peripheral}; /// I2C error abort reason #[derive(Debug)] @@ -312,7 +312,7 @@ pub struct InterruptHandler { _uart: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { // Mask interrupts and wake any task waiting for this interrupt unsafe fn on_interrupt() { let i2c = T::regs(); @@ -760,14 +760,15 @@ fn i2c_reserved_addr(addr: u16) -> bool { } mod sealed { - use embassy_cortex_m::interrupt::Interrupt; use embassy_sync::waitqueue::AtomicWaker; + use crate::interrupt; + pub trait Instance { const TX_DREQ: u8; const RX_DREQ: u8; - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; fn regs() -> crate::pac::i2c::I2c; fn reset() -> crate::pac::resets::regs::Peripherals; @@ -803,7 +804,7 @@ macro_rules! impl_instance { const TX_DREQ: u8 = $tx_dreq; const RX_DREQ: u8 = $rx_dreq; - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; #[inline] fn regs() -> pac::i2c::I2c { diff --git a/embassy-rp/src/interrupt.rs b/embassy-rp/src/interrupt.rs deleted file mode 100644 index c9298644..00000000 --- a/embassy-rp/src/interrupt.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Interrupt definitions and macros to bind them. -pub use cortex_m::interrupt::{CriticalSection, Mutex}; -use embassy_cortex_m::interrupt::_export::declare; -pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority}; - -use crate::pac::Interrupt as InterruptEnum; -declare!(TIMER_IRQ_0); -declare!(TIMER_IRQ_1); -declare!(TIMER_IRQ_2); -declare!(TIMER_IRQ_3); -declare!(PWM_IRQ_WRAP); -declare!(USBCTRL_IRQ); -declare!(XIP_IRQ); -declare!(PIO0_IRQ_0); -declare!(PIO0_IRQ_1); -declare!(PIO1_IRQ_0); -declare!(PIO1_IRQ_1); -declare!(DMA_IRQ_0); -declare!(DMA_IRQ_1); -declare!(IO_IRQ_BANK0); -declare!(IO_IRQ_QSPI); -declare!(SIO_IRQ_PROC0); -declare!(SIO_IRQ_PROC1); -declare!(CLOCKS_IRQ); -declare!(SPI0_IRQ); -declare!(SPI1_IRQ); -declare!(UART0_IRQ); -declare!(UART1_IRQ); -declare!(ADC_IRQ_FIFO); -declare!(I2C0_IRQ); -declare!(I2C1_IRQ); -declare!(RTC_IRQ); -declare!(SWI_IRQ_0); -declare!(SWI_IRQ_1); -declare!(SWI_IRQ_2); -declare!(SWI_IRQ_3); -declare!(SWI_IRQ_4); -declare!(SWI_IRQ_5); - -/// Macro to bind interrupts to handlers. -/// -/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) -/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to -/// prove at compile-time that the right interrupts have been bound. -// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. -#[macro_export] -macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { - $vis struct $name; - - $( - #[allow(non_snake_case)] - #[no_mangle] - unsafe extern "C" fn $irq() { - $( - <$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt(); - )* - } - - $( - unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {} - )* - )* - }; -} diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 4e4542d7..70a410ef 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -16,7 +16,6 @@ pub mod flash; mod float; pub mod gpio; pub mod i2c; -pub mod interrupt; pub mod multicore; pub mod pwm; mod reset; @@ -38,13 +37,74 @@ pub mod relocate; // Reexports pub use embassy_cortex_m::executor; -pub use embassy_cortex_m::interrupt::_export::interrupt; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; #[cfg(feature = "unstable-pac")] pub use rp_pac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use rp_pac as pac; +embassy_cortex_m::interrupt_mod!( + TIMER_IRQ_0, + TIMER_IRQ_1, + TIMER_IRQ_2, + TIMER_IRQ_3, + PWM_IRQ_WRAP, + USBCTRL_IRQ, + XIP_IRQ, + PIO0_IRQ_0, + PIO0_IRQ_1, + PIO1_IRQ_0, + PIO1_IRQ_1, + DMA_IRQ_0, + DMA_IRQ_1, + IO_IRQ_BANK0, + IO_IRQ_QSPI, + SIO_IRQ_PROC0, + SIO_IRQ_PROC1, + CLOCKS_IRQ, + SPI0_IRQ, + SPI1_IRQ, + UART0_IRQ, + UART1_IRQ, + ADC_IRQ_FIFO, + I2C0_IRQ, + I2C1_IRQ, + RTC_IRQ, + SWI_IRQ_0, + SWI_IRQ_1, + SWI_IRQ_2, + SWI_IRQ_3, + SWI_IRQ_4, + SWI_IRQ_5, +); + +/// Macro to bind interrupts to handlers. +/// +/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) +/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to +/// prove at compile-time that the right interrupts have been bound. +// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. +#[macro_export] +macro_rules! bind_interrupts { + ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { + $vis struct $name; + + $( + #[allow(non_snake_case)] + #[no_mangle] + unsafe extern "C" fn $irq() { + $( + <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt(); + )* + } + + $( + unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {} + )* + )* + }; +} + embassy_hal_common::peripherals! { PIN_0, PIN_1, diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs index 807fda57..e1246ce8 100644 --- a/embassy-rp/src/multicore.rs +++ b/embassy-rp/src/multicore.rs @@ -50,7 +50,7 @@ use core::mem::ManuallyDrop; use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; -use crate::interrupt::Interrupt; +use crate::interrupt::InterruptExt; use crate::peripherals::CORE1; use crate::{gpio, interrupt, pac}; @@ -156,7 +156,7 @@ where IS_CORE1_INIT.store(true, Ordering::Release); // Enable fifo interrupt on CORE1 for `pause` functionality. - unsafe { interrupt::SIO_IRQ_PROC1::enable() }; + unsafe { interrupt::SIO_IRQ_PROC1.enable() }; entry() } diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index 93e5bd34..f0a5c17a 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs @@ -5,7 +5,6 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::{Context, Poll}; use atomic_polyfill::{AtomicU32, AtomicU8}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use fixed::types::extra::U8; @@ -17,6 +16,7 @@ use pio::{SideSet, Wrap}; use crate::dma::{Channel, Transfer, Word}; use crate::gpio::sealed::Pin as SealedPin; use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate}; +use crate::interrupt::InterruptExt; use crate::pac::dma::vals::TreqSel; use crate::relocate::RelocatedProgram; use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; @@ -110,15 +110,15 @@ unsafe fn PIO1_IRQ_0() { } pub(crate) unsafe fn init() { - interrupt::PIO0_IRQ_0::disable(); - interrupt::PIO0_IRQ_0::set_priority(interrupt::Priority::P3); + interrupt::PIO0_IRQ_0.disable(); + interrupt::PIO0_IRQ_0.set_priority(interrupt::Priority::P3); pac::PIO0.irqs(0).inte().write(|m| m.0 = 0); - interrupt::PIO0_IRQ_0::enable(); + interrupt::PIO0_IRQ_0.enable(); - interrupt::PIO1_IRQ_0::disable(); - interrupt::PIO1_IRQ_0::set_priority(interrupt::Priority::P3); + interrupt::PIO1_IRQ_0.disable(); + interrupt::PIO1_IRQ_0.set_priority(interrupt::Priority::P3); pac::PIO1.irqs(0).inte().write(|m| m.0 = 0); - interrupt::PIO1_IRQ_0::enable(); + interrupt::PIO1_IRQ_0.enable(); } /// Future that waits for TX-FIFO to become writable diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/timer.rs index 68793950..37f86c93 100644 --- a/embassy-rp/src/timer.rs +++ b/embassy-rp/src/timer.rs @@ -6,7 +6,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::Mutex; use embassy_time::driver::{AlarmHandle, Driver}; -use crate::interrupt::Interrupt; +use crate::interrupt::InterruptExt; use crate::{interrupt, pac}; struct AlarmState { @@ -145,10 +145,10 @@ pub unsafe fn init() { w.set_alarm(2, true); w.set_alarm(3, true); }); - interrupt::TIMER_IRQ_0::enable(); - interrupt::TIMER_IRQ_1::enable(); - interrupt::TIMER_IRQ_2::enable(); - interrupt::TIMER_IRQ_3::enable(); + interrupt::TIMER_IRQ_0.enable(); + interrupt::TIMER_IRQ_1.enable(); + interrupt::TIMER_IRQ_2.enable(); + interrupt::TIMER_IRQ_3.enable(); } #[interrupt] diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index bb808c46..6660d5dc 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -3,14 +3,14 @@ use core::slice; use core::task::Poll; use atomic_polyfill::{AtomicU8, Ordering}; -use embassy_cortex_m::interrupt::{self, Binding, Interrupt}; use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_sync::waitqueue::AtomicWaker; use embassy_time::{Duration, Timer}; use super::*; use crate::clocks::clk_peri_freq; -use crate::RegExt; +use crate::interrupt::typelevel::{Binding, Interrupt}; +use crate::{interrupt, RegExt}; pub struct State { tx_waker: AtomicWaker, @@ -485,7 +485,7 @@ pub struct BufferedInterruptHandler { _uart: PhantomData, } -impl interrupt::Handler for BufferedInterruptHandler { +impl interrupt::typelevel::Handler for BufferedInterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); if r.uartdmacr().read().rxdmae() { diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index a83d94e4..5e3ae8a2 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -3,7 +3,6 @@ use core::marker::PhantomData; use core::task::Poll; use atomic_polyfill::{AtomicU16, Ordering}; -use embassy_cortex_m::interrupt::{self, Binding, Interrupt}; use embassy_futures::select::{select, Either}; use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; @@ -14,8 +13,9 @@ use crate::clocks::clk_peri_freq; use crate::dma::{AnyChannel, Channel}; use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; +use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::pac::io::vals::{Inover, Outover}; -use crate::{pac, peripherals, Peripheral, RegExt}; +use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; #[cfg(feature = "nightly")] mod buffered; @@ -332,7 +332,7 @@ pub struct InterruptHandler { _uart: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let uart = T::regs(); if !uart.uartdmacr().read().rxdmae() { @@ -930,7 +930,7 @@ mod sealed { const TX_DREQ: u8; const RX_DREQ: u8; - type Interrupt: crate::interrupt::Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; fn regs() -> pac::uart::Uart; @@ -968,7 +968,7 @@ macro_rules! impl_instance { const TX_DREQ: u8 = $tx_dreq; const RX_DREQ: u8 = $rx_dreq; - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; fn regs() -> pac::uart::Uart { pac::$inst diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index cc88226d..9fb0dfb7 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs @@ -4,15 +4,14 @@ use core::slice; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::{self, Binding}; use embassy_sync::waitqueue::AtomicWaker; use embassy_usb_driver as driver; use embassy_usb_driver::{ Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, }; -use crate::interrupt::Interrupt; -use crate::{pac, peripherals, Peripheral, RegExt}; +use crate::interrupt::typelevel::{Binding, Interrupt}; +use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; pub(crate) mod sealed { pub trait Instance { @@ -22,7 +21,7 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + 'static { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } impl crate::usb::sealed::Instance for peripherals::USB { @@ -35,7 +34,7 @@ impl crate::usb::sealed::Instance for peripherals::USB { } impl crate::usb::Instance for peripherals::USB { - type Interrupt = crate::interrupt::USBCTRL_IRQ; + type Interrupt = crate::interrupt::typelevel::USBCTRL_IRQ; } const EP_COUNT: usize = 16; @@ -249,7 +248,7 @@ pub struct InterruptHandler { _uart: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let regs = T::regs(); //let x = regs.istr().read().0; diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 730c78f5..267fec38 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -160,13 +160,11 @@ fn main() { } g.extend(quote! { - pub mod interrupt { - use crate::pac::Interrupt as InterruptEnum; - use embassy_cortex_m::interrupt::_export::declare; + embassy_cortex_m::interrupt_mod!( #( - declare!(#irqs); + #irqs, )* - } + ); }); // ======== diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index c13915a1..41305d27 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -8,7 +8,7 @@ use embassy_sync::waitqueue::AtomicWaker; use crate::dma::Transfer; use crate::gpio::sealed::AFType; use crate::gpio::Speed; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, Peripheral}; /// Interrupt handler. @@ -16,7 +16,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let ris = crate::pac::DCMI.ris().read(); if ris.err_ris() { @@ -119,7 +119,7 @@ where pub fn new_8bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -143,7 +143,7 @@ where pub fn new_10bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -169,7 +169,7 @@ where pub fn new_12bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -197,7 +197,7 @@ where pub fn new_14bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -227,7 +227,7 @@ where pub fn new_es_8bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -249,7 +249,7 @@ where pub fn new_es_10bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -273,7 +273,7 @@ where pub fn new_es_12bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -299,7 +299,7 @@ where pub fn new_es_14bit( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, d0: impl Peripheral

> + 'd, d1: impl Peripheral

> + 'd, d2: impl Peripheral

> + 'd, @@ -570,7 +570,7 @@ mod sealed { } pub trait Instance: sealed::Instance + 'static { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } pin_trait!(D0Pin, Instance); @@ -602,7 +602,7 @@ macro_rules! impl_peripheral { } impl Instance for crate::peripherals::$inst { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; } diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 7a1ecda3..83ab4b18 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -14,7 +14,7 @@ use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; use super::word::{Word, WordSize}; use super::Dir; use crate::_generated::BDMA_CHANNEL_COUNT; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac; use crate::pac::bdma::{regs, vals}; @@ -70,8 +70,8 @@ static STATE: State = State::new(); pub(crate) unsafe fn init(irq_priority: Priority) { foreach_interrupt! { ($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => { - crate::interrupt::$irq::set_priority(irq_priority); - crate::interrupt::$irq::enable(); + crate::interrupt::typelevel::$irq::set_priority(irq_priority); + crate::interrupt::typelevel::$irq::enable(); }; } crate::_generated::init_bdma(); diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 3b602b99..17313b31 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -13,7 +13,7 @@ use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; use super::word::{Word, WordSize}; use super::Dir; use crate::_generated::DMA_CHANNEL_COUNT; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac::dma::{regs, vals}; use crate::{interrupt, pac}; @@ -149,8 +149,8 @@ static STATE: State = State::new(); pub(crate) unsafe fn init(irq_priority: Priority) { foreach_interrupt! { ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => { - interrupt::$irq::set_priority(irq_priority); - interrupt::$irq::enable(); + interrupt::typelevel::$irq::set_priority(irq_priority); + interrupt::typelevel::$irq::enable(); }; } crate::_generated::init_dma(); diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 7f8b82b4..07fef360 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -56,8 +56,8 @@ static STATE: State = State::new(); pub(crate) unsafe fn init(irq_priority: Priority) { foreach_interrupt! { ($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => { - crate::interrupt::$irq::set_priority(irq_priority); - crate::interrupt::$irq::enable(); + crate::interrupt::typelevel::$irq::set_priority(irq_priority); + crate::interrupt::typelevel::$irq::enable(); }; } crate::_generated::init_gpdma(); diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index a5f1a268..540cdd02 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -5,7 +5,6 @@ mod tx_desc; use core::sync::atomic::{fence, Ordering}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{into_ref, PeripheralRef}; use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; @@ -14,6 +13,7 @@ pub(crate) use self::tx_desc::{TDes, TDesRing}; use super::*; use crate::gpio::sealed::{AFType, Pin as __GpioPin}; use crate::gpio::AnyPin; +use crate::interrupt::InterruptExt; #[cfg(eth_v1a)] use crate::pac::AFIO; #[cfg(any(eth_v1b, eth_v1c))] @@ -24,7 +24,7 @@ use crate::{interrupt, Peripheral}; /// Interrupt handler. pub struct InterruptHandler {} -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { WAKER.wake(); @@ -100,7 +100,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { pub fn new( queue: &'d mut PacketQueue, peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding + 'd, + _irq: impl interrupt::typelevel::Binding + 'd, ref_clk: impl Peripheral

> + 'd, mdio: impl Peripheral

> + 'd, mdc: impl Peripheral

> + 'd, @@ -267,8 +267,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { P::phy_reset(&mut this); P::phy_init(&mut this); - interrupt::ETH::unpend(); - interrupt::ETH::enable(); + interrupt::ETH.unpend(); + interrupt::ETH.enable(); this } diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 9efa436a..3e45eafd 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -2,20 +2,20 @@ mod descriptors; use core::sync::atomic::{fence, Ordering}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{into_ref, PeripheralRef}; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; use super::*; use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::{AnyPin, Speed}; +use crate::interrupt::InterruptExt; use crate::pac::ETH; use crate::{interrupt, Peripheral}; /// Interrupt handler. pub struct InterruptHandler {} -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { WAKER.wake(); @@ -64,7 +64,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { pub fn new( queue: &'d mut PacketQueue, peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding + 'd, + _irq: impl interrupt::typelevel::Binding + 'd, ref_clk: impl Peripheral

> + 'd, mdio: impl Peripheral

> + 'd, mdc: impl Peripheral

> + 'd, @@ -238,8 +238,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { P::phy_reset(&mut this); P::phy_init(&mut this); - interrupt::ETH::unpend(); - interrupt::ETH::enable(); + interrupt::ETH.unpend(); + interrupt::ETH.enable(); this } diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index c2fa31b2..a2ed0709 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -354,13 +354,13 @@ impl_exti!(EXTI15, 15); macro_rules! enable_irq { ($e:ident) => { - crate::interrupt::$e::enable(); + crate::interrupt::typelevel::$e::enable(); }; } /// safety: must be called only once pub(crate) unsafe fn init() { - use crate::interrupt::Interrupt; + use crate::interrupt::typelevel::Interrupt; foreach_exti_irq!(enable_irq); diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs index 872614d4..70a5ded6 100644 --- a/embassy-stm32/src/flash/asynch.rs +++ b/embassy-stm32/src/flash/asynch.rs @@ -1,7 +1,6 @@ use core::marker::PhantomData; use atomic_polyfill::{fence, Ordering}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::into_ref; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; @@ -11,6 +10,7 @@ use super::{ blocking_read, ensure_sector_aligned, family, get_sector, Async, Error, Flash, FlashLayout, FLASH_BASE, FLASH_SIZE, WRITE_SIZE, }; +use crate::interrupt::InterruptExt; use crate::peripherals::FLASH; use crate::{interrupt, Peripheral}; @@ -19,12 +19,12 @@ pub(super) static REGION_ACCESS: Mutex = Mutex::new impl<'d> Flash<'d, Async> { pub fn new( p: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding + 'd, + _irq: impl interrupt::typelevel::Binding + 'd, ) -> Self { into_ref!(p); - crate::interrupt::FLASH::unpend(); - unsafe { crate::interrupt::FLASH::enable() }; + crate::interrupt::FLASH.unpend(); + unsafe { crate::interrupt::FLASH.enable() }; Self { inner: p, @@ -49,7 +49,7 @@ impl<'d> Flash<'d, Async> { /// Interrupt handler pub struct InterruptHandler; -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { family::on_interrupt(); } diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index f898fcc8..b35678ed 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -1,6 +1,6 @@ #![macro_use] -use crate::interrupt::Interrupt; +use crate::interrupt; #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(i2c_v2, path = "v2.rs")] @@ -35,7 +35,7 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + 'static { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } pin_trait!(SclPin, Instance); @@ -57,7 +57,7 @@ foreach_interrupt!( } impl Instance for peripherals::$inst { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; ); diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index b9be2e58..e0403888 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -16,7 +16,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() {} } @@ -57,7 +57,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _peri: impl Peripheral

+ 'd, scl: impl Peripheral

> + 'd, sda: impl Peripheral

> + 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, freq: Hertz, diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 10f57f70..1aaf2b46 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -3,7 +3,6 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_embedded_hal::SetConfig; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; @@ -13,6 +12,7 @@ use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; use crate::gpio::Pull; use crate::i2c::{Error, Instance, SclPin, SdaPin}; +use crate::interrupt::typelevel::Interrupt; use crate::pac::i2c; use crate::time::Hertz; use crate::{interrupt, Peripheral}; @@ -22,7 +22,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let regs = T::regs(); let isr = regs.isr().read(); @@ -78,7 +78,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { peri: impl Peripheral

+ 'd, scl: impl Peripheral

> + 'd, sda: impl Peripheral

> + 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, freq: Hertz, diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 75d8af3d..b4286456 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -72,46 +72,39 @@ pub(crate) mod _generated { include!(concat!(env!("OUT_DIR"), "/_generated.rs")); } -pub mod interrupt { - //! Interrupt definitions and macros to bind them. - pub use cortex_m::interrupt::{CriticalSection, Mutex}; - pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority}; +pub use crate::_generated::interrupt; - pub use crate::_generated::interrupt::*; +/// Macro to bind interrupts to handlers. +/// +/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) +/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to +/// prove at compile-time that the right interrupts have been bound. +// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. +#[macro_export] +macro_rules! bind_interrupts { + ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { + $vis struct $name; - /// Macro to bind interrupts to handlers. - /// - /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) - /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to - /// prove at compile-time that the right interrupts have been bound. - // developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. - #[macro_export] - macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { - $vis struct $name; + $( + #[allow(non_snake_case)] + #[no_mangle] + unsafe extern "C" fn $irq() { + $( + <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt(); + )* + } $( - #[allow(non_snake_case)] - #[no_mangle] - unsafe extern "C" fn $irq() { - $( - <$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt(); - )* - } - - $( - unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {} - )* + unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {} )* - }; - } + )* + }; } // Reexports pub use _generated::{peripherals, Peripherals}; pub use embassy_cortex_m::executor; use embassy_cortex_m::interrupt::Priority; -pub use embassy_cortex_m::interrupt::_export::interrupt; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; #[cfg(feature = "unstable-pac")] pub use stm32_metapac as pac; diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 3cc17aa6..28eb49ab 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -14,7 +14,7 @@ use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, use crate::dma::NoDma; use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::{AnyPin, Pull, Speed}; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::rcc::RccPeripheral; use crate::time::Hertz; @@ -42,7 +42,7 @@ impl InterruptHandler { } } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { Self::data_interrupts(false); T::state().wake(); @@ -276,7 +276,7 @@ pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma = NoDma> { impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { pub fn new_1bit( sdmmc: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, dma: impl Peripheral

+ 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, @@ -310,7 +310,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { pub fn new_4bit( sdmmc: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, dma: impl Peripheral

+ 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, @@ -356,7 +356,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { pub fn new_1bit( sdmmc: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, d0: impl Peripheral

> + 'd, @@ -389,7 +389,7 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { pub fn new_4bit( sdmmc: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, d0: impl Peripheral

> + 'd, @@ -1401,7 +1401,7 @@ pub(crate) mod sealed { use super::*; pub trait Instance { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; fn regs() -> RegBlock; fn state() -> &'static AtomicWaker; @@ -1490,7 +1490,7 @@ cfg_if::cfg_if! { foreach_peripheral!( (sdmmc, $inst:ident) => { impl sealed::Instance for peripherals::$inst { - type Interrupt = crate::interrupt::$inst; + type Interrupt = crate::interrupt::typelevel::$inst; fn regs() -> RegBlock { crate::pac::$inst diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index bab70099..8f282baf 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -11,7 +11,7 @@ use embassy_time::driver::{AlarmHandle, Driver}; use embassy_time::TICK_HZ; use stm32_metapac::timer::regs; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac::timer::vals; use crate::rcc::sealed::RccPeripheral; use crate::timer::sealed::{Basic16bitInstance as BasicInstance, GeneralPurpose16bitInstance as Instance}; diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 772c6768..14db9702 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -1,6 +1,6 @@ use stm32_metapac::timer::vals; -use crate::interrupt::Interrupt; +use crate::interrupt; use crate::rcc::sealed::RccPeripheral as __RccPeri; use crate::rcc::RccPeripheral; use crate::time::Hertz; @@ -13,7 +13,7 @@ pub mod low_level { pub(crate) mod sealed { use super::*; pub trait Basic16bitInstance: RccPeripheral { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; fn regs() -> crate::pac::timer::TimBasic; @@ -57,7 +57,7 @@ pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} macro_rules! impl_basic_16bit_timer { ($inst:ident, $irq:ident) => { impl sealed::Basic16bitInstance for crate::peripherals::$inst { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; fn regs() -> crate::pac::timer::TimBasic { crate::pac::timer::TimBasic(crate::pac::$inst.0) diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs index efbbf2d1..d39c78b2 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32/src/tl_mbox/mod.rs @@ -2,7 +2,6 @@ use core::mem::MaybeUninit; use atomic_polyfill::{compiler_fence, Ordering}; use bit_field::BitField; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; @@ -15,6 +14,7 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam}; use self::sys::Sys; use self::unsafe_linked_list::LinkedListNode; use crate::interrupt; +use crate::interrupt::InterruptExt; use crate::peripherals::IPCC; pub use crate::tl_mbox::ipcc::Config; use crate::tl_mbox::ipcc::Ipcc; @@ -63,7 +63,7 @@ pub struct FusInfoTable { /// Interrupt handler. pub struct ReceiveInterruptHandler {} -impl interrupt::Handler for ReceiveInterruptHandler { +impl interrupt::typelevel::Handler for ReceiveInterruptHandler { unsafe fn on_interrupt() { // info!("ipcc rx interrupt"); @@ -79,7 +79,7 @@ impl interrupt::Handler for ReceiveInterruptHandler { pub struct TransmitInterruptHandler {} -impl interrupt::Handler for TransmitInterruptHandler { +impl interrupt::typelevel::Handler for TransmitInterruptHandler { unsafe fn on_interrupt() { // info!("ipcc tx interrupt"); @@ -324,8 +324,8 @@ impl<'d> TlMbox<'d> { /// initializes low-level transport between CPU1 and BLE stack on CPU2 pub fn new( ipcc: impl Peripheral

+ 'd, - _irqs: impl interrupt::Binding - + interrupt::Binding, + _irqs: impl interrupt::typelevel::Binding + + interrupt::typelevel::Binding, config: Config, ) -> Self { into_ref!(ipcc); @@ -379,11 +379,11 @@ impl<'d> TlMbox<'d> { MemoryManager::enable(); // enable interrupts - crate::interrupt::IPCC_C1_RX::unpend(); - crate::interrupt::IPCC_C1_TX::unpend(); + crate::interrupt::IPCC_C1_RX.unpend(); + crate::interrupt::IPCC_C1_TX.unpend(); - unsafe { crate::interrupt::IPCC_C1_RX::enable() }; - unsafe { crate::interrupt::IPCC_C1_TX::enable() }; + unsafe { crate::interrupt::IPCC_C1_RX.enable() }; + unsafe { crate::interrupt::IPCC_C1_TX.enable() }; Self { _ipcc: ipcc } } diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 252e945d..613da567 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -2,18 +2,18 @@ use core::future::poll_fn; use core::slice; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_sync::waitqueue::AtomicWaker; use super::*; +use crate::interrupt::typelevel::Interrupt; /// Interrupt handler. pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let state = T::buffered_state(); @@ -115,7 +115,7 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { impl<'d, T: BasicInstance> BufferedUart<'d, T> { pub fn new( peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, tx_buffer: &'d mut [u8], @@ -130,7 +130,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { pub fn new_with_rtscts( peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, rts: impl Peripheral

> + 'd, @@ -159,7 +159,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { #[cfg(not(any(usart_v1, usart_v2)))] pub fn new_with_de( peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, de: impl Peripheral

> + 'd, diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index ef108015..da3644a8 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -5,13 +5,13 @@ use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; use futures::future::{select, Either}; use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; +use crate::interrupt::typelevel::Interrupt; #[cfg(not(any(usart_v1, usart_v2)))] #[allow(unused_imports)] use crate::pac::usart::regs::Isr as Sr; @@ -31,7 +31,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { let r = T::regs(); let s = T::state(); @@ -281,7 +281,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. pub fn new( peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rx: impl Peripheral

> + 'd, rx_dma: impl Peripheral

+ 'd, config: Config, @@ -294,7 +294,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { pub fn new_with_rts( peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rx: impl Peripheral

> + 'd, rts: impl Peripheral

> + 'd, rx_dma: impl Peripheral

+ 'd, @@ -650,7 +650,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { peri: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, config: Config, @@ -665,7 +665,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { peri: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, rts: impl Peripheral

> + 'd, cts: impl Peripheral

> + 'd, tx_dma: impl Peripheral

+ 'd, @@ -693,7 +693,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { peri: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, tx: impl Peripheral

> + 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, de: impl Peripheral

> + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, @@ -1179,7 +1179,7 @@ pub(crate) mod sealed { pub trait BasicInstance: crate::rcc::RccPeripheral { const KIND: Kind; - type Interrupt: crate::interrupt::Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; fn regs() -> Regs; fn state() -> &'static State; @@ -1211,7 +1211,7 @@ macro_rules! impl_usart { ($inst:ident, $irq:ident, $kind:expr) => { impl sealed::BasicInstance for crate::peripherals::$inst { const KIND: Kind = $kind; - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; fn regs() -> Regs { Regs(crate::pac::$inst.0) diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index fbd1fa82..bee287fe 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs @@ -1,4 +1,4 @@ -use crate::interrupt::Interrupt; +use crate::interrupt; use crate::rcc::RccPeripheral; #[cfg(feature = "nightly")] @@ -13,7 +13,7 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + RccPeripheral + 'static { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } // Internal PHY pins @@ -29,7 +29,7 @@ foreach_interrupt!( } impl Instance for crate::peripherals::$inst { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; ); diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 13410797..7486bd37 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -14,7 +14,7 @@ use embassy_usb_driver::{ use super::{DmPin, DpPin, Instance}; use crate::gpio::sealed::AFType; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac::usb::regs; use crate::pac::usb::vals::{EpType, Stat}; use crate::pac::USBRAM; @@ -26,7 +26,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { unsafe { let regs = T::regs(); @@ -255,7 +255,7 @@ pub struct Driver<'d, T: Instance> { impl<'d, T: Instance> Driver<'d, T> { pub fn new( _usb: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, dp: impl Peripheral

> + 'd, dm: impl Peripheral

> + 'd, ) -> Self { diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs index 193e0df0..317264cb 100644 --- a/embassy-stm32/src/usb_otg/mod.rs +++ b/embassy-stm32/src/usb_otg/mod.rs @@ -1,7 +1,5 @@ -use embassy_cortex_m::interrupt::Interrupt; - -use crate::peripherals; use crate::rcc::RccPeripheral; +use crate::{interrupt, peripherals}; #[cfg(feature = "nightly")] mod usb; @@ -25,7 +23,7 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + RccPeripheral { - type Interrupt: Interrupt; + type Interrupt: interrupt::typelevel::Interrupt; } // Internal PHY pins @@ -109,7 +107,7 @@ foreach_interrupt!( } impl Instance for peripherals::USB_OTG_FS { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; @@ -161,7 +159,7 @@ foreach_interrupt!( } impl Instance for peripherals::USB_OTG_HS { - type Interrupt = crate::interrupt::$irq; + type Interrupt = crate::interrupt::typelevel::$irq; } }; ); diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index e602bcb7..16cbf1a9 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -3,7 +3,6 @@ use core::marker::PhantomData; use core::task::Poll; use atomic_polyfill::{AtomicBool, AtomicU16, Ordering}; -use embassy_cortex_m::interrupt::Interrupt; use embassy_hal_common::{into_ref, Peripheral}; use embassy_sync::waitqueue::AtomicWaker; use embassy_usb_driver::{ @@ -15,6 +14,7 @@ use futures::future::poll_fn; use super::*; use crate::gpio::sealed::AFType; use crate::interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac::otg::{regs, vals}; use crate::rcc::sealed::RccPeripheral; use crate::time::Hertz; @@ -24,7 +24,7 @@ pub struct InterruptHandler { _phantom: PhantomData, } -impl interrupt::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { trace!("irq"); let r = T::regs(); @@ -291,7 +291,7 @@ impl<'d, T: Instance> Driver<'d, T> { /// Endpoint allocation will fail if it is too small. pub fn new_fs( _peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, dp: impl Peripheral

> + 'd, dm: impl Peripheral

> + 'd, ep_out_buffer: &'d mut [u8], @@ -322,7 +322,7 @@ impl<'d, T: Instance> Driver<'d, T> { /// Endpoint allocation will fail if it is too small. pub fn new_hs_ulpi( _peri: impl Peripheral

+ 'd, - _irq: impl interrupt::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, ulpi_clk: impl Peripheral

> + 'd, ulpi_dir: impl Peripheral

> + 'd, ulpi_nxt: impl Peripheral

> + 'd, diff --git a/examples/stm32f7/build.rs b/examples/stm32f7/build.rs index c4e15f19..2b5d412a 100644 --- a/examples/stm32f7/build.rs +++ b/examples/stm32f7/build.rs @@ -1,9 +1,8 @@ //! adapted from https://github.com/stm32-rs/stm32f7xx-hal/blob/master/build.rs -use std::env; use std::fs::File; use std::io::prelude::*; -use std::io::{self}; use std::path::PathBuf; +use std::{env, io}; #[derive(Debug)] enum Error { From bce24e800516402a3a3991ebde0432e5167be174 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 18:07:44 +0200 Subject: [PATCH 23/28] asdg --- embassy-stm32/src/dma/gpdma.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 07fef360..59ec205b 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -12,7 +12,7 @@ use embassy_sync::waitqueue::AtomicWaker; use super::word::{Word, WordSize}; use super::Dir; use crate::_generated::GPDMA_CHANNEL_COUNT; -use crate::interrupt::Interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::pac; use crate::pac::gpdma::vals; From 5c2f02c73505cf630c2fbe9b098707a33293d702 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 16:39:05 +0200 Subject: [PATCH 24/28] Reexport NVIC_PRIO_BITS at HAL root. This allows using RTIC with `#[rtic::app(device = embassy_nrf, ...)]` --- embassy-nrf/src/chips/nrf5340_app.rs | 2 ++ embassy-nrf/src/chips/nrf5340_net.rs | 2 ++ embassy-nrf/src/chips/nrf9160.rs | 2 ++ embassy-nrf/src/lib.rs | 5 +++-- embassy-rp/src/lib.rs | 2 ++ embassy-stm32/src/lib.rs | 2 ++ 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index c1052005..cb879f73 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -5,6 +5,8 @@ pub mod pac { // The nRF5340 has a secure and non-secure (NS) mode. // To avoid cfg spam, we remove _ns or _s suffixes here. + pub use nrf5340_app_pac::NVIC_PRIO_BITS; + #[doc(no_inline)] pub use nrf5340_app_pac::{ interrupt, diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index a6fb1d4c..6e2c0bb6 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -5,6 +5,8 @@ pub mod pac { // The nRF5340 has a secure and non-secure (NS) mode. // To avoid cfg spam, we remove _ns or _s suffixes here. + pub use nrf5340_net_pac::NVIC_PRIO_BITS; + #[doc(no_inline)] pub use nrf5340_net_pac::{ interrupt, diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index b6ae78bb..9944ac4a 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -5,6 +5,8 @@ pub mod pac { // The nRF9160 has a secure and non-secure (NS) mode. // To avoid cfg spam, we remove _ns or _s suffixes here. + pub use nrf9160_pac::NVIC_PRIO_BITS; + #[doc(no_inline)] pub use nrf9160_pac::{ interrupt, diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index a73d22a6..ddabf93a 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -93,8 +93,6 @@ pub mod wdt; #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] mod chip; -pub use crate::chip::interrupt; - /// Macro to bind interrupts to handlers. /// /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) @@ -132,6 +130,9 @@ pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; pub use embassy_cortex_m::executor; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; +pub use crate::chip::interrupt; +pub use crate::pac::NVIC_PRIO_BITS; + pub mod config { //! Configuration options used when initializing the HAL. diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 70a410ef..5e3e5969 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -43,6 +43,8 @@ pub use rp_pac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use rp_pac as pac; +pub use crate::pac::NVIC_PRIO_BITS; + embassy_cortex_m::interrupt_mod!( TIMER_IRQ_0, TIMER_IRQ_1, diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index b4286456..565d6817 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -111,6 +111,8 @@ pub use stm32_metapac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use stm32_metapac as pac; +pub use crate::pac::NVIC_PRIO_BITS; + #[non_exhaustive] pub struct Config { pub rcc: rcc::Config, From f498c689e7c3a2314c7a80bf14fc2cb491528aa4 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 16:40:02 +0200 Subject: [PATCH 25/28] Add RTIC example. --- ci.sh | 1 + examples/nrf52840-rtic/.cargo/config.toml | 9 +++++ examples/nrf52840-rtic/Cargo.toml | 21 +++++++++++ examples/nrf52840-rtic/build.rs | 35 ++++++++++++++++++ examples/nrf52840-rtic/memory.x | 7 ++++ examples/nrf52840-rtic/src/bin/blinky.rs | 43 +++++++++++++++++++++++ 6 files changed, 116 insertions(+) create mode 100644 examples/nrf52840-rtic/.cargo/config.toml create mode 100644 examples/nrf52840-rtic/Cargo.toml create mode 100644 examples/nrf52840-rtic/build.rs create mode 100644 examples/nrf52840-rtic/memory.x create mode 100644 examples/nrf52840-rtic/src/bin/blinky.rs diff --git a/ci.sh b/ci.sh index 08558a18..da2414d6 100755 --- a/ci.sh +++ b/ci.sh @@ -104,6 +104,7 @@ cargo batch \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \ + --- build --release --manifest-path examples/nrf52840-rtic/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840-rtic \ --- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \ --- build --release --manifest-path examples/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/rp \ --- build --release --manifest-path examples/stm32f0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32f0 \ diff --git a/examples/nrf52840-rtic/.cargo/config.toml b/examples/nrf52840-rtic/.cargo/config.toml new file mode 100644 index 00000000..3872e718 --- /dev/null +++ b/examples/nrf52840-rtic/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace nRF82840_xxAA with your chip as listed in `probe-rs-cli chip list` +runner = "probe-rs-cli run --chip nRF52840_xxAA" + +[build] +target = "thumbv7em-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml new file mode 100644 index 00000000..0f9048b0 --- /dev/null +++ b/examples/nrf52840-rtic/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2021" +name = "embassy-nrf52840-rtic-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +rtic = { version = "2", features = ["thumbv7-backend"] } + +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } +embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } +embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nightly", "unstable-traits", "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } + +defmt = "0.3" +defmt-rtt = "0.4" + +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.0" +panic-probe = { version = "0.3", features = ["print-defmt"] } +futures = { version = "0.3.17", default-features = false, features = ["async-await"] } diff --git a/examples/nrf52840-rtic/build.rs b/examples/nrf52840-rtic/build.rs new file mode 100644 index 00000000..30691aa9 --- /dev/null +++ b/examples/nrf52840-rtic/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/nrf52840-rtic/memory.x b/examples/nrf52840-rtic/memory.x new file mode 100644 index 00000000..9b04edec --- /dev/null +++ b/examples/nrf52840-rtic/memory.x @@ -0,0 +1,7 @@ +MEMORY +{ + /* NOTE 1 K = 1 KiBi = 1024 bytes */ + /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */ + FLASH : ORIGIN = 0x00000000, LENGTH = 1024K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/nrf52840-rtic/src/bin/blinky.rs b/examples/nrf52840-rtic/src/bin/blinky.rs new file mode 100644 index 00000000..a682c193 --- /dev/null +++ b/examples/nrf52840-rtic/src/bin/blinky.rs @@ -0,0 +1,43 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use {defmt_rtt as _, panic_probe as _}; + +#[rtic::app(device = embassy_nrf, peripherals = false, dispatchers = [SWI0_EGU0, SWI1_EGU1])] +mod app { + use defmt::info; + use embassy_nrf::gpio::{Level, Output, OutputDrive}; + use embassy_nrf::peripherals; + use embassy_time::{Duration, Timer}; + + #[shared] + struct Shared {} + + #[local] + struct Local {} + + #[init] + fn init(_: init::Context) -> (Shared, Local) { + info!("Hello World!"); + + let p = embassy_nrf::init(Default::default()); + blink::spawn(p.P0_13).map_err(|_| ()).unwrap(); + + (Shared {}, Local {}) + } + + #[task(priority = 1)] + async fn blink(_cx: blink::Context, pin: peripherals::P0_13) { + let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); + + loop { + info!("off!"); + led.set_high(); + Timer::after(Duration::from_millis(300)).await; + info!("on!"); + led.set_low(); + Timer::after(Duration::from_millis(300)).await; + } + } +} From 8c93805ab5a13c784e072c8e6e59b354ee902d99 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 18:00:19 +0200 Subject: [PATCH 26/28] Add `rt` feature to HALs, cfg out interrupt handling when not set. --- embassy-cortex-m/src/interrupt.rs | 3 ++- embassy-nrf/Cargo.toml | 3 ++- embassy-nrf/src/gpiote.rs | 3 +++ embassy-nrf/src/time_driver.rs | 1 + embassy-rp/Cargo.toml | 3 ++- embassy-rp/src/dma.rs | 1 + embassy-rp/src/gpio.rs | 1 + embassy-rp/src/lib.rs | 1 + embassy-rp/src/multicore.rs | 2 ++ embassy-rp/src/pio.rs | 2 ++ embassy-rp/src/timer.rs | 4 ++++ embassy-stm32/Cargo.toml | 4 +++- embassy-stm32/build.rs | 1 + embassy-stm32/src/exti.rs | 1 + embassy-stm32/src/lib.rs | 1 + embassy-stm32/src/rng.rs | 2 ++ embassy-stm32/src/time_driver.rs | 6 ++++++ 17 files changed, 35 insertions(+), 4 deletions(-) diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs index 8e45c36c..e9fa43e8 100644 --- a/embassy-cortex-m/src/interrupt.rs +++ b/embassy-cortex-m/src/interrupt.rs @@ -9,12 +9,13 @@ use cortex_m::peripheral::NVIC; #[macro_export] macro_rules! interrupt_mod { ($($irqs:ident),* $(,)?) => { + #[cfg(feature = "rt")] pub use cortex_m_rt::interrupt; /// Interrupt definitions. pub mod interrupt { pub use embassy_cortex_m::interrupt::{InterruptExt, Priority}; - pub use crate::pac::interrupt::*; + pub use crate::pac::Interrupt::*; pub use crate::pac::Interrupt; /// Type-level interrupt infrastructure. diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 83900d4d..5fab11f3 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -16,7 +16,8 @@ flavors = [ ] [features] -default = [ +default = ["rt"] +rt = [ "nrf52805-pac?/rt", "nrf52810-pac?/rt", "nrf52811-pac?/rt", diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 1d7725bd..21d0d956 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -91,18 +91,21 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { } #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))] +#[cfg(feature = "rt")] #[interrupt] fn GPIOTE0() { unsafe { handle_gpiote_interrupt() }; } #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] +#[cfg(feature = "rt")] #[interrupt] fn GPIOTE1() { unsafe { handle_gpiote_interrupt() }; } #[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))] +#[cfg(feature = "rt")] #[interrupt] fn GPIOTE() { unsafe { handle_gpiote_interrupt() }; diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index f993d7b2..f1ab4f8f 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs @@ -295,6 +295,7 @@ impl Driver for RtcDriver { } } +#[cfg(feature = "rt")] #[interrupt] fn RTC1() { DRIVER.on_interrupt() diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index ddada655..ee06e99c 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -13,7 +13,8 @@ flavors = [ ] [features] -default = [ "rp-pac/rt" ] +default = [ "rt" ] +rt = [ "rp-pac/rt" ] defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"] diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 042ca99a..25819f03 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -12,6 +12,7 @@ use crate::interrupt::InterruptExt; use crate::pac::dma::vals; use crate::{interrupt, pac, peripherals}; +#[cfg(feature = "rt")] #[interrupt] unsafe fn DMA_IRQ_0() { let ints0 = pac::DMA.ints0().read().ints0(); diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index ebd932f5..66faa248 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -142,6 +142,7 @@ pub(crate) unsafe fn init() { interrupt::IO_IRQ_BANK0.enable(); } +#[cfg(feature = "rt")] #[interrupt] unsafe fn IO_IRQ_BANK0() { let cpu = SIO.cpuid().read() as usize; diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 5e3e5969..4e4b7614 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -43,6 +43,7 @@ pub use rp_pac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use rp_pac as pac; +#[cfg(feature = "rt")] pub use crate::pac::NVIC_PRIO_BITS; embassy_cortex_m::interrupt_mod!( diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs index e1246ce8..2a7e4822 100644 --- a/embassy-rp/src/multicore.rs +++ b/embassy-rp/src/multicore.rs @@ -106,6 +106,7 @@ impl Stack { } } +#[cfg(feature = "rt")] #[interrupt] #[link_section = ".data.ram_func"] unsafe fn SIO_IRQ_PROC1() { @@ -297,6 +298,7 @@ fn fifo_read() -> u32 { // Pop a value from inter-core FIFO, `wfe` until available #[inline(always)] +#[allow(unused)] fn fifo_read_wfe() -> u32 { unsafe { let sio = pac::SIO; diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index f0a5c17a..0fa3bd77 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs @@ -85,6 +85,7 @@ const RXNEMPTY_MASK: u32 = 1 << 0; const TXNFULL_MASK: u32 = 1 << 4; const SMIRQ_MASK: u32 = 1 << 8; +#[cfg(feature = "rt")] #[interrupt] unsafe fn PIO0_IRQ_0() { use crate::pac; @@ -97,6 +98,7 @@ unsafe fn PIO0_IRQ_0() { pac::PIO0.irqs(0).inte().write_clear(|m| m.0 = ints); } +#[cfg(feature = "rt")] #[interrupt] unsafe fn PIO1_IRQ_0() { use crate::pac; diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/timer.rs index 37f86c93..ca8c96c0 100644 --- a/embassy-rp/src/timer.rs +++ b/embassy-rp/src/timer.rs @@ -151,21 +151,25 @@ pub unsafe fn init() { interrupt::TIMER_IRQ_3.enable(); } +#[cfg(feature = "rt")] #[interrupt] unsafe fn TIMER_IRQ_0() { DRIVER.check_alarm(0) } +#[cfg(feature = "rt")] #[interrupt] unsafe fn TIMER_IRQ_1() { DRIVER.check_alarm(1) } +#[cfg(feature = "rt")] #[interrupt] unsafe fn TIMER_IRQ_2() { DRIVER.check_alarm(2) } +#[cfg(feature = "rt")] #[interrupt] unsafe fn TIMER_IRQ_3() { DRIVER.check_alarm(3) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 4e29bb32..f1f894c6 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -79,7 +79,9 @@ quote = "1.0.15" stm32-metapac = { version = "9", default-features = false, features = ["metadata"]} [features] -default = ["stm32-metapac/rt"] +default = ["rt"] +rt = ["stm32-metapac/rt"] + defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] memory-x = ["stm32-metapac/memory-x"] exti = [] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 267fec38..ba5f91cc 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -295,6 +295,7 @@ fn main() { let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); g.extend(quote! { + #[cfg(feature = "rt")] #[crate::interrupt] unsafe fn #irq () { #( diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index a2ed0709..0631ae47 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -291,6 +291,7 @@ macro_rules! foreach_exti_irq { macro_rules! impl_irq { ($e:ident) => { + #[cfg(feature = "rt")] #[interrupt] unsafe fn $e() { on_irq() diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 565d6817..f8857fdd 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -111,6 +111,7 @@ pub use stm32_metapac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use stm32_metapac as pac; +#[cfg(feature = "rt")] pub use crate::pac::NVIC_PRIO_BITS; #[non_exhaustive] diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 1e16b847..c657bf70 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -149,6 +149,7 @@ foreach_peripheral!( }; ); +#[cfg(feature = "rt")] macro_rules! irq { ($irq:ident) => { mod rng_irq { @@ -166,6 +167,7 @@ macro_rules! irq { }; } +#[cfg(feature = "rt")] foreach_interrupt!( (RNG) => { irq!(RNG); diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 8f282baf..e82501a4 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -40,6 +40,7 @@ type T = peripherals::TIM15; foreach_interrupt! { (TIM2, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim2)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() @@ -47,6 +48,7 @@ foreach_interrupt! { }; (TIM3, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim3)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() @@ -54,6 +56,7 @@ foreach_interrupt! { }; (TIM4, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim4)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() @@ -61,6 +64,7 @@ foreach_interrupt! { }; (TIM5, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim5)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() @@ -68,6 +72,7 @@ foreach_interrupt! { }; (TIM12, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim12)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() @@ -75,6 +80,7 @@ foreach_interrupt! { }; (TIM15, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim15)] + #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() From 4716166041e78a4227331de2cab601b5e3252273 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 19:37:11 +0200 Subject: [PATCH 27/28] tests/rp: update cyw43-perf for embassy-net changes. --- tests/rp/src/bin/cyw43-perf.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index 568f1b82..dd67914a 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs @@ -63,7 +63,7 @@ async fn main(spawner: Spawner) { .set_power_management(cyw43::PowerManagementMode::PowerSave) .await; - let config = Config::Dhcp(Default::default()); + let config = Config::dhcpv4(Default::default()); //let config = embassy_net::Config::Static(embassy_net::Config { // address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), // dns_servers: Vec::new(), @@ -93,7 +93,7 @@ async fn main(spawner: Spawner) { } info!("Waiting for DHCP up..."); - while stack.config().is_none() { + while stack.config_v4().is_none() { Timer::after(Duration::from_millis(100)).await; } info!("IP addressing up!"); From 3dde01597a7861817ee52fef6ea4b5732a77debc Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 8 Jun 2023 21:12:34 +0200 Subject: [PATCH 28/28] tests/rp: make cyw43-perf less strict. --- tests/rp/src/bin/cyw43-perf.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index dd67914a..7a94ea19 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs @@ -115,9 +115,9 @@ const WIFI_NETWORK: &str = "EmbassyTest"; const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; const TEST_DURATION: usize = 10; -const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 500; -const TEST_EXPECTED_UPLOAD_KBPS: usize = 500; -const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 400; +const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 300; +const TEST_EXPECTED_UPLOAD_KBPS: usize = 300; +const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 300; const RX_BUFFER_SIZE: usize = 4096; const TX_BUFFER_SIZE: usize = 4096; const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);