diff --git a/embassy-stm32/src/pwr/mod.rs b/embassy-stm32/src/pwr/mod.rs
index 18f462bd2..d948c398d 100644
--- a/embassy-stm32/src/pwr/mod.rs
+++ b/embassy-stm32/src/pwr/mod.rs
@@ -7,6 +7,7 @@
 #[cfg_attr(pwr_g4, path = "g4.rs")]
 #[cfg_attr(pwr_l1, path = "l1.rs")]
 #[cfg_attr(pwr_u5, path = "u5.rs")]
+#[cfg_attr(pwr_wb55, path = "wb55.rs")]
 mod _version;
 
 pub use _version::*;
diff --git a/embassy-stm32/src/pwr/wb55.rs b/embassy-stm32/src/pwr/wb55.rs
new file mode 100644
index 000000000..e69de29bb
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index 08a9bc9b4..58a08adbf 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -7,17 +7,18 @@ use embassy::util::Unborrow;
 
 const HSI: u32 = 16_000_000;
 
-/// Clocks configutation
+/// Clocks configuration
 #[non_exhaustive]
 #[derive(Default)]
 pub struct Config {
     pub hse: Option<Hertz>,
     pub bypass_hse: bool,
-    pub pll48: bool,
-    pub sys_ck: Option<Hertz>,
     pub hclk: Option<Hertz>,
+    pub sys_ck: Option<Hertz>,
     pub pclk1: Option<Hertz>,
     pub pclk2: Option<Hertz>,
+
+    pub pll48: bool,
 }
 
 /// RCC peripheral
@@ -38,6 +39,8 @@ impl<'d> Rcc<'d> {
         use super::sealed::RccPeripheral;
         use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw};
 
+        peripherals::PWR::enable();
+
         let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
         let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
         let sysclk_on_pll = sysclk != pllsrcclk;
@@ -50,12 +53,9 @@ impl<'d> Rcc<'d> {
         );
 
         if self.config.pll48 {
-            assert!(
-                // USB specification allows +-0.25%
-                plls.pll48clk
-                    .map(|freq| (48_000_000 - freq as i32).abs() <= 120_000)
-                    .unwrap_or(false)
-            );
+            let freq = unwrap!(plls.pll48clk);
+
+            assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32);
         }
 
         let sysclk = if sysclk_on_pll {
@@ -64,6 +64,7 @@ impl<'d> Rcc<'d> {
             sysclk
         };
 
+        // AHB prescaler
         let hclk = self.config.hclk.map(|h| h.0).unwrap_or(sysclk);
         let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk {
             0 => unreachable!(),
@@ -86,6 +87,7 @@ impl<'d> Rcc<'d> {
             .pclk1
             .map(|p| p.0)
             .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk));
+
         let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 {
             0 => unreachable!(),
             1 => (0b000, 1),
@@ -136,14 +138,12 @@ impl<'d> Rcc<'d> {
             unsafe {
                 RCC.cr().modify(|w| w.set_pllon(true));
 
-                if hclk > 168_000_000 {
-                    peripherals::PWR::enable();
+                if hclk > max::HCLK_OVERDRIVE_FREQUENCY {
+                    PWR.cr1().modify(|w| w.set_oden(true));
+                    while !PWR.csr1().read().odrdy() {}
 
-                    PWR.cr().modify(|w| w.set_oden(true));
-                    while !PWR.csr().read().odrdy() {}
-
-                    PWR.cr().modify(|w| w.set_odswen(true));
-                    while !PWR.csr().read().odswrdy() {}
+                    PWR.cr1().modify(|w| w.set_odswen(true));
+                    while !PWR.csr1().read().odswrdy() {}
                 }
 
                 while !RCC.cr().read().pllrdy() {}
@@ -310,23 +310,24 @@ struct PllResults {
 mod max {
     #[cfg(stm32f401)]
     pub(crate) const SYSCLK_MAX: u32 = 84_000_000;
-
     #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))]
     pub(crate) const SYSCLK_MAX: u32 = 168_000_000;
-
     #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
     pub(crate) const SYSCLK_MAX: u32 = 100_000_000;
-
     #[cfg(any(
         stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,
     ))]
     pub(crate) const SYSCLK_MAX: u32 = 180_000_000;
 
+    pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 168_000_000;
+
+    pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2;
+
     #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
     pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX;
-
     #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))]
     pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2;
 
-    pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2;
+    pub(crate) const PLL_48_CLK: u32 = 48_000_000;
+    pub(crate) const PLL_48_TOLERANCE: u32 = 120_000;
 }
diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs
index 25f78c701..d29ba31f0 100644
--- a/embassy-stm32/src/rcc/f7.rs
+++ b/embassy-stm32/src/rcc/f7.rs
@@ -7,6 +7,7 @@ use embassy::util::Unborrow;
 
 const HSI: u32 = 16_000_000;
 
+/// Clocks configuration
 #[non_exhaustive]
 #[derive(Default)]
 pub struct Config {
@@ -46,27 +47,25 @@ impl<'d> Rcc<'d> {
         use crate::pac::pwr::vals::Vos;
         use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw};
 
-        let base_clock = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
-        let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(base_clock);
-        let sysclk_on_pll = sysclk != base_clock;
+        peripherals::PWR::enable();
+
+        let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
+        let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
+        let sysclk_on_pll = sysclk != pllsrcclk;
 
         assert!((max::SYSCLK_MIN..=max::SYSCLK_MAX).contains(&sysclk));
 
         let plls = self.setup_pll(
-            base_clock,
+            pllsrcclk,
             self.config.hse.is_some(),
             if sysclk_on_pll { Some(sysclk) } else { None },
             self.config.pll48,
         );
 
         if self.config.pll48 {
-            assert!(
-                // USB specification allows +-0.25%
-                plls.pll48clk
-                    .map(|freq| (max::PLL_48_CLK as i32 - freq as i32).abs()
-                        <= max::PLL_48_TOLERANCE as i32)
-                    .unwrap_or(false)
-            );
+            let freq = unwrap!(plls.pll48clk);
+
+            assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32);
         }
 
         let sysclk = if sysclk_on_pll {
@@ -173,11 +172,7 @@ impl<'d> Rcc<'d> {
 
                 RCC.cr().modify(|w| w.set_pllon(true));
 
-                while !RCC.cr().read().pllrdy() {}
-
                 if hclk > max::HCLK_OVERDRIVE_FREQUENCY {
-                    peripherals::PWR::enable();
-
                     PWR.cr1().modify(|w| w.set_oden(true));
                     while !PWR.csr1().read().odrdy() {}
 
@@ -222,6 +217,8 @@ impl<'d> Rcc<'d> {
             ahb1: Hertz(hclk),
             ahb2: Hertz(hclk),
             ahb3: Hertz(hclk),
+
+            pll48: plls.pll48clk.map(Hertz),
         }
     }
 
@@ -362,6 +359,7 @@ mod max {
     pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN;
     pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2;
 
+    // USB specification allows +-0.25%
     pub(crate) const PLL_48_CLK: u32 = 48_000_000;
     pub(crate) const PLL_48_TOLERANCE: u32 = 120_000;
 }
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index bf612464f..d0b6e5a18 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -61,7 +61,7 @@ pub struct Clocks {
     #[cfg(any(rcc_h7))]
     pub apb4: Hertz,
 
-    #[cfg(rcc_f4)]
+    #[cfg(any(rcc_f4, rcc_f7))]
     pub pll48: Option<Hertz>,
 
     #[cfg(rcc_f1)]
diff --git a/stm32-data b/stm32-data
index 27f9d6dc2..8530a19ff 160000
--- a/stm32-data
+++ b/stm32-data
@@ -1 +1 @@
-Subproject commit 27f9d6dc2c5afaa5003ce9afc06def9b16d30adb
+Subproject commit 8530a19ffdcdcbc608a97b40895827d09e670eb7