From d9e59e8e42ea009e365bb893b91d81fe47fe927d Mon Sep 17 00:00:00 2001
From: eZio Pan <eziopan@qq.com>
Date: Sat, 27 Apr 2024 21:37:58 +0800
Subject: [PATCH] low power for h5

---
 embassy-stm32/Cargo.toml          |  6 +--
 embassy-stm32/src/low_power.rs    | 41 +++++++++++-------
 embassy-stm32/src/rcc/f247.rs     |  3 ++
 embassy-stm32/src/rcc/h.rs        |  2 +
 embassy-stm32/src/rcc/l.rs        |  2 +
 embassy-stm32/src/rcc/u5.rs       |  1 +
 embassy-stm32/src/rtc/datetime.rs |  4 +-
 embassy-stm32/src/rtc/mod.rs      | 49 +++++++++------------
 embassy-stm32/src/rtc/v3.rs       | 36 +++++++---------
 examples/stm32h5/Cargo.toml       |  2 +-
 examples/stm32h5/src/bin/stop.rs  | 71 +++++++++++++++++++++++++++++++
 tests/stm32/Cargo.toml            |  4 +-
 tests/stm32/src/bin/stop.rs       |  7 +++
 13 files changed, 155 insertions(+), 73 deletions(-)
 create mode 100644 examples/stm32h5/src/bin/stop.rs

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 669e6537a..653a376bd 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -24,7 +24,7 @@ flavors = [
     { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" },
     { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" },
     { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] },
-    { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" },
+    { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] },
     { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" },
     { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] },
     { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" },
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
 sdio-host = "0.5.0"
 critical-section = "1.1"
 #stm32-metapac = { version = "15" }
-stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01ac9bfd035961dc75f32dcd6080501538246d5c" }
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0" }
 
 vcell = "0.1.3"
 nb = "1.0.0"
@@ -98,7 +98,7 @@ proc-macro2 = "1.0.36"
 quote = "1.0.15"
 
 #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
-stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01ac9bfd035961dc75f32dcd6080501538246d5c", default-features = false, features = ["metadata"]}
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0", default-features = false, features = ["metadata"]}
 
 [features]
 default = ["rt"]
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 4c3d288fd..604bdf416 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -10,14 +10,14 @@
 //! exceptions to this rule:
 //!
 //!  * `GPIO`
-//!  * `RCC`
+//!  * `RTC`
 //!
 //! Since entering and leaving low-power modes typically incurs a significant latency, the
 //! low-power executor will only attempt to enter when the next timer event is at least
 //! [`time_driver::MIN_STOP_PAUSE`] in the future.
 //!
 //! Currently there is no macro analogous to `embassy_executor::main` for this executor;
-//! consequently one must define their entrypoint manually. Moveover, you must relinquish control
+//! consequently one must define their entrypoint manually. Moreover, you must relinquish control
 //! of the `RTC` peripheral to the executor. This will typically look like
 //!
 //! ```rust,no_run
@@ -99,7 +99,7 @@ pub fn stop_ready(stop_mode: StopMode) -> bool {
     }
 }
 
-/// Available stop modes.
+/// Available Stop modes.
 #[non_exhaustive]
 #[derive(PartialEq)]
 pub enum StopMode {
@@ -183,6 +183,12 @@ impl Executor {
     fn configure_stop(&mut self, stop_mode: StopMode) {
         #[cfg(stm32l5)]
         crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into()));
+        #[cfg(stm32h5)]
+        crate::pac::PWR.pmcr().modify(|v| {
+            use crate::pac::pwr::vals;
+            v.set_lpms(vals::Lpms::STOP);
+            v.set_svos(vals::Svos::SCALE3);
+        });
     }
 
     fn configure_pwr(&mut self) {
@@ -191,21 +197,26 @@ impl Executor {
         compiler_fence(Ordering::SeqCst);
 
         let stop_mode = self.stop_mode();
+
         if stop_mode.is_none() {
             trace!("low power: not ready to stop");
-        } else if self.time_driver.pause_time().is_err() {
-            trace!("low power: failed to pause time");
-        } else {
-            let stop_mode = stop_mode.unwrap();
-            match stop_mode {
-                StopMode::Stop1 => trace!("low power: stop 1"),
-                StopMode::Stop2 => trace!("low power: stop 2"),
-            }
-            self.configure_stop(stop_mode);
-
-            #[cfg(not(feature = "low-power-debug-with-sleep"))]
-            self.scb.set_sleepdeep();
+            return;
         }
+
+        if self.time_driver.pause_time().is_err() {
+            trace!("low power: failed to pause time");
+            return;
+        }
+
+        let stop_mode = stop_mode.unwrap();
+        match stop_mode {
+            StopMode::Stop1 => trace!("low power: stop 1"),
+            StopMode::Stop2 => trace!("low power: stop 2"),
+        }
+        self.configure_stop(stop_mode);
+
+        #[cfg(not(feature = "low-power-debug-with-sleep"))]
+        self.scb.set_sleepdeep();
     }
 
     /// Run the executor.
diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs
index 7b252870c..e3ee9a039 100644
--- a/embassy-stm32/src/rcc/f247.rs
+++ b/embassy-stm32/src/rcc/f247.rs
@@ -277,6 +277,7 @@ pub(crate) unsafe fn init(config: Config) {
         pclk2_tim: Some(pclk2_tim),
         rtc: rtc,
         pll1_q: pll.q,
+        pll1_r: None, // TODO
 
         #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
         plli2s1_p: plli2s.p,
@@ -299,6 +300,8 @@ pub(crate) unsafe fn init(config: Config) {
         hsi_div488: hsi.map(|hsi| hsi/488u32),
         hsi_hse: None,
         afif: None,
+        #[cfg(any(stm32f4, stm32f7))]
+        dsi_phy: None, // TODO
     );
 }
 
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 1949fc891..aa8c4b1f7 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -601,6 +601,8 @@ pub(crate) unsafe fn init(config: Config) {
         #[cfg(stm32h5)]
         audioclk: None,
         i2s_ckin: None,
+        #[cfg(stm32h7)]
+        dsi_phy: None, // TODO
     );
 }
 
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs
index d7235ac7f..c625948fb 100644
--- a/embassy-stm32/src/rcc/l.rs
+++ b/embassy-stm32/src/rcc/l.rs
@@ -420,6 +420,8 @@ pub(crate) unsafe fn init(config: Config) {
         sai2_extclk: None,
         lsi: None,
         lse: None,
+        #[cfg(stm32l4)]
+        dsi_phy: None,
     );
 }
 
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 9533e16c4..4013d0a46 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -297,6 +297,7 @@ pub(crate) unsafe fn init(config: Config) {
         msik: None,
         shsi: None,
         shsi_div_2: None,
+        dsi_phy: None,
     );
 }
 
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs
index bab8cf4a3..77d89293d 100644
--- a/embassy-stm32/src/rtc/datetime.rs
+++ b/embassy-stm32/src/rtc/datetime.rs
@@ -148,9 +148,9 @@ impl DateTime {
     ) -> Result<Self, Error> {
         if year > 4095 {
             Err(Error::InvalidYear)
-        } else if month < 1 || month > 12 {
+        } else if !(1..=12).contains(&month) {
             Err(Error::InvalidMonth)
-        } else if day < 1 || day > 31 {
+        } else if !(1..=31).contains(&day) {
             Err(Error::InvalidDay)
         } else if hour > 23 {
             Err(Error::InvalidHour)
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 00abe9356..b12a0db66 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -42,7 +42,7 @@ pub(crate) enum WakeupPrescaler {
     Div16 = 16,
 }
 
-#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))]
+#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
 impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
     fn from(val: WakeupPrescaler) -> Self {
         use crate::pac::rtc::vals::Wucksel;
@@ -56,7 +56,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
     }
 }
 
-#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))]
+#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
 impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
     fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
         use crate::pac::rtc::vals::Wucksel;
@@ -81,8 +81,7 @@ impl WakeupPrescaler {
             WakeupPrescaler::Div16,
         ]
         .iter()
-        .skip_while(|psc| **psc as u32 <= val)
-        .next()
+        .find(|psc| **psc as u32 > val)
         .unwrap_or(&WakeupPrescaler::Div16)
     }
 }
@@ -159,7 +158,7 @@ impl RtcTimeProvider {
             }
         }
 
-        return Err(RtcError::ReadFailure);
+        Err(RtcError::ReadFailure)
     }
 }
 
@@ -190,7 +189,7 @@ impl Default for RtcConfig {
 }
 
 /// Calibration cycle period.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Default, Copy, Clone, Debug, PartialEq)]
 #[repr(u8)]
 pub enum RtcCalibrationCyclePeriod {
     /// 8-second calibration period
@@ -198,15 +197,10 @@ pub enum RtcCalibrationCyclePeriod {
     /// 16-second calibration period
     Seconds16,
     /// 32-second calibration period
+    #[default]
     Seconds32,
 }
 
-impl Default for RtcCalibrationCyclePeriod {
-    fn default() -> Self {
-        RtcCalibrationCyclePeriod::Seconds32
-    }
-}
-
 impl Rtc {
     /// Create a new RTC instance.
     pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
@@ -254,13 +248,13 @@ impl Rtc {
     /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
     pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> {
         self.write(true, |rtc| {
-            let (ht, hu) = byte_to_bcd2(t.hour() as u8);
-            let (mnt, mnu) = byte_to_bcd2(t.minute() as u8);
-            let (st, su) = byte_to_bcd2(t.second() as u8);
+            let (ht, hu) = byte_to_bcd2(t.hour());
+            let (mnt, mnu) = byte_to_bcd2(t.minute());
+            let (st, su) = byte_to_bcd2(t.second());
 
-            let (dt, du) = byte_to_bcd2(t.day() as u8);
-            let (mt, mu) = byte_to_bcd2(t.month() as u8);
-            let yr = t.year() as u16;
+            let (dt, du) = byte_to_bcd2(t.day());
+            let (mt, mu) = byte_to_bcd2(t.month());
+            let yr = t.year();
             let yr_offset = (yr - 2000_u16) as u8;
             let (yt, yu) = byte_to_bcd2(yr_offset);
 
@@ -338,7 +332,7 @@ impl Rtc {
     }
 
     #[cfg(feature = "low-power")]
-    /// start the wakeup alarm and wtih a duration that is as close to but less than
+    /// start the wakeup alarm and with a duration that is as close to but less than
     /// the requested duration, and record the instant the wakeup alarm was started
     pub(crate) fn start_wakeup_alarm(
         &self,
@@ -422,20 +416,15 @@ impl Rtc {
                 #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
                 regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 
-                #[cfg(all(stm32g0))]
-                crate::pac::EXTI
-                    .rpr(0)
-                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
-                #[cfg(all(not(stm32g0), not(stm32l5)))]
+                // Check RM for EXTI and/or NVIC section, "Event event input mapping" or "EXTI interrupt/event mapping" or something similar,
+                // there is a table for every "Event input" / "EXTI Line".
+                // If you find the EXTI line related to "RTC wakeup" marks as "Configurable" (not "Direct"),
+                // then write 1 to related field of Pending Register, to clean it's pending state.
+                #[cfg(any(exti_v1, stm32h7, stm32wb))]
                 crate::pac::EXTI
                     .pr(0)
                     .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 
-                #[cfg(stm32l5)]
-                crate::pac::EXTI
-                    .fpr(0)
-                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
-
                 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
             });
         }
@@ -465,7 +454,7 @@ pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) {
         value -= 10;
     }
 
-    (bcd_high, ((bcd_high << 4) | value) as u8)
+    (bcd_high, ((bcd_high << 4) | value))
 }
 
 pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 8a78d16e1..e51e09e7c 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -50,7 +50,7 @@ impl super::Rtc {
             clock_drift = Self::RTC_CALR_MAX_PPM;
         }
 
-        clock_drift = clock_drift / Self::RTC_CALR_RESOLUTION_PPM;
+        clock_drift /= Self::RTC_CALR_RESOLUTION_PPM;
 
         self.write(false, |rtc| {
             rtc.calr().write(|w| {
@@ -129,29 +129,25 @@ impl super::Rtc {
 impl SealedInstance for crate::peripherals::RTC {
     const BACKUP_REGISTER_COUNT: usize = 32;
 
-    #[cfg(all(feature = "low-power", stm32g4))]
-    const EXTI_WAKEUP_LINE: usize = 20;
-
-    #[cfg(all(feature = "low-power", stm32g0))]
-    const EXTI_WAKEUP_LINE: usize = 19;
-
-    #[cfg(all(feature = "low-power", stm32g0))]
-    type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP;
-
-    #[cfg(all(feature = "low-power", stm32g4))]
-    type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
-
-    #[cfg(all(feature = "low-power", stm32l5))]
-    const EXTI_WAKEUP_LINE: usize = 17;
-
-    #[cfg(all(feature = "low-power", stm32l5))]
-    type WakeupInterrupt = crate::interrupt::typelevel::RTC;
+    #[cfg(feature = "low-power")]
+    cfg_if::cfg_if!(
+        if #[cfg(stm32g4)] {
+            const EXTI_WAKEUP_LINE: usize = 20;
+            type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
+        } else if #[cfg(stm32g0)] {
+            const EXTI_WAKEUP_LINE: usize = 19;
+            type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP;
+        } else if #[cfg(any(stm32l5, stm32h5))] {
+            const EXTI_WAKEUP_LINE: usize = 17;
+            type WakeupInterrupt = crate::interrupt::typelevel::RTC;
+        }
+    );
 
     fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
         #[allow(clippy::if_same_then_else)]
         if register < Self::BACKUP_REGISTER_COUNT {
             //Some(rtc.bkpr()[register].read().bits())
-            None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
+            None // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
         } else {
             None
         }
@@ -159,7 +155,7 @@ impl SealedInstance for crate::peripherals::RTC {
 
     fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) {
         if register < Self::BACKUP_REGISTER_COUNT {
-            // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC
+            // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
             //self.rtc.bkpr()[register].write(|w| w.bits(value))
         }
     }
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 4527f4bcb..82760db64 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
 
 [dependencies]
 # Change stm32h563zi to your chip name, if necessary.
-embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] }
+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.5.0", path = "../../embassy-sync", features = ["defmt"] }
 embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
 embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs
new file mode 100644
index 000000000..0d14c0668
--- /dev/null
+++ b/examples/stm32h5/src/bin/stop.rs
@@ -0,0 +1,71 @@
+// Notice:
+// the MCU might need an extra reset to make the code actually running
+
+#![no_std]
+#![no_main]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
+use embassy_stm32::low_power::Executor;
+use embassy_stm32::rcc::{HSIPrescaler, LsConfig};
+use embassy_stm32::rtc::{Rtc, RtcConfig};
+use embassy_stm32::Config;
+use embassy_time::Timer;
+use static_cell::StaticCell;
+use {defmt_rtt as _, panic_probe as _};
+
+#[cortex_m_rt::entry]
+fn main() -> ! {
+    Executor::take().run(|spawner| {
+        unwrap!(spawner.spawn(async_main(spawner)));
+    })
+}
+
+#[embassy_executor::task]
+async fn async_main(spawner: Spawner) {
+    defmt::info!("Program Start");
+
+    let mut config = Config::default();
+
+    // System Clock seems need to be equal or lower than 16 MHz
+    config.rcc.hsi = Some(HSIPrescaler::DIV4);
+
+    config.rcc.ls = LsConfig::default_lsi();
+    // when enabled the power-consumption is much higher during stop, but debugging and RTT is working
+    // if you wan't to measure the power-consumption, or for production: uncomment this line
+    // config.enable_debug_during_sleep = false;
+    let p = embassy_stm32::init(config);
+
+    // give the RTC to the executor...
+    let rtc = Rtc::new(p.RTC, RtcConfig::default());
+    static RTC: StaticCell<Rtc> = StaticCell::new();
+    let rtc = RTC.init(rtc);
+    embassy_stm32::low_power::stop_with_rtc(rtc);
+
+    unwrap!(spawner.spawn(blinky(p.PB4.into())));
+    unwrap!(spawner.spawn(timeout()));
+}
+
+#[embassy_executor::task]
+async fn blinky(led: AnyPin) {
+    let mut led = Output::new(led, Level::Low, Speed::Low);
+    loop {
+        info!("high");
+        led.set_high();
+        Timer::after_millis(300).await;
+
+        info!("low");
+        led.set_low();
+        Timer::after_millis(300).await;
+    }
+}
+
+// when enable_debug_during_sleep is false, it is more difficult to reprogram the MCU
+// therefore we block the MCU after 30s to be able to reprogram it easily
+#[embassy_executor::task]
+async fn timeout() -> ! {
+    Timer::after_secs(30).await;
+    #[allow(clippy::empty_loop)]
+    loop {}
+}
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 004846a9b..30669b88c 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -15,7 +15,7 @@ stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma"
 stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"]
 stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"]
 stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"]
-stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "fdcan", "hash", "cordic"]
+stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"]
 stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"]
 stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"]
 stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"]
@@ -31,7 +31,7 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac"
 stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"]
 stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"]
 stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
-stm32h503rb = ["embassy-stm32/stm32h503rb", "rng"]
+stm32h503rb = ["embassy-stm32/stm32h503rb", "rng", "stop"]
 
 cryp = []
 hash = []
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 000296d46..c1106bb2f 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -51,6 +51,13 @@ async fn async_main(spawner: Spawner) {
     let mut config = Config::default();
     config.rcc.ls = LsConfig::default_lse();
 
+    // System Clock seems cannot be greater than 16 MHz
+    #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))]
+    {
+        use embassy_stm32::rcc::HSIPrescaler;
+        config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4
+    }
+
     let p = embassy_stm32::init(config);
     info!("Hello World!");