aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorWillaWillNot <[email protected]>2025-11-21 16:38:34 -0500
committerWillaWillNot <[email protected]>2025-11-21 16:39:10 -0500
commita5f7764eb4f01a0668cbd3b534cde486b97f5ba4 (patch)
tree1dde242388f703630d4a2ecc34c95df459ccf2c1 /embassy-stm32
parent623623a25f213f76de932eaf4458c3120823d205 (diff)
parent96a026c73bad2ebb8dfc78e88c9690611bf2cb97 (diff)
Synchronize with main branch
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/CHANGELOG.md3
-rw-r--r--embassy-stm32/src/adc/adc4.rs18
-rw-r--r--embassy-stm32/src/adc/mod.rs6
-rw-r--r--embassy-stm32/src/adc/ringbuffered.rs4
-rw-r--r--embassy-stm32/src/hsem/mod.rs9
-rw-r--r--embassy-stm32/src/low_power.rs35
-rw-r--r--embassy-stm32/src/usart/buffered.rs2
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}
439impl_peripheral!(AnyAdcChannel<T: Instance>); 439impl_peripheral!(AnyAdcChannel<T: AnyInstance>);
440impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {} 440impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<T> {}
441impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { 441impl<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"))]
296pub(crate) fn init_hsem(_cs: CriticalSection) { 296pub(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
300struct State { 305struct 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;
50use embassy_executor::*; 50use embassy_executor::*;
51 51
52use crate::interrupt; 52use crate::interrupt;
53use crate::rcc::{REFCOUNT_STOP1, REFCOUNT_STOP2}; 53use crate::rcc::{RCC_CONFIG, REFCOUNT_STOP1, REFCOUNT_STOP2};
54use crate::time_driver::get_driver; 54use crate::time_driver::get_driver;
55 55
56const THREAD_PENDER: usize = usize::MAX; 56const 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))]
151use crate::pac::pwr::vals::Lpms; 151use 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))]
154impl Into<Lpms> for StopMode { 154impl 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));