From df4aa0fe253252734dacd555364f5613044f7ecf Mon Sep 17 00:00:00 2001
From: xoviat <xoviat@users.noreply.github.com>
Date: Mon, 23 Oct 2023 16:26:34 -0500
Subject: [PATCH] stm32: fix low-power test

---
 embassy-stm32/src/rcc/f4f7.rs | 23 +++++++++++++++++------
 embassy-stm32/src/rtc/mod.rs  |  6 +++++-
 tests/stm32/src/bin/stop.rs   |  4 +++-
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs
index 3f9a2be67..7cc076efa 100644
--- a/embassy-stm32/src/rcc/f4f7.rs
+++ b/embassy-stm32/src/rcc/f4f7.rs
@@ -152,9 +152,9 @@ pub(crate) unsafe fn init(config: Config) {
         source: config.pll_src,
     };
     let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
-    #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))]
+    #[cfg(any(all(stm32f4, not(any(stm32f410, stm32f429))), stm32f7))]
     let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input);
-    #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
+    #[cfg(all(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7), not(stm32f429)))]
     let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
 
     // Configure sysclk
@@ -197,15 +197,25 @@ pub(crate) unsafe fn init(config: Config) {
         pclk2_tim,
         rtc,
         pll1_q: pll.q,
-        #[cfg(all(rcc_f4, not(stm32f410)))]
+        #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))]
         plli2s1_q: _plli2s.q,
-        #[cfg(all(rcc_f4, not(stm32f410)))]
+        #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))]
         plli2s1_r: _plli2s.r,
 
-        #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
+        #[cfg(stm32f429)]
+        plli2s1_q: None,
+        #[cfg(stm32f429)]
+        plli2s1_r: None,
+
+        #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
         pllsai1_q: _pllsai.q,
-        #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
+        #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
         pllsai1_r: _pllsai.r,
+
+        #[cfg(stm32f429)]
+        pllsai1_q: None,
+        #[cfg(stm32f429)]
+        pllsai1_r: None,
     });
 }
 
@@ -223,6 +233,7 @@ struct PllOutput {
     r: Option<Hertz>,
 }
 
+#[allow(dead_code)]
 #[derive(PartialEq, Eq, Clone, Copy)]
 enum PllInstance {
     Pll,
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 552dcc76f..d77443a9c 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -184,7 +184,11 @@ impl Default for RtcCalibrationCyclePeriod {
 impl Rtc {
     pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
         #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
-        <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset();
+        critical_section::with(|cs| {
+            <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(cs);
+            #[cfg(feature = "low-power")]
+            crate::rcc::clock_refcount_sub(cs);
+        });
 
         let mut this = Self {
             #[cfg(feature = "low-power")]
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index f38924c90..4f62ecae2 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -11,7 +11,7 @@ use common::*;
 use cortex_m_rt::entry;
 use embassy_executor::Spawner;
 use embassy_stm32::low_power::{stop_with_rtc, Executor};
-use embassy_stm32::rcc::LsConfig;
+use embassy_stm32::rcc::{low_power_ready, LsConfig};
 use embassy_stm32::rtc::{Rtc, RtcConfig};
 use embassy_stm32::Config;
 use embassy_time::Timer;
@@ -28,6 +28,7 @@ fn main() -> ! {
 async fn task_1() {
     for _ in 0..9 {
         info!("task 1: waiting for 500ms...");
+        defmt::assert!(low_power_ready());
         Timer::after_millis(500).await;
     }
 }
@@ -36,6 +37,7 @@ async fn task_1() {
 async fn task_2() {
     for _ in 0..5 {
         info!("task 2: waiting for 1000ms...");
+        defmt::assert!(low_power_ready());
         Timer::after_millis(1000).await;
     }