aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/rust.yml2
-rw-r--r--.vscode/settings.json2
-rw-r--r--embassy-boot/boot/Cargo.toml2
-rw-r--r--embassy-boot/nrf/Cargo.toml2
-rw-r--r--embassy-boot/stm32/Cargo.toml2
-rw-r--r--embassy-cortex-m/Cargo.toml2
-rw-r--r--embassy-cortex-m/src/executor.rs2
-rw-r--r--embassy-embedded-hal/Cargo.toml2
-rw-r--r--embassy-embedded-hal/src/shared_bus/asynch/i2c.rs12
-rw-r--r--embassy-embedded-hal/src/shared_bus/asynch/spi.rs12
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/i2c.rs10
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/spi.rs10
-rw-r--r--embassy-executor/Cargo.toml5
-rw-r--r--embassy-executor/src/arch/cortex_m.rs2
-rw-r--r--embassy-executor/src/arch/riscv32.rs2
-rw-r--r--embassy-executor/src/arch/std.rs2
-rw-r--r--embassy-executor/src/arch/wasm.rs2
-rw-r--r--embassy-executor/src/arch/xtensa.rs2
-rw-r--r--embassy-executor/src/lib.rs31
-rw-r--r--embassy-executor/src/raw/mod.rs39
-rw-r--r--embassy-futures/Cargo.toml14
-rw-r--r--embassy-futures/src/fmt.rs (renamed from embassy-util/src/fmt.rs)0
-rw-r--r--embassy-futures/src/lib.rs12
-rw-r--r--embassy-futures/src/select.rs (renamed from embassy-util/src/select.rs)0
-rw-r--r--embassy-futures/src/yield_now.rs (renamed from embassy-util/src/yield_now.rs)0
-rw-r--r--embassy-lora/Cargo.toml2
-rw-r--r--embassy-lora/src/stm32wl/mod.rs2
-rw-r--r--embassy-macros/src/macros/cortex_m_interrupt_take.rs8
-rw-r--r--embassy-macros/src/macros/main.rs4
-rw-r--r--embassy-net/Cargo.toml2
-rw-r--r--embassy-net/src/stack.rs2
-rw-r--r--embassy-nrf/Cargo.toml4
-rw-r--r--embassy-nrf/src/buffered_uarte.rs11
-rw-r--r--embassy-nrf/src/gpio.rs21
-rw-r--r--embassy-nrf/src/gpiote.rs2
-rw-r--r--embassy-nrf/src/nvmc.rs10
-rw-r--r--embassy-nrf/src/ppi/mod.rs12
-rw-r--r--embassy-nrf/src/ppi/ppi.rs3
-rw-r--r--embassy-nrf/src/qdec.rs2
-rw-r--r--embassy-nrf/src/qspi.rs2
-rw-r--r--embassy-nrf/src/rng.rs2
-rw-r--r--embassy-nrf/src/saadc.rs2
-rw-r--r--embassy-nrf/src/spim.rs2
-rw-r--r--embassy-nrf/src/temp.rs2
-rw-r--r--embassy-nrf/src/time_driver.rs4
-rw-r--r--embassy-nrf/src/timer.rs6
-rw-r--r--embassy-nrf/src/twim.rs2
-rw-r--r--embassy-nrf/src/uarte.rs2
-rw-r--r--embassy-nrf/src/usb.rs2
-rw-r--r--embassy-rp/Cargo.toml4
-rw-r--r--embassy-rp/src/gpio.rs4
-rw-r--r--embassy-rp/src/timer.rs4
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs12
-rw-r--r--embassy-stm32/src/dcmi.rs2
-rw-r--r--embassy-stm32/src/dma/bdma.rs2
-rw-r--r--embassy-stm32/src/dma/dma.rs2
-rw-r--r--embassy-stm32/src/dma/gpdma.rs2
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs2
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs2
-rw-r--r--embassy-stm32/src/exti.rs2
-rw-r--r--embassy-stm32/src/i2c/v2.rs2
-rw-r--r--embassy-stm32/src/rng.rs2
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs6
-rw-r--r--embassy-stm32/src/time_driver.rs4
-rw-r--r--embassy-stm32/src/usart/buffered.rs30
-rw-r--r--embassy-stm32/src/usart/mod.rs119
-rw-r--r--embassy-stm32/src/usb/usb.rs2
-rw-r--r--embassy-sync/Cargo.toml (renamed from embassy-util/Cargo.toml)7
-rw-r--r--embassy-sync/build.rs (renamed from embassy-util/build.rs)0
-rw-r--r--embassy-sync/src/blocking_mutex/mod.rs (renamed from embassy-util/src/blocking_mutex/mod.rs)0
-rw-r--r--embassy-sync/src/blocking_mutex/raw.rs (renamed from embassy-util/src/blocking_mutex/raw.rs)0
-rw-r--r--embassy-sync/src/channel.rs (renamed from embassy-util/src/channel/mpmc.rs)14
-rw-r--r--embassy-sync/src/fmt.rs228
-rw-r--r--embassy-sync/src/lib.rs (renamed from embassy-util/src/lib.rs)10
-rw-r--r--embassy-sync/src/mutex.rs (renamed from embassy-util/src/mutex.rs)0
-rw-r--r--embassy-sync/src/pipe.rs (renamed from embassy-util/src/pipe.rs)10
-rw-r--r--embassy-sync/src/pubsub/mod.rs (renamed from embassy-util/src/channel/pubsub/mod.rs)6
-rw-r--r--embassy-sync/src/pubsub/publisher.rs (renamed from embassy-util/src/channel/pubsub/publisher.rs)0
-rw-r--r--embassy-sync/src/pubsub/subscriber.rs (renamed from embassy-util/src/channel/pubsub/subscriber.rs)0
-rw-r--r--embassy-sync/src/ring_buffer.rs (renamed from embassy-util/src/ring_buffer.rs)0
-rw-r--r--embassy-sync/src/signal.rs (renamed from embassy-util/src/channel/signal.rs)2
-rw-r--r--embassy-sync/src/waitqueue/mod.rs (renamed from embassy-util/src/waitqueue/mod.rs)0
-rw-r--r--embassy-sync/src/waitqueue/multi_waker.rs (renamed from embassy-util/src/waitqueue/multi_waker.rs)0
-rw-r--r--embassy-sync/src/waitqueue/waker.rs (renamed from embassy-util/src/waitqueue/waker.rs)0
-rw-r--r--embassy-time/src/driver.rs2
-rw-r--r--embassy-usb-hid/Cargo.toml2
-rw-r--r--embassy-usb-ncm/Cargo.toml2
-rw-r--r--embassy-usb-serial/Cargo.toml2
-rw-r--r--embassy-usb-serial/src/lib.rs2
-rw-r--r--embassy-usb/Cargo.toml2
-rw-r--r--embassy-usb/src/builder.rs2
-rw-r--r--embassy-usb/src/control.rs3
-rw-r--r--embassy-usb/src/driver.rs6
-rw-r--r--embassy-usb/src/lib.rs2
-rw-r--r--embassy-util/src/channel/mod.rs5
-rw-r--r--embassy-util/src/forever.rs95
-rw-r--r--examples/boot/application/nrf/Cargo.toml2
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml2
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml2
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml2
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml2
-rw-r--r--examples/nrf-rtos-trace/.cargo/config.toml9
-rw-r--r--examples/nrf-rtos-trace/Cargo.toml35
-rw-r--r--examples/nrf-rtos-trace/build.rs36
-rw-r--r--examples/nrf-rtos-trace/memory.x7
-rw-r--r--examples/nrf-rtos-trace/src/bin/rtos_trace.rs69
-rw-r--r--examples/nrf/Cargo.toml4
-rw-r--r--examples/nrf/src/bin/channel.rs4
-rw-r--r--examples/nrf/src/bin/channel_sender_receiver.rs10
-rw-r--r--examples/nrf/src/bin/multiprio.rs14
-rw-r--r--examples/nrf/src/bin/mutex.rs4
-rw-r--r--examples/nrf/src/bin/pubsub.rs4
-rw-r--r--examples/nrf/src/bin/raw_spawn.rs6
-rw-r--r--examples/nrf/src/bin/uart_split.rs4
-rw-r--r--examples/nrf/src/bin/usb_ethernet.rs18
-rw-r--r--examples/nrf/src/bin/usb_hid_keyboard.rs4
-rw-r--r--examples/nrf/src/bin/usb_serial_multitask.rs6
-rw-r--r--examples/rp/Cargo.toml2
-rw-r--r--examples/std/Cargo.toml3
-rw-r--r--examples/std/src/bin/net.rs16
-rw-r--r--examples/std/src/bin/net_udp.rs16
-rw-r--r--examples/std/src/bin/serial.rs6
-rw-r--r--examples/stm32f0/Cargo.toml2
-rw-r--r--examples/stm32f1/Cargo.toml2
-rw-r--r--examples/stm32f2/Cargo.toml2
-rw-r--r--examples/stm32f3/Cargo.toml3
-rw-r--r--examples/stm32f3/src/bin/button_events.rs4
-rw-r--r--examples/stm32f3/src/bin/multiprio.rs14
-rw-r--r--examples/stm32f4/Cargo.toml3
-rw-r--r--examples/stm32f4/src/bin/multiprio.rs14
-rw-r--r--examples/stm32f7/Cargo.toml3
-rw-r--r--examples/stm32f7/src/bin/eth.rs14
-rw-r--r--examples/stm32g0/Cargo.toml2
-rw-r--r--examples/stm32g4/Cargo.toml2
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/src/bin/eth.rs14
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs14
-rw-r--r--examples/stm32h7/src/bin/signal.rs2
-rw-r--r--examples/stm32h7/src/bin/spi.rs6
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs6
-rw-r--r--examples/stm32h7/src/bin/usart.rs6
-rw-r--r--examples/stm32h7/src/bin/usart_dma.rs6
-rw-r--r--examples/stm32h7/src/bin/usart_split.rs4
-rw-r--r--examples/stm32l0/Cargo.toml3
-rw-r--r--examples/stm32l0/src/bin/raw_spawn.rs6
-rw-r--r--examples/stm32l1/Cargo.toml2
-rw-r--r--examples/stm32l4/Cargo.toml2
-rw-r--r--examples/stm32l5/Cargo.toml3
-rw-r--r--examples/stm32l5/src/bin/usb_ethernet.rs18
-rw-r--r--examples/stm32u5/Cargo.toml2
-rw-r--r--examples/stm32wb/Cargo.toml2
-rw-r--r--examples/stm32wl/Cargo.toml2
-rw-r--r--examples/stm32wl/src/bin/subghz.rs2
-rw-r--r--examples/wasm/Cargo.toml2
m---------stm32-data0
-rw-r--r--tests/rp/Cargo.toml2
-rw-r--r--tests/stm32/Cargo.toml2
-rw-r--r--tests/stm32/src/bin/usart.rs8
-rw-r--r--tests/stm32/src/bin/usart_dma.rs8
163 files changed, 921 insertions, 453 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index d76e5ced4..d2e8e316b 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -69,4 +69,4 @@ jobs:
69 steps: 69 steps:
70 - uses: actions/checkout@v2 70 - uses: actions/checkout@v2
71 - name: Test 71 - name: Test
72 run: cd embassy-util && cargo test 72 run: cd embassy-sync && cargo test
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d6ce75c99..5e9e51799 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -18,7 +18,7 @@
18 "rust-analyzer.linkedProjects": [ 18 "rust-analyzer.linkedProjects": [
19 // Declare for the target you wish to develop 19 // Declare for the target you wish to develop
20 //"embassy-executor/Cargo.toml", 20 //"embassy-executor/Cargo.toml",
21 //"embassy-util/Cargo.toml", 21 //"embassy-sync/Cargo.toml",
22 "examples/nrf/Cargo.toml", 22 "examples/nrf/Cargo.toml",
23 // "examples/rp/Cargo.toml", 23 // "examples/rp/Cargo.toml",
24 // "examples/std/Cargo.toml", 24 // "examples/std/Cargo.toml",
diff --git a/embassy-boot/boot/Cargo.toml b/embassy-boot/boot/Cargo.toml
index 9c2e72be5..a42f88688 100644
--- a/embassy-boot/boot/Cargo.toml
+++ b/embassy-boot/boot/Cargo.toml
@@ -14,7 +14,7 @@ target = "thumbv7em-none-eabi"
14[dependencies] 14[dependencies]
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
16log = { version = "0.4", optional = true } 16log = { version = "0.4", optional = true }
17embassy-util = { version = "0.1.0", path = "../../embassy-util" } 17embassy-sync = { version = "0.1.0", path = "../../embassy-sync" }
18embedded-storage = "0.3.0" 18embedded-storage = "0.3.0"
19embedded-storage-async = "0.3.0" 19embedded-storage-async = "0.3.0"
20 20
diff --git a/embassy-boot/nrf/Cargo.toml b/embassy-boot/nrf/Cargo.toml
index b06e8102c..234393e7c 100644
--- a/embassy-boot/nrf/Cargo.toml
+++ b/embassy-boot/nrf/Cargo.toml
@@ -15,7 +15,7 @@ target = "thumbv7em-none-eabi"
15[dependencies] 15[dependencies]
16defmt = { version = "0.3", optional = true } 16defmt = { version = "0.3", optional = true }
17 17
18embassy-util = { path = "../../embassy-util" } 18embassy-sync = { path = "../../embassy-sync" }
19embassy-nrf = { path = "../../embassy-nrf", default-features = false, features = ["nightly"] } 19embassy-nrf = { path = "../../embassy-nrf", default-features = false, features = ["nightly"] }
20embassy-boot = { path = "../boot", default-features = false } 20embassy-boot = { path = "../boot", default-features = false }
21cortex-m = { version = "0.7.6" } 21cortex-m = { version = "0.7.6" }
diff --git a/embassy-boot/stm32/Cargo.toml b/embassy-boot/stm32/Cargo.toml
index d8f492531..ad4657e0d 100644
--- a/embassy-boot/stm32/Cargo.toml
+++ b/embassy-boot/stm32/Cargo.toml
@@ -17,7 +17,7 @@ defmt = { version = "0.3", optional = true }
17defmt-rtt = { version = "0.3", optional = true } 17defmt-rtt = { version = "0.3", optional = true }
18log = { version = "0.4", optional = true } 18log = { version = "0.4", optional = true }
19 19
20embassy-util = { path = "../../embassy-util" } 20embassy-sync = { path = "../../embassy-sync" }
21embassy-stm32 = { path = "../../embassy-stm32", default-features = false, features = ["nightly"] } 21embassy-stm32 = { path = "../../embassy-stm32", default-features = false, features = ["nightly"] }
22embassy-boot = { path = "../boot", default-features = false } 22embassy-boot = { path = "../boot", default-features = false }
23cortex-m = { version = "0.7.6" } 23cortex-m = { version = "0.7.6" }
diff --git a/embassy-cortex-m/Cargo.toml b/embassy-cortex-m/Cargo.toml
index 1f16da31b..7efced669 100644
--- a/embassy-cortex-m/Cargo.toml
+++ b/embassy-cortex-m/Cargo.toml
@@ -35,7 +35,7 @@ prio-bits-8 = []
35defmt = { version = "0.3", optional = true } 35defmt = { version = "0.3", optional = true }
36log = { version = "0.4.14", optional = true } 36log = { version = "0.4.14", optional = true }
37 37
38embassy-util = { version = "0.1.0", path = "../embassy-util" } 38embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
39embassy-executor = { version = "0.1.0", path = "../embassy-executor"} 39embassy-executor = { version = "0.1.0", path = "../embassy-executor"}
40embassy-macros = { version = "0.1.0", path = "../embassy-macros"} 40embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
41embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common"} 41embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common"}
diff --git a/embassy-cortex-m/src/executor.rs b/embassy-cortex-m/src/executor.rs
index 80c452f84..0d1745d8a 100644
--- a/embassy-cortex-m/src/executor.rs
+++ b/embassy-cortex-m/src/executor.rs
@@ -71,7 +71,7 @@ impl<I: Interrupt> InterruptExecutor<I> {
71 /// Executor instance in a place where it'll live forever and grants you mutable 71 /// Executor instance in a place where it'll live forever and grants you mutable
72 /// access. There's a few ways to do this: 72 /// access. There's a few ways to do this:
73 /// 73 ///
74 /// - a [Forever](embassy_util::Forever) (safe) 74 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
75 /// - a `static mut` (unsafe) 75 /// - a `static mut` (unsafe)
76 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 76 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
77 pub fn start(&'static mut self) -> SendSpawner { 77 pub fn start(&'static mut self) -> SendSpawner {
diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml
index 866666871..462680720 100644
--- a/embassy-embedded-hal/Cargo.toml
+++ b/embassy-embedded-hal/Cargo.toml
@@ -16,7 +16,7 @@ std = []
16nightly = ["embedded-hal-async", "embedded-storage-async"] 16nightly = ["embedded-hal-async", "embedded-storage-async"]
17 17
18[dependencies] 18[dependencies]
19embassy-util = { version = "0.1.0", path = "../embassy-util" } 19embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
20embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 20embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
21embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" } 21embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" }
22embedded-hal-async = { version = "0.1.0-alpha.1", optional = true } 22embedded-hal-async = { version = "0.1.0-alpha.1", optional = true }
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
index bd023fb6a..0bc6afd98 100644
--- a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
@@ -4,15 +4,15 @@
4//! 4//!
5//! ```rust 5//! ```rust
6//! use embassy_embedded_hal::shared_bus::i2c::I2cDevice; 6//! use embassy_embedded_hal::shared_bus::i2c::I2cDevice;
7//! use embassy_util::mutex::Mutex; 7//! use embassy_sync::mutex::Mutex;
8//! use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; 8//! use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
9//! 9//!
10//! static I2C_BUS: Forever<Mutex::<ThreadModeRawMutex, Twim<TWISPI0>>> = Forever::new(); 10//! static I2C_BUS: StaticCell<Mutex::<ThreadModeRawMutex, Twim<TWISPI0>>> = StaticCell::new();
11//! let config = twim::Config::default(); 11//! let config = twim::Config::default();
12//! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); 12//! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
13//! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); 13//! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
14//! let i2c_bus = Mutex::<ThreadModeRawMutex, _>::new(i2c); 14//! let i2c_bus = Mutex::<ThreadModeRawMutex, _>::new(i2c);
15//! let i2c_bus = I2C_BUS.put(i2c_bus); 15//! let i2c_bus = I2C_BUS.init(i2c_bus);
16//! 16//!
17//! // Device 1, using embedded-hal-async compatible driver for QMC5883L compass 17//! // Device 1, using embedded-hal-async compatible driver for QMC5883L compass
18//! let i2c_dev1 = I2cDevice::new(i2c_bus); 18//! let i2c_dev1 = I2cDevice::new(i2c_bus);
@@ -24,8 +24,8 @@
24//! ``` 24//! ```
25use core::future::Future; 25use core::future::Future;
26 26
27use embassy_util::blocking_mutex::raw::RawMutex; 27use embassy_sync::blocking_mutex::raw::RawMutex;
28use embassy_util::mutex::Mutex; 28use embassy_sync::mutex::Mutex;
29use embedded_hal_async::i2c; 29use embedded_hal_async::i2c;
30 30
31use crate::shared_bus::I2cDeviceError; 31use crate::shared_bus::I2cDeviceError;
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
index caa37f6f3..c95b59ef0 100644
--- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
@@ -4,16 +4,16 @@
4//! 4//!
5//! ```rust 5//! ```rust
6//! use embassy_embedded_hal::shared_bus::spi::SpiDevice; 6//! use embassy_embedded_hal::shared_bus::spi::SpiDevice;
7//! use embassy_util::mutex::Mutex; 7//! use embassy_sync::mutex::Mutex;
8//! use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; 8//! use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
9//! 9//!
10//! static SPI_BUS: Forever<Mutex<ThreadModeRawMutex, spim::Spim<SPI3>>> = Forever::new(); 10//! static SPI_BUS: StaticCell<Mutex<ThreadModeRawMutex, spim::Spim<SPI3>>> = StaticCell::new();
11//! let mut config = spim::Config::default(); 11//! let mut config = spim::Config::default();
12//! config.frequency = spim::Frequency::M32; 12//! config.frequency = spim::Frequency::M32;
13//! let irq = interrupt::take!(SPIM3); 13//! let irq = interrupt::take!(SPIM3);
14//! let spi = spim::Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, config); 14//! let spi = spim::Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, config);
15//! let spi_bus = Mutex::<ThreadModeRawMutex, _>::new(spi); 15//! let spi_bus = Mutex::<ThreadModeRawMutex, _>::new(spi);
16//! let spi_bus = SPI_BUS.put(spi_bus); 16//! let spi_bus = SPI_BUS.init(spi_bus);
17//! 17//!
18//! // Device 1, using embedded-hal-async compatible driver for ST7735 LCD display 18//! // Device 1, using embedded-hal-async compatible driver for ST7735 LCD display
19//! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard); 19//! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard);
@@ -27,8 +27,8 @@
27//! ``` 27//! ```
28use core::future::Future; 28use core::future::Future;
29 29
30use embassy_util::blocking_mutex::raw::RawMutex; 30use embassy_sync::blocking_mutex::raw::RawMutex;
31use embassy_util::mutex::Mutex; 31use embassy_sync::mutex::Mutex;
32use embedded_hal_1::digital::blocking::OutputPin; 32use embedded_hal_1::digital::blocking::OutputPin;
33use embedded_hal_1::spi::ErrorType; 33use embedded_hal_1::spi::ErrorType;
34use embedded_hal_async::spi; 34use embedded_hal_async::spi;
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
index 1fc343d15..a611e2d27 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
@@ -4,13 +4,13 @@
4//! 4//!
5//! ```rust 5//! ```rust
6//! use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; 6//! use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
7//! use embassy_util::blocking_mutex::{NoopMutex, raw::NoopRawMutex}; 7//! use embassy_sync::blocking_mutex::{NoopMutex, raw::NoopRawMutex};
8//! 8//!
9//! static I2C_BUS: Forever<NoopMutex<RefCell<Twim<TWISPI0>>>> = Forever::new(); 9//! static I2C_BUS: StaticCell<NoopMutex<RefCell<Twim<TWISPI0>>>> = StaticCell::new();
10//! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); 10//! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
11//! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, Config::default()); 11//! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, Config::default());
12//! let i2c_bus = NoopMutex::new(RefCell::new(i2c)); 12//! let i2c_bus = NoopMutex::new(RefCell::new(i2c));
13//! let i2c_bus = I2C_BUS.put(i2c_bus); 13//! let i2c_bus = I2C_BUS.init(i2c_bus);
14//! 14//!
15//! let i2c_dev1 = I2cDevice::new(i2c_bus); 15//! let i2c_dev1 = I2cDevice::new(i2c_bus);
16//! let mpu = Mpu6050::new(i2c_dev1); 16//! let mpu = Mpu6050::new(i2c_dev1);
@@ -18,8 +18,8 @@
18 18
19use core::cell::RefCell; 19use core::cell::RefCell;
20 20
21use embassy_util::blocking_mutex::raw::RawMutex; 21use embassy_sync::blocking_mutex::raw::RawMutex;
22use embassy_util::blocking_mutex::Mutex; 22use embassy_sync::blocking_mutex::Mutex;
23use embedded_hal_1::i2c::blocking::{I2c, Operation}; 23use embedded_hal_1::i2c::blocking::{I2c, Operation};
24use embedded_hal_1::i2c::ErrorType; 24use embedded_hal_1::i2c::ErrorType;
25 25
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
index a61326594..23845d887 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
@@ -4,13 +4,13 @@
4//! 4//!
5//! ```rust 5//! ```rust
6//! use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; 6//! use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice;
7//! use embassy_util::blocking_mutex::{NoopMutex, raw::NoopRawMutex}; 7//! use embassy_sync::blocking_mutex::{NoopMutex, raw::NoopRawMutex};
8//! 8//!
9//! static SPI_BUS: Forever<NoopMutex<RefCell<Spim<SPI3>>>> = Forever::new(); 9//! static SPI_BUS: StaticCell<NoopMutex<RefCell<Spim<SPI3>>>> = StaticCell::new();
10//! let irq = interrupt::take!(SPIM3); 10//! let irq = interrupt::take!(SPIM3);
11//! let spi = Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, Config::default()); 11//! let spi = Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, Config::default());
12//! let spi_bus = NoopMutex::new(RefCell::new(spi)); 12//! let spi_bus = NoopMutex::new(RefCell::new(spi));
13//! let spi_bus = SPI_BUS.put(spi_bus); 13//! let spi_bus = SPI_BUS.init(spi_bus);
14//! 14//!
15//! // Device 1, using embedded-hal compatible driver for ST7735 LCD display 15//! // Device 1, using embedded-hal compatible driver for ST7735 LCD display
16//! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard); 16//! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard);
@@ -20,8 +20,8 @@
20 20
21use core::cell::RefCell; 21use core::cell::RefCell;
22 22
23use embassy_util::blocking_mutex::raw::RawMutex; 23use embassy_sync::blocking_mutex::raw::RawMutex;
24use embassy_util::blocking_mutex::Mutex; 24use embassy_sync::blocking_mutex::Mutex;
25use embedded_hal_1::digital::blocking::OutputPin; 25use embedded_hal_1::digital::blocking::OutputPin;
26use embedded_hal_1::spi; 26use embedded_hal_1::spi;
27use embedded_hal_1::spi::blocking::SpiBusFlush; 27use embedded_hal_1::spi::blocking::SpiBusFlush;
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index 25c3f0abd..184e770cd 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -30,9 +30,13 @@ nightly = []
30 30
31integrated-timers = ["dep:embassy-time"] 31integrated-timers = ["dep:embassy-time"]
32 32
33# Trace interrupt invocations with rtos-trace.
34rtos-trace-interrupt = ["rtos-trace"]
35
33[dependencies] 36[dependencies]
34defmt = { version = "0.3", optional = true } 37defmt = { version = "0.3", optional = true }
35log = { version = "0.4.14", optional = true } 38log = { version = "0.4.14", optional = true }
39rtos-trace = { version = "0.1.2", optional = true }
36 40
37futures-util = { version = "0.3.17", default-features = false } 41futures-util = { version = "0.3.17", default-features = false }
38embassy-macros = { version = "0.1.0", path = "../embassy-macros"} 42embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
@@ -40,6 +44,7 @@ embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true}
40atomic-polyfill = "1.0.1" 44atomic-polyfill = "1.0.1"
41critical-section = "1.1" 45critical-section = "1.1"
42cfg-if = "1.0.0" 46cfg-if = "1.0.0"
47static_cell = "1.0"
43 48
44# WASM dependencies 49# WASM dependencies
45wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } 50wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs
index d6e758dfb..4b27a264e 100644
--- a/embassy-executor/src/arch/cortex_m.rs
+++ b/embassy-executor/src/arch/cortex_m.rs
@@ -41,7 +41,7 @@ impl Executor {
41 /// Executor instance in a place where it'll live forever and grants you mutable 41 /// Executor instance in a place where it'll live forever and grants you mutable
42 /// access. There's a few ways to do this: 42 /// access. There's a few ways to do this:
43 /// 43 ///
44 /// - a [Forever](crate::util::Forever) (safe) 44 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
45 /// - a `static mut` (unsafe) 45 /// - a `static mut` (unsafe)
46 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 46 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
47 /// 47 ///
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs
index 7a7d5698c..2a4b006da 100644
--- a/embassy-executor/src/arch/riscv32.rs
+++ b/embassy-executor/src/arch/riscv32.rs
@@ -43,7 +43,7 @@ impl Executor {
43 /// Executor instance in a place where it'll live forever and grants you mutable 43 /// Executor instance in a place where it'll live forever and grants you mutable
44 /// access. There's a few ways to do this: 44 /// access. There's a few ways to do this:
45 /// 45 ///
46 /// - a [Forever](crate::util::Forever) (safe) 46 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
47 /// - a `static mut` (unsafe) 47 /// - a `static mut` (unsafe)
48 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 48 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
49 /// 49 ///
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs
index b93ab8a79..701f0eb18 100644
--- a/embassy-executor/src/arch/std.rs
+++ b/embassy-executor/src/arch/std.rs
@@ -40,7 +40,7 @@ impl Executor {
40 /// Executor instance in a place where it'll live forever and grants you mutable 40 /// Executor instance in a place where it'll live forever and grants you mutable
41 /// access. There's a few ways to do this: 41 /// access. There's a few ways to do this:
42 /// 42 ///
43 /// - a [Forever](crate::util::Forever) (safe) 43 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
44 /// - a `static mut` (unsafe) 44 /// - a `static mut` (unsafe)
45 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 45 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
46 /// 46 ///
diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs
index 9d5aa31ed..98091cfbb 100644
--- a/embassy-executor/src/arch/wasm.rs
+++ b/embassy-executor/src/arch/wasm.rs
@@ -59,7 +59,7 @@ impl Executor {
59 /// Executor instance in a place where it'll live forever and grants you mutable 59 /// Executor instance in a place where it'll live forever and grants you mutable
60 /// access. There's a few ways to do this: 60 /// access. There's a few ways to do this:
61 /// 61 ///
62 /// - a [Forever](crate::util::Forever) (safe) 62 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
63 /// - a `static mut` (unsafe) 63 /// - a `static mut` (unsafe)
64 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 64 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
65 pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { 65 pub fn start(&'static mut self, init: impl FnOnce(Spawner)) {
diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs
index 20bd7b8a5..f908aaa70 100644
--- a/embassy-executor/src/arch/xtensa.rs
+++ b/embassy-executor/src/arch/xtensa.rs
@@ -43,7 +43,7 @@ impl Executor {
43 /// Executor instance in a place where it'll live forever and grants you mutable 43 /// Executor instance in a place where it'll live forever and grants you mutable
44 /// access. There's a few ways to do this: 44 /// access. There's a few ways to do this:
45 /// 45 ///
46 /// - a [Forever](crate::util::Forever) (safe) 46 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
47 /// - a `static mut` (unsafe) 47 /// - a `static mut` (unsafe)
48 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) 48 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
49 /// 49 ///
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index 9328a7378..e4cbd04b9 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -38,7 +38,38 @@ cfg_if::cfg_if! {
38 } 38 }
39} 39}
40 40
41#[doc(hidden)]
42/// Implementation details for embassy macros. DO NOT USE.
43pub mod export {
44 #[cfg(feature = "rtos-trace")]
45 pub use rtos_trace::trace;
46
47 /// Expands the given block of code when `embassy-executor` is compiled with
48 /// the `rtos-trace-interrupt` feature.
49 #[doc(hidden)]
50 #[macro_export]
51 #[cfg(feature = "rtos-trace-interrupt")]
52 macro_rules! rtos_trace_interrupt {
53 ($($tt:tt)*) => { $($tt)* };
54 }
55
56 /// Does not expand the given block of code when `embassy-executor` is
57 /// compiled without the `rtos-trace-interrupt` feature.
58 #[doc(hidden)]
59 #[macro_export]
60 #[cfg(not(feature = "rtos-trace-interrupt"))]
61 macro_rules! rtos_trace_interrupt {
62 ($($tt:tt)*) => {};
63 }
64}
65
41pub mod raw; 66pub mod raw;
42 67
43mod spawner; 68mod spawner;
44pub use spawner::*; 69pub use spawner::*;
70
71/// Do not use. Used for macros and HALs only. Not covered by semver guarantees.
72#[doc(hidden)]
73pub mod _export {
74 pub use static_cell::StaticCell;
75}
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index afe67decb..e1258ebb5 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -5,7 +5,7 @@
5//! ## WARNING: here be dragons! 5//! ## WARNING: here be dragons!
6//! 6//!
7//! Using this module requires respecting subtle safety contracts. If you can, prefer using the safe 7//! Using this module requires respecting subtle safety contracts. If you can, prefer using the safe
8//! executor wrappers in [`executor`](crate::executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe. 8//! [executor wrappers](crate::Executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe.
9 9
10mod run_queue; 10mod run_queue;
11#[cfg(feature = "integrated-timers")] 11#[cfg(feature = "integrated-timers")]
@@ -26,6 +26,8 @@ use critical_section::CriticalSection;
26use embassy_time::driver::{self, AlarmHandle}; 26use embassy_time::driver::{self, AlarmHandle};
27#[cfg(feature = "integrated-timers")] 27#[cfg(feature = "integrated-timers")]
28use embassy_time::Instant; 28use embassy_time::Instant;
29#[cfg(feature = "rtos-trace")]
30use rtos_trace::trace;
29 31
30use self::run_queue::{RunQueue, RunQueueItem}; 32use self::run_queue::{RunQueue, RunQueueItem};
31use self::util::UninitCell; 33use self::util::UninitCell;
@@ -247,7 +249,7 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
247/// 249///
248/// This is the core of the Embassy executor. It is low-level, requiring manual 250/// This is the core of the Embassy executor. It is low-level, requiring manual
249/// handling of wakeups and task polling. If you can, prefer using one of the 251/// handling of wakeups and task polling. If you can, prefer using one of the
250/// higher level executors in [`crate::executor`]. 252/// [higher level executors](crate::Executor).
251/// 253///
252/// The raw executor leaves it up to you to handle wakeups and scheduling: 254/// The raw executor leaves it up to you to handle wakeups and scheduling:
253/// 255///
@@ -306,6 +308,9 @@ impl Executor {
306 /// - `task` must NOT be already enqueued (in this executor or another one). 308 /// - `task` must NOT be already enqueued (in this executor or another one).
307 #[inline(always)] 309 #[inline(always)]
308 unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) { 310 unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) {
311 #[cfg(feature = "rtos-trace")]
312 trace::task_ready_begin(task.as_ptr() as u32);
313
309 if self.run_queue.enqueue(cs, task) { 314 if self.run_queue.enqueue(cs, task) {
310 (self.signal_fn)(self.signal_ctx) 315 (self.signal_fn)(self.signal_ctx)
311 } 316 }
@@ -323,6 +328,9 @@ impl Executor {
323 pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) { 328 pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) {
324 task.as_ref().executor.set(self); 329 task.as_ref().executor.set(self);
325 330
331 #[cfg(feature = "rtos-trace")]
332 trace::task_new(task.as_ptr() as u32);
333
326 critical_section::with(|cs| { 334 critical_section::with(|cs| {
327 self.enqueue(cs, task); 335 self.enqueue(cs, task);
328 }) 336 })
@@ -365,9 +373,15 @@ impl Executor {
365 return; 373 return;
366 } 374 }
367 375
376 #[cfg(feature = "rtos-trace")]
377 trace::task_exec_begin(p.as_ptr() as u32);
378
368 // Run the task 379 // Run the task
369 task.poll_fn.read()(p as _); 380 task.poll_fn.read()(p as _);
370 381
382 #[cfg(feature = "rtos-trace")]
383 trace::task_exec_end();
384
371 // Enqueue or update into timer_queue 385 // Enqueue or update into timer_queue
372 #[cfg(feature = "integrated-timers")] 386 #[cfg(feature = "integrated-timers")]
373 self.timer_queue.update(p); 387 self.timer_queue.update(p);
@@ -381,6 +395,9 @@ impl Executor {
381 let next_expiration = self.timer_queue.next_expiration(); 395 let next_expiration = self.timer_queue.next_expiration();
382 driver::set_alarm(self.alarm, next_expiration.as_ticks()); 396 driver::set_alarm(self.alarm, next_expiration.as_ticks());
383 } 397 }
398
399 #[cfg(feature = "rtos-trace")]
400 trace::system_idle();
384 } 401 }
385 402
386 /// Get a spawner that spawns tasks in this executor. 403 /// Get a spawner that spawns tasks in this executor.
@@ -426,3 +443,21 @@ unsafe fn _embassy_time_schedule_wake(at: Instant, waker: &core::task::Waker) {
426 let expires_at = task.expires_at.get(); 443 let expires_at = task.expires_at.get();
427 task.expires_at.set(expires_at.min(at)); 444 task.expires_at.set(expires_at.min(at));
428} 445}
446
447#[cfg(feature = "rtos-trace")]
448impl rtos_trace::RtosTraceOSCallbacks for Executor {
449 fn task_list() {
450 // We don't know what tasks exist, so we can't send them.
451 }
452 #[cfg(feature = "integrated-timers")]
453 fn time() -> u64 {
454 Instant::now().as_micros()
455 }
456 #[cfg(not(feature = "integrated-timers"))]
457 fn time() -> u64 {
458 0
459 }
460}
461
462#[cfg(feature = "rtos-trace")]
463rtos_trace::global_os_callbacks! {Executor}
diff --git a/embassy-futures/Cargo.toml b/embassy-futures/Cargo.toml
new file mode 100644
index 000000000..e564f5a96
--- /dev/null
+++ b/embassy-futures/Cargo.toml
@@ -0,0 +1,14 @@
1[package]
2name = "embassy-futures"
3version = "0.1.0"
4edition = "2021"
5
6[package.metadata.embassy_docs]
7src_base = "https://github.com/embassy-rs/embassy/blob/embassy-futures-v$VERSION/embassy-futures/src/"
8src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-futures/src/"
9features = ["nightly"]
10target = "thumbv7em-none-eabi"
11
12[dependencies]
13defmt = { version = "0.3", optional = true }
14log = { version = "0.4.14", optional = true }
diff --git a/embassy-util/src/fmt.rs b/embassy-futures/src/fmt.rs
index f8bb0a035..f8bb0a035 100644
--- a/embassy-util/src/fmt.rs
+++ b/embassy-futures/src/fmt.rs
diff --git a/embassy-futures/src/lib.rs b/embassy-futures/src/lib.rs
new file mode 100644
index 000000000..48c9c8574
--- /dev/null
+++ b/embassy-futures/src/lib.rs
@@ -0,0 +1,12 @@
1#![no_std]
2#![doc = include_str!("../../README.md")]
3#![warn(missing_docs)]
4
5// This mod MUST go first, so that the others see its macros.
6pub(crate) mod fmt;
7
8mod select;
9mod yield_now;
10
11pub use select::*;
12pub use yield_now::*;
diff --git a/embassy-util/src/select.rs b/embassy-futures/src/select.rs
index 8cecb7fa0..8cecb7fa0 100644
--- a/embassy-util/src/select.rs
+++ b/embassy-futures/src/select.rs
diff --git a/embassy-util/src/yield_now.rs b/embassy-futures/src/yield_now.rs
index 1ebecb916..1ebecb916 100644
--- a/embassy-util/src/yield_now.rs
+++ b/embassy-futures/src/yield_now.rs
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml
index c7435ab3e..9d5e7aed2 100644
--- a/embassy-lora/Cargo.toml
+++ b/embassy-lora/Cargo.toml
@@ -25,7 +25,7 @@ defmt = { version = "0.3", optional = true }
25log = { version = "0.4.14", optional = true } 25log = { version = "0.4.14", optional = true }
26 26
27embassy-time = { version = "0.1.0", path = "../embassy-time" } 27embassy-time = { version = "0.1.0", path = "../embassy-time" }
28embassy-util = { version = "0.1.0", path = "../embassy-util" } 28embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
29embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } 29embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
30embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" } 30embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" }
31embedded-hal-async = { version = "0.1.0-alpha.1" } 31embedded-hal-async = { version = "0.1.0-alpha.1" }
diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs
index 4a4c5cfb7..7822d0153 100644
--- a/embassy-lora/src/stm32wl/mod.rs
+++ b/embassy-lora/src/stm32wl/mod.rs
@@ -12,7 +12,7 @@ use embassy_stm32::subghz::{
12 Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams, 12 Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
13}; 13};
14use embassy_stm32::Peripheral; 14use embassy_stm32::Peripheral;
15use embassy_util::channel::signal::Signal; 15use embassy_sync::signal::Signal;
16use lorawan_device::async_device::radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig}; 16use lorawan_device::async_device::radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig};
17use lorawan_device::async_device::Timings; 17use lorawan_device::async_device::Timings;
18 18
diff --git a/embassy-macros/src/macros/cortex_m_interrupt_take.rs b/embassy-macros/src/macros/cortex_m_interrupt_take.rs
index 9e40a56f1..f6e41bcb4 100644
--- a/embassy-macros/src/macros/cortex_m_interrupt_take.rs
+++ b/embassy-macros/src/macros/cortex_m_interrupt_take.rs
@@ -19,7 +19,13 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
19 let func = HANDLER.func.load(interrupt::_export::atomic::Ordering::Relaxed); 19 let func = HANDLER.func.load(interrupt::_export::atomic::Ordering::Relaxed);
20 let ctx = HANDLER.ctx.load(interrupt::_export::atomic::Ordering::Relaxed); 20 let ctx = HANDLER.ctx.load(interrupt::_export::atomic::Ordering::Relaxed);
21 let func: fn(*mut ()) = ::core::mem::transmute(func); 21 let func: fn(*mut ()) = ::core::mem::transmute(func);
22 func(ctx) 22 ::embassy_executor::rtos_trace_interrupt! {
23 ::embassy_executor::export::trace::isr_enter();
24 }
25 func(ctx);
26 ::embassy_executor::rtos_trace_interrupt! {
27 ::embassy_executor::export::trace::isr_exit();
28 }
23 } 29 }
24 30
25 static TAKEN: interrupt::_export::atomic::AtomicBool = interrupt::_export::atomic::AtomicBool::new(false); 31 static TAKEN: interrupt::_export::atomic::AtomicBool = interrupt::_export::atomic::AtomicBool::new(false);
diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs
index 52987d7d2..afe9bd3e2 100644
--- a/embassy-macros/src/macros/main.rs
+++ b/embassy-macros/src/macros/main.rs
@@ -34,8 +34,8 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
34 let main = quote! { 34 let main = quote! {
35 #[wasm_bindgen::prelude::wasm_bindgen(start)] 35 #[wasm_bindgen::prelude::wasm_bindgen(start)]
36 pub fn main() -> Result<(), wasm_bindgen::JsValue> { 36 pub fn main() -> Result<(), wasm_bindgen::JsValue> {
37 static EXECUTOR: ::embassy_util::Forever<::embassy_executor::Executor> = ::embassy_util::Forever::new(); 37 static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new();
38 let executor = EXECUTOR.put(::embassy_executor::Executor::new()); 38 let executor = EXECUTOR.init(::embassy_executor::Executor::new());
39 39
40 executor.start(|spawner| { 40 executor.start(|spawner| {
41 spawner.spawn(__embassy_main(spawner)).unwrap(); 41 spawner.spawn(__embassy_main(spawner)).unwrap();
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 9f9bb2261..2143f36d3 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -38,7 +38,7 @@ defmt = { version = "0.3", optional = true }
38log = { version = "0.4.14", optional = true } 38log = { version = "0.4.14", optional = true }
39 39
40embassy-time = { version = "0.1.0", path = "../embassy-time" } 40embassy-time = { version = "0.1.0", path = "../embassy-time" }
41embassy-util = { version = "0.1.0", path = "../embassy-util" } 41embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
42embedded-io = { version = "0.3.0", features = [ "async" ] } 42embedded-io = { version = "0.3.0", features = [ "async" ] }
43 43
44managed = { version = "0.8.0", default-features = false, features = [ "map" ] } 44managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs
index 4b6a7ae2a..8d2dd4bca 100644
--- a/embassy-net/src/stack.rs
+++ b/embassy-net/src/stack.rs
@@ -2,8 +2,8 @@ use core::cell::UnsafeCell;
2use core::future::Future; 2use core::future::Future;
3use core::task::{Context, Poll}; 3use core::task::{Context, Poll};
4 4
5use embassy_sync::waitqueue::WakerRegistration;
5use embassy_time::{Instant, Timer}; 6use embassy_time::{Instant, Timer};
6use embassy_util::waitqueue::WakerRegistration;
7use futures::future::poll_fn; 7use futures::future::poll_fn;
8use futures::pin_mut; 8use futures::pin_mut;
9use heapless::Vec; 9use heapless::Vec;
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 0ef7f5bbd..186c73a58 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -18,7 +18,7 @@ flavors = [
18 18
19time = ["dep:embassy-time"] 19time = ["dep:embassy-time"]
20 20
21defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-util/defmt", "embassy-usb?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"] 21defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-sync/defmt", "embassy-usb?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"]
22 22
23# Enable nightly-only features 23# Enable nightly-only features
24nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io", "embassy-embedded-hal/nightly"] 24nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io", "embassy-embedded-hal/nightly"]
@@ -66,7 +66,7 @@ _gpio-p1 = []
66[dependencies] 66[dependencies]
67embassy-executor = { version = "0.1.0", path = "../embassy-executor", optional = true } 67embassy-executor = { version = "0.1.0", path = "../embassy-executor", optional = true }
68embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true } 68embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
69embassy-util = { version = "0.1.0", path = "../embassy-util" } 69embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
70embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]} 70embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
71embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } 71embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
72embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 72embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 21ff1d73b..62af544ae 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -21,7 +21,7 @@ use core::task::Poll;
21use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 21use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
22use embassy_hal_common::ring_buffer::RingBuffer; 22use embassy_hal_common::ring_buffer::RingBuffer;
23use embassy_hal_common::{into_ref, PeripheralRef}; 23use embassy_hal_common::{into_ref, PeripheralRef};
24use embassy_util::waitqueue::WakerRegistration; 24use embassy_sync::waitqueue::WakerRegistration;
25use futures::future::poll_fn; 25use futures::future::poll_fn;
26// Re-export SVD variants to allow user to directly set values 26// Re-export SVD variants to allow user to directly set values
27pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 27pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
@@ -45,8 +45,10 @@ enum TxState {
45 Transmitting(usize), 45 Transmitting(usize),
46} 46}
47 47
48/// A type for storing the state of the UARTE peripheral that can be stored in a static.
48pub struct State<'d, U: UarteInstance, T: TimerInstance>(StateStorage<StateInner<'d, U, T>>); 49pub struct State<'d, U: UarteInstance, T: TimerInstance>(StateStorage<StateInner<'d, U, T>>);
49impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { 50impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
51 /// Create an instance for storing UARTE peripheral state.
50 pub fn new() -> Self { 52 pub fn new() -> Self {
51 Self(StateStorage::new()) 53 Self(StateStorage::new())
52 } 54 }
@@ -75,6 +77,12 @@ pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
75impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} 77impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {}
76 78
77impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { 79impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
80 /// Create a new instance of a BufferedUarte.
81 ///
82 /// See the [module documentation](crate::buffered_uarte) for more details about the intended use.
83 ///
84 /// The BufferedUarte uses the provided state to store the buffers and peripheral state. The timer and ppi channels are used to 'emulate' idle line detection so that read operations
85 /// can return early if there is no data to receive.
78 pub fn new( 86 pub fn new(
79 state: &'d mut State<'d, U, T>, 87 state: &'d mut State<'d, U, T>,
80 peri: impl Peripheral<P = U> + 'd, 88 peri: impl Peripheral<P = U> + 'd,
@@ -178,6 +186,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
178 } 186 }
179 } 187 }
180 188
189 /// Adjust the baud rate to the provided value.
181 pub fn set_baudrate(&mut self, baudrate: Baudrate) { 190 pub fn set_baudrate(&mut self, baudrate: Baudrate) {
182 self.inner.with(|state| { 191 self.inner.with(|state| {
183 let r = U::regs(); 192 let r = U::regs();
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index a61ff6aa5..924629908 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -1,3 +1,4 @@
1//! General purpose input/output for nRF.
1#![macro_use] 2#![macro_use]
2 3
3use core::convert::Infallible; 4use core::convert::Infallible;
@@ -26,8 +27,11 @@ pub enum Port {
26#[derive(Debug, Eq, PartialEq)] 27#[derive(Debug, Eq, PartialEq)]
27#[cfg_attr(feature = "defmt", derive(defmt::Format))] 28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
28pub enum Pull { 29pub enum Pull {
30 /// No pull.
29 None, 31 None,
32 /// Internal pull-up resistor.
30 Up, 33 Up,
34 /// Internal pull-down resistor.
31 Down, 35 Down,
32} 36}
33 37
@@ -37,6 +41,7 @@ pub struct Input<'d, T: Pin> {
37} 41}
38 42
39impl<'d, T: Pin> Input<'d, T> { 43impl<'d, T: Pin> Input<'d, T> {
44 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
40 #[inline] 45 #[inline]
41 pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self { 46 pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
42 let mut pin = Flex::new(pin); 47 let mut pin = Flex::new(pin);
@@ -45,11 +50,13 @@ impl<'d, T: Pin> Input<'d, T> {
45 Self { pin } 50 Self { pin }
46 } 51 }
47 52
53 /// Test if current pin level is high.
48 #[inline] 54 #[inline]
49 pub fn is_high(&self) -> bool { 55 pub fn is_high(&self) -> bool {
50 self.pin.is_high() 56 self.pin.is_high()
51 } 57 }
52 58
59 /// Test if current pin level is low.
53 #[inline] 60 #[inline]
54 pub fn is_low(&self) -> bool { 61 pub fn is_low(&self) -> bool {
55 self.pin.is_low() 62 self.pin.is_low()
@@ -66,7 +73,9 @@ impl<'d, T: Pin> Input<'d, T> {
66#[derive(Debug, Eq, PartialEq)] 73#[derive(Debug, Eq, PartialEq)]
67#[cfg_attr(feature = "defmt", derive(defmt::Format))] 74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
68pub enum Level { 75pub enum Level {
76 /// Logical low.
69 Low, 77 Low,
78 /// Logical high.
70 High, 79 High,
71} 80}
72 81
@@ -88,6 +97,7 @@ impl Into<bool> for Level {
88 } 97 }
89} 98}
90 99
100/// Drive strength settings for an output pin.
91// These numbers match DRIVE_A exactly so hopefully the compiler will unify them. 101// These numbers match DRIVE_A exactly so hopefully the compiler will unify them.
92#[derive(Clone, Copy, Debug, PartialEq)] 102#[derive(Clone, Copy, Debug, PartialEq)]
93#[cfg_attr(feature = "defmt", derive(defmt::Format))] 103#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -117,6 +127,7 @@ pub struct Output<'d, T: Pin> {
117} 127}
118 128
119impl<'d, T: Pin> Output<'d, T> { 129impl<'d, T: Pin> Output<'d, T> {
130 /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
120 #[inline] 131 #[inline]
121 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self { 132 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
122 let mut pin = Flex::new(pin); 133 let mut pin = Flex::new(pin);
@@ -264,11 +275,13 @@ impl<'d, T: Pin> Flex<'d, T> {
264 self.pin.conf().reset(); 275 self.pin.conf().reset();
265 } 276 }
266 277
278 /// Test if current pin level is high.
267 #[inline] 279 #[inline]
268 pub fn is_high(&self) -> bool { 280 pub fn is_high(&self) -> bool {
269 !self.is_low() 281 !self.is_low()
270 } 282 }
271 283
284 /// Test if current pin level is low.
272 #[inline] 285 #[inline]
273 pub fn is_low(&self) -> bool { 286 pub fn is_low(&self) -> bool {
274 self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0 287 self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0
@@ -374,6 +387,7 @@ pub(crate) mod sealed {
374 } 387 }
375} 388}
376 389
390/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
377pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static { 391pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
378 /// Number of the pin within the port (0..31) 392 /// Number of the pin within the port (0..31)
379 #[inline] 393 #[inline]
@@ -392,6 +406,7 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
392 } 406 }
393 } 407 }
394 408
409 /// Peripheral port register value
395 #[inline] 410 #[inline]
396 fn psel_bits(&self) -> u32 { 411 fn psel_bits(&self) -> u32 {
397 self.pin_port() as u32 412 self.pin_port() as u32
@@ -406,12 +421,16 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
406 } 421 }
407} 422}
408 423
409// Type-erased GPIO pin 424/// Type-erased GPIO pin
410pub struct AnyPin { 425pub struct AnyPin {
411 pin_port: u8, 426 pin_port: u8,
412} 427}
413 428
414impl AnyPin { 429impl AnyPin {
430 /// Create an [AnyPin] for a specific pin.
431 ///
432 /// # Safety
433 /// - `pin_port` should not in use by another driver.
415 #[inline] 434 #[inline]
416 pub unsafe fn steal(pin_port: u8) -> Self { 435 pub unsafe fn steal(pin_port: u8) -> Self {
417 Self { pin_port } 436 Self { pin_port }
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index cf49b0db0..b52035705 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -3,7 +3,7 @@ use core::future::Future;
3use core::task::{Context, Poll}; 3use core::task::{Context, Poll};
4 4
5use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef}; 5use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef};
6use embassy_util::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7use futures::future::poll_fn; 7use futures::future::poll_fn;
8 8
9use crate::gpio::sealed::Pin as _; 9use crate::gpio::sealed::Pin as _;
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs
index cd6100339..6f66f7a78 100644
--- a/embassy-nrf/src/nvmc.rs
+++ b/embassy-nrf/src/nvmc.rs
@@ -1,4 +1,4 @@
1//! Nvmcerature sensor interface. 1//! Non-Volatile Memory Controller (NVMC) module.
2 2
3use core::{ptr, slice}; 3use core::{ptr, slice};
4 4
@@ -10,13 +10,19 @@ use embedded_storage::nor_flash::{
10use crate::peripherals::NVMC; 10use crate::peripherals::NVMC;
11use crate::{pac, Peripheral}; 11use crate::{pac, Peripheral};
12 12
13/// Erase size of NVMC flash in bytes.
13pub const PAGE_SIZE: usize = 4096; 14pub const PAGE_SIZE: usize = 4096;
15
16/// Size of NVMC flash in bytes.
14pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE; 17pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE;
15 18
19/// Error type for NVMC operations.
16#[derive(Debug, Copy, Clone, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "defmt", derive(defmt::Format))] 21#[cfg_attr(feature = "defmt", derive(defmt::Format))]
18pub enum Error { 22pub enum Error {
23 /// Opration using a location not in flash.
19 OutOfBounds, 24 OutOfBounds,
25 /// Unaligned operation or using unaligned buffers.
20 Unaligned, 26 Unaligned,
21} 27}
22 28
@@ -29,11 +35,13 @@ impl NorFlashError for Error {
29 } 35 }
30} 36}
31 37
38/// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits.
32pub struct Nvmc<'d> { 39pub struct Nvmc<'d> {
33 _p: PeripheralRef<'d, NVMC>, 40 _p: PeripheralRef<'d, NVMC>,
34} 41}
35 42
36impl<'d> Nvmc<'d> { 43impl<'d> Nvmc<'d> {
44 /// Create Nvmc driver.
37 pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self { 45 pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
38 into_ref!(_p); 46 into_ref!(_p);
39 Self { _p } 47 Self { _p }
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index 23ab011bc..1fdd35717 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -26,6 +26,7 @@ mod dppi;
26#[cfg(feature = "_ppi")] 26#[cfg(feature = "_ppi")]
27mod ppi; 27mod ppi;
28 28
29/// An instance of the Programmable peripheral interconnect on nRF devices.
29pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { 30pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
30 ch: PeripheralRef<'d, C>, 31 ch: PeripheralRef<'d, C>,
31 #[cfg(feature = "_dppi")] 32 #[cfg(feature = "_dppi")]
@@ -48,6 +49,7 @@ impl Task {
48 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) 49 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
49 } 50 }
50 51
52 /// Address off subscription register for this task.
51 pub fn subscribe_reg(&self) -> *mut u32 { 53 pub fn subscribe_reg(&self) -> *mut u32 {
52 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } 54 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
53 } 55 }
@@ -69,6 +71,7 @@ impl Event {
69 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }) 71 Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
70 } 72 }
71 73
74 /// Address of publish register for this event.
72 pub fn publish_reg(&self) -> *mut u32 { 75 pub fn publish_reg(&self) -> *mut u32 {
73 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) } 76 unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
74 } 77 }
@@ -87,21 +90,29 @@ pub(crate) mod sealed {
87 pub trait Group {} 90 pub trait Group {}
88} 91}
89 92
93/// Interface for PPI channels.
90pub trait Channel: sealed::Channel + Peripheral<P = Self> + Sized { 94pub trait Channel: sealed::Channel + Peripheral<P = Self> + Sized {
91 /// Returns the number of the channel 95 /// Returns the number of the channel
92 fn number(&self) -> usize; 96 fn number(&self) -> usize;
93} 97}
94 98
99/// Interface for PPI channels that can be configured.
95pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> { 100pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {
101 /// Convert into a type erased configurable channel.
96 fn degrade(self) -> AnyConfigurableChannel; 102 fn degrade(self) -> AnyConfigurableChannel;
97} 103}
98 104
105/// Interface for PPI channels that cannot be configured.
99pub trait StaticChannel: Channel + Into<AnyStaticChannel> { 106pub trait StaticChannel: Channel + Into<AnyStaticChannel> {
107 /// Convert into a type erased static channel.
100 fn degrade(self) -> AnyStaticChannel; 108 fn degrade(self) -> AnyStaticChannel;
101} 109}
102 110
111/// Interface for a group of PPI channels.
103pub trait Group: sealed::Group + Sized { 112pub trait Group: sealed::Group + Sized {
113 /// Returns the number of the group.
104 fn number(&self) -> usize; 114 fn number(&self) -> usize;
115 /// Convert into a type erased group.
105 fn degrade(self) -> AnyGroup { 116 fn degrade(self) -> AnyGroup {
106 AnyGroup { 117 AnyGroup {
107 number: self.number() as u8, 118 number: self.number() as u8,
@@ -196,6 +207,7 @@ macro_rules! impl_ppi_channel {
196// ====================== 207// ======================
197// groups 208// groups
198 209
210/// A type erased PPI group.
199pub struct AnyGroup { 211pub struct AnyGroup {
200 number: u8, 212 number: u8,
201} 213}
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
index 450a290a2..19abc4e18 100644
--- a/embassy-nrf/src/ppi/ppi.rs
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -20,6 +20,7 @@ fn regs() -> &'static pac::ppi::RegisterBlock {
20 20
21#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task 21#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
22impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { 22impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
23 /// Configure PPI channel to trigger `task`.
23 pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self { 24 pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self {
24 into_ref!(ch); 25 into_ref!(ch);
25 26
@@ -32,6 +33,7 @@ impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
32} 33}
33 34
34impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { 35impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
36 /// Configure PPI channel to trigger `task` on `event`.
35 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self { 37 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
36 into_ref!(ch); 38 into_ref!(ch);
37 39
@@ -46,6 +48,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
46 48
47#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task 49#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
48impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { 50impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
51 /// Configure PPI channel to trigger `task1` and `task2` on `event`.
49 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self { 52 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
50 into_ref!(ch); 53 into_ref!(ch);
51 54
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index 83f2916b9..762e09715 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -3,7 +3,7 @@
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_common::{into_ref, PeripheralRef};
6use embassy_util::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7use futures::future::poll_fn; 7use futures::future::poll_fn;
8 8
9use crate::gpio::sealed::Pin as _; 9use crate::gpio::sealed::Pin as _;
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 6d7ebb4b1..c97cb1656 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -526,7 +526,7 @@ cfg_if::cfg_if! {
526} 526}
527 527
528pub(crate) mod sealed { 528pub(crate) mod sealed {
529 use embassy_util::waitqueue::AtomicWaker; 529 use embassy_sync::waitqueue::AtomicWaker;
530 530
531 use super::*; 531 use super::*;
532 532
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 7aad561b6..42da51d0f 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
4 4
5use embassy_hal_common::drop::OnDrop; 5use embassy_hal_common::drop::OnDrop;
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_common::{into_ref, PeripheralRef};
7use embassy_util::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use futures::future::poll_fn; 8use futures::future::poll_fn;
9 9
10use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index f2ef46d8d..7dc66349e 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -4,7 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 6use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
7use embassy_util::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use futures::future::poll_fn; 8use futures::future::poll_fn;
9use pac::{saadc, SAADC}; 9use pac::{saadc, SAADC};
10use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; 10use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 57c0c14c7..be2fc02fc 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -363,7 +363,7 @@ impl<'d, T: Instance> Drop for Spim<'d, T> {
363} 363}
364 364
365pub(crate) mod sealed { 365pub(crate) mod sealed {
366 use embassy_util::waitqueue::AtomicWaker; 366 use embassy_sync::waitqueue::AtomicWaker;
367 367
368 use super::*; 368 use super::*;
369 369
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
index 1491e4268..d520fd686 100644
--- a/embassy-nrf/src/temp.rs
+++ b/embassy-nrf/src/temp.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
4 4
5use embassy_hal_common::drop::OnDrop; 5use embassy_hal_common::drop::OnDrop;
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_common::{into_ref, PeripheralRef};
7use embassy_util::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use fixed::types::I30F2; 8use fixed::types::I30F2;
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs
index b961d65a0..c32a44637 100644
--- a/embassy-nrf/src/time_driver.rs
+++ b/embassy-nrf/src/time_driver.rs
@@ -3,9 +3,9 @@ use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
3use core::{mem, ptr}; 3use core::{mem, ptr};
4 4
5use critical_section::CriticalSection; 5use critical_section::CriticalSection;
6use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
6use embassy_time::driver::{AlarmHandle, Driver}; 8use embassy_time::driver::{AlarmHandle, Driver};
7use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
8use embassy_util::blocking_mutex::CriticalSectionMutex as Mutex;
9 9
10use crate::interrupt::{Interrupt, InterruptExt}; 10use crate::interrupt::{Interrupt, InterruptExt};
11use crate::{interrupt, pac}; 11use crate::{interrupt, pac};
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index b3b613db2..3de5a8962 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5 5
6use embassy_hal_common::drop::OnDrop; 6use embassy_hal_common::drop::OnDrop;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_common::{into_ref, PeripheralRef};
8use embassy_util::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
11use crate::interrupt::{Interrupt, InterruptExt}; 11use crate::interrupt::{Interrupt, InterruptExt};
@@ -40,8 +40,8 @@ macro_rules! impl_timer {
40 fn regs() -> &'static pac::timer0::RegisterBlock { 40 fn regs() -> &'static pac::timer0::RegisterBlock {
41 unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } 41 unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
42 } 42 }
43 fn waker(n: usize) -> &'static ::embassy_util::waitqueue::AtomicWaker { 43 fn waker(n: usize) -> &'static ::embassy_sync::waitqueue::AtomicWaker {
44 use ::embassy_util::waitqueue::AtomicWaker; 44 use ::embassy_sync::waitqueue::AtomicWaker;
45 const NEW_AW: AtomicWaker = AtomicWaker::new(); 45 const NEW_AW: AtomicWaker = AtomicWaker::new();
46 static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs]; 46 static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs];
47 &WAKERS[n] 47 &WAKERS[n]
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 9587d1f40..850f6d0fa 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -13,9 +13,9 @@ use core::task::Poll;
13 13
14use embassy_embedded_hal::SetConfig; 14use embassy_embedded_hal::SetConfig;
15use embassy_hal_common::{into_ref, PeripheralRef}; 15use embassy_hal_common::{into_ref, PeripheralRef};
16use embassy_sync::waitqueue::AtomicWaker;
16#[cfg(feature = "time")] 17#[cfg(feature = "time")]
17use embassy_time::{Duration, Instant}; 18use embassy_time::{Duration, Instant};
18use embassy_util::waitqueue::AtomicWaker;
19use futures::future::poll_fn; 19use futures::future::poll_fn;
20 20
21use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 21use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 0d24cf65f..4347ea558 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -932,7 +932,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> {
932pub(crate) mod sealed { 932pub(crate) mod sealed {
933 use core::sync::atomic::AtomicU8; 933 use core::sync::atomic::AtomicU8;
934 934
935 use embassy_util::waitqueue::AtomicWaker; 935 use embassy_sync::waitqueue::AtomicWaker;
936 936
937 use super::*; 937 use super::*;
938 938
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index 509ee313e..688326e9c 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -7,10 +7,10 @@ use core::task::Poll;
7 7
8use cortex_m::peripheral::NVIC; 8use cortex_m::peripheral::NVIC;
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_common::{into_ref, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker;
10pub use embassy_usb; 11pub use embassy_usb;
11use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; 12use embassy_usb::driver::{self, EndpointError, Event, Unsupported};
12use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; 13use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
13use embassy_util::waitqueue::AtomicWaker;
14use futures::future::poll_fn; 14use futures::future::poll_fn;
15use futures::Future; 15use futures::Future;
16use pac::usbd::RegisterBlock; 16use pac::usbd::RegisterBlock;
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index af7c8ee6e..cfd95b7b4 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -27,10 +27,10 @@ nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "
27unstable-traits = ["embedded-hal-1"] 27unstable-traits = ["embedded-hal-1"]
28 28
29[dependencies] 29[dependencies]
30embassy-util = { version = "0.1.0", path = "../embassy-util" } 30embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
31embassy-executor = { version = "0.1.0", path = "../embassy-executor" } 31embassy-executor = { version = "0.1.0", path = "../embassy-executor" }
32embassy-time = { version = "0.1.0", path = "../embassy-time", features = [ "tick-1mhz" ] } 32embassy-time = { version = "0.1.0", path = "../embassy-time", features = [ "tick-1mhz" ] }
33embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]} 33embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-2"]}
34embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } 34embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
35embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 35embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
36atomic-polyfill = "1.0.1" 36atomic-polyfill = "1.0.1"
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index f9fa8378b..428855c7f 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -5,7 +5,7 @@ use core::task::{Context, Poll};
5 5
6use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; 6use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
7use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 7use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
8use embassy_util::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::pac::common::{Reg, RW}; 10use crate::pac::common::{Reg, RW};
11use crate::pac::SIO; 11use crate::pac::SIO;
@@ -189,7 +189,7 @@ impl<'d, T: Pin> InputFuture<'d, T> {
189 unsafe { 189 unsafe {
190 let irq = interrupt::IO_IRQ_BANK0::steal(); 190 let irq = interrupt::IO_IRQ_BANK0::steal();
191 irq.disable(); 191 irq.disable();
192 irq.set_priority(interrupt::Priority::P6); 192 irq.set_priority(interrupt::Priority::P3);
193 193
194 // Each INTR register is divided into 8 groups, one group for each 194 // Each INTR register is divided into 8 groups, one group for each
195 // pin, and each group consists of LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, 195 // pin, and each group consists of LEVEL_LOW, LEVEL_HIGH, EDGE_LOW,
diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/timer.rs
index 5bc1f66c8..5215c0c0f 100644
--- a/embassy-rp/src/timer.rs
+++ b/embassy-rp/src/timer.rs
@@ -2,9 +2,9 @@ use core::cell::Cell;
2 2
3use atomic_polyfill::{AtomicU8, Ordering}; 3use atomic_polyfill::{AtomicU8, Ordering};
4use critical_section::CriticalSection; 4use critical_section::CriticalSection;
5use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
6use embassy_sync::blocking_mutex::Mutex;
5use embassy_time::driver::{AlarmHandle, Driver}; 7use embassy_time::driver::{AlarmHandle, Driver};
6use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_util::blocking_mutex::Mutex;
8 8
9use crate::interrupt::{Interrupt, InterruptExt}; 9use crate::interrupt::{Interrupt, InterruptExt};
10use crate::{interrupt, pac}; 10use crate::{interrupt, pac};
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index c47ea0bca..7a8e5c59b 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -31,7 +31,7 @@ flavors = [
31] 31]
32 32
33[dependencies] 33[dependencies]
34embassy-util = { version = "0.1.0", path = "../embassy-util" } 34embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
35embassy-executor = { version = "0.1.0", path = "../embassy-executor" } 35embassy-executor = { version = "0.1.0", path = "../embassy-executor" }
36embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true } 36embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
37embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]} 37embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]}
@@ -72,7 +72,7 @@ quote = "1.0.15"
72stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]} 72stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]}
73 73
74[features] 74[features]
75defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-util/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embedded-io?/defmt", "embassy-usb?/defmt"] 75defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embedded-io?/defmt", "embassy-usb?/defmt"]
76sdmmc-rs = ["embedded-sdmmc"] 76sdmmc-rs = ["embedded-sdmmc"]
77net = ["embassy-net" ] 77net = ["embassy-net" ]
78memory-x = ["stm32-metapac/memory-x"] 78memory-x = ["stm32-metapac/memory-x"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index c892007a3..a4709f4ca 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -244,11 +244,11 @@ fn main() {
244 (("usart", "CTS"), quote!(crate::usart::CtsPin)), 244 (("usart", "CTS"), quote!(crate::usart::CtsPin)),
245 (("usart", "RTS"), quote!(crate::usart::RtsPin)), 245 (("usart", "RTS"), quote!(crate::usart::RtsPin)),
246 (("usart", "CK"), quote!(crate::usart::CkPin)), 246 (("usart", "CK"), quote!(crate::usart::CkPin)),
247 (("usart", "TX"), quote!(crate::usart::TxPin)), 247 (("lpuart", "TX"), quote!(crate::usart::TxPin)),
248 (("usart", "RX"), quote!(crate::usart::RxPin)), 248 (("lpuart", "RX"), quote!(crate::usart::RxPin)),
249 (("usart", "CTS"), quote!(crate::usart::CtsPin)), 249 (("lpuart", "CTS"), quote!(crate::usart::CtsPin)),
250 (("usart", "RTS"), quote!(crate::usart::RtsPin)), 250 (("lpuart", "RTS"), quote!(crate::usart::RtsPin)),
251 (("usart", "CK"), quote!(crate::usart::CkPin)), 251 (("lpuart", "CK"), quote!(crate::usart::CkPin)),
252 (("spi", "SCK"), quote!(crate::spi::SckPin)), 252 (("spi", "SCK"), quote!(crate::spi::SckPin)),
253 (("spi", "MOSI"), quote!(crate::spi::MosiPin)), 253 (("spi", "MOSI"), quote!(crate::spi::MosiPin)),
254 (("spi", "MISO"), quote!(crate::spi::MisoPin)), 254 (("spi", "MISO"), quote!(crate::spi::MisoPin)),
@@ -497,6 +497,8 @@ fn main() {
497 // (kind, signal) => trait 497 // (kind, signal) => trait
498 (("usart", "RX"), quote!(crate::usart::RxDma)), 498 (("usart", "RX"), quote!(crate::usart::RxDma)),
499 (("usart", "TX"), quote!(crate::usart::TxDma)), 499 (("usart", "TX"), quote!(crate::usart::TxDma)),
500 (("lpuart", "RX"), quote!(crate::usart::RxDma)),
501 (("lpuart", "TX"), quote!(crate::usart::TxDma)),
500 (("spi", "RX"), quote!(crate::spi::RxDma)), 502 (("spi", "RX"), quote!(crate::spi::RxDma)),
501 (("spi", "TX"), quote!(crate::spi::TxDma)), 503 (("spi", "TX"), quote!(crate::spi::TxDma)),
502 (("i2c", "RX"), quote!(crate::i2c::RxDma)), 504 (("i2c", "RX"), quote!(crate::i2c::RxDma)),
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index bbb9a12cb..fb9dc9d08 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -1,7 +1,7 @@
1use core::task::Poll; 1use core::task::Poll;
2 2
3use embassy_hal_common::{into_ref, PeripheralRef}; 3use embassy_hal_common::{into_ref, PeripheralRef};
4use embassy_util::waitqueue::AtomicWaker; 4use embassy_sync::waitqueue::AtomicWaker;
5use futures::future::poll_fn; 5use futures::future::poll_fn;
6 6
7use crate::gpio::sealed::AFType; 7use crate::gpio::sealed::AFType;
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index bd2cd5b57..674255ddc 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -3,7 +3,7 @@
3use core::sync::atomic::{fence, Ordering}; 3use core::sync::atomic::{fence, Ordering};
4use core::task::Waker; 4use core::task::Waker;
5 5
6use embassy_util::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7 7
8use super::{TransferOptions, Word, WordSize}; 8use super::{TransferOptions, Word, WordSize};
9use crate::_generated::BDMA_CHANNEL_COUNT; 9use crate::_generated::BDMA_CHANNEL_COUNT;
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 0c66005c7..a45b8780b 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -1,7 +1,7 @@
1use core::sync::atomic::{fence, Ordering}; 1use core::sync::atomic::{fence, Ordering};
2use core::task::Waker; 2use core::task::Waker;
3 3
4use embassy_util::waitqueue::AtomicWaker; 4use embassy_sync::waitqueue::AtomicWaker;
5 5
6use super::{Burst, FlowControl, Request, TransferOptions, Word, WordSize}; 6use super::{Burst, FlowControl, Request, TransferOptions, Word, WordSize};
7use crate::_generated::DMA_CHANNEL_COUNT; 7use crate::_generated::DMA_CHANNEL_COUNT;
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index 1aea6c65d..bde8c3ef3 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -1,7 +1,7 @@
1use core::sync::atomic::{fence, Ordering}; 1use core::sync::atomic::{fence, Ordering};
2use core::task::Waker; 2use core::task::Waker;
3 3
4use embassy_util::waitqueue::AtomicWaker; 4use embassy_sync::waitqueue::AtomicWaker;
5 5
6use super::{Request, TransferOptions, Word, WordSize}; 6use super::{Request, TransferOptions, Word, WordSize};
7use crate::_generated::GPDMA_CHANNEL_COUNT; 7use crate::_generated::GPDMA_CHANNEL_COUNT;
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index 37593914f..1ab0438ad 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -7,7 +7,7 @@ use core::task::Waker;
7use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 7use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
8use embassy_hal_common::{into_ref, PeripheralRef}; 8use embassy_hal_common::{into_ref, PeripheralRef};
9use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 9use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
10use embassy_util::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 12use crate::gpio::sealed::{AFType, Pin as __GpioPin};
13use crate::gpio::{AnyPin, Speed}; 13use crate::gpio::{AnyPin, Speed};
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 1bc1fb72e..d67c3c5e4 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -5,7 +5,7 @@ use core::task::Waker;
5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_common::{into_ref, PeripheralRef};
7use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 7use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
8use embassy_util::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::gpio::sealed::{AFType, Pin as _}; 10use crate::gpio::sealed::{AFType, Pin as _};
11use crate::gpio::{AnyPin, Speed}; 11use crate::gpio::{AnyPin, Speed};
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index ecb180bbe..935149b13 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy_hal_common::impl_peripheral; 6use embassy_hal_common::impl_peripheral;
7use embassy_util::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::gpio::{AnyPin, Input, Pin as GpioPin}; 9use crate::gpio::{AnyPin, Input, Pin as GpioPin};
10use crate::pac::exti::regs::Lines; 10use crate::pac::exti::regs::Lines;
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index b4303d3d4..07a3105da 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -5,7 +5,7 @@ use atomic_polyfill::{AtomicUsize, Ordering};
5use embassy_embedded_hal::SetConfig; 5use embassy_embedded_hal::SetConfig;
6use embassy_hal_common::drop::OnDrop; 6use embassy_hal_common::drop::OnDrop;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_common::{into_ref, PeripheralRef};
8use embassy_util::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
11use crate::dma::NoDma; 11use crate::dma::NoDma;
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 81e28f355..520f2ab9a 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -3,7 +3,7 @@
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_common::{into_ref, PeripheralRef};
6use embassy_util::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7use futures::future::poll_fn; 7use futures::future::poll_fn;
8use rand_core::{CryptoRng, RngCore}; 8use rand_core::{CryptoRng, RngCore};
9 9
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 3ad31ec87..67758c492 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5 5
6use embassy_hal_common::drop::OnDrop; 6use embassy_hal_common::drop::OnDrop;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_common::{into_ref, PeripheralRef};
8use embassy_util::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 10use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
11 11
@@ -1514,8 +1514,8 @@ foreach_peripheral!(
1514 INNER 1514 INNER
1515 } 1515 }
1516 1516
1517 fn state() -> &'static ::embassy_util::waitqueue::AtomicWaker { 1517 fn state() -> &'static ::embassy_sync::waitqueue::AtomicWaker {
1518 static WAKER: ::embassy_util::waitqueue::AtomicWaker = ::embassy_util::waitqueue::AtomicWaker::new(); 1518 static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new();
1519 &WAKER 1519 &WAKER
1520 } 1520 }
1521 } 1521 }
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 7f4723162..6989a43d3 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -4,10 +4,10 @@ use core::sync::atomic::{compiler_fence, Ordering};
4use core::{mem, ptr}; 4use core::{mem, ptr};
5 5
6use atomic_polyfill::{AtomicU32, AtomicU8}; 6use atomic_polyfill::{AtomicU32, AtomicU8};
7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
8use embassy_sync::blocking_mutex::Mutex;
7use embassy_time::driver::{AlarmHandle, Driver}; 9use embassy_time::driver::{AlarmHandle, Driver};
8use embassy_time::TICKS_PER_SECOND; 10use embassy_time::TICKS_PER_SECOND;
9use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
10use embassy_util::blocking_mutex::Mutex;
11use stm32_metapac::timer::regs; 11use stm32_metapac::timer::regs;
12 12
13use crate::interrupt::{CriticalSection, InterruptExt}; 13use crate::interrupt::{CriticalSection, InterruptExt};
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 0e8d0d682..a7fa43894 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -4,19 +4,19 @@ use core::task::Poll;
4use atomic_polyfill::{compiler_fence, Ordering}; 4use atomic_polyfill::{compiler_fence, Ordering};
5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
6use embassy_hal_common::ring_buffer::RingBuffer; 6use embassy_hal_common::ring_buffer::RingBuffer;
7use embassy_util::waitqueue::WakerRegistration; 7use embassy_sync::waitqueue::WakerRegistration;
8use futures::future::poll_fn; 8use futures::future::poll_fn;
9 9
10use super::*; 10use super::*;
11 11
12pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>); 12pub struct State<'d, T: BasicInstance>(StateStorage<StateInner<'d, T>>);
13impl<'d, T: Instance> State<'d, T> { 13impl<'d, T: BasicInstance> State<'d, T> {
14 pub fn new() -> Self { 14 pub fn new() -> Self {
15 Self(StateStorage::new()) 15 Self(StateStorage::new())
16 } 16 }
17} 17}
18 18
19struct StateInner<'d, T: Instance> { 19struct StateInner<'d, T: BasicInstance> {
20 phantom: PhantomData<&'d mut T>, 20 phantom: PhantomData<&'d mut T>,
21 21
22 rx_waker: WakerRegistration, 22 rx_waker: WakerRegistration,
@@ -26,16 +26,16 @@ struct StateInner<'d, T: Instance> {
26 tx: RingBuffer<'d>, 26 tx: RingBuffer<'d>,
27} 27}
28 28
29unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {} 29unsafe impl<'d, T: BasicInstance> Send for StateInner<'d, T> {}
30unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {} 30unsafe impl<'d, T: BasicInstance> Sync for StateInner<'d, T> {}
31 31
32pub struct BufferedUart<'d, T: Instance> { 32pub struct BufferedUart<'d, T: BasicInstance> {
33 inner: PeripheralMutex<'d, StateInner<'d, T>>, 33 inner: PeripheralMutex<'d, StateInner<'d, T>>,
34} 34}
35 35
36impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {} 36impl<'d, T: BasicInstance> Unpin for BufferedUart<'d, T> {}
37 37
38impl<'d, T: Instance> BufferedUart<'d, T> { 38impl<'d, T: BasicInstance> BufferedUart<'d, T> {
39 pub fn new( 39 pub fn new(
40 state: &'d mut State<'d, T>, 40 state: &'d mut State<'d, T>,
41 _uart: Uart<'d, T, NoDma, NoDma>, 41 _uart: Uart<'d, T, NoDma, NoDma>,
@@ -66,7 +66,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
66 } 66 }
67} 67}
68 68
69impl<'d, T: Instance> StateInner<'d, T> 69impl<'d, T: BasicInstance> StateInner<'d, T>
70where 70where
71 Self: 'd, 71 Self: 'd,
72{ 72{
@@ -135,7 +135,7 @@ where
135 } 135 }
136} 136}
137 137
138impl<'d, T: Instance> PeripheralState for StateInner<'d, T> 138impl<'d, T: BasicInstance> PeripheralState for StateInner<'d, T>
139where 139where
140 Self: 'd, 140 Self: 'd,
141{ 141{
@@ -152,11 +152,11 @@ impl embedded_io::Error for Error {
152 } 152 }
153} 153}
154 154
155impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> { 155impl<'d, T: BasicInstance> embedded_io::Io for BufferedUart<'d, T> {
156 type Error = Error; 156 type Error = Error;
157} 157}
158 158
159impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> { 159impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUart<'d, T> {
160 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> 160 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
161 where 161 where
162 Self: 'a; 162 Self: 'a;
@@ -194,7 +194,7 @@ impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> {
194 } 194 }
195} 195}
196 196
197impl<'d, T: Instance> embedded_io::asynch::BufRead for BufferedUart<'d, T> { 197impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T> {
198 type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> 198 type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>>
199 where 199 where
200 Self: 'a; 200 Self: 'a;
@@ -231,7 +231,7 @@ impl<'d, T: Instance> embedded_io::asynch::BufRead for BufferedUart<'d, T> {
231 } 231 }
232} 232}
233 233
234impl<'d, T: Instance> embedded_io::asynch::Write for BufferedUart<'d, T> { 234impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUart<'d, T> {
235 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> 235 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
236 where 236 where
237 Self: 'a; 237 Self: 'a;
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index ca75bab41..2ad85c675 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -6,9 +6,10 @@ use embassy_hal_common::{into_ref, PeripheralRef};
6 6
7use crate::dma::NoDma; 7use crate::dma::NoDma;
8use crate::gpio::sealed::AFType; 8use crate::gpio::sealed::AFType;
9use crate::interrupt::Interrupt; 9#[cfg(any(lpuart_v1, lpuart_v2))]
10use crate::pac::usart::{regs, vals}; 10use crate::pac::lpuart::{regs, vals, Lpuart as Regs};
11use crate::rcc::RccPeripheral; 11#[cfg(not(any(lpuart_v1, lpuart_v2)))]
12use crate::pac::usart::{regs, vals, Usart as Regs};
12use crate::{peripherals, Peripheral}; 13use crate::{peripherals, Peripheral};
13 14
14#[derive(Clone, Copy, PartialEq, Eq, Debug)] 15#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -71,22 +72,23 @@ pub enum Error {
71 Parity, 72 Parity,
72} 73}
73 74
74pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { 75pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> {
76 phantom: PhantomData<&'d mut T>,
75 tx: UartTx<'d, T, TxDma>, 77 tx: UartTx<'d, T, TxDma>,
76 rx: UartRx<'d, T, RxDma>, 78 rx: UartRx<'d, T, RxDma>,
77} 79}
78 80
79pub struct UartTx<'d, T: Instance, TxDma = NoDma> { 81pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> {
80 phantom: PhantomData<&'d mut T>, 82 phantom: PhantomData<&'d mut T>,
81 tx_dma: PeripheralRef<'d, TxDma>, 83 tx_dma: PeripheralRef<'d, TxDma>,
82} 84}
83 85
84pub struct UartRx<'d, T: Instance, RxDma = NoDma> { 86pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> {
85 phantom: PhantomData<&'d mut T>, 87 phantom: PhantomData<&'d mut T>,
86 rx_dma: PeripheralRef<'d, RxDma>, 88 rx_dma: PeripheralRef<'d, RxDma>,
87} 89}
88 90
89impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { 91impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> {
90 fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self { 92 fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self {
91 Self { 93 Self {
92 tx_dma, 94 tx_dma,
@@ -132,7 +134,7 @@ impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
132 } 134 }
133} 135}
134 136
135impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> { 137impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
136 fn new(rx_dma: PeripheralRef<'d, RxDma>) -> Self { 138 fn new(rx_dma: PeripheralRef<'d, RxDma>) -> Self {
137 Self { 139 Self {
138 rx_dma, 140 rx_dma,
@@ -187,7 +189,7 @@ impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
187 } 189 }
188} 190}
189 191
190impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { 192impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
191 pub fn new( 193 pub fn new(
192 _inner: impl Peripheral<P = T> + 'd, 194 _inner: impl Peripheral<P = T> + 'd,
193 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 195 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -203,7 +205,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
203 let pclk_freq = T::frequency(); 205 let pclk_freq = T::frequency();
204 206
205 // TODO: better calculation, including error checking and OVER8 if possible. 207 // TODO: better calculation, including error checking and OVER8 if possible.
206 let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate; 208 let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate * T::MULTIPLIER;
207 209
208 let r = T::regs(); 210 let r = T::regs();
209 211
@@ -235,6 +237,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
235 Self { 237 Self {
236 tx: UartTx::new(tx_dma), 238 tx: UartTx::new(tx_dma),
237 rx: UartRx::new(rx_dma), 239 rx: UartRx::new(rx_dma),
240 phantom: PhantomData {},
238 } 241 }
239 } 242 }
240 243
@@ -275,7 +278,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
275mod eh02 { 278mod eh02 {
276 use super::*; 279 use super::*;
277 280
278 impl<'d, T: Instance, RxDma> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, RxDma> { 281 impl<'d, T: BasicInstance, RxDma> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, RxDma> {
279 type Error = Error; 282 type Error = Error;
280 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 283 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
281 let r = T::regs(); 284 let r = T::regs();
@@ -302,7 +305,7 @@ mod eh02 {
302 } 305 }
303 } 306 }
304 307
305 impl<'d, T: Instance, TxDma> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, TxDma> { 308 impl<'d, T: BasicInstance, TxDma> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, TxDma> {
306 type Error = Error; 309 type Error = Error;
307 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 310 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
308 self.blocking_write(buffer) 311 self.blocking_write(buffer)
@@ -312,14 +315,14 @@ mod eh02 {
312 } 315 }
313 } 316 }
314 317
315 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> { 318 impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> {
316 type Error = Error; 319 type Error = Error;
317 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 320 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
318 embedded_hal_02::serial::Read::read(&mut self.rx) 321 embedded_hal_02::serial::Read::read(&mut self.rx)
319 } 322 }
320 } 323 }
321 324
322 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, TxDma, RxDma> { 325 impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, TxDma, RxDma> {
323 type Error = Error; 326 type Error = Error;
324 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 327 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
325 self.blocking_write(buffer) 328 self.blocking_write(buffer)
@@ -345,15 +348,15 @@ mod eh1 {
345 } 348 }
346 } 349 }
347 350
348 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_1::serial::ErrorType for Uart<'d, T, TxDma, RxDma> { 351 impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_1::serial::ErrorType for Uart<'d, T, TxDma, RxDma> {
349 type Error = Error; 352 type Error = Error;
350 } 353 }
351 354
352 impl<'d, T: Instance, TxDma> embedded_hal_1::serial::ErrorType for UartTx<'d, T, TxDma> { 355 impl<'d, T: BasicInstance, TxDma> embedded_hal_1::serial::ErrorType for UartTx<'d, T, TxDma> {
353 type Error = Error; 356 type Error = Error;
354 } 357 }
355 358
356 impl<'d, T: Instance, RxDma> embedded_hal_1::serial::ErrorType for UartRx<'d, T, RxDma> { 359 impl<'d, T: BasicInstance, RxDma> embedded_hal_1::serial::ErrorType for UartRx<'d, T, RxDma> {
357 type Error = Error; 360 type Error = Error;
358 } 361 }
359} 362}
@@ -362,7 +365,7 @@ cfg_if::cfg_if! {
362 if #[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "_todo_embedded_hal_serial"))] { 365 if #[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "_todo_embedded_hal_serial"))] {
363 use core::future::Future; 366 use core::future::Future;
364 367
365 impl<'d, T: Instance, TxDma> embedded_hal_async::serial::Write for UartTx<'d, T, TxDma> 368 impl<'d, T: BasicInstance, TxDma> embedded_hal_async::serial::Write for UartTx<'d, T, TxDma>
366 where 369 where
367 TxDma: crate::usart::TxDma<T>, 370 TxDma: crate::usart::TxDma<T>,
368 { 371 {
@@ -379,7 +382,7 @@ cfg_if::cfg_if! {
379 } 382 }
380 } 383 }
381 384
382 impl<'d, T: Instance, RxDma> embedded_hal_async::serial::Read for UartRx<'d, T, RxDma> 385 impl<'d, T: BasicInstance, RxDma> embedded_hal_async::serial::Read for UartRx<'d, T, RxDma>
383 where 386 where
384 RxDma: crate::usart::RxDma<T>, 387 RxDma: crate::usart::RxDma<T>,
385 { 388 {
@@ -390,7 +393,7 @@ cfg_if::cfg_if! {
390 } 393 }
391 } 394 }
392 395
393 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> 396 impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma>
394 where 397 where
395 TxDma: crate::usart::TxDma<T>, 398 TxDma: crate::usart::TxDma<T>,
396 { 399 {
@@ -407,7 +410,7 @@ cfg_if::cfg_if! {
407 } 410 }
408 } 411 }
409 412
410 impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma> 413 impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
411 where 414 where
412 RxDma: crate::usart::RxDma<T>, 415 RxDma: crate::usart::RxDma<T>,
413 { 416 {
@@ -442,60 +445,90 @@ fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Sr, crate::p
442 445
443#[cfg(usart_v1)] 446#[cfg(usart_v1)]
444#[allow(unused)] 447#[allow(unused)]
445unsafe fn clear_interrupt_flags(_r: crate::pac::usart::Usart, _sr: regs::Sr) { 448unsafe fn clear_interrupt_flags(_r: Regs, _sr: regs::Sr) {
446 // On v1 the flags are cleared implicitly by reads and writes to DR. 449 // On v1 the flags are cleared implicitly by reads and writes to DR.
447} 450}
448 451
449#[cfg(usart_v2)] 452#[cfg(usart_v2)]
450fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { 453fn tdr(r: Regs) -> *mut u8 {
451 r.tdr().ptr() as _ 454 r.tdr().ptr() as _
452} 455}
453 456
454#[cfg(usart_v2)] 457#[cfg(usart_v2)]
455fn rdr(r: crate::pac::usart::Usart) -> *mut u8 { 458fn rdr(r: Regs) -> *mut u8 {
456 r.rdr().ptr() as _ 459 r.rdr().ptr() as _
457} 460}
458 461
459#[cfg(usart_v2)] 462#[cfg(usart_v2)]
460fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Ixr, crate::pac::common::R> { 463fn sr(r: Regs) -> crate::pac::common::Reg<regs::Isr, crate::pac::common::R> {
461 r.isr() 464 r.isr()
462} 465}
463 466
464#[cfg(usart_v2)] 467#[cfg(usart_v2)]
465#[allow(unused)] 468#[allow(unused)]
466unsafe fn clear_interrupt_flags(r: crate::pac::usart::Usart, sr: regs::Ixr) { 469unsafe fn clear_interrupt_flags(r: Regs, sr: regs::Isr) {
467 r.icr().write(|w| *w = sr); 470 r.icr().write(|w| *w = regs::Icr(sr.0));
468} 471}
469 472
470pub(crate) mod sealed { 473pub(crate) mod sealed {
471 pub trait Instance { 474 use super::*;
472 fn regs() -> crate::pac::usart::Usart; 475
476 pub trait BasicInstance: crate::rcc::RccPeripheral {
477 const MULTIPLIER: u32;
478 type Interrupt: crate::interrupt::Interrupt;
479
480 fn regs() -> Regs;
473 } 481 }
474}
475 482
476pub trait Instance: sealed::Instance + RccPeripheral { 483 pub trait FullInstance: BasicInstance {
477 type Interrupt: Interrupt; 484 fn regs_uart() -> crate::pac::usart::Usart;
485 }
478} 486}
479 487
480pin_trait!(RxPin, Instance); 488pub trait BasicInstance: sealed::BasicInstance {}
481pin_trait!(TxPin, Instance); 489
482pin_trait!(CtsPin, Instance); 490pub trait FullInstance: sealed::FullInstance {}
483pin_trait!(RtsPin, Instance);
484pin_trait!(CkPin, Instance);
485 491
486dma_trait!(TxDma, Instance); 492pin_trait!(RxPin, BasicInstance);
487dma_trait!(RxDma, Instance); 493pin_trait!(TxPin, BasicInstance);
494pin_trait!(CtsPin, BasicInstance);
495pin_trait!(RtsPin, BasicInstance);
496pin_trait!(CkPin, BasicInstance);
497
498dma_trait!(TxDma, BasicInstance);
499dma_trait!(RxDma, BasicInstance);
500
501macro_rules! impl_lpuart {
502 ($inst:ident, $irq:ident, $mul:expr) => {
503 impl sealed::BasicInstance for crate::peripherals::$inst {
504 const MULTIPLIER: u32 = $mul;
505 type Interrupt = crate::interrupt::$irq;
506
507 fn regs() -> Regs {
508 Regs(crate::pac::$inst.0)
509 }
510 }
511
512 impl BasicInstance for peripherals::$inst {}
513 };
514}
488 515
489foreach_interrupt!( 516foreach_interrupt!(
517 ($inst:ident, lpuart, $block:ident, $signal_name:ident, $irq:ident) => {
518 impl_lpuart!($inst, $irq, 255);
519 };
520
490 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { 521 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
491 impl sealed::Instance for peripherals::$inst { 522 impl_lpuart!($inst, $irq, 1);
492 fn regs() -> crate::pac::usart::Usart { 523
524 impl sealed::FullInstance for peripherals::$inst {
525
526 fn regs_uart() -> crate::pac::usart::Usart {
493 crate::pac::$inst 527 crate::pac::$inst
494 } 528 }
495 } 529 }
496 530
497 impl Instance for peripherals::$inst { 531 impl FullInstance for peripherals::$inst {
498 type Interrupt = crate::interrupt::$irq;
499 } 532 }
500 }; 533 };
501); 534);
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 3861e42d0..db965824a 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -6,10 +6,10 @@ use core::task::Poll;
6 6
7use atomic_polyfill::{AtomicBool, AtomicU8}; 7use atomic_polyfill::{AtomicBool, AtomicU8};
8use embassy_hal_common::into_ref; 8use embassy_hal_common::into_ref;
9use embassy_sync::waitqueue::AtomicWaker;
9use embassy_time::{block_for, Duration}; 10use embassy_time::{block_for, Duration};
10use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported}; 11use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};
11use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; 12use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
12use embassy_util::waitqueue::AtomicWaker;
13use futures::future::poll_fn; 13use futures::future::poll_fn;
14use futures::Future; 14use futures::Future;
15use pac::common::{Reg, RW}; 15use pac::common::{Reg, RW};
diff --git a/embassy-util/Cargo.toml b/embassy-sync/Cargo.toml
index d4708d735..0d14bba55 100644
--- a/embassy-util/Cargo.toml
+++ b/embassy-sync/Cargo.toml
@@ -1,11 +1,11 @@
1[package] 1[package]
2name = "embassy-util" 2name = "embassy-sync"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5 5
6[package.metadata.embassy_docs] 6[package.metadata.embassy_docs]
7src_base = "https://github.com/embassy-rs/embassy/blob/embassy-util-v$VERSION/embassy-util/src/" 7src_base = "https://github.com/embassy-rs/embassy/blob/embassy-sync-v$VERSION/embassy-sync/src/"
8src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-util/src/" 8src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-sync/src/"
9features = ["nightly"] 9features = ["nightly"]
10target = "thumbv7em-none-eabi" 10target = "thumbv7em-none-eabi"
11 11
@@ -31,3 +31,4 @@ futures-util = { version = "0.3.17", features = [ "channel" ] }
31 31
32# Enable critical-section implementation for std, for tests 32# Enable critical-section implementation for std, for tests
33critical-section = { version = "1.1", features = ["std"] } 33critical-section = { version = "1.1", features = ["std"] }
34static_cell = "1.0"
diff --git a/embassy-util/build.rs b/embassy-sync/build.rs
index 6fe82b44f..6fe82b44f 100644
--- a/embassy-util/build.rs
+++ b/embassy-sync/build.rs
diff --git a/embassy-util/src/blocking_mutex/mod.rs b/embassy-sync/src/blocking_mutex/mod.rs
index 8a4a4c642..8a4a4c642 100644
--- a/embassy-util/src/blocking_mutex/mod.rs
+++ b/embassy-sync/src/blocking_mutex/mod.rs
diff --git a/embassy-util/src/blocking_mutex/raw.rs b/embassy-sync/src/blocking_mutex/raw.rs
index 15796f1b2..15796f1b2 100644
--- a/embassy-util/src/blocking_mutex/raw.rs
+++ b/embassy-sync/src/blocking_mutex/raw.rs
diff --git a/embassy-util/src/channel/mpmc.rs b/embassy-sync/src/channel.rs
index 535f77e6f..76f42d0e7 100644
--- a/embassy-util/src/channel/mpmc.rs
+++ b/embassy-sync/src/channel.rs
@@ -373,8 +373,8 @@ where
373 /// Establish a new bounded channel. For example, to create one with a NoopMutex: 373 /// Establish a new bounded channel. For example, to create one with a NoopMutex:
374 /// 374 ///
375 /// ``` 375 /// ```
376 /// use embassy_util::channel::mpmc::Channel; 376 /// use embassy_sync::channel::Channel;
377 /// use embassy_util::blocking_mutex::raw::NoopRawMutex; 377 /// use embassy_sync::blocking_mutex::raw::NoopRawMutex;
378 /// 378 ///
379 /// // Declare a bounded channel of 3 u32s. 379 /// // Declare a bounded channel of 3 u32s.
380 /// let mut channel = Channel::<NoopRawMutex, u32, 3>::new(); 380 /// let mut channel = Channel::<NoopRawMutex, u32, 3>::new();
@@ -471,10 +471,10 @@ mod tests {
471 use futures_executor::ThreadPool; 471 use futures_executor::ThreadPool;
472 use futures_timer::Delay; 472 use futures_timer::Delay;
473 use futures_util::task::SpawnExt; 473 use futures_util::task::SpawnExt;
474 use static_cell::StaticCell;
474 475
475 use super::*; 476 use super::*;
476 use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; 477 use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
477 use crate::Forever;
478 478
479 fn capacity<T, const N: usize>(c: &ChannelState<T, N>) -> usize { 479 fn capacity<T, const N: usize>(c: &ChannelState<T, N>) -> usize {
480 c.queue.capacity() - c.queue.len() 480 c.queue.capacity() - c.queue.len()
@@ -549,8 +549,8 @@ mod tests {
549 async fn receiver_receives_given_try_send_async() { 549 async fn receiver_receives_given_try_send_async() {
550 let executor = ThreadPool::new().unwrap(); 550 let executor = ThreadPool::new().unwrap();
551 551
552 static CHANNEL: Forever<Channel<CriticalSectionRawMutex, u32, 3>> = Forever::new(); 552 static CHANNEL: StaticCell<Channel<CriticalSectionRawMutex, u32, 3>> = StaticCell::new();
553 let c = &*CHANNEL.put(Channel::new()); 553 let c = &*CHANNEL.init(Channel::new());
554 let c2 = c; 554 let c2 = c;
555 assert!(executor 555 assert!(executor
556 .spawn(async move { 556 .spawn(async move {
@@ -571,8 +571,8 @@ mod tests {
571 async fn senders_sends_wait_until_capacity() { 571 async fn senders_sends_wait_until_capacity() {
572 let executor = ThreadPool::new().unwrap(); 572 let executor = ThreadPool::new().unwrap();
573 573
574 static CHANNEL: Forever<Channel<CriticalSectionRawMutex, u32, 1>> = Forever::new(); 574 static CHANNEL: StaticCell<Channel<CriticalSectionRawMutex, u32, 1>> = StaticCell::new();
575 let c = &*CHANNEL.put(Channel::new()); 575 let c = &*CHANNEL.init(Channel::new());
576 assert!(c.try_send(1).is_ok()); 576 assert!(c.try_send(1).is_ok());
577 577
578 let c2 = c; 578 let c2 = c;
diff --git a/embassy-sync/src/fmt.rs b/embassy-sync/src/fmt.rs
new file mode 100644
index 000000000..f8bb0a035
--- /dev/null
+++ b/embassy-sync/src/fmt.rs
@@ -0,0 +1,228 @@
1#![macro_use]
2#![allow(unused_macros)]
3
4#[cfg(all(feature = "defmt", feature = "log"))]
5compile_error!("You may not enable both `defmt` and `log` features.");
6
7macro_rules! assert {
8 ($($x:tt)*) => {
9 {
10 #[cfg(not(feature = "defmt"))]
11 ::core::assert!($($x)*);
12 #[cfg(feature = "defmt")]
13 ::defmt::assert!($($x)*);
14 }
15 };
16}
17
18macro_rules! assert_eq {
19 ($($x:tt)*) => {
20 {
21 #[cfg(not(feature = "defmt"))]
22 ::core::assert_eq!($($x)*);
23 #[cfg(feature = "defmt")]
24 ::defmt::assert_eq!($($x)*);
25 }
26 };
27}
28
29macro_rules! assert_ne {
30 ($($x:tt)*) => {
31 {
32 #[cfg(not(feature = "defmt"))]
33 ::core::assert_ne!($($x)*);
34 #[cfg(feature = "defmt")]
35 ::defmt::assert_ne!($($x)*);
36 }
37 };
38}
39
40macro_rules! debug_assert {
41 ($($x:tt)*) => {
42 {
43 #[cfg(not(feature = "defmt"))]
44 ::core::debug_assert!($($x)*);
45 #[cfg(feature = "defmt")]
46 ::defmt::debug_assert!($($x)*);
47 }
48 };
49}
50
51macro_rules! debug_assert_eq {
52 ($($x:tt)*) => {
53 {
54 #[cfg(not(feature = "defmt"))]
55 ::core::debug_assert_eq!($($x)*);
56 #[cfg(feature = "defmt")]
57 ::defmt::debug_assert_eq!($($x)*);
58 }
59 };
60}
61
62macro_rules! debug_assert_ne {
63 ($($x:tt)*) => {
64 {
65 #[cfg(not(feature = "defmt"))]
66 ::core::debug_assert_ne!($($x)*);
67 #[cfg(feature = "defmt")]
68 ::defmt::debug_assert_ne!($($x)*);
69 }
70 };
71}
72
73macro_rules! todo {
74 ($($x:tt)*) => {
75 {
76 #[cfg(not(feature = "defmt"))]
77 ::core::todo!($($x)*);
78 #[cfg(feature = "defmt")]
79 ::defmt::todo!($($x)*);
80 }
81 };
82}
83
84macro_rules! unreachable {
85 ($($x:tt)*) => {
86 {
87 #[cfg(not(feature = "defmt"))]
88 ::core::unreachable!($($x)*);
89 #[cfg(feature = "defmt")]
90 ::defmt::unreachable!($($x)*);
91 }
92 };
93}
94
95macro_rules! panic {
96 ($($x:tt)*) => {
97 {
98 #[cfg(not(feature = "defmt"))]
99 ::core::panic!($($x)*);
100 #[cfg(feature = "defmt")]
101 ::defmt::panic!($($x)*);
102 }
103 };
104}
105
106macro_rules! trace {
107 ($s:literal $(, $x:expr)* $(,)?) => {
108 {
109 #[cfg(feature = "log")]
110 ::log::trace!($s $(, $x)*);
111 #[cfg(feature = "defmt")]
112 ::defmt::trace!($s $(, $x)*);
113 #[cfg(not(any(feature = "log", feature="defmt")))]
114 let _ = ($( & $x ),*);
115 }
116 };
117}
118
119macro_rules! debug {
120 ($s:literal $(, $x:expr)* $(,)?) => {
121 {
122 #[cfg(feature = "log")]
123 ::log::debug!($s $(, $x)*);
124 #[cfg(feature = "defmt")]
125 ::defmt::debug!($s $(, $x)*);
126 #[cfg(not(any(feature = "log", feature="defmt")))]
127 let _ = ($( & $x ),*);
128 }
129 };
130}
131
132macro_rules! info {
133 ($s:literal $(, $x:expr)* $(,)?) => {
134 {
135 #[cfg(feature = "log")]
136 ::log::info!($s $(, $x)*);
137 #[cfg(feature = "defmt")]
138 ::defmt::info!($s $(, $x)*);
139 #[cfg(not(any(feature = "log", feature="defmt")))]
140 let _ = ($( & $x ),*);
141 }
142 };
143}
144
145macro_rules! warn {
146 ($s:literal $(, $x:expr)* $(,)?) => {
147 {
148 #[cfg(feature = "log")]
149 ::log::warn!($s $(, $x)*);
150 #[cfg(feature = "defmt")]
151 ::defmt::warn!($s $(, $x)*);
152 #[cfg(not(any(feature = "log", feature="defmt")))]
153 let _ = ($( & $x ),*);
154 }
155 };
156}
157
158macro_rules! error {
159 ($s:literal $(, $x:expr)* $(,)?) => {
160 {
161 #[cfg(feature = "log")]
162 ::log::error!($s $(, $x)*);
163 #[cfg(feature = "defmt")]
164 ::defmt::error!($s $(, $x)*);
165 #[cfg(not(any(feature = "log", feature="defmt")))]
166 let _ = ($( & $x ),*);
167 }
168 };
169}
170
171#[cfg(feature = "defmt")]
172macro_rules! unwrap {
173 ($($x:tt)*) => {
174 ::defmt::unwrap!($($x)*)
175 };
176}
177
178#[cfg(not(feature = "defmt"))]
179macro_rules! unwrap {
180 ($arg:expr) => {
181 match $crate::fmt::Try::into_result($arg) {
182 ::core::result::Result::Ok(t) => t,
183 ::core::result::Result::Err(e) => {
184 ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
185 }
186 }
187 };
188 ($arg:expr, $($msg:expr),+ $(,)? ) => {
189 match $crate::fmt::Try::into_result($arg) {
190 ::core::result::Result::Ok(t) => t,
191 ::core::result::Result::Err(e) => {
192 ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
193 }
194 }
195 }
196}
197
198#[cfg(feature = "defmt-timestamp-uptime")]
199defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
200
201#[derive(Debug, Copy, Clone, Eq, PartialEq)]
202pub struct NoneError;
203
204pub trait Try {
205 type Ok;
206 type Error;
207 fn into_result(self) -> Result<Self::Ok, Self::Error>;
208}
209
210impl<T> Try for Option<T> {
211 type Ok = T;
212 type Error = NoneError;
213
214 #[inline]
215 fn into_result(self) -> Result<T, NoneError> {
216 self.ok_or(NoneError)
217 }
218}
219
220impl<T, E> Try for Result<T, E> {
221 type Ok = T;
222 type Error = E;
223
224 #[inline]
225 fn into_result(self) -> Self {
226 self
227 }
228}
diff --git a/embassy-util/src/lib.rs b/embassy-sync/src/lib.rs
index 110c72811..8e81e5cbe 100644
--- a/embassy-util/src/lib.rs
+++ b/embassy-sync/src/lib.rs
@@ -14,12 +14,6 @@ pub mod blocking_mutex;
14pub mod channel; 14pub mod channel;
15pub mod mutex; 15pub mod mutex;
16pub mod pipe; 16pub mod pipe;
17pub mod pubsub;
18pub mod signal;
17pub mod waitqueue; 19pub mod waitqueue;
18
19mod forever;
20mod select;
21mod yield_now;
22
23pub use forever::*;
24pub use select::*;
25pub use yield_now::*;
diff --git a/embassy-util/src/mutex.rs b/embassy-sync/src/mutex.rs
index 75a6e8dd3..75a6e8dd3 100644
--- a/embassy-util/src/mutex.rs
+++ b/embassy-sync/src/mutex.rs
diff --git a/embassy-util/src/pipe.rs b/embassy-sync/src/pipe.rs
index 9c20aeeff..7d64b648e 100644
--- a/embassy-util/src/pipe.rs
+++ b/embassy-sync/src/pipe.rs
@@ -241,8 +241,8 @@ where
241 /// Establish a new bounded pipe. For example, to create one with a NoopMutex: 241 /// Establish a new bounded pipe. For example, to create one with a NoopMutex:
242 /// 242 ///
243 /// ``` 243 /// ```
244 /// use embassy_util::pipe::Pipe; 244 /// use embassy_sync::pipe::Pipe;
245 /// use embassy_util::blocking_mutex::raw::NoopRawMutex; 245 /// use embassy_sync::blocking_mutex::raw::NoopRawMutex;
246 /// 246 ///
247 /// // Declare a bounded pipe, with a buffer of 256 bytes. 247 /// // Declare a bounded pipe, with a buffer of 256 bytes.
248 /// let mut pipe = Pipe::<NoopRawMutex, 256>::new(); 248 /// let mut pipe = Pipe::<NoopRawMutex, 256>::new();
@@ -461,10 +461,10 @@ mod io_impls {
461mod tests { 461mod tests {
462 use futures_executor::ThreadPool; 462 use futures_executor::ThreadPool;
463 use futures_util::task::SpawnExt; 463 use futures_util::task::SpawnExt;
464 use static_cell::StaticCell;
464 465
465 use super::*; 466 use super::*;
466 use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; 467 use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
467 use crate::Forever;
468 468
469 fn capacity<const N: usize>(c: &PipeState<N>) -> usize { 469 fn capacity<const N: usize>(c: &PipeState<N>) -> usize {
470 N - c.buffer.len() 470 N - c.buffer.len()
@@ -528,8 +528,8 @@ mod tests {
528 async fn receiver_receives_given_try_write_async() { 528 async fn receiver_receives_given_try_write_async() {
529 let executor = ThreadPool::new().unwrap(); 529 let executor = ThreadPool::new().unwrap();
530 530
531 static CHANNEL: Forever<Pipe<CriticalSectionRawMutex, 3>> = Forever::new(); 531 static CHANNEL: StaticCell<Pipe<CriticalSectionRawMutex, 3>> = StaticCell::new();
532 let c = &*CHANNEL.put(Pipe::new()); 532 let c = &*CHANNEL.init(Pipe::new());
533 let c2 = c; 533 let c2 = c;
534 let f = async move { 534 let f = async move {
535 assert_eq!(c2.try_write(&[42]), Ok(1)); 535 assert_eq!(c2.try_write(&[42]), Ok(1));
diff --git a/embassy-util/src/channel/pubsub/mod.rs b/embassy-sync/src/pubsub/mod.rs
index ecc8fbd8f..62a9e4763 100644
--- a/embassy-util/src/channel/pubsub/mod.rs
+++ b/embassy-sync/src/pubsub/mod.rs
@@ -33,9 +33,9 @@ pub use subscriber::{DynSubscriber, Subscriber};
33/// ## Example 33/// ## Example
34/// 34///
35/// ``` 35/// ```
36/// # use embassy_util::blocking_mutex::raw::NoopRawMutex; 36/// # use embassy_sync::blocking_mutex::raw::NoopRawMutex;
37/// # use embassy_util::channel::pubsub::WaitResult; 37/// # use embassy_sync::pubsub::WaitResult;
38/// # use embassy_util::channel::pubsub::PubSubChannel; 38/// # use embassy_sync::pubsub::PubSubChannel;
39/// # use futures_executor::block_on; 39/// # use futures_executor::block_on;
40/// # let test = async { 40/// # let test = async {
41/// // Create the channel. This can be static as well 41/// // Create the channel. This can be static as well
diff --git a/embassy-util/src/channel/pubsub/publisher.rs b/embassy-sync/src/pubsub/publisher.rs
index 705797f60..705797f60 100644
--- a/embassy-util/src/channel/pubsub/publisher.rs
+++ b/embassy-sync/src/pubsub/publisher.rs
diff --git a/embassy-util/src/channel/pubsub/subscriber.rs b/embassy-sync/src/pubsub/subscriber.rs
index b9a2cbe18..b9a2cbe18 100644
--- a/embassy-util/src/channel/pubsub/subscriber.rs
+++ b/embassy-sync/src/pubsub/subscriber.rs
diff --git a/embassy-util/src/ring_buffer.rs b/embassy-sync/src/ring_buffer.rs
index 521084024..521084024 100644
--- a/embassy-util/src/ring_buffer.rs
+++ b/embassy-sync/src/ring_buffer.rs
diff --git a/embassy-util/src/channel/signal.rs b/embassy-sync/src/signal.rs
index 05889f5a4..3f665e388 100644
--- a/embassy-util/src/channel/signal.rs
+++ b/embassy-sync/src/signal.rs
@@ -19,7 +19,7 @@ use core::task::{Context, Poll, Waker};
19/// Signals are generally declared as `static`s and then borrowed as required. 19/// Signals are generally declared as `static`s and then borrowed as required.
20/// 20///
21/// ``` 21/// ```
22/// use embassy_util::channel::signal::Signal; 22/// use embassy_sync::signal::Signal;
23/// 23///
24/// enum SomeCommand { 24/// enum SomeCommand {
25/// On, 25/// On,
diff --git a/embassy-util/src/waitqueue/mod.rs b/embassy-sync/src/waitqueue/mod.rs
index 6661a6b61..6661a6b61 100644
--- a/embassy-util/src/waitqueue/mod.rs
+++ b/embassy-sync/src/waitqueue/mod.rs
diff --git a/embassy-util/src/waitqueue/multi_waker.rs b/embassy-sync/src/waitqueue/multi_waker.rs
index 325d2cb3a..325d2cb3a 100644
--- a/embassy-util/src/waitqueue/multi_waker.rs
+++ b/embassy-sync/src/waitqueue/multi_waker.rs
diff --git a/embassy-util/src/waitqueue/waker.rs b/embassy-sync/src/waitqueue/waker.rs
index 64e300eb8..64e300eb8 100644
--- a/embassy-util/src/waitqueue/waker.rs
+++ b/embassy-sync/src/waitqueue/waker.rs
diff --git a/embassy-time/src/driver.rs b/embassy-time/src/driver.rs
index 216b27408..79ae14b91 100644
--- a/embassy-time/src/driver.rs
+++ b/embassy-time/src/driver.rs
@@ -6,7 +6,7 @@
6//! 6//!
7//! - Define a struct `MyDriver` 7//! - Define a struct `MyDriver`
8//! - Implement [`Driver`] for it 8//! - Implement [`Driver`] for it
9//! - Register it as the global driver with [`time_driver_impl`]. 9//! - Register it as the global driver with [`time_driver_impl`](crate::time_driver_impl).
10//! - Enable the Cargo features `embassy-executor/time` and one of `embassy-time/tick-*` corresponding to the 10//! - Enable the Cargo features `embassy-executor/time` and one of `embassy-time/tick-*` corresponding to the
11//! tick rate of your driver. 11//! tick rate of your driver.
12//! 12//!
diff --git a/embassy-usb-hid/Cargo.toml b/embassy-usb-hid/Cargo.toml
index 5e9cfebf7..730351485 100644
--- a/embassy-usb-hid/Cargo.toml
+++ b/embassy-usb-hid/Cargo.toml
@@ -14,7 +14,7 @@ default = ["usbd-hid"]
14usbd-hid = ["dep:usbd-hid", "ssmarshal"] 14usbd-hid = ["dep:usbd-hid", "ssmarshal"]
15 15
16[dependencies] 16[dependencies]
17embassy-util = { version = "0.1.0", path = "../embassy-util" } 17embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
18embassy-usb = { version = "0.1.0", path = "../embassy-usb" } 18embassy-usb = { version = "0.1.0", path = "../embassy-usb" }
19 19
20defmt = { version = "0.3", optional = true } 20defmt = { version = "0.3", optional = true }
diff --git a/embassy-usb-ncm/Cargo.toml b/embassy-usb-ncm/Cargo.toml
index 47c1f36bd..15d3db96f 100644
--- a/embassy-usb-ncm/Cargo.toml
+++ b/embassy-usb-ncm/Cargo.toml
@@ -10,7 +10,7 @@ features = ["defmt"]
10target = "thumbv7em-none-eabi" 10target = "thumbv7em-none-eabi"
11 11
12[dependencies] 12[dependencies]
13embassy-util = { version = "0.1.0", path = "../embassy-util" } 13embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
14embassy-usb = { version = "0.1.0", path = "../embassy-usb" } 14embassy-usb = { version = "0.1.0", path = "../embassy-usb" }
15 15
16defmt = { version = "0.3", optional = true } 16defmt = { version = "0.3", optional = true }
diff --git a/embassy-usb-serial/Cargo.toml b/embassy-usb-serial/Cargo.toml
index 633610471..9788588e9 100644
--- a/embassy-usb-serial/Cargo.toml
+++ b/embassy-usb-serial/Cargo.toml
@@ -10,7 +10,7 @@ features = ["defmt"]
10target = "thumbv7em-none-eabi" 10target = "thumbv7em-none-eabi"
11 11
12[dependencies] 12[dependencies]
13embassy-util = { version = "0.1.0", path = "../embassy-util" } 13embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
14embassy-usb = { version = "0.1.0", path = "../embassy-usb" } 14embassy-usb = { version = "0.1.0", path = "../embassy-usb" }
15 15
16defmt = { version = "0.3", optional = true } 16defmt = { version = "0.3", optional = true }
diff --git a/embassy-usb-serial/src/lib.rs b/embassy-usb-serial/src/lib.rs
index e561be9df..f3de2ec1b 100644
--- a/embassy-usb-serial/src/lib.rs
+++ b/embassy-usb-serial/src/lib.rs
@@ -9,11 +9,11 @@ use core::cell::Cell;
9use core::mem::{self, MaybeUninit}; 9use core::mem::{self, MaybeUninit};
10use core::sync::atomic::{AtomicBool, Ordering}; 10use core::sync::atomic::{AtomicBool, Ordering};
11 11
12use embassy_sync::blocking_mutex::CriticalSectionMutex;
12use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request}; 13use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request};
13use embassy_usb::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; 14use embassy_usb::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
14use embassy_usb::types::*; 15use embassy_usb::types::*;
15use embassy_usb::Builder; 16use embassy_usb::Builder;
16use embassy_util::blocking_mutex::CriticalSectionMutex;
17 17
18/// This should be used as `device_class` when building the `UsbDevice`. 18/// This should be used as `device_class` when building the `UsbDevice`.
19pub const USB_CLASS_CDC: u8 = 0x02; 19pub const USB_CLASS_CDC: u8 = 0x02;
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml
index 6adbd399b..8cad4d314 100644
--- a/embassy-usb/Cargo.toml
+++ b/embassy-usb/Cargo.toml
@@ -10,7 +10,7 @@ features = ["defmt"]
10target = "thumbv7em-none-eabi" 10target = "thumbv7em-none-eabi"
11 11
12[dependencies] 12[dependencies]
13embassy-util = { version = "0.1.0", path = "../embassy-util" } 13embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
16log = { version = "0.4.14", optional = true } 16log = { version = "0.4.14", optional = true }
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs
index 1ca24cc08..6be88bc76 100644
--- a/embassy-usb/src/builder.rs
+++ b/embassy-usb/src/builder.rs
@@ -10,6 +10,7 @@ use crate::{Interface, STRING_INDEX_CUSTOM_START};
10#[derive(Debug, Copy, Clone)] 10#[derive(Debug, Copy, Clone)]
11#[cfg_attr(feature = "defmt", derive(defmt::Format))] 11#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12#[non_exhaustive] 12#[non_exhaustive]
13/// Configuration used when creating [UsbDevice].
13pub struct Config<'a> { 14pub struct Config<'a> {
14 pub(crate) vendor_id: u16, 15 pub(crate) vendor_id: u16,
15 pub(crate) product_id: u16, 16 pub(crate) product_id: u16,
@@ -96,6 +97,7 @@ pub struct Config<'a> {
96} 97}
97 98
98impl<'a> Config<'a> { 99impl<'a> Config<'a> {
100 /// Create default configuration with the provided vid and pid values.
99 pub fn new(vid: u16, pid: u16) -> Self { 101 pub fn new(vid: u16, pid: u16) -> Self {
100 Self { 102 Self {
101 device_class: 0x00, 103 device_class: 0x00,
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs
index 12e5303c3..3e5749a01 100644
--- a/embassy-usb/src/control.rs
+++ b/embassy-usb/src/control.rs
@@ -1,3 +1,4 @@
1//! USB control data types.
1use core::mem; 2use core::mem;
2 3
3use super::types::*; 4use super::types::*;
@@ -8,7 +9,7 @@ use super::types::*;
8#[cfg_attr(feature = "defmt", derive(defmt::Format))] 9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub enum RequestType { 10pub enum RequestType {
10 /// Request is a USB standard request. Usually handled by 11 /// Request is a USB standard request. Usually handled by
11 /// [`UsbDevice`](crate::device::UsbDevice). 12 /// [`UsbDevice`](crate::UsbDevice).
12 Standard = 0, 13 Standard = 0,
13 /// Request is intended for a USB class. 14 /// Request is intended for a USB class.
14 Class = 1, 15 Class = 1,
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs
index 2a84ff9e7..7888f1639 100644
--- a/embassy-usb/src/driver.rs
+++ b/embassy-usb/src/driver.rs
@@ -12,7 +12,7 @@ pub trait Driver<'a> {
12 12
13 /// Allocates an endpoint and specified endpoint parameters. This method is called by the device 13 /// Allocates an endpoint and specified endpoint parameters. This method is called by the device
14 /// and class implementations to allocate endpoints, and can only be called before 14 /// and class implementations to allocate endpoints, and can only be called before
15 /// [`start`](UsbBus::start) is called. 15 /// [`start`](Self::start) is called.
16 /// 16 ///
17 /// # Arguments 17 /// # Arguments
18 /// 18 ///
@@ -95,7 +95,7 @@ pub trait Bus {
95 /// 95 ///
96 /// # Errors 96 /// # Errors
97 /// 97 ///
98 /// * [`Unsupported`](crate::UsbError::Unsupported) - This UsbBus implementation doesn't support 98 /// * [`Unsupported`](crate::driver::Unsupported) - This UsbBus implementation doesn't support
99 /// simulating a disconnect or it has not been enabled at creation time. 99 /// simulating a disconnect or it has not been enabled at creation time.
100 fn force_reset(&mut self) -> Result<(), Unsupported> { 100 fn force_reset(&mut self) -> Result<(), Unsupported> {
101 Err(Unsupported) 101 Err(Unsupported)
@@ -105,7 +105,7 @@ pub trait Bus {
105 /// 105 ///
106 /// # Errors 106 /// # Errors
107 /// 107 ///
108 /// * [`Unsupported`](crate::UsbError::Unsupported) - This UsbBus implementation doesn't support 108 /// * [`Unsupported`](crate::driver::Unsupported) - This UsbBus implementation doesn't support
109 /// remote wakeup or it has not been enabled at creation time. 109 /// remote wakeup or it has not been enabled at creation time.
110 fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_>; 110 fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_>;
111} 111}
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs
index 3f6e13472..5a3f8ba88 100644
--- a/embassy-usb/src/lib.rs
+++ b/embassy-usb/src/lib.rs
@@ -12,7 +12,7 @@ mod descriptor_reader;
12pub mod driver; 12pub mod driver;
13pub mod types; 13pub mod types;
14 14
15use embassy_util::{select, Either}; 15use embassy_futures::{select, Either};
16use heapless::Vec; 16use heapless::Vec;
17 17
18pub use self::builder::{Builder, Config}; 18pub use self::builder::{Builder, Config};
diff --git a/embassy-util/src/channel/mod.rs b/embassy-util/src/channel/mod.rs
deleted file mode 100644
index 5df1f5c5c..000000000
--- a/embassy-util/src/channel/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
1//! Async channels
2
3pub mod mpmc;
4pub mod pubsub;
5pub mod signal;
diff --git a/embassy-util/src/forever.rs b/embassy-util/src/forever.rs
deleted file mode 100644
index 4f3698211..000000000
--- a/embassy-util/src/forever.rs
+++ /dev/null
@@ -1,95 +0,0 @@
1use core::cell::UnsafeCell;
2use core::mem::MaybeUninit;
3
4use atomic_polyfill::{AtomicBool, Ordering};
5
6/// Type with static lifetime that may be written to once at runtime.
7///
8/// This may be used to initialize static objects at runtime, typically in the init routine.
9/// This is useful for objects such as Embassy's RTC, which cannot be initialized in a const
10/// context.
11///
12/// Note: IF a global mutable variable is desired, use a CriticalSectionMutex or ThreadModeMutex instead.
13///
14/// ```
15/// use embassy_util::Forever;
16/// // Using an integer for the sake of keeping this example self-contained,
17/// // see https://github.com/embassy-rs/embassy/wiki/Getting-Started for a more "proper" example.
18/// static SOME_INT: Forever<u32> =Forever::new();
19///
20/// // put returns a mutable pointer to the object stored in the forever, which may then be passed
21/// // around.
22/// let mut x = SOME_INT.put(42);
23/// assert_eq!(*x, 42);
24/// ```
25pub struct Forever<T> {
26 used: AtomicBool,
27 t: UnsafeCell<MaybeUninit<T>>,
28}
29
30unsafe impl<T> Send for Forever<T> {}
31unsafe impl<T> Sync for Forever<T> {}
32
33impl<T> Forever<T> {
34 /// Create a new `Forever`.
35 #[inline(always)]
36 pub const fn new() -> Self {
37 Self {
38 used: AtomicBool::new(false),
39 t: UnsafeCell::new(MaybeUninit::uninit()),
40 }
41 }
42
43 /// Store a value in this `Forever`, returning a mutable reference to it.
44 ///
45 /// Using this method, the compiler usually constructs `val` in the stack and then moves
46 /// it into the `Forever`. If `T` is big, this is likely to cause stack overflows.
47 /// Considering using [`Signal::put_with`] instead, which will construct it in-place inside the `Forever`.
48 ///
49 /// # Panics
50 ///
51 /// Panics if this `Forever` already has a value stored in it.
52 #[inline(always)]
53 #[allow(clippy::mut_from_ref)]
54 pub fn put(&'static self, val: T) -> &'static mut T {
55 self.put_with(|| val)
56 }
57
58 /// Store the closure return value in this `Forever`, returning a mutable reference to it.
59 ///
60 /// The advantage over [`Forever::put`] is that this method allows the closure to construct
61 /// the `T` value in-place directly inside the `Forever`, saving stack space.
62 ///
63 /// # Panics
64 ///
65 /// Panics if this `Forever` already has a value stored in it.
66 #[inline(always)]
67 #[allow(clippy::mut_from_ref)]
68 pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T {
69 if self
70 .used
71 .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
72 .is_err()
73 {
74 panic!("Forever.put() called multiple times");
75 }
76
77 let p: &'static mut MaybeUninit<T> = unsafe { &mut *self.t.get() };
78 p.write(val())
79 }
80
81 /// Unsafely get a mutable reference to the contents of this Forever.
82 ///
83 /// # Safety
84 ///
85 /// This is undefined behavior if:
86 ///
87 /// - The `Forever` has not been initialized yet (with `put' or `put_with`), or
88 /// - A reference to the contents (mutable or not) already exists.
89 #[inline(always)]
90 #[allow(clippy::mut_from_ref)]
91 pub unsafe fn steal(&self) -> &mut T {
92 let p: &mut MaybeUninit<T> = &mut *self.t.get();
93 p.assume_init_mut()
94 }
95}
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index ef9346639..b9ff92578 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-nrf-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util" } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] }
10embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly", "nrf52840"] } 10embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly", "nrf52840"] }
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 27eafa653..f143d1e8d 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32f3-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] }
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index 7de0b82d7..29c87eee1 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32f7-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] }
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 65d34c70b..5669527fe 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32h7-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] }
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 8f37869e3..48624d5ec 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32l0-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] }
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 6abf1986d..00b638ca5 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32l1-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] }
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 6f2d12ff1..51ba730d5 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32l4-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] }
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index be97d4ebb..182acf694 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-boot-stm32wl-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] }
diff --git a/examples/nrf-rtos-trace/.cargo/config.toml b/examples/nrf-rtos-trace/.cargo/config.toml
new file mode 100644
index 000000000..8ca28df39
--- /dev/null
+++ b/examples/nrf-rtos-trace/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace nRF82840_xxAA with your chip as listed in `probe-run --list-chips`
3runner = "probe-run --chip nRF52840_xxAA"
4
5[build]
6target = "thumbv7em-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml
new file mode 100644
index 000000000..87c9f33f5
--- /dev/null
+++ b/examples/nrf-rtos-trace/Cargo.toml
@@ -0,0 +1,35 @@
1[package]
2edition = "2021"
3name = "embassy-nrf-rtos-trace-examples"
4version = "0.1.0"
5
6[features]
7default = ["log", "nightly"]
8nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-nrf/unstable-traits"]
9log = [
10 "dep:log",
11 "embassy-sync/log",
12 "embassy-executor/log",
13 "embassy-time/log",
14 "embassy-nrf/log",
15]
16
17[dependencies]
18embassy-sync = { version = "0.1.0", path = "../../embassy-sync" }
19embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features=["rtos-trace", "rtos-trace-interrupt", "integrated-timers"] }
20embassy-time = { version = "0.1.0", path = "../../embassy-time" }
21embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
22
23cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
24cortex-m-rt = "0.7.0"
25panic-probe = { version = "0.3" }
26futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
27rand = { version = "0.8.4", default-features = false }
28serde = { version = "1.0.136", default-features = false }
29rtos-trace = "0.1.3"
30systemview-target = { version = "0.1.2", features = ["callbacks-app", "callbacks-os", "log", "cortex-m"] }
31log = { version = "0.4.17", optional = true }
32
33[[bin]]
34name = "rtos_trace"
35required-features = ["nightly"]
diff --git a/examples/nrf-rtos-trace/build.rs b/examples/nrf-rtos-trace/build.rs
new file mode 100644
index 000000000..36cdb65a8
--- /dev/null
+++ b/examples/nrf-rtos-trace/build.rs
@@ -0,0 +1,36 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 #[cfg(feature = "defmt")]
35 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
36}
diff --git a/examples/nrf-rtos-trace/memory.x b/examples/nrf-rtos-trace/memory.x
new file mode 100644
index 000000000..9b04edec0
--- /dev/null
+++ b/examples/nrf-rtos-trace/memory.x
@@ -0,0 +1,7 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */
5 FLASH : ORIGIN = 0x00000000, LENGTH = 1024K
6 RAM : ORIGIN = 0x20000000, LENGTH = 256K
7}
diff --git a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs
new file mode 100644
index 000000000..7d1ad87c8
--- /dev/null
+++ b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs
@@ -0,0 +1,69 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use core::task::Poll;
6
7use embassy_executor::Spawner;
8use embassy_time::{Duration, Instant, Timer};
9#[cfg(feature = "log")]
10use log::*;
11use panic_probe as _;
12// N.B. systemview_target cannot be used at the same time as defmt_rtt.
13use rtos_trace;
14use systemview_target::SystemView;
15
16static LOGGER: systemview_target::SystemView = systemview_target::SystemView::new();
17rtos_trace::global_trace! {SystemView}
18
19struct TraceInfo();
20
21impl rtos_trace::RtosTraceApplicationCallbacks for TraceInfo {
22 fn system_description() {}
23 fn sysclock() -> u32 {
24 64000000
25 }
26}
27rtos_trace::global_application_callbacks! {TraceInfo}
28
29#[embassy_executor::task]
30async fn run1() {
31 loop {
32 #[cfg(feature = "log")]
33 info!("DING DONG");
34 #[cfg(not(feature = "log"))]
35 rtos_trace::trace::marker(13);
36 Timer::after(Duration::from_ticks(16000)).await;
37 }
38}
39
40#[embassy_executor::task]
41async fn run2() {
42 loop {
43 Timer::at(Instant::from_ticks(0)).await;
44 }
45}
46
47#[embassy_executor::task]
48async fn run3() {
49 futures::future::poll_fn(|cx| {
50 cx.waker().wake_by_ref();
51 Poll::<()>::Pending
52 })
53 .await;
54}
55
56#[embassy_executor::main]
57async fn main(spawner: Spawner) {
58 let _p = embassy_nrf::init(Default::default());
59 LOGGER.init();
60 #[cfg(feature = "log")]
61 {
62 ::log::set_logger(&LOGGER).ok();
63 ::log::set_max_level(::log::LevelFilter::Trace);
64 }
65
66 spawner.spawn(run1()).unwrap();
67 spawner.spawn(run2()).unwrap();
68 spawner.spawn(run3()).unwrap();
69}
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 2fcc31221..b0af0c86e 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -8,7 +8,8 @@ default = ["nightly"]
8nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net"] 8nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net"]
9 9
10[dependencies] 10[dependencies]
11embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 11embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
12embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 13embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
13embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 14embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } 15embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
@@ -22,6 +23,7 @@ embedded-io = "0.3.0"
22defmt = "0.3" 23defmt = "0.3"
23defmt-rtt = "0.3" 24defmt-rtt = "0.3"
24 25
26static_cell = "1.0"
25cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
26cortex-m-rt = "0.7.0" 28cortex-m-rt = "0.7.0"
27panic-probe = { version = "0.3", features = ["print-defmt"] } 29panic-probe = { version = "0.3", features = ["print-defmt"] }
diff --git a/examples/nrf/src/bin/channel.rs b/examples/nrf/src/bin/channel.rs
index 195200988..d782a79e7 100644
--- a/examples/nrf/src/bin/channel.rs
+++ b/examples/nrf/src/bin/channel.rs
@@ -5,9 +5,9 @@
5use defmt::unwrap; 5use defmt::unwrap;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::gpio::{Level, Output, OutputDrive}; 7use embassy_nrf::gpio::{Level, Output, OutputDrive};
8use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
9use embassy_sync::channel::Channel;
8use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
9use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
10use embassy_util::channel::mpmc::Channel;
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13enum LedState { 13enum LedState {
diff --git a/examples/nrf/src/bin/channel_sender_receiver.rs b/examples/nrf/src/bin/channel_sender_receiver.rs
index c9c458aec..fcccdaed5 100644
--- a/examples/nrf/src/bin/channel_sender_receiver.rs
+++ b/examples/nrf/src/bin/channel_sender_receiver.rs
@@ -5,10 +5,10 @@
5use defmt::unwrap; 5use defmt::unwrap;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; 7use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin};
8use embassy_sync::blocking_mutex::raw::NoopRawMutex;
9use embassy_sync::channel::{Channel, Receiver, Sender};
8use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
9use embassy_util::blocking_mutex::raw::NoopRawMutex; 11use static_cell::StaticCell;
10use embassy_util::channel::mpmc::{Channel, Receiver, Sender};
11use embassy_util::Forever;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14enum LedState { 14enum LedState {
@@ -16,7 +16,7 @@ enum LedState {
16 Off, 16 Off,
17} 17}
18 18
19static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new(); 19static CHANNEL: StaticCell<Channel<NoopRawMutex, LedState, 1>> = StaticCell::new();
20 20
21#[embassy_executor::task] 21#[embassy_executor::task]
22async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) { 22async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
@@ -43,7 +43,7 @@ async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedSta
43#[embassy_executor::main] 43#[embassy_executor::main]
44async fn main(spawner: Spawner) { 44async fn main(spawner: Spawner) {
45 let p = embassy_nrf::init(Default::default()); 45 let p = embassy_nrf::init(Default::default());
46 let channel = CHANNEL.put(Channel::new()); 46 let channel = CHANNEL.init(Channel::new());
47 47
48 unwrap!(spawner.spawn(send_task(channel.sender()))); 48 unwrap!(spawner.spawn(send_task(channel.sender())));
49 unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver()))); 49 unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver())));
diff --git a/examples/nrf/src/bin/multiprio.rs b/examples/nrf/src/bin/multiprio.rs
index b653689a7..25806ae48 100644
--- a/examples/nrf/src/bin/multiprio.rs
+++ b/examples/nrf/src/bin/multiprio.rs
@@ -63,7 +63,7 @@ use embassy_nrf::executor::{Executor, InterruptExecutor};
63use embassy_nrf::interrupt; 63use embassy_nrf::interrupt;
64use embassy_nrf::interrupt::InterruptExt; 64use embassy_nrf::interrupt::InterruptExt;
65use embassy_time::{Duration, Instant, Timer}; 65use embassy_time::{Duration, Instant, Timer};
66use embassy_util::Forever; 66use static_cell::StaticCell;
67use {defmt_rtt as _, panic_probe as _}; 67use {defmt_rtt as _, panic_probe as _};
68 68
69#[embassy_executor::task] 69#[embassy_executor::task]
@@ -108,9 +108,9 @@ async fn run_low() {
108 } 108 }
109} 109}
110 110
111static EXECUTOR_HIGH: Forever<InterruptExecutor<interrupt::SWI1_EGU1>> = Forever::new(); 111static EXECUTOR_HIGH: StaticCell<InterruptExecutor<interrupt::SWI1_EGU1>> = StaticCell::new();
112static EXECUTOR_MED: Forever<InterruptExecutor<interrupt::SWI0_EGU0>> = Forever::new(); 112static EXECUTOR_MED: StaticCell<InterruptExecutor<interrupt::SWI0_EGU0>> = StaticCell::new();
113static EXECUTOR_LOW: Forever<Executor> = Forever::new(); 113static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
114 114
115#[entry] 115#[entry]
116fn main() -> ! { 116fn main() -> ! {
@@ -121,19 +121,19 @@ fn main() -> ! {
121 // High-priority executor: SWI1_EGU1, priority level 6 121 // High-priority executor: SWI1_EGU1, priority level 6
122 let irq = interrupt::take!(SWI1_EGU1); 122 let irq = interrupt::take!(SWI1_EGU1);
123 irq.set_priority(interrupt::Priority::P6); 123 irq.set_priority(interrupt::Priority::P6);
124 let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); 124 let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq));
125 let spawner = executor.start(); 125 let spawner = executor.start();
126 unwrap!(spawner.spawn(run_high())); 126 unwrap!(spawner.spawn(run_high()));
127 127
128 // Medium-priority executor: SWI0_EGU0, priority level 7 128 // Medium-priority executor: SWI0_EGU0, priority level 7
129 let irq = interrupt::take!(SWI0_EGU0); 129 let irq = interrupt::take!(SWI0_EGU0);
130 irq.set_priority(interrupt::Priority::P7); 130 irq.set_priority(interrupt::Priority::P7);
131 let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); 131 let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq));
132 let spawner = executor.start(); 132 let spawner = executor.start();
133 unwrap!(spawner.spawn(run_med())); 133 unwrap!(spawner.spawn(run_med()));
134 134
135 // Low priority executor: runs in thread mode, using WFE/SEV 135 // Low priority executor: runs in thread mode, using WFE/SEV
136 let executor = EXECUTOR_LOW.put(Executor::new()); 136 let executor = EXECUTOR_LOW.init(Executor::new());
137 executor.run(|spawner| { 137 executor.run(|spawner| {
138 unwrap!(spawner.spawn(run_low())); 138 unwrap!(spawner.spawn(run_low()));
139 }); 139 });
diff --git a/examples/nrf/src/bin/mutex.rs b/examples/nrf/src/bin/mutex.rs
index 876297883..c402c6ba1 100644
--- a/examples/nrf/src/bin/mutex.rs
+++ b/examples/nrf/src/bin/mutex.rs
@@ -4,9 +4,9 @@
4 4
5use defmt::{info, unwrap}; 5use defmt::{info, unwrap};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
8use embassy_sync::mutex::Mutex;
7use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
8use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
9use embassy_util::mutex::Mutex;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12static MUTEX: Mutex<ThreadModeRawMutex, u32> = Mutex::new(0); 12static MUTEX: Mutex<ThreadModeRawMutex, u32> = Mutex::new(0);
diff --git a/examples/nrf/src/bin/pubsub.rs b/examples/nrf/src/bin/pubsub.rs
index 1d90217f2..688e6d075 100644
--- a/examples/nrf/src/bin/pubsub.rs
+++ b/examples/nrf/src/bin/pubsub.rs
@@ -4,9 +4,9 @@
4 4
5use defmt::unwrap; 5use defmt::unwrap;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
8use embassy_sync::pubsub::{DynSubscriber, PubSubChannel, Subscriber};
7use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
8use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
9use embassy_util::channel::pubsub::{DynSubscriber, PubSubChannel, Subscriber};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12/// Create the message bus. It has a queue of 4, supports 3 subscribers and 1 publisher 12/// Create the message bus. It has a queue of 4, supports 3 subscribers and 1 publisher
diff --git a/examples/nrf/src/bin/raw_spawn.rs b/examples/nrf/src/bin/raw_spawn.rs
index 415579be7..1b067f5e4 100644
--- a/examples/nrf/src/bin/raw_spawn.rs
+++ b/examples/nrf/src/bin/raw_spawn.rs
@@ -8,7 +8,7 @@ use defmt::{info, unwrap};
8use embassy_executor::raw::TaskStorage; 8use embassy_executor::raw::TaskStorage;
9use embassy_executor::Executor; 9use embassy_executor::Executor;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use embassy_util::Forever; 11use static_cell::StaticCell;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14async fn run1() { 14async fn run1() {
@@ -25,14 +25,14 @@ async fn run2() {
25 } 25 }
26} 26}
27 27
28static EXECUTOR: Forever<Executor> = Forever::new(); 28static EXECUTOR: StaticCell<Executor> = StaticCell::new();
29 29
30#[entry] 30#[entry]
31fn main() -> ! { 31fn main() -> ! {
32 info!("Hello World!"); 32 info!("Hello World!");
33 33
34 let _p = embassy_nrf::init(Default::default()); 34 let _p = embassy_nrf::init(Default::default());
35 let executor = EXECUTOR.put(Executor::new()); 35 let executor = EXECUTOR.init(Executor::new());
36 36
37 let run1_task = TaskStorage::new(); 37 let run1_task = TaskStorage::new();
38 let run2_task = TaskStorage::new(); 38 let run2_task = TaskStorage::new();
diff --git a/examples/nrf/src/bin/uart_split.rs b/examples/nrf/src/bin/uart_split.rs
index dab8e475d..1adaf53fd 100644
--- a/examples/nrf/src/bin/uart_split.rs
+++ b/examples/nrf/src/bin/uart_split.rs
@@ -7,8 +7,8 @@ use embassy_executor::Spawner;
7use embassy_nrf::peripherals::UARTE0; 7use embassy_nrf::peripherals::UARTE0;
8use embassy_nrf::uarte::UarteRx; 8use embassy_nrf::uarte::UarteRx;
9use embassy_nrf::{interrupt, uarte}; 9use embassy_nrf::{interrupt, uarte};
10use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; 10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
11use embassy_util::channel::mpmc::Channel; 11use embassy_sync::channel::Channel;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); 14static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs
index f0a870317..ca6c7e0d1 100644
--- a/examples/nrf/src/bin/usb_ethernet.rs
+++ b/examples/nrf/src/bin/usb_ethernet.rs
@@ -14,21 +14,21 @@ use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources};
14use embassy_nrf::rng::Rng; 14use embassy_nrf::rng::Rng;
15use embassy_nrf::usb::{Driver, PowerUsb}; 15use embassy_nrf::usb::{Driver, PowerUsb};
16use embassy_nrf::{interrupt, pac, peripherals}; 16use embassy_nrf::{interrupt, pac, peripherals};
17use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
18use embassy_sync::channel::Channel;
17use embassy_usb::{Builder, Config, UsbDevice}; 19use embassy_usb::{Builder, Config, UsbDevice};
18use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; 20use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State};
19use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
20use embassy_util::channel::mpmc::Channel;
21use embassy_util::Forever;
22use embedded_io::asynch::{Read, Write}; 21use embedded_io::asynch::{Read, Write};
22use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
24 24
25type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>; 25type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
26 26
27macro_rules! forever { 27macro_rules! singleton {
28 ($val:expr) => {{ 28 ($val:expr) => {{
29 type T = impl Sized; 29 type T = impl Sized;
30 static FOREVER: Forever<T> = Forever::new(); 30 static STATIC_CELL: StaticCell<T> = StaticCell::new();
31 FOREVER.put_with(move || $val) 31 STATIC_CELL.init_with(move || $val)
32 }}; 32 }};
33} 33}
34 34
@@ -116,7 +116,7 @@ async fn main(spawner: Spawner) {
116 control_buf: [u8; 128], 116 control_buf: [u8; 128],
117 serial_state: State<'static>, 117 serial_state: State<'static>,
118 } 118 }
119 let res: &mut Resources = forever!(Resources { 119 let res: &mut Resources = singleton!(Resources {
120 device_descriptor: [0; 256], 120 device_descriptor: [0; 256],
121 config_descriptor: [0; 256], 121 config_descriptor: [0; 256],
122 bos_descriptor: [0; 256], 122 bos_descriptor: [0; 256],
@@ -174,10 +174,10 @@ async fn main(spawner: Spawner) {
174 174
175 // Init network stack 175 // Init network stack
176 let device = Device { mac_addr: our_mac_addr }; 176 let device = Device { mac_addr: our_mac_addr };
177 let stack = &*forever!(Stack::new( 177 let stack = &*singleton!(Stack::new(
178 device, 178 device,
179 config, 179 config,
180 forever!(StackResources::<1, 2, 8>::new()), 180 singleton!(StackResources::<1, 2, 8>::new()),
181 seed 181 seed
182 )); 182 ));
183 183
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs
index cf0078eec..ba2159c72 100644
--- a/examples/nrf/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf/src/bin/usb_hid_keyboard.rs
@@ -8,14 +8,14 @@ use core::sync::atomic::{AtomicBool, Ordering};
8 8
9use defmt::*; 9use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_futures::{select, Either};
11use embassy_nrf::gpio::{Input, Pin, Pull}; 12use embassy_nrf::gpio::{Input, Pin, Pull};
12use embassy_nrf::usb::{Driver, PowerUsb}; 13use embassy_nrf::usb::{Driver, PowerUsb};
13use embassy_nrf::{interrupt, pac}; 14use embassy_nrf::{interrupt, pac};
15use embassy_sync::signal::Signal;
14use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Config, DeviceStateHandler}; 17use embassy_usb::{Builder, Config, DeviceStateHandler};
16use embassy_usb_hid::{HidReaderWriter, ReportId, RequestHandler, State}; 18use embassy_usb_hid::{HidReaderWriter, ReportId, RequestHandler, State};
17use embassy_util::channel::signal::Signal;
18use embassy_util::{select, Either};
19use futures::future::join; 19use futures::future::join;
20use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 20use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
21use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
index 4c1a93087..d62d7e520 100644
--- a/examples/nrf/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -12,7 +12,7 @@ use embassy_nrf::{interrupt, pac, peripherals};
12use embassy_usb::driver::EndpointError; 12use embassy_usb::driver::EndpointError;
13use embassy_usb::{Builder, Config, UsbDevice}; 13use embassy_usb::{Builder, Config, UsbDevice};
14use embassy_usb_serial::{CdcAcmClass, State}; 14use embassy_usb_serial::{CdcAcmClass, State};
15use embassy_util::Forever; 15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17 17
18type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>; 18type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>;
@@ -67,8 +67,8 @@ async fn main(spawner: Spawner) {
67 control_buf: [u8; 64], 67 control_buf: [u8; 64],
68 serial_state: State<'static>, 68 serial_state: State<'static>,
69 } 69 }
70 static RESOURCES: Forever<Resources> = Forever::new(); 70 static RESOURCES: StaticCell<Resources> = StaticCell::new();
71 let res = RESOURCES.put(Resources { 71 let res = RESOURCES.init(Resources {
72 device_descriptor: [0; 256], 72 device_descriptor: [0; 256],
73 config_descriptor: [0; 256], 73 config_descriptor: [0; 256],
74 bos_descriptor: [0; 256], 74 bos_descriptor: [0; 256],
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index c2dcf429a..d804a660b 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5 5
6 6
7[dependencies] 7[dependencies]
8embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
11embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] } 11embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] }
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index b7009017c..c7cec6b19 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-std-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["log"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] }
10embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "tcp", "udp", "dhcpv4", "pool-16"] } 10embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "tcp", "udp", "dhcpv4", "pool-16"] }
@@ -20,3 +20,4 @@ libc = "0.2.101"
20clap = { version = "3.0.0-beta.5", features = ["derive"] } 20clap = { version = "3.0.0-beta.5", features = ["derive"] }
21rand_core = { version = "0.6.3", features = ["std"] } 21rand_core = { version = "0.6.3", features = ["std"] }
22heapless = { version = "0.7.5", default-features = false } 22heapless = { version = "0.7.5", default-features = false }
23static_cell = "1.0"
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 528609260..9b1450b72 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -4,22 +4,22 @@ use clap::Parser;
4use embassy_executor::{Executor, Spawner}; 4use embassy_executor::{Executor, Spawner};
5use embassy_net::tcp::TcpSocket; 5use embassy_net::tcp::TcpSocket;
6use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 6use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources};
7use embassy_util::Forever;
8use embedded_io::asynch::Write; 7use embedded_io::asynch::Write;
9use heapless::Vec; 8use heapless::Vec;
10use log::*; 9use log::*;
11use rand_core::{OsRng, RngCore}; 10use rand_core::{OsRng, RngCore};
11use static_cell::StaticCell;
12 12
13#[path = "../tuntap.rs"] 13#[path = "../tuntap.rs"]
14mod tuntap; 14mod tuntap;
15 15
16use crate::tuntap::TunTapDevice; 16use crate::tuntap::TunTapDevice;
17 17
18macro_rules! forever { 18macro_rules! singleton {
19 ($val:expr) => {{ 19 ($val:expr) => {{
20 type T = impl Sized; 20 type T = impl Sized;
21 static FOREVER: Forever<T> = Forever::new(); 21 static STATIC_CELL: StaticCell<T> = StaticCell::new();
22 FOREVER.put_with(move || $val) 22 STATIC_CELL.init_with(move || $val)
23 }}; 23 }};
24} 24}
25 25
@@ -63,10 +63,10 @@ async fn main_task(spawner: Spawner) {
63 let seed = u64::from_le_bytes(seed); 63 let seed = u64::from_le_bytes(seed);
64 64
65 // Init network stack 65 // Init network stack
66 let stack = &*forever!(Stack::new( 66 let stack = &*singleton!(Stack::new(
67 device, 67 device,
68 config, 68 config,
69 forever!(StackResources::<1, 2, 8>::new()), 69 singleton!(StackResources::<1, 2, 8>::new()),
70 seed 70 seed
71 )); 71 ));
72 72
@@ -97,7 +97,7 @@ async fn main_task(spawner: Spawner) {
97 } 97 }
98} 98}
99 99
100static EXECUTOR: Forever<Executor> = Forever::new(); 100static EXECUTOR: StaticCell<Executor> = StaticCell::new();
101 101
102fn main() { 102fn main() {
103 env_logger::builder() 103 env_logger::builder()
@@ -106,7 +106,7 @@ fn main() {
106 .format_timestamp_nanos() 106 .format_timestamp_nanos()
107 .init(); 107 .init();
108 108
109 let executor = EXECUTOR.put(Executor::new()); 109 let executor = EXECUTOR.init(Executor::new());
110 executor.run(|spawner| { 110 executor.run(|spawner| {
111 spawner.spawn(main_task(spawner)).unwrap(); 111 spawner.spawn(main_task(spawner)).unwrap();
112 }); 112 });
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index 07e11c385..392a97f0d 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -4,21 +4,21 @@ use clap::Parser;
4use embassy_executor::{Executor, Spawner}; 4use embassy_executor::{Executor, Spawner};
5use embassy_net::udp::UdpSocket; 5use embassy_net::udp::UdpSocket;
6use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; 6use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources};
7use embassy_util::Forever;
8use heapless::Vec; 7use heapless::Vec;
9use log::*; 8use log::*;
10use rand_core::{OsRng, RngCore}; 9use rand_core::{OsRng, RngCore};
10use static_cell::StaticCell;
11 11
12#[path = "../tuntap.rs"] 12#[path = "../tuntap.rs"]
13mod tuntap; 13mod tuntap;
14 14
15use crate::tuntap::TunTapDevice; 15use crate::tuntap::TunTapDevice;
16 16
17macro_rules! forever { 17macro_rules! singleton {
18 ($val:expr) => {{ 18 ($val:expr) => {{
19 type T = impl Sized; 19 type T = impl Sized;
20 static FOREVER: Forever<T> = Forever::new(); 20 static STATIC_CELL: StaticCell<T> = StaticCell::new();
21 FOREVER.put_with(move || $val) 21 STATIC_CELL.init_with(move || $val)
22 }}; 22 }};
23} 23}
24 24
@@ -62,10 +62,10 @@ async fn main_task(spawner: Spawner) {
62 let seed = u64::from_le_bytes(seed); 62 let seed = u64::from_le_bytes(seed);
63 63
64 // Init network stack 64 // Init network stack
65 let stack = &*forever!(Stack::new( 65 let stack = &*singleton!(Stack::new(
66 device, 66 device,
67 config, 67 config,
68 forever!(StackResources::<1, 2, 8>::new()), 68 singleton!(StackResources::<1, 2, 8>::new()),
69 seed 69 seed
70 )); 70 ));
71 71
@@ -93,7 +93,7 @@ async fn main_task(spawner: Spawner) {
93 } 93 }
94} 94}
95 95
96static EXECUTOR: Forever<Executor> = Forever::new(); 96static EXECUTOR: StaticCell<Executor> = StaticCell::new();
97 97
98fn main() { 98fn main() {
99 env_logger::builder() 99 env_logger::builder()
@@ -102,7 +102,7 @@ fn main() {
102 .format_timestamp_nanos() 102 .format_timestamp_nanos()
103 .init(); 103 .init();
104 104
105 let executor = EXECUTOR.put(Executor::new()); 105 let executor = EXECUTOR.init(Executor::new());
106 executor.run(|spawner| { 106 executor.run(|spawner| {
107 spawner.spawn(main_task(spawner)).unwrap(); 107 spawner.spawn(main_task(spawner)).unwrap();
108 }); 108 });
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index 35cba4cee..85ee54f70 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -5,10 +5,10 @@ mod serial_port;
5 5
6use async_io::Async; 6use async_io::Async;
7use embassy_executor::Executor; 7use embassy_executor::Executor;
8use embassy_util::Forever;
9use embedded_io::asynch::Read; 8use embedded_io::asynch::Read;
10use log::*; 9use log::*;
11use nix::sys::termios; 10use nix::sys::termios;
11use static_cell::StaticCell;
12 12
13use self::serial_port::SerialPort; 13use self::serial_port::SerialPort;
14 14
@@ -40,7 +40,7 @@ async fn run() {
40 } 40 }
41} 41}
42 42
43static EXECUTOR: Forever<Executor> = Forever::new(); 43static EXECUTOR: StaticCell<Executor> = StaticCell::new();
44 44
45fn main() { 45fn main() {
46 env_logger::builder() 46 env_logger::builder()
@@ -49,7 +49,7 @@ fn main() {
49 .format_timestamp_nanos() 49 .format_timestamp_nanos()
50 .init(); 50 .init();
51 51
52 let executor = EXECUTOR.put(Executor::new()); 52 let executor = EXECUTOR.init(Executor::new());
53 executor.run(|spawner| { 53 executor.run(|spawner| {
54 spawner.spawn(run()).unwrap(); 54 spawner.spawn(run()).unwrap();
55 }); 55 });
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index 8476200d4..cd2995d2c 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -11,7 +11,7 @@ cortex-m-rt = "0.7.0"
11defmt = "0.3" 11defmt = "0.3"
12defmt-rtt = "0.3" 12defmt-rtt = "0.3"
13panic-probe = "0.3" 13panic-probe = "0.3"
14embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 14embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
15embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 15embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
16embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 16embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
17embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f030f4", "time-driver-any"] } 17embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f030f4", "time-driver-any"] }
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index fbc96400c..8660e743d 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32f1-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] }
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 27894df50..b4bff4d85 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32f2-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index b5ea28bb6..d152b145f 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32f3-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
@@ -23,3 +23,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
23heapless = { version = "0.7.5", default-features = false } 23heapless = { version = "0.7.5", default-features = false }
24nb = "1.0.0" 24nb = "1.0.0"
25embedded-storage = "0.3.0" 25embedded-storage = "0.3.0"
26static_cell = "1.0"
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs
index 61fc6dcab..02c475f66 100644
--- a/examples/stm32f3/src/bin/button_events.rs
+++ b/examples/stm32f3/src/bin/button_events.rs
@@ -15,9 +15,9 @@ use embassy_executor::Spawner;
15use embassy_stm32::exti::ExtiInput; 15use embassy_stm32::exti::ExtiInput;
16use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; 16use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed};
17use embassy_stm32::peripherals::PA0; 17use embassy_stm32::peripherals::PA0;
18use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
19use embassy_sync::channel::Channel;
18use embassy_time::{with_timeout, Duration, Timer}; 20use embassy_time::{with_timeout, Duration, Timer};
19use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
20use embassy_util::channel::mpmc::Channel;
21use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
22 22
23struct Leds<'a> { 23struct Leds<'a> {
diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs
index e96c31249..9e8228a4b 100644
--- a/examples/stm32f3/src/bin/multiprio.rs
+++ b/examples/stm32f3/src/bin/multiprio.rs
@@ -63,7 +63,7 @@ use embassy_stm32::executor::{Executor, InterruptExecutor};
63use embassy_stm32::interrupt; 63use embassy_stm32::interrupt;
64use embassy_stm32::interrupt::InterruptExt; 64use embassy_stm32::interrupt::InterruptExt;
65use embassy_time::{Duration, Instant, Timer}; 65use embassy_time::{Duration, Instant, Timer};
66use embassy_util::Forever; 66use static_cell::StaticCell;
67use {defmt_rtt as _, panic_probe as _}; 67use {defmt_rtt as _, panic_probe as _};
68 68
69#[embassy_executor::task] 69#[embassy_executor::task]
@@ -108,9 +108,9 @@ async fn run_low() {
108 } 108 }
109} 109}
110 110
111static EXECUTOR_HIGH: Forever<InterruptExecutor<interrupt::UART4>> = Forever::new(); 111static EXECUTOR_HIGH: StaticCell<InterruptExecutor<interrupt::UART4>> = StaticCell::new();
112static EXECUTOR_MED: Forever<InterruptExecutor<interrupt::UART5>> = Forever::new(); 112static EXECUTOR_MED: StaticCell<InterruptExecutor<interrupt::UART5>> = StaticCell::new();
113static EXECUTOR_LOW: Forever<Executor> = Forever::new(); 113static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
114 114
115#[entry] 115#[entry]
116fn main() -> ! { 116fn main() -> ! {
@@ -121,19 +121,19 @@ fn main() -> ! {
121 // High-priority executor: SWI1_EGU1, priority level 6 121 // High-priority executor: SWI1_EGU1, priority level 6
122 let irq = interrupt::take!(UART4); 122 let irq = interrupt::take!(UART4);
123 irq.set_priority(interrupt::Priority::P6); 123 irq.set_priority(interrupt::Priority::P6);
124 let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); 124 let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq));
125 let spawner = executor.start(); 125 let spawner = executor.start();
126 unwrap!(spawner.spawn(run_high())); 126 unwrap!(spawner.spawn(run_high()));
127 127
128 // Medium-priority executor: SWI0_EGU0, priority level 7 128 // Medium-priority executor: SWI0_EGU0, priority level 7
129 let irq = interrupt::take!(UART5); 129 let irq = interrupt::take!(UART5);
130 irq.set_priority(interrupt::Priority::P7); 130 irq.set_priority(interrupt::Priority::P7);
131 let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); 131 let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq));
132 let spawner = executor.start(); 132 let spawner = executor.start();
133 unwrap!(spawner.spawn(run_med())); 133 unwrap!(spawner.spawn(run_med()));
134 134
135 // Low priority executor: runs in thread mode, using WFE/SEV 135 // Low priority executor: runs in thread mode, using WFE/SEV
136 let executor = EXECUTOR_LOW.put(Executor::new()); 136 let executor = EXECUTOR_LOW.init(Executor::new());
137 executor.run(|spawner| { 137 executor.run(|spawner| {
138 unwrap!(spawner.spawn(run_low())); 138 unwrap!(spawner.spawn(run_low()));
139 }); 139 });
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index 04a217aff..9bfdda92d 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5 5
6 6
7[dependencies] 7[dependencies]
8embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 8embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 9embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] } 10embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
@@ -23,6 +23,7 @@ heapless = { version = "0.7.5", default-features = false }
23nb = "1.0.0" 23nb = "1.0.0"
24embedded-storage = "0.3.0" 24embedded-storage = "0.3.0"
25micromath = "2.0.0" 25micromath = "2.0.0"
26static_cell = "1.0"
26 27
27usb-device = "0.2" 28usb-device = "0.2"
28usbd-serial = "0.1.1" 29usbd-serial = "0.1.1"
diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs
index e96c31249..9e8228a4b 100644
--- a/examples/stm32f4/src/bin/multiprio.rs
+++ b/examples/stm32f4/src/bin/multiprio.rs
@@ -63,7 +63,7 @@ use embassy_stm32::executor::{Executor, InterruptExecutor};
63use embassy_stm32::interrupt; 63use embassy_stm32::interrupt;
64use embassy_stm32::interrupt::InterruptExt; 64use embassy_stm32::interrupt::InterruptExt;
65use embassy_time::{Duration, Instant, Timer}; 65use embassy_time::{Duration, Instant, Timer};
66use embassy_util::Forever; 66use static_cell::StaticCell;
67use {defmt_rtt as _, panic_probe as _}; 67use {defmt_rtt as _, panic_probe as _};
68 68
69#[embassy_executor::task] 69#[embassy_executor::task]
@@ -108,9 +108,9 @@ async fn run_low() {
108 } 108 }
109} 109}
110 110
111static EXECUTOR_HIGH: Forever<InterruptExecutor<interrupt::UART4>> = Forever::new(); 111static EXECUTOR_HIGH: StaticCell<InterruptExecutor<interrupt::UART4>> = StaticCell::new();
112static EXECUTOR_MED: Forever<InterruptExecutor<interrupt::UART5>> = Forever::new(); 112static EXECUTOR_MED: StaticCell<InterruptExecutor<interrupt::UART5>> = StaticCell::new();
113static EXECUTOR_LOW: Forever<Executor> = Forever::new(); 113static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
114 114
115#[entry] 115#[entry]
116fn main() -> ! { 116fn main() -> ! {
@@ -121,19 +121,19 @@ fn main() -> ! {
121 // High-priority executor: SWI1_EGU1, priority level 6 121 // High-priority executor: SWI1_EGU1, priority level 6
122 let irq = interrupt::take!(UART4); 122 let irq = interrupt::take!(UART4);
123 irq.set_priority(interrupt::Priority::P6); 123 irq.set_priority(interrupt::Priority::P6);
124 let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); 124 let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq));
125 let spawner = executor.start(); 125 let spawner = executor.start();
126 unwrap!(spawner.spawn(run_high())); 126 unwrap!(spawner.spawn(run_high()));
127 127
128 // Medium-priority executor: SWI0_EGU0, priority level 7 128 // Medium-priority executor: SWI0_EGU0, priority level 7
129 let irq = interrupt::take!(UART5); 129 let irq = interrupt::take!(UART5);
130 irq.set_priority(interrupt::Priority::P7); 130 irq.set_priority(interrupt::Priority::P7);
131 let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); 131 let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq));
132 let spawner = executor.start(); 132 let spawner = executor.start();
133 unwrap!(spawner.spawn(run_med())); 133 unwrap!(spawner.spawn(run_med()));
134 134
135 // Low priority executor: runs in thread mode, using WFE/SEV 135 // Low priority executor: runs in thread mode, using WFE/SEV
136 let executor = EXECUTOR_LOW.put(Executor::new()); 136 let executor = EXECUTOR_LOW.init(Executor::new());
137 executor.run(|spawner| { 137 executor.run(|spawner| {
138 unwrap!(spawner.spawn(run_low())); 138 unwrap!(spawner.spawn(run_low()));
139 }); 139 });
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 29d6da4d8..a446fe3fb 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32f7-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] }
@@ -24,3 +24,4 @@ nb = "1.0.0"
24rand_core = "0.6.3" 24rand_core = "0.6.3"
25critical-section = "1.1" 25critical-section = "1.1"
26embedded-storage = "0.3.0" 26embedded-storage = "0.3.0"
27static_cell = "1.0"
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index bdffabcb3..5202edf62 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -13,16 +13,16 @@ use embassy_stm32::rng::Rng;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{interrupt, Config}; 14use embassy_stm32::{interrupt, Config};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use embassy_util::Forever;
17use embedded_io::asynch::Write; 16use embedded_io::asynch::Write;
18use rand_core::RngCore; 17use rand_core::RngCore;
18use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21macro_rules! forever { 21macro_rules! singleton {
22 ($val:expr) => {{ 22 ($val:expr) => {{
23 type T = impl Sized; 23 type T = impl Sized;
24 static FOREVER: Forever<T> = Forever::new(); 24 static STATIC_CELL: StaticCell<T> = StaticCell::new();
25 FOREVER.put_with(move || $val) 25 STATIC_CELL.init_with(move || $val)
26 }}; 26 }};
27} 27}
28 28
@@ -52,7 +52,7 @@ async fn main(spawner: Spawner) -> ! {
52 52
53 let device = unsafe { 53 let device = unsafe {
54 Ethernet::new( 54 Ethernet::new(
55 forever!(State::new()), 55 singleton!(State::new()),
56 p.ETH, 56 p.ETH,
57 eth_int, 57 eth_int,
58 p.PA1, 58 p.PA1,
@@ -78,10 +78,10 @@ async fn main(spawner: Spawner) -> ! {
78 //}); 78 //});
79 79
80 // Init network stack 80 // Init network stack
81 let stack = &*forever!(Stack::new( 81 let stack = &*singleton!(Stack::new(
82 device, 82 device,
83 config, 83 config,
84 forever!(StackResources::<1, 2, 8>::new()), 84 singleton!(StackResources::<1, 2, 8>::new()),
85 seed 85 seed
86 )); 86 ));
87 87
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index 5c80d43eb..30f2b86f8 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32g0-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] }
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index 74c645cf5..f81df0b70 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32g4-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] }
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index a416796ea..0f76f3226 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32h7-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
@@ -28,6 +28,7 @@ critical-section = "1.1"
28micromath = "2.0.0" 28micromath = "2.0.0"
29stm32-fmc = "0.2.4" 29stm32-fmc = "0.2.4"
30embedded-storage = "0.3.0" 30embedded-storage = "0.3.0"
31static_cell = "1.0"
31 32
32# cargo build/run 33# cargo build/run
33[profile.dev] 34[profile.dev]
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 83210bcb5..4ccc0b5ef 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -13,16 +13,16 @@ use embassy_stm32::rng::Rng;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{interrupt, Config}; 14use embassy_stm32::{interrupt, Config};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use embassy_util::Forever;
17use embedded_io::asynch::Write; 16use embedded_io::asynch::Write;
18use rand_core::RngCore; 17use rand_core::RngCore;
18use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21macro_rules! forever { 21macro_rules! singleton {
22 ($val:expr) => {{ 22 ($val:expr) => {{
23 type T = impl Sized; 23 type T = impl Sized;
24 static FOREVER: Forever<T> = Forever::new(); 24 static STATIC_CELL: StaticCell<T> = StaticCell::new();
25 FOREVER.put_with(move || $val) 25 STATIC_CELL.init_with(move || $val)
26 }}; 26 }};
27} 27}
28 28
@@ -53,7 +53,7 @@ async fn main(spawner: Spawner) -> ! {
53 53
54 let device = unsafe { 54 let device = unsafe {
55 Ethernet::new( 55 Ethernet::new(
56 forever!(State::new()), 56 singleton!(State::new()),
57 p.ETH, 57 p.ETH,
58 eth_int, 58 eth_int,
59 p.PA1, 59 p.PA1,
@@ -79,10 +79,10 @@ async fn main(spawner: Spawner) -> ! {
79 //}); 79 //});
80 80
81 // Init network stack 81 // Init network stack
82 let stack = &*forever!(Stack::new( 82 let stack = &*singleton!(Stack::new(
83 device, 83 device,
84 config, 84 config,
85 forever!(StackResources::<1, 2, 8>::new()), 85 singleton!(StackResources::<1, 2, 8>::new()),
86 seed 86 seed
87 )); 87 ));
88 88
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 99946f504..64fd84141 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -13,17 +13,17 @@ use embassy_stm32::rng::Rng;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{interrupt, Config}; 14use embassy_stm32::{interrupt, Config};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use embassy_util::Forever;
17use embedded_io::asynch::Write; 16use embedded_io::asynch::Write;
18use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; 17use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
19use rand_core::RngCore; 18use rand_core::RngCore;
19use static_cell::StaticCell;
20use {defmt_rtt as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _};
21 21
22macro_rules! forever { 22macro_rules! singleton {
23 ($val:expr) => {{ 23 ($val:expr) => {{
24 type T = impl Sized; 24 type T = impl Sized;
25 static FOREVER: Forever<T> = Forever::new(); 25 static STATIC_CELL: StaticCell<T> = StaticCell::new();
26 FOREVER.put_with(move || $val) 26 STATIC_CELL.init_with(move || $val)
27 }}; 27 }};
28} 28}
29 29
@@ -54,7 +54,7 @@ async fn main(spawner: Spawner) -> ! {
54 54
55 let device = unsafe { 55 let device = unsafe {
56 Ethernet::new( 56 Ethernet::new(
57 forever!(State::new()), 57 singleton!(State::new()),
58 p.ETH, 58 p.ETH,
59 eth_int, 59 eth_int,
60 p.PA1, 60 p.PA1,
@@ -80,10 +80,10 @@ async fn main(spawner: Spawner) -> ! {
80 //}); 80 //});
81 81
82 // Init network stack 82 // Init network stack
83 let stack = &*forever!(Stack::new( 83 let stack = &*singleton!(Stack::new(
84 device, 84 device,
85 config, 85 config,
86 forever!(StackResources::<1, 2, 8>::new()), 86 singleton!(StackResources::<1, 2, 8>::new()),
87 seed 87 seed
88 )); 88 ));
89 89
diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs
index be2ac268e..cc3e4e3ca 100644
--- a/examples/stm32h7/src/bin/signal.rs
+++ b/examples/stm32h7/src/bin/signal.rs
@@ -4,8 +4,8 @@
4 4
5use defmt::{info, unwrap}; 5use defmt::{info, unwrap};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_sync::signal::Signal;
7use embassy_time::{Duration, Timer}; 8use embassy_time::{Duration, Timer};
8use embassy_util::channel::signal::Signal;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
11static SIGNAL: Signal<u32> = Signal::new(); 11static SIGNAL: Signal<u32> = Signal::new();
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index c28f937a8..1f407f002 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -12,8 +12,8 @@ use embassy_stm32::dma::NoDma;
12use embassy_stm32::peripherals::SPI3; 12use embassy_stm32::peripherals::SPI3;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{spi, Config}; 14use embassy_stm32::{spi, Config};
15use embassy_util::Forever;
16use heapless::String; 15use heapless::String;
16use static_cell::StaticCell;
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19#[embassy_executor::task] 19#[embassy_executor::task]
@@ -31,7 +31,7 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, NoDma, NoDma>) {
31 } 31 }
32} 32}
33 33
34static EXECUTOR: Forever<Executor> = Forever::new(); 34static EXECUTOR: StaticCell<Executor> = StaticCell::new();
35 35
36#[entry] 36#[entry]
37fn main() -> ! { 37fn main() -> ! {
@@ -54,7 +54,7 @@ fn main() -> ! {
54 spi::Config::default(), 54 spi::Config::default(),
55 ); 55 );
56 56
57 let executor = EXECUTOR.put(Executor::new()); 57 let executor = EXECUTOR.init(Executor::new());
58 58
59 executor.run(|spawner| { 59 executor.run(|spawner| {
60 unwrap!(spawner.spawn(main_task(spi))); 60 unwrap!(spawner.spawn(main_task(spi)));
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index 6c78c194f..53004fc9b 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -11,8 +11,8 @@ use embassy_executor::Executor;
11use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; 11use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3};
12use embassy_stm32::time::mhz; 12use embassy_stm32::time::mhz;
13use embassy_stm32::{spi, Config}; 13use embassy_stm32::{spi, Config};
14use embassy_util::Forever;
15use heapless::String; 14use heapless::String;
15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17 17
18#[embassy_executor::task] 18#[embassy_executor::task]
@@ -27,7 +27,7 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) {
27 } 27 }
28} 28}
29 29
30static EXECUTOR: Forever<Executor> = Forever::new(); 30static EXECUTOR: StaticCell<Executor> = StaticCell::new();
31 31
32#[entry] 32#[entry]
33fn main() -> ! { 33fn main() -> ! {
@@ -50,7 +50,7 @@ fn main() -> ! {
50 spi::Config::default(), 50 spi::Config::default(),
51 ); 51 );
52 52
53 let executor = EXECUTOR.put(Executor::new()); 53 let executor = EXECUTOR.init(Executor::new());
54 54
55 executor.run(|spawner| { 55 executor.run(|spawner| {
56 unwrap!(spawner.spawn(main_task(spi))); 56 unwrap!(spawner.spawn(main_task(spi)));
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs
index 1384d54c6..87c2b1253 100644
--- a/examples/stm32h7/src/bin/usart.rs
+++ b/examples/stm32h7/src/bin/usart.rs
@@ -7,7 +7,7 @@ use defmt::*;
7use embassy_executor::Executor; 7use embassy_executor::Executor;
8use embassy_stm32::dma::NoDma; 8use embassy_stm32::dma::NoDma;
9use embassy_stm32::usart::{Config, Uart}; 9use embassy_stm32::usart::{Config, Uart};
10use embassy_util::Forever; 10use static_cell::StaticCell;
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13#[embassy_executor::task] 13#[embassy_executor::task]
@@ -27,13 +27,13 @@ async fn main_task() {
27 } 27 }
28} 28}
29 29
30static EXECUTOR: Forever<Executor> = Forever::new(); 30static EXECUTOR: StaticCell<Executor> = StaticCell::new();
31 31
32#[entry] 32#[entry]
33fn main() -> ! { 33fn main() -> ! {
34 info!("Hello World!"); 34 info!("Hello World!");
35 35
36 let executor = EXECUTOR.put(Executor::new()); 36 let executor = EXECUTOR.init(Executor::new());
37 37
38 executor.run(|spawner| { 38 executor.run(|spawner| {
39 unwrap!(spawner.spawn(main_task())); 39 unwrap!(spawner.spawn(main_task()));
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index f8d58bb84..3adffcbeb 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -9,8 +9,8 @@ use defmt::*;
9use embassy_executor::Executor; 9use embassy_executor::Executor;
10use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
11use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
12use embassy_util::Forever;
13use heapless::String; 12use heapless::String;
13use static_cell::StaticCell;
14use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
15 15
16#[embassy_executor::task] 16#[embassy_executor::task]
@@ -30,13 +30,13 @@ async fn main_task() {
30 } 30 }
31} 31}
32 32
33static EXECUTOR: Forever<Executor> = Forever::new(); 33static EXECUTOR: StaticCell<Executor> = StaticCell::new();
34 34
35#[entry] 35#[entry]
36fn main() -> ! { 36fn main() -> ! {
37 info!("Hello World!"); 37 info!("Hello World!");
38 38
39 let executor = EXECUTOR.put(Executor::new()); 39 let executor = EXECUTOR.init(Executor::new());
40 40
41 executor.run(|spawner| { 41 executor.run(|spawner| {
42 unwrap!(spawner.spawn(main_task())); 42 unwrap!(spawner.spawn(main_task()));
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs
index 64080ec45..df2b600f8 100644
--- a/examples/stm32h7/src/bin/usart_split.rs
+++ b/examples/stm32h7/src/bin/usart_split.rs
@@ -7,8 +7,8 @@ use embassy_executor::Spawner;
7use embassy_stm32::dma::NoDma; 7use embassy_stm32::dma::NoDma;
8use embassy_stm32::peripherals::{DMA1_CH1, UART7}; 8use embassy_stm32::peripherals::{DMA1_CH1, UART7};
9use embassy_stm32::usart::{Config, Uart, UartRx}; 9use embassy_stm32::usart::{Config, Uart, UartRx};
10use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; 10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
11use embassy_util::channel::mpmc::Channel; 11use embassy_sync::channel::Channel;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14#[embassy_executor::task] 14#[embassy_executor::task]
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index fdb716d15..11751a21d 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -8,7 +8,7 @@ default = ["nightly"]
8nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan", "embedded-io/async"] 8nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan", "embedded-io/async"]
9 9
10[dependencies] 10[dependencies]
11embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 11embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 12embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
13embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 13embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
14embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } 14embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
@@ -29,3 +29,4 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
29futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 29futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
30heapless = { version = "0.7.5", default-features = false } 30heapless = { version = "0.7.5", default-features = false }
31embedded-hal = "0.2.6" 31embedded-hal = "0.2.6"
32static_cell = "1.0"
diff --git a/examples/stm32l0/src/bin/raw_spawn.rs b/examples/stm32l0/src/bin/raw_spawn.rs
index bd87e62a4..edc17304a 100644
--- a/examples/stm32l0/src/bin/raw_spawn.rs
+++ b/examples/stm32l0/src/bin/raw_spawn.rs
@@ -8,7 +8,7 @@ use defmt::*;
8use embassy_executor::raw::TaskStorage; 8use embassy_executor::raw::TaskStorage;
9use embassy_executor::Executor; 9use embassy_executor::Executor;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use embassy_util::Forever; 11use static_cell::StaticCell;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14async fn run1() { 14async fn run1() {
@@ -25,14 +25,14 @@ async fn run2() {
25 } 25 }
26} 26}
27 27
28static EXECUTOR: Forever<Executor> = Forever::new(); 28static EXECUTOR: StaticCell<Executor> = StaticCell::new();
29 29
30#[entry] 30#[entry]
31fn main() -> ! { 31fn main() -> ! {
32 info!("Hello World!"); 32 info!("Hello World!");
33 33
34 let _p = embassy_stm32::init(Default::default()); 34 let _p = embassy_stm32::init(Default::default());
35 let executor = EXECUTOR.put(Executor::new()); 35 let executor = EXECUTOR.init(Executor::new());
36 36
37 let run1_task = TaskStorage::new(); 37 let run1_task = TaskStorage::new();
38 let run2_task = TaskStorage::new(); 38 let run2_task = TaskStorage::new();
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index 43f844b67..18b35b305 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32l1-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] }
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index eaffa253e..cb7238e4c 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.1.0"
6[features] 6[features]
7 7
8[dependencies] 8[dependencies]
9embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 9embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } 12embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 4d96d31fc..624c73c26 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.1.0"
6[features] 6[features]
7 7
8[dependencies] 8[dependencies]
9embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 9embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 10embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 11embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } 12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
@@ -28,3 +28,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
28heapless = { version = "0.7.5", default-features = false } 28heapless = { version = "0.7.5", default-features = false }
29rand_core = { version = "0.6.3", default-features = false } 29rand_core = { version = "0.6.3", default-features = false }
30embedded-io = { version = "0.3.0", features = ["async"] } 30embedded-io = { version = "0.3.0", features = ["async"] }
31static_cell = "1.0"
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index 7c53d03cc..3286f5c4d 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -15,22 +15,22 @@ use embassy_stm32::rng::Rng;
15use embassy_stm32::time::Hertz; 15use embassy_stm32::time::Hertz;
16use embassy_stm32::usb::Driver; 16use embassy_stm32::usb::Driver;
17use embassy_stm32::{interrupt, Config}; 17use embassy_stm32::{interrupt, Config};
18use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
19use embassy_sync::channel::Channel;
18use embassy_usb::{Builder, UsbDevice}; 20use embassy_usb::{Builder, UsbDevice};
19use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; 21use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State};
20use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
21use embassy_util::channel::mpmc::Channel;
22use embassy_util::Forever;
23use embedded_io::asynch::{Read, Write}; 22use embedded_io::asynch::{Read, Write};
24use rand_core::RngCore; 23use rand_core::RngCore;
24use static_cell::StaticCell;
25use {defmt_rtt as _, panic_probe as _}; 25use {defmt_rtt as _, panic_probe as _};
26 26
27type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>; 27type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>;
28 28
29macro_rules! forever { 29macro_rules! singleton {
30 ($val:expr) => {{ 30 ($val:expr) => {{
31 type T = impl Sized; 31 type T = impl Sized;
32 static FOREVER: Forever<T> = Forever::new(); 32 static STATIC_CELL: StaticCell<T> = StaticCell::new();
33 FOREVER.put_with(move || $val) 33 STATIC_CELL.init_with(move || $val)
34 }}; 34 }};
35} 35}
36 36
@@ -115,7 +115,7 @@ async fn main(spawner: Spawner) {
115 control_buf: [u8; 128], 115 control_buf: [u8; 128],
116 serial_state: State<'static>, 116 serial_state: State<'static>,
117 } 117 }
118 let res: &mut Resources = forever!(Resources { 118 let res: &mut Resources = singleton!(Resources {
119 device_descriptor: [0; 256], 119 device_descriptor: [0; 256],
120 config_descriptor: [0; 256], 120 config_descriptor: [0; 256],
121 bos_descriptor: [0; 256], 121 bos_descriptor: [0; 256],
@@ -171,10 +171,10 @@ async fn main(spawner: Spawner) {
171 171
172 // Init network stack 172 // Init network stack
173 let device = Device { mac_addr: our_mac_addr }; 173 let device = Device { mac_addr: our_mac_addr };
174 let stack = &*forever!(Stack::new( 174 let stack = &*singleton!(Stack::new(
175 device, 175 device,
176 config, 176 config,
177 forever!(StackResources::<1, 2, 8>::new()), 177 singleton!(StackResources::<1, 2, 8>::new()),
178 seed 178 seed
179 )); 179 ));
180 180
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 48833664a..ff0ec9f42 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32u5-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] }
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index b46300764..3b10da0ad 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32wb-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55cc", "time-driver-any", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55cc", "time-driver-any", "exti"] }
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index ae33478af..5f6679f4b 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-stm32wl-examples"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] } 10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] }
diff --git a/examples/stm32wl/src/bin/subghz.rs b/examples/stm32wl/src/bin/subghz.rs
index d16e3f5e4..c5e9bb597 100644
--- a/examples/stm32wl/src/bin/subghz.rs
+++ b/examples/stm32wl/src/bin/subghz.rs
@@ -13,7 +13,7 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_stm32::interrupt; 13use embassy_stm32::interrupt;
14use embassy_stm32::interrupt::{Interrupt, InterruptExt}; 14use embassy_stm32::interrupt::{Interrupt, InterruptExt};
15use embassy_stm32::subghz::*; 15use embassy_stm32::subghz::*;
16use embassy_util::channel::signal::Signal; 16use embassy_sync::signal::Signal;
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19const PING_DATA: &str = "PING"; 19const PING_DATA: &str = "PING";
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index c7f980366..194e8f4b8 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -7,7 +7,7 @@ version = "0.1.0"
7crate-type = ["cdylib"] 7crate-type = ["cdylib"]
8 8
9[dependencies] 9[dependencies]
10embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["log"] } 10embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] }
11embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "wasm", "nightly", "integrated-timers"] } 11embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "wasm", "nightly", "integrated-timers"] }
12embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } 12embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "wasm", "nightly"] }
13 13
diff --git a/stm32-data b/stm32-data
Subproject 758c9e74625c68bc23d66ced8bfeb5643c63cec Subproject 14a448c318192fe9da1c95a4de1beb4ec4892f1
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 8740cc488..4d6877ccd 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -4,7 +4,7 @@ name = "embassy-rp-tests"
4version = "0.1.0" 4version = "0.1.0"
5 5
6[dependencies] 6[dependencies]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } 9embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] }
10embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits"] } 10embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits"] }
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 1d12995a2..f1441d00c 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -13,7 +13,7 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg"] # Nucleo
13stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board 13stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board
14 14
15[dependencies] 15[dependencies]
16embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 16embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
17embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } 17embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
18embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-32768hz"] } 18embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-32768hz"] }
19embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-tim2"] } 19embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-tim2"] }
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs
index fb4b3fcca..7673bfe6d 100644
--- a/tests/stm32/src/bin/usart.rs
+++ b/tests/stm32/src/bin/usart.rs
@@ -15,12 +15,6 @@ async fn main(_spawner: Spawner) {
15 let p = embassy_stm32::init(config()); 15 let p = embassy_stm32::init(config());
16 info!("Hello World!"); 16 info!("Hello World!");
17 17
18 #[cfg(feature = "stm32wb55rg")]
19 {
20 info!("Test SKIPPED");
21 cortex_m::asm::bkpt();
22 }
23
24 // Arduino pins D0 and D1 18 // Arduino pins D0 and D1
25 // They're connected together with a 1K resistor. 19 // They're connected together with a 1K resistor.
26 #[cfg(feature = "stm32f103c8")] 20 #[cfg(feature = "stm32f103c8")]
@@ -32,7 +26,7 @@ async fn main(_spawner: Spawner) {
32 #[cfg(feature = "stm32f429zi")] 26 #[cfg(feature = "stm32f429zi")]
33 let (tx, rx, usart) = (p.PG14, p.PG9, p.USART6); 27 let (tx, rx, usart) = (p.PG14, p.PG9, p.USART6);
34 #[cfg(feature = "stm32wb55rg")] 28 #[cfg(feature = "stm32wb55rg")]
35 let (tx, rx, usart) = (p.PA9, p.PA10, p.USART1); // TODO this is wrong 29 let (tx, rx, usart) = (p.PA2, p.PA3, p.LPUART1);
36 #[cfg(feature = "stm32h755zi")] 30 #[cfg(feature = "stm32h755zi")]
37 let (tx, rx, usart) = (p.PB6, p.PB7, p.USART1); 31 let (tx, rx, usart) = (p.PB6, p.PB7, p.USART1);
38 #[cfg(feature = "stm32u585ai")] 32 #[cfg(feature = "stm32u585ai")]
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs
index 09382a022..e0389446f 100644
--- a/tests/stm32/src/bin/usart_dma.rs
+++ b/tests/stm32/src/bin/usart_dma.rs
@@ -14,12 +14,6 @@ async fn main(_spawner: Spawner) {
14 let p = embassy_stm32::init(config()); 14 let p = embassy_stm32::init(config());
15 info!("Hello World!"); 15 info!("Hello World!");
16 16
17 #[cfg(feature = "stm32wb55rg")]
18 {
19 info!("Test SKIPPED");
20 cortex_m::asm::bkpt();
21 }
22
23 // Arduino pins D0 and D1 17 // Arduino pins D0 and D1
24 // They're connected together with a 1K resistor. 18 // They're connected together with a 1K resistor.
25 #[cfg(feature = "stm32f103c8")] 19 #[cfg(feature = "stm32f103c8")]
@@ -31,7 +25,7 @@ async fn main(_spawner: Spawner) {
31 #[cfg(feature = "stm32f429zi")] 25 #[cfg(feature = "stm32f429zi")]
32 let (tx, rx, usart, tx_dma, rx_dma) = (p.PG14, p.PG9, p.USART6, p.DMA2_CH6, p.DMA2_CH1); 26 let (tx, rx, usart, tx_dma, rx_dma) = (p.PG14, p.PG9, p.USART6, p.DMA2_CH6, p.DMA2_CH1);
33 #[cfg(feature = "stm32wb55rg")] 27 #[cfg(feature = "stm32wb55rg")]
34 let (tx, rx, usart, tx_dma, rx_dma) = (p.PA9, p.PA10, p.USART1, p.DMA1_CH1, p.DMA1_CH2); // TODO this is wrong 28 let (tx, rx, usart, tx_dma, rx_dma) = (p.PA2, p.PA3, p.LPUART1, p.DMA1_CH1, p.DMA1_CH2);
35 #[cfg(feature = "stm32h755zi")] 29 #[cfg(feature = "stm32h755zi")]
36 let (tx, rx, usart, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, p.DMA1_CH0, p.DMA1_CH1); 30 let (tx, rx, usart, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, p.DMA1_CH0, p.DMA1_CH1);
37 #[cfg(feature = "stm32u585ai")] 31 #[cfg(feature = "stm32u585ai")]