diff options
| -rw-r--r-- | embassy-stm32/src/clock.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0/mod.rs | 78 | ||||
| -rw-r--r-- | 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}; | |||
| 10 | 10 | ||
| 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; | 11 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; |
| 12 | use crate::pac::timer::TimGp16; | 12 | use crate::pac::timer::TimGp16; |
| 13 | use crate::rcc::get_freqs; | ||
| 13 | use crate::time::Hertz; | 14 | use crate::time::Hertz; |
| 14 | 15 | ||
| 15 | // Clock timekeeping works with something we call "periods", which are time intervals | 16 | // Clock timekeeping works with something we call "periods", which are time intervals |
| @@ -33,20 +34,6 @@ fn calc_now(period: u32, counter: u16) -> u64 { | |||
| 33 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) | 34 | ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | static mut CLOCK_FREQS: Option<ClockFreqs> = None; | ||
| 37 | |||
| 38 | #[derive(Copy, Clone)] | ||
| 39 | pub struct ClockFreqs { | ||
| 40 | pub tim2: Hertz, | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Sets the clock frequencies | ||
| 44 | /// | ||
| 45 | /// Safety: Sets a mutable global. | ||
| 46 | pub unsafe fn set_freqs(freqs: ClockFreqs) { | ||
| 47 | CLOCK_FREQS.replace(freqs); | ||
| 48 | } | ||
| 49 | |||
| 50 | struct AlarmState { | 37 | struct AlarmState { |
| 51 | timestamp: Cell<u64>, | 38 | timestamp: Cell<u64>, |
| 52 | #[allow(clippy::type_complexity)] | 39 | #[allow(clippy::type_complexity)] |
| @@ -91,17 +78,20 @@ impl<T: Instance> Clock<T> { | |||
| 91 | 78 | ||
| 92 | // TODO: Temporary until clock code generation is in place | 79 | // TODO: Temporary until clock code generation is in place |
| 93 | pub fn start_tim2(&'static self) { | 80 | pub fn start_tim2(&'static self) { |
| 94 | #[cfg(feature = "_stm32l0")] | 81 | cfg_if::cfg_if! { |
| 95 | unsafe { | 82 | if #[cfg(feature = "_stm32l0")] { |
| 96 | let rcc = crate::pac::RCC; | 83 | unsafe { |
| 97 | rcc.apb1enr() | 84 | let rcc = crate::pac::RCC; |
| 98 | .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED)); | 85 | rcc.apb1enr() |
| 99 | rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); | 86 | .modify(|w| w.set_tim2en(crate::pac::rcc::vals::Lptimen::ENABLED)); |
| 100 | rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); | 87 | rcc.apb1rstr().modify(|w| w.set_tim2rst(true)); |
| 101 | } | 88 | rcc.apb1rstr().modify(|w| w.set_tim2rst(false)); |
| 89 | } | ||
| 102 | 90 | ||
| 103 | let timer_freq = unsafe { CLOCK_FREQS.unwrap().tim2 }; | 91 | let timer_freq = unsafe { crate::rcc::get_freqs().apb1_clk }; |
| 104 | self.start(timer_freq); | 92 | self.start(timer_freq); |
| 93 | } | ||
| 94 | } | ||
| 105 | } | 95 | } |
| 106 | 96 | ||
| 107 | pub fn start(&'static self, timer_freq: Hertz) { | 97 | 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 @@ | |||
| 1 | use crate::clock::Clock; | ||
| 2 | use crate::clock::{set_freqs, ClockFreqs}; | ||
| 3 | use crate::interrupt; | ||
| 4 | use crate::pac; | 1 | use crate::pac; |
| 5 | use crate::pac::peripherals::{self, RCC, TIM2}; | 2 | use crate::pac::peripherals::{self, RCC}; |
| 3 | use crate::rcc::{set_freqs, Clocks}; | ||
| 6 | use crate::time::Hertz; | 4 | use crate::time::Hertz; |
| 7 | use crate::time::U32Ext; | 5 | use crate::time::U32Ext; |
| 8 | use embassy::util::Unborrow; | 6 | use embassy::util::Unborrow; |
| 9 | use pac::rcc::vals; | 7 | use pac::rcc::vals; |
| 10 | use vals::{Hpre, Lptimen, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw}; | 8 | use vals::{Hpre, Msirange, Plldiv, Pllmul, Pllon, Pllsrc, Ppre, Sw}; |
| 11 | 9 | ||
| 12 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 10 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, |
| 13 | /// and with the addition of the init function to configure a system clock. | 11 | /// and with the addition of the init function to configure a system clock. |
| @@ -492,7 +490,6 @@ impl RccExt for RCC { | |||
| 492 | }; | 490 | }; |
| 493 | 491 | ||
| 494 | Clocks { | 492 | Clocks { |
| 495 | source: cfgr.mux, | ||
| 496 | sys_clk: sys_clk.hz(), | 493 | sys_clk: sys_clk.hz(), |
| 497 | ahb_clk: ahb_freq.hz(), | 494 | ahb_clk: ahb_freq.hz(), |
| 498 | apb1_clk: apb1_freq.hz(), | 495 | apb1_clk: apb1_freq.hz(), |
| @@ -505,69 +502,6 @@ impl RccExt for RCC { | |||
| 505 | } | 502 | } |
| 506 | } | 503 | } |
| 507 | 504 | ||
| 508 | /// Frozen clock frequencies | ||
| 509 | /// | ||
| 510 | /// The existence of this value indicates that the clock configuration can no longer be changed | ||
| 511 | #[derive(Clone, Copy)] | ||
| 512 | pub struct Clocks { | ||
| 513 | source: ClockSrc, | ||
| 514 | sys_clk: Hertz, | ||
| 515 | ahb_clk: Hertz, | ||
| 516 | apb1_clk: Hertz, | ||
| 517 | apb1_tim_clk: Hertz, | ||
| 518 | apb2_clk: Hertz, | ||
| 519 | apb2_tim_clk: Hertz, | ||
| 520 | apb1_pre: u8, | ||
| 521 | apb2_pre: u8, | ||
| 522 | } | ||
| 523 | |||
| 524 | impl Clocks { | ||
| 525 | /// Returns the clock source | ||
| 526 | pub fn source(&self) -> &ClockSrc { | ||
| 527 | &self.source | ||
| 528 | } | ||
| 529 | |||
| 530 | /// Returns the system (core) frequency | ||
| 531 | pub fn sys_clk(&self) -> Hertz { | ||
| 532 | self.sys_clk | ||
| 533 | } | ||
| 534 | |||
| 535 | /// Returns the frequency of the AHB | ||
| 536 | pub fn ahb_clk(&self) -> Hertz { | ||
| 537 | self.ahb_clk | ||
| 538 | } | ||
| 539 | |||
| 540 | /// Returns the frequency of the APB1 | ||
| 541 | pub fn apb1_clk(&self) -> Hertz { | ||
| 542 | self.apb1_clk | ||
| 543 | } | ||
| 544 | |||
| 545 | /// Returns the frequency of the APB1 timers | ||
| 546 | pub fn apb1_tim_clk(&self) -> Hertz { | ||
| 547 | self.apb1_tim_clk | ||
| 548 | } | ||
| 549 | |||
| 550 | /// Returns the prescaler of the APB1 | ||
| 551 | pub fn apb1_pre(&self) -> u8 { | ||
| 552 | self.apb1_pre | ||
| 553 | } | ||
| 554 | |||
| 555 | /// Returns the frequency of the APB2 | ||
| 556 | pub fn apb2_clk(&self) -> Hertz { | ||
| 557 | self.apb2_clk | ||
| 558 | } | ||
| 559 | |||
| 560 | /// Returns the frequency of the APB2 timers | ||
| 561 | pub fn apb2_tim_clk(&self) -> Hertz { | ||
| 562 | self.apb2_tim_clk | ||
| 563 | } | ||
| 564 | |||
| 565 | /// Returns the prescaler of the APB2 | ||
| 566 | pub fn apb2_pre(&self) -> u8 { | ||
| 567 | self.apb2_pre | ||
| 568 | } | ||
| 569 | } | ||
| 570 | |||
| 571 | /// Token that exists only, if the HSI48 clock has been enabled | 505 | /// Token that exists only, if the HSI48 clock has been enabled |
| 572 | /// | 506 | /// |
| 573 | /// You can get an instance of this struct by calling [`Rcc::enable_hsi48`]. | 507 | /// You can get an instance of this struct by calling [`Rcc::enable_hsi48`]. |
| @@ -598,9 +532,7 @@ pub unsafe fn init(config: Config) { | |||
| 598 | w.set_iophen(enabled); | 532 | w.set_iophen(enabled); |
| 599 | }); | 533 | }); |
| 600 | 534 | ||
| 601 | let mut r = <peripherals::RCC as embassy::util::Steal>::steal(); | 535 | let r = <peripherals::RCC as embassy::util::Steal>::steal(); |
| 602 | let clocks = r.freeze(config); | 536 | let clocks = r.freeze(config); |
| 603 | set_freqs(ClockFreqs { | 537 | set_freqs(clocks); |
| 604 | tim2: clocks.apb1_clk(), | ||
| 605 | }); | ||
| 606 | } | 538 | } |
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 @@ | |||
| 1 | use crate::time::Hertz; | ||
| 2 | use core::mem::MaybeUninit; | ||
| 3 | |||
| 4 | /// Frozen clock frequencies | ||
| 5 | /// | ||
| 6 | /// The existence of this value indicates that the clock configuration can no longer be changed | ||
| 7 | #[derive(Clone, Copy)] | ||
| 8 | pub struct Clocks { | ||
| 9 | pub sys_clk: Hertz, | ||
| 10 | pub ahb_clk: Hertz, | ||
| 11 | pub apb1_clk: Hertz, | ||
| 12 | pub apb1_tim_clk: Hertz, | ||
| 13 | pub apb2_clk: Hertz, | ||
| 14 | pub apb2_tim_clk: Hertz, | ||
| 15 | pub apb1_pre: u8, | ||
| 16 | pub apb2_pre: u8, | ||
| 17 | } | ||
| 18 | |||
| 19 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); | ||
| 20 | |||
| 21 | /// Sets the clock frequencies | ||
| 22 | /// | ||
| 23 | /// Safety: Sets a mutable global. | ||
| 24 | pub unsafe fn set_freqs(freqs: Clocks) { | ||
| 25 | CLOCK_FREQS.as_mut_ptr().write(freqs); | ||
| 26 | } | ||
| 27 | |||
| 28 | /// Safety: Reads a mutable global. | ||
| 29 | pub unsafe fn get_freqs() -> &'static Clocks { | ||
| 30 | &*CLOCK_FREQS.as_ptr() | ||
| 31 | } | ||
| 32 | |||
| 1 | cfg_if::cfg_if! { | 33 | cfg_if::cfg_if! { |
| 2 | if #[cfg(feature = "_stm32h7")] { | 34 | if #[cfg(feature = "_stm32h7")] { |
| 3 | mod h7; | 35 | mod h7; |
