From a41a8123456f29b00220ea474594255cc07f2ecf Mon Sep 17 00:00:00 2001
From: Ulf Lilleengen <ulf.lilleengen@gmail.com>
Date: Thu, 27 May 2021 09:50:11 +0200
Subject: [PATCH] Move clocks to rcc mod

---
 embassy-stm32/src/clock.rs      | 38 ++++++----------
 embassy-stm32/src/rcc/l0/mod.rs | 78 +++------------------------------
 embassy-stm32/src/rcc/mod.rs    | 32 ++++++++++++++
 3 files changed, 51 insertions(+), 97 deletions(-)

diff --git a/embassy-stm32/src/clock.rs b/embassy-stm32/src/clock.rs
index 70679c141..3ae83bbb0 100644
--- a/embassy-stm32/src/clock.rs
+++ b/embassy-stm32/src/clock.rs
@@ -10,6 +10,7 @@ use embassy::time::{Clock as EmbassyClock, TICKS_PER_SECOND};
 
 use crate::interrupt::{CriticalSection, Interrupt, Mutex};
 use crate::pac::timer::TimGp16;
+use crate::rcc::get_freqs;
 use crate::time::Hertz;
 
 // Clock timekeeping works with something we call "periods", which are time intervals
@@ -33,20 +34,6 @@ fn calc_now(period: u32, counter: u16) -> u64 {
     ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
 }
 
-static mut CLOCK_FREQS: Option<ClockFreqs> = None;
-
-#[derive(Copy, Clone)]
-pub struct ClockFreqs {
-    pub tim2: Hertz,
-}
-
-/// Sets the clock frequencies
-///
-/// Safety: Sets a mutable global.
-pub unsafe fn set_freqs(freqs: ClockFreqs) {
-    CLOCK_FREQS.replace(freqs);
-}
-
 struct AlarmState {
     timestamp: Cell<u64>,
     #[allow(clippy::type_complexity)]
@@ -91,17 +78,20 @@ impl<T: Instance> Clock<T> {
 
     // TODO: Temporary until clock code generation is in place
     pub fn start_tim2(&'static self) {
-        #[cfg(feature = "_stm32l0")]
-        unsafe {
-            let rcc = crate::pac::RCC;
-            rcc.apb1enr()
-                .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED));
-            rcc.apb1rstr().modify(|w| w.set_tim2rst(true));
-            rcc.apb1rstr().modify(|w| w.set_tim2rst(false));
-        }
+        cfg_if::cfg_if! {
+            if #[cfg(feature = "_stm32l0")] {
+                unsafe {
+                    let rcc = crate::pac::RCC;
+                    rcc.apb1enr()
+                        .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED));
+                    rcc.apb1rstr().modify(|w| w.set_tim2rst(true));
+                    rcc.apb1rstr().modify(|w| w.set_tim2rst(false));
+                }
 
-        let timer_freq = unsafe { CLOCK_FREQS.unwrap().tim2 };
-        self.start(timer_freq);
+                let timer_freq = unsafe { crate::rcc::get_freqs().apb1_clk };
+                self.start(timer_freq);
+            }
+        }
     }
 
     pub fn start(&'static self, timer_freq: Hertz) {
diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs
index 44e88d365..99055d906 100644
--- a/embassy-stm32/src/rcc/l0/mod.rs
+++ b/embassy-stm32/src/rcc/l0/mod.rs
@@ -1,13 +1,11 @@
-use crate::clock::Clock;
-use crate::clock::{set_freqs, ClockFreqs};
-use crate::interrupt;
 use crate::pac;
-use crate::pac::peripherals::{self, RCC, TIM2};
+use crate::pac::peripherals::{self, RCC};
+use crate::rcc::{set_freqs, Clocks};
 use crate::time::Hertz;
 use crate::time::U32Ext;
 use embassy::util::Unborrow;
 use pac::rcc::vals;
-use vals::{Hpre, Lptimen, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw};
+use vals::{Hpre, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw};
 
 /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
 /// and with the addition of the init function to configure a system clock.
@@ -492,7 +490,6 @@ impl RccExt for RCC {
         };
 
         Clocks {
-            source: cfgr.mux,
             sys_clk: sys_clk.hz(),
             ahb_clk: ahb_freq.hz(),
             apb1_clk: apb1_freq.hz(),
@@ -505,69 +502,6 @@ impl RccExt for RCC {
     }
 }
 
-/// Frozen clock frequencies
-///
-/// The existence of this value indicates that the clock configuration can no longer be changed
-#[derive(Clone, Copy)]
-pub struct Clocks {
-    source: ClockSrc,
-    sys_clk: Hertz,
-    ahb_clk: Hertz,
-    apb1_clk: Hertz,
-    apb1_tim_clk: Hertz,
-    apb2_clk: Hertz,
-    apb2_tim_clk: Hertz,
-    apb1_pre: u8,
-    apb2_pre: u8,
-}
-
-impl Clocks {
-    /// Returns the clock source
-    pub fn source(&self) -> &ClockSrc {
-        &self.source
-    }
-
-    /// Returns the system (core) frequency
-    pub fn sys_clk(&self) -> Hertz {
-        self.sys_clk
-    }
-
-    /// Returns the frequency of the AHB
-    pub fn ahb_clk(&self) -> Hertz {
-        self.ahb_clk
-    }
-
-    /// Returns the frequency of the APB1
-    pub fn apb1_clk(&self) -> Hertz {
-        self.apb1_clk
-    }
-
-    /// Returns the frequency of the APB1 timers
-    pub fn apb1_tim_clk(&self) -> Hertz {
-        self.apb1_tim_clk
-    }
-
-    /// Returns the prescaler of the APB1
-    pub fn apb1_pre(&self) -> u8 {
-        self.apb1_pre
-    }
-
-    /// Returns the frequency of the APB2
-    pub fn apb2_clk(&self) -> Hertz {
-        self.apb2_clk
-    }
-
-    /// Returns the frequency of the APB2 timers
-    pub fn apb2_tim_clk(&self) -> Hertz {
-        self.apb2_tim_clk
-    }
-
-    /// Returns the prescaler of the APB2
-    pub fn apb2_pre(&self) -> u8 {
-        self.apb2_pre
-    }
-}
-
 /// Token that exists only, if the HSI48 clock has been enabled
 ///
 /// You can get an instance of this struct by calling [`Rcc::enable_hsi48`].
@@ -598,9 +532,7 @@ pub unsafe fn init(config: Config) {
         w.set_iophen(enabled);
     });
 
-    let mut r = <peripherals::RCC as embassy::util::Steal>::steal();
+    let r = <peripherals::RCC as embassy::util::Steal>::steal();
     let clocks = r.freeze(config);
-    set_freqs(ClockFreqs {
-        tim2: clocks.apb1_clk(),
-    });
+    set_freqs(clocks);
 }
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index f15cee7f6..cb8780343 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -1,3 +1,35 @@
+use crate::time::Hertz;
+use core::mem::MaybeUninit;
+
+/// Frozen clock frequencies
+///
+/// The existence of this value indicates that the clock configuration can no longer be changed
+#[derive(Clone, Copy)]
+pub struct Clocks {
+    pub sys_clk: Hertz,
+    pub ahb_clk: Hertz,
+    pub apb1_clk: Hertz,
+    pub apb1_tim_clk: Hertz,
+    pub apb2_clk: Hertz,
+    pub apb2_tim_clk: Hertz,
+    pub apb1_pre: u8,
+    pub apb2_pre: u8,
+}
+
+static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
+
+/// Sets the clock frequencies
+///
+/// Safety: Sets a mutable global.
+pub unsafe fn set_freqs(freqs: Clocks) {
+    CLOCK_FREQS.as_mut_ptr().write(freqs);
+}
+
+/// Safety: Reads a mutable global.
+pub unsafe fn get_freqs() -> &'static Clocks {
+    &*CLOCK_FREQS.as_ptr()
+}
+
 cfg_if::cfg_if! {
     if #[cfg(feature = "_stm32h7")] {
         mod h7;