diff options
| author | xoviat <[email protected]> | 2025-11-19 15:24:05 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-11-19 15:24:05 -0600 |
| commit | 4104d114955be79cf419cb4cfb5c0e72b0abd261 (patch) | |
| tree | e67e5a10072606f3be2c326870ce3790696c4653 /embassy-stm32/src/hsem | |
| parent | a68b5d5d29514dcaf0a6ed08207d3a1f1fa9b464 (diff) | |
stm32: impl. stop for stm32wb
Diffstat (limited to 'embassy-stm32/src/hsem')
| -rw-r--r-- | embassy-stm32/src/hsem/mod.rs | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs index a6b910a53..5f1ed9b09 100644 --- a/embassy-stm32/src/hsem/mod.rs +++ b/embassy-stm32/src/hsem/mod.rs | |||
| @@ -5,6 +5,8 @@ use core::marker::PhantomData; | |||
| 5 | use core::sync::atomic::{Ordering, compiler_fence}; | 5 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | #[cfg(all(stm32wb, feature = "low-power"))] | ||
| 9 | use critical_section::CriticalSection; | ||
| 8 | use embassy_hal_internal::PeripheralType; | 10 | use embassy_hal_internal::PeripheralType; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 12 | ||
| @@ -78,6 +80,12 @@ impl CoreId { | |||
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 83 | #[cfg(not(all(stm32wb, feature = "low-power")))] | ||
| 84 | const PUB_CHANNELS: usize = 6; | ||
| 85 | |||
| 86 | #[cfg(all(stm32wb, feature = "low-power"))] | ||
| 87 | const PUB_CHANNELS: usize = 4; | ||
| 88 | |||
| 81 | /// TX interrupt handler. | 89 | /// TX interrupt handler. |
| 82 | pub struct HardwareSemaphoreInterruptHandler<T: Instance> { | 90 | pub struct HardwareSemaphoreInterruptHandler<T: Instance> { |
| 83 | _phantom: PhantomData<T>, | 91 | _phantom: PhantomData<T>, |
| @@ -127,7 +135,7 @@ pub struct HardwareSemaphoreChannel<'a, T: Instance> { | |||
| 127 | } | 135 | } |
| 128 | 136 | ||
| 129 | impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { | 137 | impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { |
| 130 | pub(self) const fn new(number: u8) -> Self { | 138 | pub(crate) const fn new(number: u8) -> Self { |
| 131 | core::assert!(number > 0 && number <= 6); | 139 | core::assert!(number > 0 && number <= 6); |
| 132 | 140 | ||
| 133 | Self { | 141 | Self { |
| @@ -151,19 +159,29 @@ impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { | |||
| 151 | .ier(core_id.to_index()) | 159 | .ier(core_id.to_index()) |
| 152 | .modify(|w| w.set_ise(self.index as usize, true)); | 160 | .modify(|w| w.set_ise(self.index as usize, true)); |
| 153 | 161 | ||
| 154 | if self.two_step_lock(process_id).is_ok() { | 162 | match self.try_lock(process_id) { |
| 155 | Poll::Ready(HardwareSemaphoreMutex { | 163 | Some(mutex) => Poll::Ready(mutex), |
| 156 | index: self.index, | 164 | None => Poll::Pending, |
| 157 | process_id: process_id, | ||
| 158 | _lifetime: PhantomData, | ||
| 159 | }) | ||
| 160 | } else { | ||
| 161 | Poll::Pending | ||
| 162 | } | 165 | } |
| 163 | }) | 166 | }) |
| 164 | .await | 167 | .await |
| 165 | } | 168 | } |
| 166 | 169 | ||
| 170 | /// Try to lock the semaphor | ||
| 171 | /// The 2-step lock procedure consists in a write to lock the semaphore, followed by a read to | ||
| 172 | /// check if the lock has been successful, carried out from the HSEM_Rx register. | ||
| 173 | pub fn try_lock(&mut self, process_id: u8) -> Option<HardwareSemaphoreMutex<'a, T>> { | ||
| 174 | if self.two_step_lock(process_id).is_ok() { | ||
| 175 | Some(HardwareSemaphoreMutex { | ||
| 176 | index: self.index, | ||
| 177 | process_id: process_id, | ||
| 178 | _lifetime: PhantomData, | ||
| 179 | }) | ||
| 180 | } else { | ||
| 181 | None | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 167 | /// Locks the semaphore. | 185 | /// Locks the semaphore. |
| 168 | /// The 2-step lock procedure consists in a write to lock the semaphore, followed by a read to | 186 | /// The 2-step lock procedure consists in a write to lock the semaphore, followed by a read to |
| 169 | /// check if the lock has been successful, carried out from the HSEM_Rx register. | 187 | /// check if the lock has been successful, carried out from the HSEM_Rx register. |
| @@ -206,9 +224,9 @@ impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { | |||
| 206 | }); | 224 | }); |
| 207 | } | 225 | } |
| 208 | 226 | ||
| 209 | /// Checks if the semaphore is locked. | 227 | /// Return the channel number |
| 210 | pub fn is_semaphore_locked(&self) -> bool { | 228 | pub const fn channel(&self) -> u8 { |
| 211 | T::regs().r(self.index as usize).read().lock() | 229 | self.index + 1 |
| 212 | } | 230 | } |
| 213 | } | 231 | } |
| 214 | 232 | ||
| @@ -230,15 +248,22 @@ impl<T: Instance> HardwareSemaphore<T> { | |||
| 230 | 248 | ||
| 231 | /// Get a single channel, and keep the global struct | 249 | /// Get a single channel, and keep the global struct |
| 232 | pub const fn channel_for<'a>(&'a mut self, number: u8) -> HardwareSemaphoreChannel<'a, T> { | 250 | pub const fn channel_for<'a>(&'a mut self, number: u8) -> HardwareSemaphoreChannel<'a, T> { |
| 251 | #[cfg(all(stm32wb, feature = "low-power"))] | ||
| 252 | core::assert!(number != 3 && number != 4); | ||
| 253 | |||
| 233 | HardwareSemaphoreChannel::new(number) | 254 | HardwareSemaphoreChannel::new(number) |
| 234 | } | 255 | } |
| 235 | 256 | ||
| 236 | /// Split the global struct into channels | 257 | /// Split the global struct into channels |
| 237 | pub const fn split<'a>(self) -> [HardwareSemaphoreChannel<'a, T>; 6] { | 258 | /// |
| 259 | /// If using low-power mode, channels 3 and 4 will not be returned | ||
| 260 | pub const fn split<'a>(self) -> [HardwareSemaphoreChannel<'a, T>; PUB_CHANNELS] { | ||
| 238 | [ | 261 | [ |
| 239 | HardwareSemaphoreChannel::new(1), | 262 | HardwareSemaphoreChannel::new(1), |
| 240 | HardwareSemaphoreChannel::new(2), | 263 | HardwareSemaphoreChannel::new(2), |
| 264 | #[cfg(not(all(stm32wb, feature = "low-power")))] | ||
| 241 | HardwareSemaphoreChannel::new(3), | 265 | HardwareSemaphoreChannel::new(3), |
| 266 | #[cfg(not(all(stm32wb, feature = "low-power")))] | ||
| 242 | HardwareSemaphoreChannel::new(4), | 267 | HardwareSemaphoreChannel::new(4), |
| 243 | HardwareSemaphoreChannel::new(5), | 268 | HardwareSemaphoreChannel::new(5), |
| 244 | HardwareSemaphoreChannel::new(6), | 269 | HardwareSemaphoreChannel::new(6), |
| @@ -267,6 +292,11 @@ impl<T: Instance> HardwareSemaphore<T> { | |||
| 267 | } | 292 | } |
| 268 | } | 293 | } |
| 269 | 294 | ||
| 295 | #[cfg(all(stm32wb, feature = "low-power"))] | ||
| 296 | pub(crate) fn init_hsem(_cs: CriticalSection) { | ||
| 297 | rcc::enable_and_reset::<crate::peripherals::HSEM>(); | ||
| 298 | } | ||
| 299 | |||
| 270 | struct State { | 300 | struct State { |
| 271 | wakers: [AtomicWaker; 6], | 301 | wakers: [AtomicWaker; 6], |
| 272 | } | 302 | } |
| @@ -278,8 +308,8 @@ impl State { | |||
| 278 | } | 308 | } |
| 279 | } | 309 | } |
| 280 | 310 | ||
| 281 | const fn waker_for(&self, number: u8) -> &AtomicWaker { | 311 | const fn waker_for(&self, index: u8) -> &AtomicWaker { |
| 282 | &self.wakers[number as usize] | 312 | &self.wakers[index as usize] |
| 283 | } | 313 | } |
| 284 | } | 314 | } |
| 285 | 315 | ||
