diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-05-20 23:36:21 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-05-20 23:37:20 +0200 |
| commit | eeb6ffce4cfa0e0055da8d6738f6d28c3fa43f15 (patch) | |
| tree | b6cb52689168a50e2d7e93c70830c3da75eb21b5 /embassy-stm32/src/rcc/mod.rs | |
| parent | 8e7361f4ca1fe0917eeefaeaced571e6395c265b (diff) | |
stm32/rcc: add ClockEnableBit struct.
Diffstat (limited to 'embassy-stm32/src/rcc/mod.rs')
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 50 |
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::*; | |||
| 31 | mod _version; | 31 | mod _version; |
| 32 | 32 | ||
| 33 | pub use _version::*; | 33 | pub use _version::*; |
| 34 | use stm32_metapac::RCC; | ||
| 34 | 35 | ||
| 35 | pub use crate::_generated::{mux, Clocks}; | 36 | pub use crate::_generated::{mux, Clocks}; |
| 36 | use crate::time::Hertz; | 37 | use crate::time::Hertz; |
| @@ -66,9 +67,10 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks { | |||
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | pub(crate) trait SealedRccPeripheral { | 69 | pub(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>() { | |||
| 137 | pub unsafe fn disable<T: RccPeripheral>() { | 139 | pub 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)] | ||
| 145 | pub(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 | |||
| 152 | impl 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 | } | ||
