aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/rcc/mod.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-20 23:36:21 +0200
committerDario Nieuwenhuis <[email protected]>2024-05-20 23:37:20 +0200
commiteeb6ffce4cfa0e0055da8d6738f6d28c3fa43f15 (patch)
treeb6cb52689168a50e2d7e93c70830c3da75eb21b5 /embassy-stm32/src/rcc/mod.rs
parent8e7361f4ca1fe0917eeefaeaced571e6395c265b (diff)
stm32/rcc: add ClockEnableBit struct.
Diffstat (limited to 'embassy-stm32/src/rcc/mod.rs')
-rw-r--r--embassy-stm32/src/rcc/mod.rs50
1 files changed, 49 insertions, 1 deletions
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index a585940bc..c413b62ef 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -31,6 +31,7 @@ pub use hsi48::*;
31mod _version; 31mod _version;
32 32
33pub use _version::*; 33pub use _version::*;
34use stm32_metapac::RCC;
34 35
35pub use crate::_generated::{mux, Clocks}; 36pub use crate::_generated::{mux, Clocks};
36use crate::time::Hertz; 37use crate::time::Hertz;
@@ -66,9 +67,10 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
66} 67}
67 68
68pub(crate) trait SealedRccPeripheral { 69pub(crate) trait SealedRccPeripheral {
69 fn frequency() -> crate::time::Hertz; 70 fn frequency() -> Hertz;
70 fn enable_and_reset_with_cs(cs: CriticalSection); 71 fn enable_and_reset_with_cs(cs: CriticalSection);
71 fn disable_with_cs(cs: CriticalSection); 72 fn disable_with_cs(cs: CriticalSection);
73 fn enable_bit() -> ClockEnableBit;
72 74
73 fn enable_and_reset() { 75 fn enable_and_reset() {
74 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) 76 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
@@ -137,3 +139,49 @@ pub unsafe fn enable_and_reset<T: RccPeripheral>() {
137pub unsafe fn disable<T: RccPeripheral>() { 139pub unsafe fn disable<T: RccPeripheral>() {
138 T::disable(); 140 T::disable();
139} 141}
142
143/// Struct representing some clock enable bit (xxxENR.xxEN), only known at runtime.
144#[derive(Clone, Copy)]
145pub(crate) struct ClockEnableBit {
146 /// offset in 32bit words of the xxxENR register into the RCC register block.
147 offset: u8,
148 /// bit within the register (0..=31)
149 bit: u8,
150}
151
152impl ClockEnableBit {
153 /// Safety: offset+bit must correspond to a valid xxxEN bit.
154 pub(crate) unsafe fn new(offset: u8, bit: u8) -> Self {
155 Self { offset, bit }
156 }
157
158 fn ptr(self) -> *mut u32 {
159 unsafe { (RCC.as_ptr() as *mut u32).add(self.offset as _) }
160 }
161
162 #[allow(unused)]
163 pub(crate) fn enable_with_cs(self, _cs: CriticalSection) {
164 let p = self.ptr();
165 unsafe {
166 let val = p.read_volatile();
167 p.write_volatile(val | 1u32 << self.bit);
168 }
169 }
170
171 pub(crate) fn disable_with_cs(self, _cs: CriticalSection) {
172 let p = self.ptr();
173 unsafe {
174 let val = p.read_volatile();
175 p.write_volatile(val & !(1u32 << self.bit));
176 }
177 }
178
179 #[allow(unused)]
180 pub(crate) fn enable(self) {
181 critical_section::with(|cs| self.enable_with_cs(cs))
182 }
183
184 pub(crate) fn disable(self) {
185 critical_section::with(|cs| self.disable_with_cs(cs))
186 }
187}