diff options
| author | WillaWillNot <[email protected]> | 2025-11-21 16:38:34 -0500 |
|---|---|---|
| committer | WillaWillNot <[email protected]> | 2025-11-21 16:39:10 -0500 |
| commit | a5f7764eb4f01a0668cbd3b534cde486b97f5ba4 (patch) | |
| tree | 1dde242388f703630d4a2ecc34c95df459ccf2c1 /embassy-stm32 | |
| parent | 623623a25f213f76de932eaf4458c3120823d205 (diff) | |
| parent | 96a026c73bad2ebb8dfc78e88c9690611bf2cb97 (diff) | |
Synchronize with main branch
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/adc4.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/ringbuffered.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/hsem/mod.rs | 9 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 35 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 2 |
7 files changed, 54 insertions, 23 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 7311ea683..6e6a07037 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 7 | 7 | ||
| 8 | ## Unreleased - ReleaseDate | 8 | ## Unreleased - ReleaseDate |
| 9 | 9 | ||
| 10 | - fix: Fixed ADC4 enable() for WBA | ||
| 11 | - feat: allow use of anyadcchannel for adc4 | ||
| 12 | - fix: fix incorrect logic for buffered usart transmission complete. | ||
| 10 | - feat: add poll_for methods to exti | 13 | - feat: add poll_for methods to exti |
| 11 | - feat: implement stop for stm32wb. | 14 | - feat: implement stop for stm32wb. |
| 12 | - change: rework hsem and add HIL test for some chips. | 15 | - change: rework hsem and add HIL test for some chips. |
diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs index 499fc2093..472eb46fd 100644 --- a/embassy-stm32/src/adc/adc4.rs +++ b/embassy-stm32/src/adc/adc4.rs | |||
| @@ -113,10 +113,26 @@ foreach_adc!( | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | fn enable() { | 115 | fn enable() { |
| 116 | let cr_initial = ADC4::regs().cr().read(); | ||
| 117 | let isr_initial = ADC4::regs().isr().read(); | ||
| 118 | |||
| 119 | if cr_initial.aden() && isr_initial.adrdy() { | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | |||
| 123 | if cr_initial.aden() || cr_initial.adstart() { | ||
| 124 | if cr_initial.adstart() { | ||
| 125 | ADC4::regs().cr().modify(|w| w.set_adstp(true)); | ||
| 126 | while ADC4::regs().cr().read().adstart() {} | ||
| 127 | } | ||
| 128 | |||
| 129 | ADC4::regs().cr().modify(|w| w.set_addis(true)); | ||
| 130 | while ADC4::regs().cr().read().aden() {} | ||
| 131 | } | ||
| 132 | |||
| 116 | ADC4::regs().isr().write(|w| w.set_adrdy(true)); | 133 | ADC4::regs().isr().write(|w| w.set_adrdy(true)); |
| 117 | ADC4::regs().cr().modify(|w| w.set_aden(true)); | 134 | ADC4::regs().cr().modify(|w| w.set_aden(true)); |
| 118 | while !ADC4::regs().isr().read().adrdy() {} | 135 | while !ADC4::regs().isr().read().adrdy() {} |
| 119 | ADC4::regs().isr().write(|w| w.set_adrdy(true)); | ||
| 120 | } | 136 | } |
| 121 | 137 | ||
| 122 | fn start() { | 138 | fn start() { |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 74648cc21..755cb78c2 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -436,9 +436,9 @@ pub struct AnyAdcChannel<T> { | |||
| 436 | is_differential: bool, | 436 | is_differential: bool, |
| 437 | _phantom: PhantomData<T>, | 437 | _phantom: PhantomData<T>, |
| 438 | } | 438 | } |
| 439 | impl_peripheral!(AnyAdcChannel<T: Instance>); | 439 | impl_peripheral!(AnyAdcChannel<T: AnyInstance>); |
| 440 | impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {} | 440 | impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<T> {} |
| 441 | impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { | 441 | impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<T> { |
| 442 | fn channel(&self) -> u8 { | 442 | fn channel(&self) -> u8 { |
| 443 | self.channel | 443 | self.channel |
| 444 | } | 444 | } |
diff --git a/embassy-stm32/src/adc/ringbuffered.rs b/embassy-stm32/src/adc/ringbuffered.rs index a56f8ca0b..5437866d3 100644 --- a/embassy-stm32/src/adc/ringbuffered.rs +++ b/embassy-stm32/src/adc/ringbuffered.rs | |||
| @@ -49,8 +49,6 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> { | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | pub fn stop(&mut self) { | 51 | pub fn stop(&mut self) { |
| 52 | T::stop(); | ||
| 53 | |||
| 54 | self.ring_buf.request_pause(); | 52 | self.ring_buf.request_pause(); |
| 55 | 53 | ||
| 56 | compiler_fence(Ordering::SeqCst); | 54 | compiler_fence(Ordering::SeqCst); |
| @@ -161,7 +159,7 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> { | |||
| 161 | return Ok(len); | 159 | return Ok(len); |
| 162 | } | 160 | } |
| 163 | Err(_) => { | 161 | Err(_) => { |
| 164 | self.stop(); | 162 | self.ring_buf.request_pause(); |
| 165 | 163 | ||
| 166 | return Err(OverrunError); | 164 | return Err(OverrunError); |
| 167 | } | 165 | } |
diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs index 5f1ed9b09..e62de0454 100644 --- a/embassy-stm32/src/hsem/mod.rs +++ b/embassy-stm32/src/hsem/mod.rs | |||
| @@ -293,8 +293,13 @@ impl<T: Instance> HardwareSemaphore<T> { | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | #[cfg(all(stm32wb, feature = "low-power"))] | 295 | #[cfg(all(stm32wb, feature = "low-power"))] |
| 296 | pub(crate) fn init_hsem(_cs: CriticalSection) { | 296 | pub(crate) fn init_hsem(cs: CriticalSection) { |
| 297 | rcc::enable_and_reset::<crate::peripherals::HSEM>(); | 297 | rcc::enable_and_reset_with_cs::<crate::peripherals::HSEM>(cs); |
| 298 | |||
| 299 | unsafe { | ||
| 300 | crate::rcc::REFCOUNT_STOP1 = 0; | ||
| 301 | crate::rcc::REFCOUNT_STOP2 = 0; | ||
| 302 | } | ||
| 298 | } | 303 | } |
| 299 | 304 | ||
| 300 | struct State { | 305 | struct State { |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 15478eed4..9de49c867 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -50,7 +50,7 @@ use critical_section::CriticalSection; | |||
| 50 | use embassy_executor::*; | 50 | use embassy_executor::*; |
| 51 | 51 | ||
| 52 | use crate::interrupt; | 52 | use crate::interrupt; |
| 53 | use crate::rcc::{REFCOUNT_STOP1, REFCOUNT_STOP2}; | 53 | use crate::rcc::{RCC_CONFIG, REFCOUNT_STOP1, REFCOUNT_STOP2}; |
| 54 | use crate::time_driver::get_driver; | 54 | use crate::time_driver::get_driver; |
| 55 | 55 | ||
| 56 | const THREAD_PENDER: usize = usize::MAX; | 56 | const THREAD_PENDER: usize = usize::MAX; |
| @@ -147,17 +147,17 @@ pub enum StopMode { | |||
| 147 | Stop2, | 147 | Stop2, |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wlex, stm32u0))] | 150 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wlex, stm32u0))] |
| 151 | use crate::pac::pwr::vals::Lpms; | 151 | use crate::pac::pwr::vals::Lpms; |
| 152 | 152 | ||
| 153 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wlex, stm32u0))] | 153 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wlex, stm32u0))] |
| 154 | impl Into<Lpms> for StopMode { | 154 | impl Into<Lpms> for StopMode { |
| 155 | fn into(self) -> Lpms { | 155 | fn into(self) -> Lpms { |
| 156 | match self { | 156 | match self { |
| 157 | StopMode::Stop1 => Lpms::STOP1, | 157 | StopMode::Stop1 => Lpms::STOP1, |
| 158 | #[cfg(not(stm32wba))] | 158 | #[cfg(not(any(stm32wb, stm32wba)))] |
| 159 | StopMode::Stop2 => Lpms::STOP2, | 159 | StopMode::Stop2 => Lpms::STOP2, |
| 160 | #[cfg(stm32wba)] | 160 | #[cfg(any(stm32wb, stm32wba))] |
| 161 | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? | 161 | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? |
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| @@ -201,7 +201,7 @@ impl Executor { | |||
| 201 | { | 201 | { |
| 202 | use crate::pac::rcc::vals::Sw; | 202 | use crate::pac::rcc::vals::Sw; |
| 203 | use crate::pac::{PWR, RCC}; | 203 | use crate::pac::{PWR, RCC}; |
| 204 | use crate::rcc::{RCC_CONFIG, init as init_rcc}; | 204 | use crate::rcc::init as init_rcc; |
| 205 | 205 | ||
| 206 | let extscr = PWR.extscr().read(); | 206 | let extscr = PWR.extscr().read(); |
| 207 | if extscr.c1stop2f() || extscr.c1stopf() { | 207 | if extscr.c1stop2f() || extscr.c1stopf() { |
| @@ -237,13 +237,15 @@ impl Executor { | |||
| 237 | trace!("low power: stop 1"); | 237 | trace!("low power: stop 1"); |
| 238 | Some(StopMode::Stop1) | 238 | Some(StopMode::Stop1) |
| 239 | } else { | 239 | } else { |
| 240 | trace!("low power: not ready to stop"); | 240 | trace!("low power: not ready to stop (refcount_stop1: {})", unsafe { |
| 241 | REFCOUNT_STOP1 | ||
| 242 | }); | ||
| 241 | None | 243 | None |
| 242 | } | 244 | } |
| 243 | } | 245 | } |
| 244 | 246 | ||
| 245 | #[cfg(all(stm32wb, feature = "low-power"))] | 247 | #[cfg(all(stm32wb, feature = "low-power"))] |
| 246 | fn configure_stop_stm32wb(&self, _stop_mode: StopMode) -> Result<(), ()> { | 248 | fn configure_stop_stm32wb(&self, _cs: CriticalSection) -> Result<(), ()> { |
| 247 | use core::task::Poll; | 249 | use core::task::Poll; |
| 248 | 250 | ||
| 249 | use embassy_futures::poll_once; | 251 | use embassy_futures::poll_once; |
| @@ -252,14 +254,20 @@ impl Executor { | |||
| 252 | use crate::pac::rcc::vals::{Smps, Sw}; | 254 | use crate::pac::rcc::vals::{Smps, Sw}; |
| 253 | use crate::pac::{PWR, RCC}; | 255 | use crate::pac::{PWR, RCC}; |
| 254 | 256 | ||
| 257 | trace!("low power: trying to get sem3"); | ||
| 258 | |||
| 255 | let sem3_mutex = match poll_once(HardwareSemaphoreChannel::<crate::peripherals::HSEM>::new(3).lock(0)) { | 259 | let sem3_mutex = match poll_once(HardwareSemaphoreChannel::<crate::peripherals::HSEM>::new(3).lock(0)) { |
| 256 | Poll::Pending => None, | 260 | Poll::Pending => None, |
| 257 | Poll::Ready(mutex) => Some(mutex), | 261 | Poll::Ready(mutex) => Some(mutex), |
| 258 | } | 262 | } |
| 259 | .ok_or(())?; | 263 | .ok_or(())?; |
| 260 | 264 | ||
| 265 | trace!("low power: got sem3"); | ||
| 266 | |||
| 261 | let sem4_mutex = HardwareSemaphoreChannel::<crate::peripherals::HSEM>::new(4).try_lock(0); | 267 | let sem4_mutex = HardwareSemaphoreChannel::<crate::peripherals::HSEM>::new(4).try_lock(0); |
| 262 | if let Some(sem4_mutex) = sem4_mutex { | 268 | if let Some(sem4_mutex) = sem4_mutex { |
| 269 | trace!("low power: got sem4"); | ||
| 270 | |||
| 263 | if PWR.extscr().read().c2ds() { | 271 | if PWR.extscr().read().c2ds() { |
| 264 | drop(sem4_mutex); | 272 | drop(sem4_mutex); |
| 265 | } else { | 273 | } else { |
| @@ -295,11 +303,11 @@ impl Executor { | |||
| 295 | } | 303 | } |
| 296 | 304 | ||
| 297 | #[allow(unused_variables)] | 305 | #[allow(unused_variables)] |
| 298 | fn configure_stop(&self, stop_mode: StopMode) -> Result<(), ()> { | 306 | fn configure_stop(&self, _cs: CriticalSection, stop_mode: StopMode) -> Result<(), ()> { |
| 299 | #[cfg(all(stm32wb, feature = "low-power"))] | 307 | #[cfg(all(stm32wb, feature = "low-power"))] |
| 300 | self.configure_stop_stm32wb(stop_mode)?; | 308 | self.configure_stop_stm32wb(_cs)?; |
| 301 | 309 | ||
| 302 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wba, stm32wlex))] | 310 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wb, stm32wba, stm32wlex))] |
| 303 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); | 311 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); |
| 304 | #[cfg(stm32h5)] | 312 | #[cfg(stm32h5)] |
| 305 | crate::pac::PWR.pmcr().modify(|v| { | 313 | crate::pac::PWR.pmcr().modify(|v| { |
| @@ -322,9 +330,10 @@ impl Executor { | |||
| 322 | compiler_fence(Ordering::SeqCst); | 330 | compiler_fence(Ordering::SeqCst); |
| 323 | 331 | ||
| 324 | critical_section::with(|cs| { | 332 | critical_section::with(|cs| { |
| 333 | let _ = unsafe { RCC_CONFIG }?; | ||
| 325 | let stop_mode = Self::stop_mode(cs)?; | 334 | let stop_mode = Self::stop_mode(cs)?; |
| 326 | let _ = get_driver().pause_time(cs).ok()?; | 335 | get_driver().pause_time(cs).ok()?; |
| 327 | self.configure_stop(stop_mode).ok()?; | 336 | self.configure_stop(cs, stop_mode).ok()?; |
| 328 | 337 | ||
| 329 | Some(()) | 338 | Some(()) |
| 330 | }) | 339 | }) |
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 69c3a740f..26d2b8991 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -87,7 +87,7 @@ unsafe fn on_interrupt(r: Regs, state: &'static State) { | |||
| 87 | // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC) | 87 | // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC) |
| 88 | // indicates that all bytes are pushed out from the FIFO. | 88 | // indicates that all bytes are pushed out from the FIFO. |
| 89 | // For other usart variants it shows that last byte from the buffer was just sent. | 89 | // For other usart variants it shows that last byte from the buffer was just sent. |
| 90 | if sr_val.tc() { | 90 | if sr_val.tc() && r.cr1().read().tcie() { |
| 91 | // For others it is cleared above with `clear_interrupt_flags`. | 91 | // For others it is cleared above with `clear_interrupt_flags`. |
| 92 | #[cfg(any(usart_v1, usart_v2))] | 92 | #[cfg(any(usart_v1, usart_v2))] |
| 93 | sr(r).modify(|w| w.set_tc(false)); | 93 | sr(r).modify(|w| w.set_tc(false)); |
