Repository: embassy-rs/embassy
Pull request #3775 (2025-01-15 10:39:38)

feat: add dynamic dispatch variants of pipe


Patch:
diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml
index f52788ba3..292cccf66 100644
--- a/cyw43-pio/Cargo.toml
+++ b/cyw43-pio/Cargo.toml
@@ -12,8 +12,8 @@ documentation = "https://docs.embassy.dev/cyw43-pio"
 [dependencies]
 cyw43 = { version = "0.3.0", path = "../cyw43" }
 embassy-rp = { version = "0.3.0", path = "../embassy-rp" }
-pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
-pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
+pio-proc = "0.2"
+pio = "0.2.1"
 fixed = "1.23.1"
 defmt = { version = "0.3", optional = true }
 
diff --git a/docs/examples/layer-by-layer/Cargo.toml b/docs/examples/layer-by-layer/Cargo.toml
index f18c9e7e4..0f233eae5 100644
--- a/docs/examples/layer-by-layer/Cargo.toml
+++ b/docs/examples/layer-by-layer/Cargo.toml
@@ -7,6 +7,10 @@ members = [
     "blinky-async",
 ]
 
+[patch.crates-io]
+embassy-executor = { path = "../../../embassy-executor" }
+embassy-stm32 = { path = "../../../embassy-stm32" }
+
 [profile.release]
 codegen-units = 1
 debug = 2
diff --git a/docs/examples/layer-by-layer/blinky-async/Cargo.toml b/docs/examples/layer-by-layer/blinky-async/Cargo.toml
index 51ddf87d4..f6d2e4fc7 100644
--- a/docs/examples/layer-by-layer/blinky-async/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-async/Cargo.toml
@@ -7,9 +7,9 @@ license = "MIT OR Apache-2.0"
 [dependencies]
 cortex-m = "0.7"
 cortex-m-rt = "0.7"
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "exti"]  }
-embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
+embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "exti"]  }
+embassy-executor = { version = "0.6.3", features = ["arch-cortex-m", "executor-thread"] }
 
-defmt = "0.3"
-defmt-rtt = "0.4"
+defmt = "0.3.0"
+defmt-rtt = "0.3.0"
 panic-probe = { version = "0.3.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
index 1e292e6b4..c15de2db2 100644
--- a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
@@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
 [dependencies]
 cortex-m = "0.7"
 cortex-m-rt = "0.7"
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x"] }
+embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x"] }
 
-defmt = "0.3"
-defmt-rtt = "0.4"
+defmt = "0.3.0"
+defmt-rtt = "0.3.0"
 panic-probe = { version = "0.3.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
index 04ffc23ba..9733658b6 100644
--- a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
@@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
 [dependencies]
 cortex-m = "0.7"
 cortex-m-rt = { version = "0.7" }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "unstable-pac"] }
+embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "unstable-pac"] }
 
-defmt = "0.3"
-defmt-rtt = "0.4"
+defmt = "0.3.0"
+defmt-rtt = "0.3.0"
 panic-probe = { version = "0.3.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
index cf2d7fede..f872b94cb 100644
--- a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
@@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
 [dependencies]
 cortex-m = "0.7"
 cortex-m-rt = "0.7"
-stm32-metapac = { version = "16", features = ["stm32l475vg"] }
+stm32-metapac = { version = "1", features = ["stm32l475vg", "memory-x"] }
 
-defmt = "0.3"
-defmt-rtt = "0.4"
+defmt = "0.3.0"
+defmt-rtt = "0.3.0"
 panic-probe = { version = "0.3.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-pac/src/main.rs b/docs/examples/layer-by-layer/blinky-pac/src/main.rs
index cfbd91306..990d46cb6 100644
--- a/docs/examples/layer-by-layer/blinky-pac/src/main.rs
+++ b/docs/examples/layer-by-layer/blinky-pac/src/main.rs
@@ -8,38 +8,46 @@ use {defmt_rtt as _, panic_probe as _, stm32_metapac as pac};
 fn main() -> ! {
     // Enable GPIO clock
     let rcc = pac::RCC;
-    rcc.ahb2enr().modify(|w| {
-        w.set_gpioben(true);
-        w.set_gpiocen(true);
-    });
+    unsafe {
+        rcc.ahb2enr().modify(|w| {
+            w.set_gpioben(true);
+            w.set_gpiocen(true);
+        });
 
-    rcc.ahb2rstr().modify(|w| {
-        w.set_gpiobrst(true);
-        w.set_gpiocrst(true);
-        w.set_gpiobrst(false);
-        w.set_gpiocrst(false);
-    });
+        rcc.ahb2rstr().modify(|w| {
+            w.set_gpiobrst(true);
+            w.set_gpiocrst(true);
+            w.set_gpiobrst(false);
+            w.set_gpiocrst(false);
+        });
+    }
 
     // Setup button
     let gpioc = pac::GPIOC;
     const BUTTON_PIN: usize = 13;
-    gpioc.pupdr().modify(|w| w.set_pupdr(BUTTON_PIN, vals::Pupdr::PULL_UP));
-    gpioc.otyper().modify(|w| w.set_ot(BUTTON_PIN, vals::Ot::PUSH_PULL));
-    gpioc.moder().modify(|w| w.set_moder(BUTTON_PIN, vals::Moder::INPUT));
+    unsafe {
+        gpioc.pupdr().modify(|w| w.set_pupdr(BUTTON_PIN, vals::Pupdr::PULLUP));
+        gpioc.otyper().modify(|w| w.set_ot(BUTTON_PIN, vals::Ot::PUSHPULL));
+        gpioc.moder().modify(|w| w.set_moder(BUTTON_PIN, vals::Moder::INPUT));
+    }
 
     // Setup LED
     let gpiob = pac::GPIOB;
     const LED_PIN: usize = 14;
-    gpiob.pupdr().modify(|w| w.set_pupdr(LED_PIN, vals::Pupdr::FLOATING));
-    gpiob.otyper().modify(|w| w.set_ot(LED_PIN, vals::Ot::PUSH_PULL));
-    gpiob.moder().modify(|w| w.set_moder(LED_PIN, vals::Moder::OUTPUT));
+    unsafe {
+        gpiob.pupdr().modify(|w| w.set_pupdr(LED_PIN, vals::Pupdr::FLOATING));
+        gpiob.otyper().modify(|w| w.set_ot(LED_PIN, vals::Ot::PUSHPULL));
+        gpiob.moder().modify(|w| w.set_moder(LED_PIN, vals::Moder::OUTPUT));
+    }
 
     // Main loop
     loop {
-        if gpioc.idr().read().idr(BUTTON_PIN) == vals::Idr::LOW {
-            gpiob.bsrr().write(|w| w.set_bs(LED_PIN, true));
-        } else {
-            gpiob.bsrr().write(|w| w.set_br(LED_PIN, true));
+        unsafe {
+            if gpioc.idr().read().idr(BUTTON_PIN) == vals::Idr::LOW {
+                gpiob.bsrr().write(|w| w.set_bs(LED_PIN, true));
+            } else {
+                gpiob.bsrr().write(|w| w.set_br(LED_PIN, true));
+            }
         }
     }
 }
diff --git a/docs/pages/overview.adoc b/docs/pages/overview.adoc
index 6ac0e0b2b..8f97d937f 100644
--- a/docs/pages/overview.adoc
+++ b/docs/pages/overview.adoc
@@ -6,7 +6,7 @@ Embassy is a project to make async/await a first-class option for embedded devel
 
 When handling I/O, software must call functions that block program execution until the I/O operation completes. When running inside of an OS such as Linux, such functions generally transfer control to the kernel so that another task (known as a “thread”) can be executed if available, or the CPU can be put to sleep until another task is ready.
 
-Because an OS cannot presume that threads will behave cooperatively, threads are relatively resource-intensive, and may be forcibly interrupted if they do not transfer control back to the kernel within an allotted time. If tasks could be presumed to behave cooperatively, or at least not maliciously, it would be possible to create tasks that appear to be almost free when compared to a traditional OS thread.
+Because an OS cannot presume that threads will behave cooperatively, threads are relatively resource-intensive, and may be forcibly interrupted they do not transfer control back to the kernel within an allotted time. If tasks could be presumed to behave cooperatively, or at least not maliciously, it would be possible to create tasks that appear to be almost free when compared to a traditional OS thread.
 
 In other programming languages, these lightweight tasks are known as “coroutines” or ”goroutines”. In Rust, they are implemented with async. Async-await works by transforming each async function into an object called a future. When a future blocks on I/O the future yields, and the scheduler, called an executor, can select a different future to execute.
 
@@ -80,5 +80,4 @@ For more reading material on async Rust and Embassy:
 
 Videos:
 
-* link:https://www.youtube.com/watch?v=pDd5mXBF4tY[Intro to Embassy]
 * link:https://www.youtube.com/watch?v=wni5h5vIPhU[From Zero to Async in Embedded Rust]
diff --git a/embassy-boot-stm32/Cargo.toml b/embassy-boot-stm32/Cargo.toml
index 2d38ba8b1..e2d7c19cb 100644
--- a/embassy-boot-stm32/Cargo.toml
+++ b/embassy-boot-stm32/Cargo.toml
@@ -25,7 +25,7 @@ defmt = { version = "0.3", optional = true }
 log = { version = "0.4", optional = true }
 
 embassy-sync = { version = "0.6.1", path = "../embassy-sync" }
-embassy-stm32 = { version = "0.2.0", path = "../embassy-stm32", default-features = false }
+embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false }
 embassy-boot = { version = "0.4.0", path = "../embassy-boot" }
 cortex-m = { version = "0.7.6" }
 cortex-m-rt = { version = "0.7" }
diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md
index 5d2468c58..2c7f8c62e 100644
--- a/embassy-executor/CHANGELOG.md
+++ b/embassy-executor/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## 0.7.0 - 2025-01-02
+## 0.7.0 - 2024-01-02
 
 - Performance optimizations.
 - Remove feature `integrated-timers`. Starting with `embassy-time-driver` v0.2, `embassy-time` v0.4 the timer queue is now part of the time driver, so it's no longer the executor's responsibility. Therefore, `embassy-executor` no longer provides an `embassy-time-queue-driver` implementation.
diff --git a/embassy-net-ppp/CHANGELOG.md b/embassy-net-ppp/CHANGELOG.md
deleted file mode 100644
index 6ce64ddcb..000000000
--- a/embassy-net-ppp/CHANGELOG.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Changelog for embassy-net-ppp
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## 0.2.0 - 2025-01-12
-
-- Update `ppproto` to v0.2.
-- Use `core::net` IP types for IPv4 configuration instead of a custom type.
-
-## 0.1.0 - 2024-01-12
-
-First release.
diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml
index 414be5e01..9c214d5ae 100644
--- a/embassy-net-ppp/Cargo.toml
+++ b/embassy-net-ppp/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "embassy-net-ppp"
-version = "0.2.0"
+version = "0.1.0"
 description = "embassy-net driver for PPP over Serial"
 keywords = ["embedded", "ppp", "embassy-net", "embedded-hal-async", "async"]
 categories = ["embedded", "hardware-support", "no-std", "network-programming", "asynchronous"]
@@ -20,7 +20,7 @@ log = { version = "0.4.14", optional = true }
 embedded-io-async = { version = "0.6.1" }
 embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
-ppproto = { version = "0.2.1"}
+ppproto = { version = "0.2.0"}
 embassy-sync = { version = "0.6.1", path = "../embassy-sync" }
 
 [package.metadata.embassy_docs]
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index c78fa4df5..cacaf1911 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -30,7 +30,7 @@ pub enum Port {
 }
 
 /// Pull setting for an input.
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub enum Pull {
     /// No pull.
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index 120e058ed..56cc39bbf 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -139,8 +139,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
 embedded-hal-async = { version = "1.0" }
 embedded-hal-nb = { version = "1.0" }
 
-pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
-pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
+pio-proc = { version= "0.2" }
+pio = { version= "0.2.1" }
 rp2040-boot2 = "0.3"
 document-features = "0.2.10"
 sha2-const-stable = "0.1"
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index 7632d3168..8916cbef0 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -50,18 +50,6 @@ pub enum FifoJoin {
     RxOnly,
     /// Tx fifo twice as deep. RX fifo disabled
     TxOnly,
-    /// Enable random writes (`FJOIN_RX_PUT`) from the state machine (through ISR),
-    /// and random reads from the system (using [`StateMachine::get_rxf_entry`]).
-    #[cfg(feature = "_rp235x")]
-    RxAsStatus,
-    /// Enable random reads (`FJOIN_RX_GET`) from the state machine (through OSR),
-    /// and random writes from the system (using [`StateMachine::set_rxf_entry`]).
-    #[cfg(feature = "_rp235x")]
-    RxAsControl,
-    /// FJOIN_RX_PUT | FJOIN_RX_GET: RX can be used as a scratch register,
-    /// not accesible from the CPU
-    #[cfg(feature = "_rp235x")]
-    PioScratch,
 }
 
 /// Shift direction.
@@ -742,17 +730,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
             w.set_in_shiftdir(config.shift_in.direction == ShiftDirection::Right);
             w.set_autopull(config.shift_out.auto_fill);
             w.set_autopush(config.shift_in.auto_fill);
-
-            #[cfg(feature = "_rp235x")]
-            {
-                w.set_fjoin_rx_get(
-                    config.fifo_join == FifoJoin::RxAsControl || config.fifo_join == FifoJoin::PioScratch,
-                );
-                w.set_fjoin_rx_put(
-                    config.fifo_join == FifoJoin::RxAsStatus || config.fifo_join == FifoJoin::PioScratch,
-                );
-                w.set_in_count(config.in_count);
-            }
         });
 
         #[cfg(feature = "rp2040")]
@@ -930,20 +907,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
     pub fn rx_tx(&mut self) -> (&mut StateMachineRx<'d, PIO, SM>, &mut StateMachineTx<'d, PIO, SM>) {
         (&mut self.rx, &mut self.tx)
     }
-
-    /// Return the contents of the nth entry of the RX FIFO
-    /// (should be used only when the FIFO config is set to [`FifoJoin::RxAsStatus`])
-    #[cfg(feature = "_rp235x")]
-    pub fn get_rxf_entry(&self, n: usize) -> u32 {
-        PIO::PIO.rxf_putget(SM).putget(n).read()
-    }
-
-    /// Set the contents of the nth entry of the RX FIFO
-    /// (should be used only when the FIFO config is set to [`FifoJoin::RxAsControl`])
-    #[cfg(feature = "_rp235x")]
-    pub fn set_rxf_entry(&self, n: usize, val: u32) {
-        PIO::PIO.rxf_putget(SM).putget(n).write_value(val)
-    }
 }
 
 /// PIO handle.
@@ -1030,9 +993,6 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
         prog: &Program<SIZE>,
         origin: u8,
     ) -> Result<LoadedProgram<'d, PIO>, usize> {
-        #[cfg(not(feature = "_rp235x"))]
-        assert!(prog.version == pio::PioVersion::V0);
-
         let prog = RelocatedProgram::new_with_origin(prog, origin);
         let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?;
         Ok(LoadedProgram {
@@ -1093,12 +1053,6 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
     /// of [`Pio`] do not keep pin registrations alive.**
     pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> {
         into_ref!(pin);
-
-        // enable the outputs
-        pin.pad_ctrl().write(|w| w.set_od(false));
-        // especially important on the 235x, where IE defaults to 0
-        pin.pad_ctrl().write(|w| w.set_ie(true));
-
         pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _));
         pin.pad_ctrl().write(|w| {
             #[cfg(feature = "_rp235x")]
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 19adc0e1b..876fc92b9 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -19,7 +19,7 @@ features = ["stm32wb55rg", "ble", "mac"]
 features = ["stm32wb55rg", "ble", "mac"]
 
 [dependencies]
-embassy-stm32 = { version = "0.2.0", path = "../embassy-stm32" }
+embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
 embassy-sync = { version = "0.6.1", path = "../embassy-sync" }
 embassy-time = { version = "0.4.0", path = "../embassy-time", optional = true }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
deleted file mode 100644
index 10b0739fb..000000000
--- a/embassy-stm32/CHANGELOG.md
+++ /dev/null
@@ -1,275 +0,0 @@
-# Changelog for embassy-stm32
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## 0.2.0 - 2025-01-10
-
-Starting 2025 strong with a release packed with new, exciting good stuff! 🚀
-
-### New chips
-
-This release adds support for many newly-released STM32 chips.
-
-- STM32H7[RS] "bootflash line" ([#2898](https://github.com/embassy-rs/embassy/pull/2898))
-- STM32U0 ([#2809](https://github.com/embassy-rs/embassy/pull/2809) [#2813](https://github.com/embassy-rs/embassy/pull/2813))
-- STM32H5[23] ([#2892](https://github.com/embassy-rs/embassy/pull/2892))
-- STM32U5[FG] ([#2892](https://github.com/embassy-rs/embassy/pull/2892))
-- STM32WBA5[045] ([#2892](https://github.com/embassy-rs/embassy/pull/2892))
-
-### Simpler APIs with less generics
-
-Many HAL APIs have been simplified thanks to reducing the amount of generic parameters. This helps with creating arrays of pins or peripherals, and for calling the same code with different pins/peripherals without incurring in code size penalties d
-
-For GPIO, the pins have been eliminated. `Output<'_, PA4>` is now `Output<'_>`.
-
-For peripherals, both pins and DMA channels have been eliminated. Peripherals now have a "mode" generic param that specifies whether it's capable of async operation. For example, `I2c<'_, I2C2, NoDma, NoDma>` is now `I2c<'_, Blocking>` and `I2c<'_, I2C2, DMA2_CH1, DMA2_CH2>` is now `I2c<'_, Async>`.
-
-- Removed DMA channel generic params for UART ([#2821](https://github.com/embassy-rs/embassy/pull/2821)), I2C ([#2820](https://github.com/embassy-rs/embassy/pull/2820)), SPI ([#2819](https://github.com/embassy-rs/embassy/pull/2819)), QSPI ([#2982](https://github.com/embassy-rs/embassy/pull/2982)), OSPI ([#2941](https://github.com/embassy-rs/embassy/pull/2941)).
-- Removed peripheral generic params for GPIO ([#2471](https://github.com/embassy-rs/embassy/pull/2471)), UART ([#2836](https://github.com/embassy-rs/embassy/pull/2836)), I2C ([#2974](https://github.com/embassy-rs/embassy/pull/2974)), SPI ([#2835](https://github.com/embassy-rs/embassy/pull/2835))
-- Remove generics in CAN ([#3012](https://github.com/embassy-rs/embassy/pull/3012), [#3020](https://github.com/embassy-rs/embassy/pull/3020), [#3032](https://github.com/embassy-rs/embassy/pull/3032), [#3033](https://github.com/embassy-rs/embassy/pull/3033))
-
-### More complete and consistent RCC
-
-RCC support has been vastly expanded and improved.
-- The API is now consistent across all STM32 families. Previously in some families you'd configure the desired target frequencies for `sysclk` and the buses and `embassy-stm32` would try to calculate dividers and muxes to hit them as close as possible. This has proved to be intractable in the general case and hard to extend to more exotic RCC configurations. So, we have standardized on an API where the user specifies the settings for dividers and muxes directly. It's lower level but gices more control to the user, supports all edge case exotic configurations, and makes it easier to translate a configuration from the STM32CubeMX tool. ([Tracking issue](https://github.com/embassy-rs/embassy/issues/2515). [#2624](https://github.com/embassy-rs/embassy/pull/2624). F0, F1 [#2564](https://github.com/embassy-rs/embassy/pull/2564), F3 [#2560](https://github.com/embassy-rs/embassy/pull/2560), U5 [#2617](https://github.com/embassy-rs/embassy/pull/2617), [#3514](https://github.com/embassy-rs/embassy/pull/3514), [#3513](https://github.com/embassy-rs/embassy/pull/3513), G4 [#2579](https://github.com/embassy-rs/embassy/pull/2579), [#2618](https://github.com/embassy-rs/embassy/pull/2618), WBA [#2520](https://github.com/embassy-rs/embassy/pull/2520), G0, C0 ([#2656](https://github.com/embassy-rs/embassy/pull/2656)).
-- Added support for configuring all per-peripheral clock muxes (CCIPRx, DCKCFGRx registers) in `config.rcc.mux`. This was previously handled in an ad-hoc way in some drivers (e.g. USB) and not at all in others (causing e.g. wrong SPI frequency) ([#2521](https://github.com/embassy-rs/embassy/pull/2521), [#2583](https://github.com/embassy-rs/embassy/pull/2583), [#2634](https://github.com/embassy-rs/embassy/pull/2634), [#2626](https://github.com/embassy-rs/embassy/pull/2626), [#2815](https://github.com/embassy-rs/embassy/pull/2815), [#2517](https://github.com/embassy-rs/embassy/pull/2517)).
-- Switch to a safe configuration before configuring RCC. This helps avoid crashes when RCC has been already configured previously (for example by a bootloader). (F2, F4, F7 [#2829](https://github.com/embassy-rs/embassy/pull/2829), C0, F0, F1, F3, G0, G4, H5, H7[#3008](https://github.com/embassy-rs/embassy/pull/3008))
-- Some new nice features:
-    - Expose RCC enable and disable in public API. ([#2807](https://github.com/embassy-rs/embassy/pull/2807))
-    - Add `unchecked-overclocking` feature that disables all asserts, allowing running RCC out of spec. ([#3574](https://github.com/embassy-rs/embassy/pull/3574))
-- Many fixes:
-    - Workaround H5 errata that accidentally clears RAM on backup domain reset. ([#2616](https://github.com/embassy-rs/embassy/pull/2616))
-    - Reset RTC on L0 ([#2597](https://github.com/embassy-rs/embassy/pull/2597))
-    - Fix H7 to use correct unit in vco clock check ([#2537](https://github.com/embassy-rs/embassy/pull/2537))
-    - Fix incorrect D1CPRE max for STM32H7 RM0468 ([#2518](https://github.com/embassy-rs/embassy/pull/2518))
-    - WBA's high speed external clock has to run at 32 MHz ([#2511](https://github.com/embassy-rs/embassy/pull/2511))
-    - Take into account clock propagation delay to peripherals after enabling a clock. ([#2677](https://github.com/embassy-rs/embassy/pull/2677))
-    - Fix crash caused by using higher MSI range as sysclk on STM32WL ([#2786](https://github.com/embassy-rs/embassy/pull/2786))
-    - fix using HSI48 as SYSCLK on F0 devices with CRS ([#3652](https://github.com/embassy-rs/embassy/pull/3652))
-    - compute LSE and LSI frequency for STM32L and STM32U0 series ([#3554](https://github.com/embassy-rs/embassy/pull/3554))
-    - Add support for LSESYS, used to pass LSE clock to peripherals ([#3518](https://github.com/embassy-rs/embassy/pull/3518))
-    - H5: LSE low drive mode is not functional ([#2738](https://github.com/embassy-rs/embassy/pull/2738))
-
-### New peripheral drivers
-
-- Dual-core support. First core initializes RCC and writes a struct into shared memory that the second core uses, ensuring no conflicts. ([#3158](https://github.com/embassy-rs/embassy/pull/3158), [#3263](https://github.com/embassy-rs/embassy/pull/3263), [#3687](https://github.com/embassy-rs/embassy/pull/3687))
-- USB Type-C/USB Power Delivery Interface (UCPD) ([#2652](https://github.com/embassy-rs/embassy/pull/2652), [#2683](https://github.com/embassy-rs/embassy/pull/2683), [#2701](https://github.com/embassy-rs/embassy/pull/2701), [#2925](https://github.com/embassy-rs/embassy/pull/2925), [#3084](https://github.com/embassy-rs/embassy/pull/3084), [#3271](https://github.com/embassy-rs/embassy/pull/3271), [#3678](https://github.com/embassy-rs/embassy/pull/3678), [#3714](https://github.com/embassy-rs/embassy/pull/3714))
-- Touch sensing controller (TSC) ([#2853](https://github.com/embassy-rs/embassy/pull/2853), [#3111](https://github.com/embassy-rs/embassy/pull/3111), [#3163](https://github.com/embassy-rs/embassy/pull/3163), [#3274](https://github.com/embassy-rs/embassy/pull/3274))
-- Display Serial Interface (DSI) [#2903](https://github.com/embassy-rs/embassy/pull/2903), ([#3082](https://github.com/embassy-rs/embassy/pull/3082))
-- LCD/TFT Display Controller (LTDC) ([#3126](https://github.com/embassy-rs/embassy/pull/3126), [#3458](https://github.com/embassy-rs/embassy/pull/3458))
-- SPDIF receiver (SPDIFRX) ([#3280](https://github.com/embassy-rs/embassy/pull/3280))
-- CORDIC math accelerator ([#2697](https://github.com/embassy-rs/embassy/pull/2697))
-- Digital Temperature Sensor (DTS) ([#3717](https://github.com/embassy-rs/embassy/pull/3717))
-- HMAC accelerator ([#2565](https://github.com/embassy-rs/embassy/pull/2565))
-- Hash accelerator ([#2528](https://github.com/embassy-rs/embassy/pull/2528))
-- Crypto accelerator ([#2619](https://github.com/embassy-rs/embassy/pull/2619), [#2691](https://github.com/embassy-rs/embassy/pull/2691))
-- Semaphore (HSEM) ([#2777](https://github.com/embassy-rs/embassy/pull/2777), [#3161](https://github.com/embassy-rs/embassy/pull/3161))
-
-### Improvements to existing drivers
-
-GPIO:
-- Generate singletons only for pins that actually exist. ([#3738](https://github.com/embassy-rs/embassy/pull/3738))
-- Add `set_as_analog` to Flex ([#3017](https://github.com/embassy-rs/embassy/pull/3017))
-- Add `embedded-hal` v0.2 `InputPin` impls for `OutputOpenDrain`. ([#2716](https://github.com/embassy-rs/embassy/pull/2716))
-- Add a config option to make the VDDIO2 supply line valid ([#2737](https://github.com/embassy-rs/embassy/pull/2737))
-- Refactor AfType ([#3031](https://github.com/embassy-rs/embassy/pull/3031))
-- Gpiov1: Do not call set_speed for AFType::Input ([#2996](https://github.com/embassy-rs/embassy/pull/2996))
-
-UART: 
-- Add embedded-io impls ([#2739](https://github.com/embassy-rs/embassy/pull/2739))
-- Add support for changing baud rate ([#3512](https://github.com/embassy-rs/embassy/pull/3512))
-- Add split_ref ([#3500](https://github.com/embassy-rs/embassy/pull/3500))
-- Add data bit selection ([#3595](https://github.com/embassy-rs/embassy/pull/3595))
-- Add RX Pull configuration option ([#3415](https://github.com/embassy-rs/embassy/pull/3415))
-- Add async flush ([#3379](https://github.com/embassy-rs/embassy/pull/3379))
-- Add support for sending breaks ([#3286](https://github.com/embassy-rs/embassy/pull/3286))
-- Disconnect pins on drop ([#3006](https://github.com/embassy-rs/embassy/pull/3006))
-- Half-duplex improvements
-    - Add half-duplex for all USART versions ([#2833](https://github.com/embassy-rs/embassy/pull/2833))
-    - configurable readback for half-duplex. ([#3679](https://github.com/embassy-rs/embassy/pull/3679))
-    - Convert uart half_duplex to use user configurable IO ([#3233](https://github.com/embassy-rs/embassy/pull/3233))
-    - Fix uart::flush with FIFO at Half-Duplex mode ([#2895](https://github.com/embassy-rs/embassy/pull/2895))
-    - Fix Half-Duplex sequential reads and writes ([#3089](https://github.com/embassy-rs/embassy/pull/3089))
-    - disable transmitter during during half-duplex flush ([#3299](https://github.com/embassy-rs/embassy/pull/3299))
-- Buffered UART improvements
-    - Add embedded-io ReadReady impls ([#3179](https://github.com/embassy-rs/embassy/pull/3179), [#3451](https://github.com/embassy-rs/embassy/pull/3451))
-    - Add constructors for RS485 ([#3441](https://github.com/embassy-rs/embassy/pull/3441))
-    - Fix RingBufferedUartRx hard-resetting DMA after initial error ([#3356](https://github.com/embassy-rs/embassy/pull/3356))
-    - Don't teardown during reconfigure ([#2989](https://github.com/embassy-rs/embassy/pull/2989))
-    - Wake receive task for each received byte ([#2722](https://github.com/embassy-rs/embassy/pull/2722))
-    - Fix dma and idle line detection in ringbuffereduartrx ([#3319](https://github.com/embassy-rs/embassy/pull/3319))
-
-SPI: 
-- Add MISO pullup configuration option ([#2943](https://github.com/embassy-rs/embassy/pull/2943))
-- Add slew rate configuration options ([#3669](https://github.com/embassy-rs/embassy/pull/3669))
-- Fix blocking_write on nosck spi. ([#3035](https://github.com/embassy-rs/embassy/pull/3035))
-- Restrict txonly_nosck to SPIv1, it hangs in other versions. ([#3028](https://github.com/embassy-rs/embassy/pull/3028))
-- Fix non-u8 word sizes. ([#3363](https://github.com/embassy-rs/embassy/pull/3363))
-- Issue correct DMA word length when reading to prevent hang. ([#3362](https://github.com/embassy-rs/embassy/pull/3362))
-- Add proper rxonly support for spi_v3 and force tx dma stream requirements. ([#3007](https://github.com/embassy-rs/embassy/pull/3007))
-
-I2C:
-- Implement asynchronous transactions ([#2742](https://github.com/embassy-rs/embassy/pull/2742))
-- Implement blocking transactions ([#2713](https://github.com/embassy-rs/embassy/pull/2713))
-- Disconnect pins on drop ([#3006](https://github.com/embassy-rs/embassy/pull/3006))
-- Ensure bus is free before master-write operation ([#3104](https://github.com/embassy-rs/embassy/pull/3104))
-- Add workaround for STM32 i2cv1 errata ([#2887](https://github.com/embassy-rs/embassy/pull/2887))
-- Fix disabling pullup accidentally enabling pulldown ([#3410](https://github.com/embassy-rs/embassy/pull/3410))
-
-Flash:
-- Add L5 support ([#3423](https://github.com/embassy-rs/embassy/pull/3423))
-- Add H5 support ([#3305](https://github.com/embassy-rs/embassy/pull/3305))
-- add F2 support ([#3303](https://github.com/embassy-rs/embassy/pull/3303))
-- Add U5 support ([#2591](https://github.com/embassy-rs/embassy/pull/2591), [#2792](https://github.com/embassy-rs/embassy/pull/2792))
-- Add H50x support ([#2600](https://github.com/embassy-rs/embassy/pull/2600), [#2808](https://github.com/embassy-rs/embassy/pull/2808))
-- Fix flash erase on F3 ([#3744](https://github.com/embassy-rs/embassy/pull/3744))
-- Support G0 second flash bank ([#3711](https://github.com/embassy-rs/embassy/pull/3711))
-- F1, F3: wait for BSY flag to clear before flashing ([#3217](https://github.com/embassy-rs/embassy/pull/3217))
-- H7: enhance resilience to program sequence errors (pgserr) ([#2539](https://github.com/embassy-rs/embassy/pull/2539))
-
-ADC:
-- Add `AnyAdcChannel` type. You can obtain it from a pin with `.degrade_adc()`. Useful for making arrays of ADC pins. ([#2985](https://github.com/embassy-rs/embassy/pull/2985))
-- Add L0 support ([#2544](https://github.com/embassy-rs/embassy/pull/2544))
-- Add U5 support ([#3688](https://github.com/embassy-rs/embassy/pull/3688))
-- Add H5 support ([#2613](https://github.com/embassy-rs/embassy/pull/2613), [#3557](https://github.com/embassy-rs/embassy/pull/3557))
-- Add G4 async support ([#3566](https://github.com/embassy-rs/embassy/pull/3566))
-- Add G4 support for calibrating differential inputs ([#3735](https://github.com/embassy-rs/embassy/pull/3735))
-- Add oversampling and differential support for G4 ([#3169](https://github.com/embassy-rs/embassy/pull/3169))
-- Add DMA support for ADC v2 ([#3116](https://github.com/embassy-rs/embassy/pull/3116))
-- Add DMA support for ADC v3 and v4 ([#3128](https://github.com/embassy-rs/embassy/pull/3128))
-- Unify naming `blocking_read` for blocking, `read` for async. ([#3148](https://github.com/embassy-rs/embassy/pull/3148))
-- Fix channel count for the STM32G4 ADCs. ([#2828](https://github.com/embassy-rs/embassy/pull/2828))
-- Fix blocking_delay_us() overflowing when sys freq is high ([#2825](https://github.com/embassy-rs/embassy/pull/2825))
-- Remove need for taking a `Delay` impl. ([#2797](https://github.com/embassy-rs/embassy/pull/2797))
-- H5: set OR.OP0 to 1 when ADCx_INP0 is selected, per RM ([#2776](https://github.com/embassy-rs/embassy/pull/2776))
-- Add oversampling support ([#3124](https://github.com/embassy-rs/embassy/pull/3124))
-- Adc averaging support for ADC v4. ([#3110](https://github.com/embassy-rs/embassy/pull/3110))
-- F2 ADC fixes ([#2513](https://github.com/embassy-rs/embassy/pull/2513))
-
-DAC:
-- Fix new_internal not setting mode as documented ([#2886](https://github.com/embassy-rs/embassy/pull/2886))
-
-OPAMP:
-- Add missing opamp external outputs for STM32G4 ([#3636](https://github.com/embassy-rs/embassy/pull/3636))
-- Add extra lifetime to opamp-using structs ([#3207](https://github.com/embassy-rs/embassy/pull/3207))
-- Make OpAmp usable in follower configuration for internal DAC channel ([#3021](https://github.com/embassy-rs/embassy/pull/3021))
-
-CAN:
-- Add FDCAN support. ([#2475](https://github.com/embassy-rs/embassy/pull/2475), [#2571](https://github.com/embassy-rs/embassy/pull/2571), [#2623](https://github.com/embassy-rs/embassy/pull/2623), [#2631](https://github.com/embassy-rs/embassy/pull/2631), [#2635](https://github.com/embassy-rs/embassy/pull/2635), [#2637](https://github.com/embassy-rs/embassy/pull/2637), [#2645](https://github.com/embassy-rs/embassy/pull/2645), [#2647](https://github.com/embassy-rs/embassy/pull/2647), [#2658](https://github.com/embassy-rs/embassy/pull/2658), [#2703](https://github.com/embassy-rs/embassy/pull/2703), [#3364](https://github.com/embassy-rs/embassy/pull/3364))
-- Simplify BXCAN API, make BXCAN and FDCAN APIs consistent. ([#2760](https://github.com/embassy-rs/embassy/pull/2760), [#2693](https://github.com/embassy-rs/embassy/pull/2693), [#2744](https://github.com/embassy-rs/embassy/pull/2744))
-- Add buffered mode support ([#2588](https://github.com/embassy-rs/embassy/pull/2588))
-- Add support for modifying the receiver filters from `BufferedCan`, `CanRx`, and `BufferedCanRx` ([#3733](https://github.com/embassy-rs/embassy/pull/3733))
-- Add support for optional FIFO scheduling for outgoing frames ([#2988](https://github.com/embassy-rs/embassy/pull/2988))
-- fdcan: Properties for common runtime get/set operations ([#2840](https://github.com/embassy-rs/embassy/pull/2840))
-- fdcan: implement bus-off recovery ([#2832](https://github.com/embassy-rs/embassy/pull/2832))
-- Add BXCAN sleep/wakeup functionality ([#2854](https://github.com/embassy-rs/embassy/pull/2854))
-- Fix BXCAN hangs ([#3468](https://github.com/embassy-rs/embassy/pull/3468))
-- add RTR flag if it is remote frame ([#3421](https://github.com/embassy-rs/embassy/pull/3421))
-- Fix log storm when no CAN is connected ([#3284](https://github.com/embassy-rs/embassy/pull/3284))
-- Fix error handling ([#2850](https://github.com/embassy-rs/embassy/pull/2850))
-- Give CAN a kick when writing into TX buffer via sender. ([#2646](https://github.com/embassy-rs/embassy/pull/2646))
-- Preseve the RTR flag in messages. ([#2745](https://github.com/embassy-rs/embassy/pull/2745))
-
-FMC:
-- Add 13bit address sdram constructors ([#3189](https://github.com/embassy-rs/embassy/pull/3189))
-
-xSPI:
-- Add OCTOSPI support ([#2672](https://github.com/embassy-rs/embassy/pull/2672))
-- Add OCTOSPIM support ([#3102](https://github.com/embassy-rs/embassy/pull/3102))
-- Add HEXADECASPI support ([#3667](https://github.com/embassy-rs/embassy/pull/3667))
-- Add memory mapping support for QSPI ([#3725](https://github.com/embassy-rs/embassy/pull/3725))
-- Add memory mapping support for OCTOSPI ([#3456](https://github.com/embassy-rs/embassy/pull/3456))
-- Add async support for QSPI ([#3475](https://github.com/embassy-rs/embassy/pull/3475))
-- Fix QSPI synchronous read operation hangs when FIFO is not full ([#3724](https://github.com/embassy-rs/embassy/pull/3724))
-- Stick to `blocking_*` naming convention for QSPI, OSPI ([#3661](https://github.com/embassy-rs/embassy/pull/3661))
-
-SDMMC:
-- Add `block-device-driver` impl for use with `embedded-fatfs` ([#2607](https://github.com/embassy-rs/embassy/pull/2607))
-- Allow cmd block to be passed in for sdmmc dma transfers ([#3188](https://github.com/embassy-rs/embassy/pull/3188))
-
-ETH:
-- Fix reception of multicast packets ([#3488](https://github.com/embassy-rs/embassy/pull/3488), [#3707](https://github.com/embassy-rs/embassy/pull/3707))
-- Add support for executing custom SMI commands ([#3355](https://github.com/embassy-rs/embassy/pull/3355))
-- Add support for MII interface ([#2465](https://github.com/embassy-rs/embassy/pull/2465))
-
-USB:
-- Assert correct clock on init. ([#2711](https://github.com/embassy-rs/embassy/pull/2711))
-- Set PWR_CR2 USV on STM32L4 ([#2605](https://github.com/embassy-rs/embassy/pull/2605))
-- USBD driver improvements:
-    - Add ISO endpoint support ([#3314](https://github.com/embassy-rs/embassy/pull/3314))
-    - Add support for L1. ([#2452](https://github.com/embassy-rs/embassy/pull/2452))
-    - set USB initialization delay to 1µs ([#3700](https://github.com/embassy-rs/embassy/pull/3700))
-- OTG driver improvements:
-    - Add ISO endpoint support ([#3314](https://github.com/embassy-rs/embassy/pull/3314))
-    - Add support for U595, U5A5 ([#3613](https://github.com/embassy-rs/embassy/pull/3613))
-    - Add support for STM32H7R/S ([#3337](https://github.com/embassy-rs/embassy/pull/3337))
-    - Add support for full-speed ULPI mode ([#3281](https://github.com/embassy-rs/embassy/pull/3281))
-    - Make max EP count configurable ([#2881](https://github.com/embassy-rs/embassy/pull/2881))
-    - fix corruption in CONTROL OUT transfers in stm32f4. ([#3565](https://github.com/embassy-rs/embassy/pull/3565))
-    - Extract Synopsys USB OTG driver to a separate crate ([#2871](https://github.com/embassy-rs/embassy/pull/2871))
-    - Add critical sections to avoid USB OTG corruption Errata ([#2823](https://github.com/embassy-rs/embassy/pull/2823))
-    - Fix support for OTG_HS in FS mode. ([#2805](https://github.com/embassy-rs/embassy/pull/2805))
-
-I2S:
-- Add SPIv3 support. ([#2992](https://github.com/embassy-rs/embassy/pull/2992))
-- Add full-duplex support. ([#2992](https://github.com/embassy-rs/embassy/pull/2992))
-- Add I2S ringbuffered DMA support ([#3023](https://github.com/embassy-rs/embassy/pull/3023))
-- Fix STM32F4 I2S clock calculations ([#3716](https://github.com/embassy-rs/embassy/pull/3716))
-
-SAI:
-- Add a function that waits for any SAI/ringbuffer write error ([#3545](https://github.com/embassy-rs/embassy/pull/3545))
-- Disallow start without an initial write ([#3541](https://github.com/embassy-rs/embassy/pull/3541))
-- Flush FIFO on init and disable ([#3538](https://github.com/embassy-rs/embassy/pull/3538))
-- Fix MCKDIV for SAI v3/v4 ([#2710](https://github.com/embassy-rs/embassy/pull/2710))
-- Pull down clock and data lines in receive mode ([#3326](https://github.com/embassy-rs/embassy/pull/3326))
-- Add function to check if SAI is muted ([#3282](https://github.com/embassy-rs/embassy/pull/3282))
-
-Low-power support:
-- Update `embassy-executor` to v0.7.
-- Add support for U0 ([#3556](https://github.com/embassy-rs/embassy/pull/3556))
-- Add support for U5 ([#3496](https://github.com/embassy-rs/embassy/pull/3496))
-- Add support for H5 ([#2877](https://github.com/embassy-rs/embassy/pull/2877))
-- Add support for L4 ([#3213](https://github.com/embassy-rs/embassy/pull/3213))
-- Fix low-power EXTI IRQ handler dropped edges ([#3404](https://github.com/embassy-rs/embassy/pull/3404))
-- Fix alarms not triggering in some cases ([#3592](https://github.com/embassy-rs/embassy/pull/3592))
-
-Timer:
-- Add Input Capture high-level driver ([#2912](https://github.com/embassy-rs/embassy/pull/2912))
-- Add PWM Input high-level driver ([#3014](https://github.com/embassy-rs/embassy/pull/3014))
-- Add support for splitting `SimplePwm` into channels ([#3317](https://github.com/embassy-rs/embassy/pull/3317))
-- Fix `SimplePwm` not enabling output pin in some stm32 families ([#2670](https://github.com/embassy-rs/embassy/pull/2670))
-- Add LPTIM low-level driver. ([#3310](https://github.com/embassy-rs/embassy/pull/3310))
-- Low-level TIM driver improvements:
-    - Simplify traits, convert from trait methods to struct. ([#2728](https://github.com/embassy-rs/embassy/pull/2728))
-    - Add `low_level::Timer::get_clock_frequency()` ([#2908](https://github.com/embassy-rs/embassy/pull/2908))
-    - Fix 32bit timer off by one ARR error ([#2876](https://github.com/embassy-rs/embassy/pull/2876))
-    - Avoid max_compare_value >= u16::MAX ([#3549](https://github.com/embassy-rs/embassy/pull/3549))
-
-DMA:
-- Add `AnyChannel` type. Similar to `AnyPin`, it allows representing any DMA channel at runtime without needing generics. ([#2606](https://github.com/embassy-rs/embassy/pull/2606))
-, Add support for BDMA on H7 ([#2606](https://github.com/embassy-rs/embassy/pull/2606))
-- Add async `stop()` function to BDMA, DMA ([#2757](https://github.com/embassy-rs/embassy/pull/2757))
-- Add configuration option for DMA Request Priority ([#2680](https://github.com/embassy-rs/embassy/pull/2680))
-- Rewrite DMA ringbuffers ([#3336](https://github.com/embassy-rs/embassy/pull/3336))
-- Enable half transfer IRQ when constructing a ReadableDmaRingBuffer ([#3093](https://github.com/embassy-rs/embassy/pull/3093))
-- Right-align `write_immediate()` in ring buffers ([#3588](https://github.com/embassy-rs/embassy/pull/3588))
-
-`embassy-time` driver:
-- Update to `embassy-time` v0.4, `embassy-time-driver` v0.2. ([#3593](https://github.com/embassy-rs/embassy/pull/3593))
-- Change preference order of `time-driver-any` to pick less-featureful timers first. ([#2570](https://github.com/embassy-rs/embassy/pull/2570))
-- Allow using more TIMx timers for the time driver  of TIM1 ([#2570](https://github.com/embassy-rs/embassy/pull/2570), [#2614](https://github.com/embassy-rs/embassy/pull/2614))
-- Correctly gate `time` feature of embassy-embedded-hal in embassy-stm32 ([#3359](https://github.com/embassy-rs/embassy/pull/3359))
-- adds timer-driver for tim21 and tim22 (on L0) ([#2450](https://github.com/embassy-rs/embassy/pull/2450))
-
-WDG:
-- Allow higher PSC value for iwdg_v3 ... ([#2628](https://github.com/embassy-rs/embassy/pull/2628))
-
-Misc:
-- Allow `bind_interrupts!` to accept conditional compilation attrs ([#3444](https://github.com/embassy-rs/embassy/pull/3444))
-
-## 0.1.0 - 2024-01-12
-
-First release.
\ No newline at end of file
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 163524343..cf336e4d0 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "embassy-stm32"
-version = "0.2.0"
+version = "0.1.0"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 description = "Embassy Hardware Abstraction Layer (HAL) for ST STM32 series microcontrollers"
@@ -72,8 +72,8 @@ futures-util = { version = "0.3.30", default-features = false }
 rand_core = "0.6.3"
 sdio-host = "0.5.0"
 critical-section = "1.1"
-stm32-metapac = { version = "16" }
-#stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c" }
+#stm32-metapac = { version = "15" }
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c" }
 
 vcell = "0.1.3"
 nb = "1.0.0"
@@ -101,8 +101,8 @@ proptest-state-machine = "0.3.0"
 proc-macro2 = "1.0.36"
 quote = "1.0.15"
 
-stm32-metapac = { version = "16", default-features = false, features = ["metadata"]}
-#stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c", default-features = false, features = ["metadata"] }
+#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c", default-features = false, features = ["metadata"] }
 
 [features]
 default = ["rt"]
diff --git a/embassy-sync/CHANGELOG.md b/embassy-sync/CHANGELOG.md
index a7547422f..b96c9416d 100644
--- a/embassy-sync/CHANGELOG.md
+++ b/embassy-sync/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## Unreleased
+
+- Add dynamic dispatch variant of `Pipe`.
+
 ## 0.6.1 - 2024-11-22
 
 - Add `LazyLock` sync primitive.
diff --git a/embassy-sync/src/pipe.rs b/embassy-sync/src/pipe.rs
index cd5b8ed75..2598652d2 100644
--- a/embassy-sync/src/pipe.rs
+++ b/embassy-sync/src/pipe.rs
@@ -532,6 +532,250 @@ impl<M: RawMutex, const N: usize> embedded_io_async::Write for Writer<'_, M, N>
     }
 }
 
+//
+// Type-erased variants
+//
+
+pub(crate) trait DynamicPipe {
+    fn write<'a>(&'a self, buf: &'a [u8]) -> DynamicWriteFuture<'a>;
+    fn read<'a>(&'a self, buf: &'a mut [u8]) -> DynamicReadFuture<'a>;
+
+    fn try_read(&self, buf: &mut [u8]) -> Result<usize, TryReadError>;
+    fn try_write(&self, buf: &[u8]) -> Result<usize, TryWriteError>;
+
+    fn try_write_with_context(&self, cx: Option<&mut Context<'_>>, buf: &[u8]) -> Result<usize, TryWriteError>;
+    fn try_read_with_context(&self, cx: Option<&mut Context<'_>>, buf: &mut [u8]) -> Result<usize, TryReadError>;
+
+    fn consume(&self, amt: usize);
+    unsafe fn try_fill_buf_with_context(&self, cx: Option<&mut Context<'_>>) -> Result<&[u8], TryReadError>;
+}
+
+impl<M, const N: usize> DynamicPipe for Pipe<M, N>
+where
+    M: RawMutex,
+{
+    fn consume(&self, amt: usize) {
+        Pipe::consume(self, amt)
+    }
+
+    unsafe fn try_fill_buf_with_context(&self, cx: Option<&mut Context<'_>>) -> Result<&[u8], TryReadError> {
+        Pipe::try_fill_buf_with_context(self, cx)
+    }
+
+    fn write<'a>(&'a self, buf: &'a [u8]) -> DynamicWriteFuture<'a> {
+        Pipe::write(self, buf).into()
+    }
+
+    fn read<'a>(&'a self, buf: &'a mut [u8]) -> DynamicReadFuture<'a> {
+        Pipe::read(self, buf).into()
+    }
+
+    fn try_read(&self, buf: &mut [u8]) -> Result<usize, TryReadError> {
+        Pipe::try_read(self, buf)
+    }
+
+    fn try_write(&self, buf: &[u8]) -> Result<usize, TryWriteError> {
+        Pipe::try_write(self, buf)
+    }
+
+    fn try_write_with_context(&self, cx: Option<&mut Context<'_>>, buf: &[u8]) -> Result<usize, TryWriteError> {
+        Pipe::try_write_with_context(self, cx, buf)
+    }
+
+    fn try_read_with_context(&self, cx: Option<&mut Context<'_>>, buf: &mut [u8]) -> Result<usize, TryReadError> {
+        Pipe::try_read_with_context(self, cx, buf)
+    }
+}
+
+/// Write-only access to a [`DynamicPipe`].
+pub struct DynamicWriter<'p> {
+    pipe: &'p dyn DynamicPipe,
+}
+
+impl<'p> Clone for DynamicWriter<'p> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<'p> Copy for DynamicWriter<'p> {}
+
+impl<'p> DynamicWriter<'p> {
+    /// Write some bytes to the pipe.
+    ///
+    /// See [`Pipe::write()`]
+    pub fn write<'a>(&'a self, buf: &'a [u8]) -> DynamicWriteFuture<'a> {
+        self.pipe.write(buf)
+    }
+
+    /// Attempt to immediately write some bytes to the pipe.
+    ///
+    /// See [`Pipe::try_write()`]
+    pub fn try_write(&self, buf: &[u8]) -> Result<usize, TryWriteError> {
+        self.pipe.try_write(buf)
+    }
+}
+
+impl<'p, M, const N: usize> From<Writer<'p, M, N>> for DynamicWriter<'p>
+where
+    M: RawMutex,
+{
+    fn from(value: Writer<'p, M, N>) -> Self {
+        Self { pipe: value.pipe }
+    }
+}
+
+/// Future returned by [`DynamicWriter::write`].
+#[must_use = "futures do nothing unless you `.await` or poll them"]
+pub struct DynamicWriteFuture<'p> {
+    pipe: &'p dyn DynamicPipe,
+    buf: &'p [u8],
+}
+
+impl<'p> Future for DynamicWriteFuture<'p> {
+    type Output = usize;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.pipe.try_write_with_context(Some(cx), self.buf) {
+            Ok(n) => Poll::Ready(n),
+            Err(TryWriteError::Full) => Poll::Pending,
+        }
+    }
+}
+
+impl<'p> Unpin for DynamicWriteFuture<'p> {}
+
+impl<'p, M, const N: usize> From<WriteFuture<'p, M, N>> for DynamicWriteFuture<'p>
+where
+    M: RawMutex,
+{
+    fn from(value: WriteFuture<'p, M, N>) -> Self {
+        Self {
+            pipe: value.pipe,
+            buf: value.buf,
+        }
+    }
+}
+
+/// Read-only access to a [`DynamicPipe`].
+pub struct DynamicReader<'p> {
+    pipe: &'p dyn DynamicPipe,
+}
+
+impl<'p> DynamicReader<'p> {
+    /// Read some bytes from the pipe.
+    ///
+    /// See [`Pipe::read()`]
+    pub fn read<'a>(&'a self, buf: &'a mut [u8]) -> DynamicReadFuture<'a> {
+        self.pipe.read(buf)
+    }
+
+    /// Attempt to immediately read some bytes from the pipe.
+    ///
+    /// See [`Pipe::try_read()`]
+    pub fn try_read(&self, buf: &mut [u8]) -> Result<usize, TryReadError> {
+        self.pipe.try_read(buf)
+    }
+
+    /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty.
+    ///
+    /// If no bytes are currently available to read, this function waits until at least one byte is available.
+    ///
+    /// If the reader is at end-of-file (EOF), an empty slice is returned.
+    pub fn fill_buf(&mut self) -> DynamicFillBufFuture<'_> {
+        DynamicFillBufFuture { pipe: Some(self.pipe) }
+    }
+
+    /// Try returning contents of the internal buffer.
+    ///
+    /// If no bytes are currently available to read, this function returns `Err(TryReadError::Empty)`.
+    ///
+    /// If the reader is at end-of-file (EOF), an empty slice is returned.
+    pub fn try_fill_buf(&mut self) -> Result<&[u8], TryReadError> {
+        unsafe { self.pipe.try_fill_buf_with_context(None) }
+    }
+
+    /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`.
+    pub fn consume(&mut self, amt: usize) {
+        self.pipe.consume(amt)
+    }
+}
+
+impl<'p, M, const N: usize> From<Reader<'p, M, N>> for DynamicReader<'p>
+where
+    M: RawMutex,
+{
+    fn from(value: Reader<'p, M, N>) -> Self {
+        Self { pipe: value.pipe }
+    }
+}
+
+/// Future returned by [`Pipe::read`] and  [`Reader::read`].
+#[must_use = "futures do nothing unless you `.await` or poll them"]
+pub struct DynamicReadFuture<'p> {
+    pipe: &'p dyn DynamicPipe,
+    buf: &'p mut [u8],
+}
+
+impl<'p> Future for DynamicReadFuture<'p> {
+    type Output = usize;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.pipe.try_read_with_context(Some(cx), self.buf) {
+            Ok(n) => Poll::Ready(n),
+            Err(TryReadError::Empty) => Poll::Pending,
+        }
+    }
+}
+
+impl<'p> Unpin for DynamicReadFuture<'p> {}
+
+impl<'p, M, const N: usize> From<ReadFuture<'p, M, N>> for DynamicReadFuture<'p>
+where
+    M: RawMutex,
+{
+    fn from(value: ReadFuture<'p, M, N>) -> Self {
+        Self {
+            pipe: value.pipe,
+            buf: value.buf,
+        }
+    }
+}
+
+/// Future returned by [`DynamicPipe::fill_buf`] and  [`DynamicReader::fill_buf`].
+#[must_use = "futures do nothing unless you `.await` or poll them"]
+pub struct DynamicFillBufFuture<'p> {
+    pipe: Option<&'p dyn DynamicPipe>,
+}
+
+impl<'p> Future for DynamicFillBufFuture<'p> {
+    type Output = &'p [u8];
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let pipe = self.pipe.take().unwrap();
+        match unsafe { pipe.try_fill_buf_with_context(Some(cx)) } {
+            Ok(buf) => Poll::Ready(buf),
+            Err(TryReadError::Empty) => {
+                self.pipe = Some(pipe);
+                Poll::Pending
+            }
+        }
+    }
+}
+
+impl<'p> Unpin for DynamicFillBufFuture<'p> {}
+
+impl<'p, M, const N: usize> From<FillBufFuture<'p, M, N>> for DynamicFillBufFuture<'p>
+where
+    M: RawMutex,
+{
+    fn from(value: FillBufFuture<'p, M, N>) -> Self {
+        Self {
+            pipe: value.pipe.map(|p| p as &dyn DynamicPipe),
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use futures_executor::ThreadPool;
@@ -619,6 +863,35 @@ mod tests {
         let _ = w.clone();
     }
 
+    #[test]
+    fn dynamic_dispatch_pipe() {
+        let mut c = Pipe::<NoopRawMutex, 3>::new();
+        let (r, w) = c.split();
+        let (mut r, w): (DynamicReader<'_>, DynamicWriter<'_>) = (r.into(), w.into());
+
+        assert!(w.try_write(&[42, 43]).is_ok());
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[42, 43]);
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[42, 43]);
+        r.consume(1);
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[43]);
+        r.consume(1);
+        assert_eq!(r.try_fill_buf(), Err(TryReadError::Empty));
+        assert_eq!(w.try_write(&[44, 45, 46]), Ok(1));
+        assert_eq!(w.try_write(&[45, 46]), Ok(2));
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[44]); // only one byte due to wraparound.
+        r.consume(1);
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[45, 46]);
+        assert!(w.try_write(&[47]).is_ok());
+        let buf = r.try_fill_buf().unwrap();
+        assert_eq!(buf, &[45, 46, 47]);
+        r.consume(3);
+    }
+
     #[futures_test::test]
     async fn receiver_receives_given_try_write_async() {
         let executor = ThreadPool::new().unwrap();
diff --git a/embassy-time-driver/CHANGELOG.md b/embassy-time-driver/CHANGELOG.md
index 744b0f648..e251a6020 100644
--- a/embassy-time-driver/CHANGELOG.md
+++ b/embassy-time-driver/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## 0.2.0 - 2025-01-02
+## 0.2.0 - 2024-01-02
 
 - The `allocate_alarm`, `set_alarm_callback`, `set_alarm` functions have been removed.
 - `schedule_wake` has been added to the `Driver` trait.
diff --git a/embassy-time/CHANGELOG.md b/embassy-time/CHANGELOG.md
index 09e951ce4..215ec27af 100644
--- a/embassy-time/CHANGELOG.md
+++ b/embassy-time/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## 0.4.0 - 2025-01-02
+## 0.4.0 - 2024-01-02
 
 - `embassy-time-driver` updated from v0.1 to v0.2.
 - embassy-time no longer provides an `embassy-time-queue-driver` implementation
diff --git a/embassy-usb-dfu/Cargo.toml b/embassy-usb-dfu/Cargo.toml
index a9565c3a5..e6522b04d 100644
--- a/embassy-usb-dfu/Cargo.toml
+++ b/embassy-usb-dfu/Cargo.toml
@@ -35,7 +35,7 @@ embassy-boot = { version = "0.4.0", path = "../embassy-boot" }
 embassy-futures = { version = "0.1.1", path = "../embassy-futures" }
 embassy-sync = { version = "0.6.1", path = "../embassy-sync" }
 embassy-time = { version = "0.4.0", path = "../embassy-time" }
-embassy-usb = { version = "0.4.0", path = "../embassy-usb", default-features = false }
+embassy-usb = { version = "0.3.0", path = "../embassy-usb", default-features = false }
 embedded-storage = { version = "0.3.1" }
 esp32c3-hal = { version = "0.13.0", optional = true, default-features = false }
 
diff --git a/embassy-usb-logger/CHANGELOG.md b/embassy-usb-logger/CHANGELOG.md
index 86a9fb032..4cd84b8be 100644
--- a/embassy-usb-logger/CHANGELOG.md
+++ b/embassy-usb-logger/CHANGELOG.md
@@ -7,18 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
-## 0.4.0 - 2025-01-15
+## 0.2.0 - 2024-05-20
 
-- Update `embassy-usb` to 0.4.0
+### Added
 
-(skipped v0.3.0 to align version numbers with `embassy-usb`)
+- [#2414](https://github.com/embassy-rs/embassy/pull/2414) USB logger can now use an existing USB device (@JomerDev)
 
-## 0.2.0 - 2024-05-20
+### Changed
 
 - Update `embassy-usb` to 0.2.0
-- Add support for using an existing USB device ([#2414](https://github.com/embassy-rs/embassy/pull/2414), @JomerDev)
-- Fix data loss at `Pipe` wraparound
-- Messages that are exactly `MAX_PACKET_SIZE` long are no longer delayed ([#2414](https://github.com/embassy-rs/embassy/pull/2414), @JomerDev)
+
+### Fixed
+
+- No more data loss at `Pipe` wraparound
+- [#2414](https://github.com/embassy-rs/embassy/pull/2414) Messages that are exactly `MAX_PACKET_SIZE` long are no
+longer delayed (@JomerDev)
 
 ## 0.1.0 - 2024-01-14
 
diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml
index 69b0a98b0..d5147de49 100644
--- a/embassy-usb-logger/Cargo.toml
+++ b/embassy-usb-logger/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "embassy-usb-logger"
-version = "0.4.0"
+version = "0.2.0"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 description = "`log` implementation for USB serial using `embassy-usb`."
@@ -15,7 +15,7 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-l
 target = "thumbv7em-none-eabi"
 
 [dependencies]
-embassy-usb = { version = "0.4.0", path = "../embassy-usb" }
+embassy-usb = { version = "0.3.0", path = "../embassy-usb" }
 embassy-sync = { version = "0.6.1", path = "../embassy-sync" }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
 log = "0.4"
diff --git a/embassy-usb/CHANGELOG.md b/embassy-usb/CHANGELOG.md
index 76fafed31..efdda96fb 100644
--- a/embassy-usb/CHANGELOG.md
+++ b/embassy-usb/CHANGELOG.md
@@ -7,19 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
-## 0.4.0 - 2025-01-15
-
-- Change config defaults to to composite with IADs. This ensures embassy-usb Just Works in more cases when using classes with multiple interfaces, or multiple classes. (breaking change)
-    - `composite_with_iads` = `true`
-    - `device_class` = `0xEF`
-    - `device_sub_class` = `0x02`
-    - `device_protocol` = `0x01`
-- Add support for USB Audio Class 1.
-- Add support for isochronous endpoints.
-- Add support for setting the USB version number.
-- Add support for device qualifier descriptors.
-- Allow `bos_descriptor_buf` to be a zero length if BOS descriptors aren't used.
-
 ## 0.3.0 - 2024-08-05
 
 - bump usbd-hid from 0.7.0 to 0.8.1
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml
index d0ce3f1df..9abf2f200 100644
--- a/embassy-usb/Cargo.toml
+++ b/embassy-usb/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "embassy-usb"
-version = "0.4.0"
+version = "0.3.0"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 description = "Async USB device stack for embedded devices in Rust."
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 35a8544fd..c49dd8335 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index dee1139df..a14536e9e 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index f0899cd86..f7b9f630e 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index fd4732742..75eaf8312 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 5792c87d6..93d651f3c 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index d2b600560..20f521084 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml
index 7e0f90e3a..70d854953 100644
--- a/examples/boot/application/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/application/stm32wb-dfu/Cargo.toml
@@ -8,10 +8,10 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
-embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb" }
+embassy-usb = { version = "0.3.0", path = "../../../../embassy-usb" }
 embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] }
 
 defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 59ef48edc..8981690af 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../../../embassy-sync" }
 embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] }
 embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
 
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
index f8d66e777..1431e7cc3 100644
--- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
@@ -18,7 +18,7 @@ embedded-storage = "0.3.1"
 embedded-storage-async = "0.4.0"
 cfg-if = "1.0.0"
 embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] }
-embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb", default-features = false }
+embassy-usb = { version = "0.3.0", path = "../../../../embassy-usb", default-features = false }
 embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" }
 
 [features]
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml
index 1c65098fe..81d130ad3 100644
--- a/examples/nrf52840/Cargo.toml
+++ b/examples/nrf52840/Cargo.toml
@@ -11,7 +11,7 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embedded-io = { version = "0.6.0", features = ["defmt-03"]  }
 embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
 embassy-net-esp-hosted = { version = "0.2.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml
index be46b7974..557a9127a 100644
--- a/examples/nrf5340/Cargo.toml
+++ b/examples/nrf5340/Cargo.toml
@@ -11,7 +11,7 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embedded-io-async = { version = "0.6.1" }
 
 defmt = "0.3"
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 5294ec477..f80ccbc0b 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -11,11 +11,11 @@ embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["de
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-rp = { version = "0.3.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp2040"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns", "proto-ipv4", "proto-ipv6", "multicast"] }
 embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
-embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" }
+embassy-usb-logger = { version = "0.2.0", path = "../../embassy-usb-logger" }
 cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] }
 cyw43-pio = { version = "0.3.0", path = "../../cyw43-pio", features = ["defmt"] }
 
@@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" }
 static_cell = "2.1"
 portable-atomic = { version = "1.5", features = ["critical-section"] }
 log = "0.4"
-pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
-pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
+pio-proc = "0.2"
+pio = "0.2.1"
 rand = { version = "0.8.5", default-features = false }
 embedded-sdmmc = "0.7.0"
 
diff --git a/examples/rp23/Cargo.toml b/examples/rp23/Cargo.toml
index 8f9c14c5c..7c94166bd 100644
--- a/examples/rp23/Cargo.toml
+++ b/examples/rp23/Cargo.toml
@@ -11,11 +11,11 @@ embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["de
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-rp = { version = "0.3.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns"] }
 embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
-embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" }
+embassy-usb-logger = { version = "0.2.0", path = "../../embassy-usb-logger" }
 cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] }
 cyw43-pio = { version = "0.3.0", path = "../../cyw43-pio", features = ["defmt"] }
 
@@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" }
 static_cell = "2.1"
 portable-atomic = { version = "1.5", features = ["critical-section"] }
 log = "0.4"
-pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
-pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
+pio-proc = "0.2"
+pio = "0.2.1"
 rand = { version = "0.8.5", default-features = false }
 embedded-sdmmc = "0.7.0"
 
diff --git a/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs b/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
deleted file mode 100644
index 7a1046610..000000000
--- a/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-//! This example shows how to use the PIO module in the RP235x to read a quadrature rotary encoder.
-//! It differs from the other example in that it uses the RX FIFO as a status register
-
-#![no_std]
-#![no_main]
-
-use defmt::info;
-use embassy_executor::Spawner;
-use embassy_rp::block::ImageDef;
-use embassy_rp::gpio::Pull;
-use embassy_rp::peripherals::PIO0;
-use embassy_rp::{bind_interrupts, pio};
-use embassy_time::Timer;
-use fixed::traits::ToFixed;
-use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
-use {defmt_rtt as _, panic_probe as _};
-
-#[link_section = ".start_block"]
-#[used]
-pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe();
-
-// Program metadata for `picotool info`
-#[link_section = ".bi_entries"]
-#[used]
-pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [
-    embassy_rp::binary_info::rp_program_name!(c"example_pio_rotary_encoder_rxf"),
-    embassy_rp::binary_info::rp_cargo_version!(),
-    embassy_rp::binary_info::rp_program_description!(c"Rotary encoder (RXF)"),
-    embassy_rp::binary_info::rp_program_build_attribute!(),
-];
-
-bind_interrupts!(struct Irqs {
-    PIO0_IRQ_0 => InterruptHandler<PIO0>;
-});
-
-pub struct PioEncoder<'d, T: Instance, const SM: usize> {
-    sm: StateMachine<'d, T, SM>,
-}
-
-impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
-    pub fn new(
-        pio: &mut Common<'d, T>,
-        mut sm: StateMachine<'d, T, SM>,
-        pin_a: impl PioPin,
-        pin_b: impl PioPin,
-    ) -> Self {
-        let mut pin_a = pio.make_pio_pin(pin_a);
-        let mut pin_b = pio.make_pio_pin(pin_b);
-        pin_a.set_pull(Pull::Up);
-        pin_b.set_pull(Pull::Up);
-
-        sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]);
-
-        let prg = pio_proc::pio_asm!(
-            "start:"
-            // encoder count is stored in X
-            "mov isr, x"
-            // and then moved to the RX FIFO register
-            "mov rxfifo[0], isr"
-
-            // wait for encoder transition
-            "wait 1 pin 1"
-            "wait 0 pin 1"
-
-            "set y, 0"
-            "mov y, pins[1]"
-
-            // update X depending on pin 1
-            "jmp !y decr"
-
-            // this is just a clever way of doing x++
-            "mov x, ~x"
-            "jmp x--, incr"
-            "incr:"
-            "mov x, ~x"
-            "jmp start"
-
-            // and this is x--
-            "decr:"
-            "jmp x--, start"
-        );
-
-        let mut cfg = Config::default();
-        cfg.set_in_pins(&[&pin_a, &pin_b]);
-        cfg.fifo_join = FifoJoin::RxAsStatus;
-        cfg.shift_in.direction = ShiftDirection::Left;
-        cfg.clock_divider = 10_000.to_fixed();
-        cfg.use_program(&pio.load_program(&prg.program), &[]);
-        sm.set_config(&cfg);
-
-        sm.set_enable(true);
-        Self { sm }
-    }
-
-    pub async fn read(&mut self) -> u32 {
-        self.sm.get_rxf_entry(0)
-    }
-}
-
-pub enum Direction {
-    Clockwise,
-    CounterClockwise,
-}
-
-#[embassy_executor::main]
-async fn main(_spawner: Spawner) {
-    let p = embassy_rp::init(Default::default());
-    let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
-
-    let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5);
-
-    loop {
-        info!("Count: {}", encoder.read().await);
-        Timer::after_millis(1000).await;
-    }
-}
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 3c9b571cd..44b62a616 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -10,7 +10,7 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["log", "std", ] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] }
 embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" }
-embassy-net-ppp = { version = "0.2.0", path = "../../embassy-net-ppp", features = ["log"]}
+embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]}
 embedded-io-async = { version = "0.6.1" }
 embedded-io-adapters = { version = "0.6.1", features = ["futures-03"] }
 critical-section = { version = "1.1", features = ["std"] }
diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs
index f667e8d4c..ea3fbebef 100644
--- a/examples/std/src/bin/net_ppp.rs
+++ b/examples/std/src/bin/net_ppp.rs
@@ -45,7 +45,7 @@ async fn net_task(mut runner: embassy_net::Runner<'static, embassy_net_ppp::Devi
 async fn ppp_task(stack: Stack<'static>, mut runner: Runner<'static>, port: SerialPort) -> ! {
     let port = Async::new(port).unwrap();
     let port = BufReader::new(port);
-    let port = embedded_io_adapters::futures_03::FromFutures::new(port);
+    let port = adapter::FromFutures::new(port);
 
     let config = embassy_net_ppp::Config {
         username: b"myuser",
@@ -163,3 +163,53 @@ fn main() {
         spawner.spawn(main_task(spawner)).unwrap();
     });
 }
+
+mod adapter {
+    use core::future::poll_fn;
+    use core::pin::Pin;
+
+    use futures::AsyncBufReadExt;
+
+    /// Adapter from `futures::io` traits.
+    #[derive(Clone)]
+    pub struct FromFutures<T: ?Sized> {
+        inner: T,
+    }
+
+    impl<T> FromFutures<T> {
+        /// Create a new adapter.
+        pub fn new(inner: T) -> Self {
+            Self { inner }
+        }
+    }
+
+    impl<T: ?Sized> embedded_io_async::ErrorType for FromFutures<T> {
+        type Error = std::io::Error;
+    }
+
+    impl<T: futures::io::AsyncRead + Unpin + ?Sized> embedded_io_async::Read for FromFutures<T> {
+        async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
+            poll_fn(|cx| Pin::new(&mut self.inner).poll_read(cx, buf)).await
+        }
+    }
+
+    impl<T: futures::io::AsyncBufRead + Unpin + ?Sized> embedded_io_async::BufRead for FromFutures<T> {
+        async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
+            self.inner.fill_buf().await
+        }
+
+        fn consume(&mut self, amt: usize) {
+            Pin::new(&mut self.inner).consume(amt)
+        }
+    }
+
+    impl<T: futures::io::AsyncWrite + Unpin + ?Sized> embedded_io_async::Write for FromFutures<T> {
+        async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
+            poll_fn(|cx| Pin::new(&mut self.inner).poll_write(cx, buf)).await
+        }
+
+        async fn flush(&mut self) -> Result<(), Self::Error> {
+            poll_fn(|cx| Pin::new(&mut self.inner).poll_flush(cx)).await
+        }
+    }
+}
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
index 18646a083..5d36b739d 100644
--- a/examples/std/src/bin/tcp_accept.rs
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -1,3 +1,5 @@
+use core::fmt::Write as _;
+
 use clap::Parser;
 use embassy_executor::{Executor, Spawner};
 use embassy_net::tcp::TcpSocket;
@@ -26,6 +28,16 @@ async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
     runner.run().await
 }
 
+#[derive(Default)]
+struct StrWrite(pub heapless::Vec<u8, 30>);
+
+impl core::fmt::Write for StrWrite {
+    fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
+        self.0.extend_from_slice(s.as_bytes()).unwrap();
+        Ok(())
+    }
+}
+
 #[embassy_executor::task]
 async fn main_task(spawner: Spawner) {
     let opts: Opts = Opts::parse();
@@ -73,8 +85,9 @@ async fn main_task(spawner: Spawner) {
 
         // Write some quick output
         for i in 1..=5 {
-            let s = format!("{}!  ", i);
-            let r = socket.write_all(s.as_bytes()).await;
+            let mut w = StrWrite::default();
+            write!(w, "{}!  ", i).unwrap();
+            let r = socket.write_all(&w.0).await;
             if let Err(e) = r {
                 warn!("write error: {:?}", e);
                 return;
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml
index 3f0aa632f..21a6882ac 100644
--- a/examples/stm32c0/Cargo.toml
+++ b/examples/stm32c0/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32c031c6 to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index 2f7246e29..9bfc9701d 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f091rc to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-tim2", "exti", "unstable-pac"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-tim2", "exti", "unstable-pac"] }
 cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
 cortex-m-rt = "0.7.0"
 defmt = "0.3"
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index 4a090ea04..4211a07a7 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f103c8 to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 50b2cd67c..8b53b2f90 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f207zg to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index 9204971d7..60ec05f36 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f303ze to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-tim2", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-tim2", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml
index aef92ca3f..02306c683 100644
--- a/examples/stm32f334/Cargo.toml
+++ b/examples/stm32f334/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index f2b077949..72cd0d7f5 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f429zi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-tim4", "exti", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-tim4", "exti", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt" ] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt" ] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
 embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml
index 2c0c9a6c8..01984f594 100644
--- a/examples/stm32f469/Cargo.toml
+++ b/examples/stm32f469/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Specific examples only for stm32f469
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index c7a2db5df..f9f2ae9a4 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32f777zi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
 embedded-io-async = { version = "0.6.1" }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index 675b03fa2..4aa665d64 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32g0b1re to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index 6c3a4e8cb..83974f1af 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32g491re to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 usbd-hid = "0.8.1"
 
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index ac670ff8f..8d43c4c1a 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h563zi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 224dc45c6..0dbaf28ce 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h743bi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml
index e9ff3a352..95a9c4a3d 100644
--- a/examples/stm32h723/Cargo.toml
+++ b/examples/stm32h723/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h723zg to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h723zg", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h723zg", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32h735/Cargo.toml b/examples/stm32h735/Cargo.toml
index e3e07e086..99e2c1049 100644
--- a/examples/stm32h735/Cargo.toml
+++ b/examples/stm32h735/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
 license = "MIT OR Apache-2.0"
 
 [dependencies]
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h735ig", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h735ig", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml
index 0bafb24e3..699561214 100644
--- a/examples/stm32h755cm4/Cargo.toml
+++ b/examples/stm32h755cm4/Cargo.toml
@@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h755zi-cm4 to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm4", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm4", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml
index d21bc00a2..1f830ec6b 100644
--- a/examples/stm32h755cm7/Cargo.toml
+++ b/examples/stm32h755cm7/Cargo.toml
@@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h743bi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm7", "time-driver-tim3", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm7", "time-driver-tim3", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml
index 6189f225c..a1b96baa9 100644
--- a/examples/stm32h7b0/Cargo.toml
+++ b/examples/stm32h7b0/Cargo.toml
@@ -5,13 +5,13 @@ version = "0.1.0"
 license = "MIT OR Apache-2.0"
 
 [dependencies]
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7b0vb", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7b0vb", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml
index 621fea21f..bd41827a5 100644
--- a/examples/stm32h7rs/Cargo.toml
+++ b/examples/stm32h7rs/Cargo.toml
@@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h743bi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 5d99de570..3acc62e96 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32l072cz to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32l073rz", "unstable-pac", "time-driver-any", "exti", "memory-x"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l073rz", "unstable-pac", "time-driver-any", "exti", "memory-x"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index 2392c4136..67a7dfbe8 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"]  }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"]  }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index d82d91d35..4e210a35d 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32l4s5vi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4r5zi", "memory-x", "time-driver-any", "exti", "chrono"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4r5zi", "memory-x", "time-driver-any", "exti", "chrono"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] }
 embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-net-adin1110 = { version = "0.3.0", path = "../../embassy-net-adin1110" }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt",  "udp", "tcp", "dhcpv4", "medium-ethernet"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
diff --git a/examples/stm32l432/Cargo.toml b/examples/stm32l432/Cargo.toml
index 87ee392a1..460561b36 100644
--- a/examples/stm32l432/Cargo.toml
+++ b/examples/stm32l432/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32l4s5vi to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l432kc", "memory-x", "time-driver-any", "exti", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l432kc", "memory-x", "time-driver-any", "exti", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = [ "defmt" ] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt" ] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] }
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 56dc907a7..7572fed3f 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32l552ze to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt",  "tcp", "dhcpv4", "medium-ethernet"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 usbd-hid = "0.8.1"
diff --git a/examples/stm32u0/Cargo.toml b/examples/stm32u0/Cargo.toml
index 722e2125b..1813881ba 100644
--- a/examples/stm32u0/Cargo.toml
+++ b/examples/stm32u0/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32u083rc to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32u083rc", "memory-x", "unstable-pac", "exti", "chrono"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32u083rc", "memory-x", "unstable-pac", "exti", "chrono"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index d31a34410..f56ee024e 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32u5g9zj to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u5g9zj", "time-driver-any", "memory-x" ]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u5g9zj", "time-driver-any", "memory-x" ]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
-embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
+embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 
 defmt = "0.3"
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index a61acb9ea..268e9347b 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32wb55rg to your chip name in both dependencies, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"]  }
 embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml
index 8af3db095..00c8b92d5 100644
--- a/examples/stm32wba/Cargo.toml
+++ b/examples/stm32wba/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
 license = "MIT OR Apache-2.0"
 
 [dependencies]
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"]  }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index ead72bf04..379fdc572 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32wl55jc-cm4 to your chip name, if necessary.
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }


Test patch:
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml
index 7af6a4af2..cb3dd3df6 100644
--- a/tests/perf-client/Cargo.toml
+++ b/tests/perf-client/Cargo.toml
@@ -7,4 +7,4 @@ edition = "2021"
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
-defmt = "0.3"
+defmt = "0.3.0"
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index dc3ca3202..4278f7b2c 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -19,7 +19,7 @@ cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
 cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] }
 perf-client = { path = "../perf-client" }
 
-defmt = "0.3"
+defmt = "0.3.0"
 defmt-rtt = "0.4"
 
 cortex-m = { version = "0.7.6" }
@@ -33,8 +33,8 @@ embedded-io-async = { version = "0.6.1" }
 embedded-storage = { version = "0.3" }
 static_cell = "2"
 portable-atomic = { version = "1.5", features = ["critical-section"] }
-pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
-pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
+pio = "0.2"
+pio-proc = "0.2"
 rand = { version = "0.8.5", default-features = false }
 
 [profile.dev]
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index ff42462fe..5537969a4 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -62,13 +62,13 @@ teleprobe-meta = "1"
 embassy-sync = { version = "0.6.1", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
 embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] }
-embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"]  }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"]  }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] }
 embassy-net = { version = "0.6.0", path = "../../embassy-net", features = ["defmt",  "tcp", "udp", "dhcpv4", "medium-ethernet"] }
 perf-client = { path = "../perf-client" }
 
-defmt = "0.3"
+defmt = "0.3.0"
 defmt-rtt = "0.4"
 
 cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }