aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/Cargo.toml6
-rw-r--r--embassy-stm32/src/low_power.rs39
-rw-r--r--embassy-stm32/src/rcc/f247.rs3
-rw-r--r--embassy-stm32/src/rcc/h.rs2
-rw-r--r--embassy-stm32/src/rcc/l.rs2
-rw-r--r--embassy-stm32/src/rcc/u5.rs1
-rw-r--r--embassy-stm32/src/rtc/datetime.rs4
-rw-r--r--embassy-stm32/src/rtc/mod.rs49
-rw-r--r--embassy-stm32/src/rtc/v3.rs36
-rw-r--r--examples/stm32h5/Cargo.toml2
-rw-r--r--examples/stm32h5/src/bin/stop.rs71
-rw-r--r--tests/stm32/Cargo.toml4
-rw-r--r--tests/stm32/src/bin/stop.rs7
13 files changed, 154 insertions, 72 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 669e6537a..653a376bd 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -24,7 +24,7 @@ flavors = [
24 { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" }, 24 { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" },
25 { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" }, 25 { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" },
26 { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, 26 { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] },
27 { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" }, 27 { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] },
28 { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, 28 { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" },
29 { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, 29 { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] },
30 { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, 30 { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" },
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
72sdio-host = "0.5.0" 72sdio-host = "0.5.0"
73critical-section = "1.1" 73critical-section = "1.1"
74#stm32-metapac = { version = "15" } 74#stm32-metapac = { version = "15" }
75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01ac9bfd035961dc75f32dcd6080501538246d5c" } 75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0" }
76 76
77vcell = "0.1.3" 77vcell = "0.1.3"
78nb = "1.0.0" 78nb = "1.0.0"
@@ -98,7 +98,7 @@ proc-macro2 = "1.0.36"
98quote = "1.0.15" 98quote = "1.0.15"
99 99
100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01ac9bfd035961dc75f32dcd6080501538246d5c", default-features = false, features = ["metadata"]} 101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0", default-features = false, features = ["metadata"]}
102 102
103[features] 103[features]
104default = ["rt"] 104default = ["rt"]
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 4c3d288fd..604bdf416 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -10,14 +10,14 @@
10//! exceptions to this rule: 10//! exceptions to this rule:
11//! 11//!
12//! * `GPIO` 12//! * `GPIO`
13//! * `RCC` 13//! * `RTC`
14//! 14//!
15//! Since entering and leaving low-power modes typically incurs a significant latency, the 15//! Since entering and leaving low-power modes typically incurs a significant latency, the
16//! low-power executor will only attempt to enter when the next timer event is at least 16//! low-power executor will only attempt to enter when the next timer event is at least
17//! [`time_driver::MIN_STOP_PAUSE`] in the future. 17//! [`time_driver::MIN_STOP_PAUSE`] in the future.
18//! 18//!
19//! Currently there is no macro analogous to `embassy_executor::main` for this executor; 19//! Currently there is no macro analogous to `embassy_executor::main` for this executor;
20//! consequently one must define their entrypoint manually. Moveover, you must relinquish control 20//! consequently one must define their entrypoint manually. Moreover, you must relinquish control
21//! of the `RTC` peripheral to the executor. This will typically look like 21//! of the `RTC` peripheral to the executor. This will typically look like
22//! 22//!
23//! ```rust,no_run 23//! ```rust,no_run
@@ -99,7 +99,7 @@ pub fn stop_ready(stop_mode: StopMode) -> bool {
99 } 99 }
100} 100}
101 101
102/// Available stop modes. 102/// Available Stop modes.
103#[non_exhaustive] 103#[non_exhaustive]
104#[derive(PartialEq)] 104#[derive(PartialEq)]
105pub enum StopMode { 105pub enum StopMode {
@@ -183,6 +183,12 @@ impl Executor {
183 fn configure_stop(&mut self, stop_mode: StopMode) { 183 fn configure_stop(&mut self, stop_mode: StopMode) {
184 #[cfg(stm32l5)] 184 #[cfg(stm32l5)]
185 crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); 185 crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into()));
186 #[cfg(stm32h5)]
187 crate::pac::PWR.pmcr().modify(|v| {
188 use crate::pac::pwr::vals;
189 v.set_lpms(vals::Lpms::STOP);
190 v.set_svos(vals::Svos::SCALE3);
191 });
186 } 192 }
187 193
188 fn configure_pwr(&mut self) { 194 fn configure_pwr(&mut self) {
@@ -191,21 +197,26 @@ impl Executor {
191 compiler_fence(Ordering::SeqCst); 197 compiler_fence(Ordering::SeqCst);
192 198
193 let stop_mode = self.stop_mode(); 199 let stop_mode = self.stop_mode();
200
194 if stop_mode.is_none() { 201 if stop_mode.is_none() {
195 trace!("low power: not ready to stop"); 202 trace!("low power: not ready to stop");
196 } else if self.time_driver.pause_time().is_err() { 203 return;
204 }
205
206 if self.time_driver.pause_time().is_err() {
197 trace!("low power: failed to pause time"); 207 trace!("low power: failed to pause time");
198 } else { 208 return;
199 let stop_mode = stop_mode.unwrap();
200 match stop_mode {
201 StopMode::Stop1 => trace!("low power: stop 1"),
202 StopMode::Stop2 => trace!("low power: stop 2"),
203 }
204 self.configure_stop(stop_mode);
205
206 #[cfg(not(feature = "low-power-debug-with-sleep"))]
207 self.scb.set_sleepdeep();
208 } 209 }
210
211 let stop_mode = stop_mode.unwrap();
212 match stop_mode {
213 StopMode::Stop1 => trace!("low power: stop 1"),
214 StopMode::Stop2 => trace!("low power: stop 2"),
215 }
216 self.configure_stop(stop_mode);
217
218 #[cfg(not(feature = "low-power-debug-with-sleep"))]
219 self.scb.set_sleepdeep();
209 } 220 }
210 221
211 /// Run the executor. 222 /// Run the executor.
diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs
index 7b252870c..e3ee9a039 100644
--- a/embassy-stm32/src/rcc/f247.rs
+++ b/embassy-stm32/src/rcc/f247.rs
@@ -277,6 +277,7 @@ pub(crate) unsafe fn init(config: Config) {
277 pclk2_tim: Some(pclk2_tim), 277 pclk2_tim: Some(pclk2_tim),
278 rtc: rtc, 278 rtc: rtc,
279 pll1_q: pll.q, 279 pll1_q: pll.q,
280 pll1_r: None, // TODO
280 281
281 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] 282 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
282 plli2s1_p: plli2s.p, 283 plli2s1_p: plli2s.p,
@@ -299,6 +300,8 @@ pub(crate) unsafe fn init(config: Config) {
299 hsi_div488: hsi.map(|hsi| hsi/488u32), 300 hsi_div488: hsi.map(|hsi| hsi/488u32),
300 hsi_hse: None, 301 hsi_hse: None,
301 afif: None, 302 afif: None,
303 #[cfg(any(stm32f4, stm32f7))]
304 dsi_phy: None, // TODO
302 ); 305 );
303} 306}
304 307
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 1949fc891..aa8c4b1f7 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -601,6 +601,8 @@ pub(crate) unsafe fn init(config: Config) {
601 #[cfg(stm32h5)] 601 #[cfg(stm32h5)]
602 audioclk: None, 602 audioclk: None,
603 i2s_ckin: None, 603 i2s_ckin: None,
604 #[cfg(stm32h7)]
605 dsi_phy: None, // TODO
604 ); 606 );
605} 607}
606 608
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs
index d7235ac7f..c625948fb 100644
--- a/embassy-stm32/src/rcc/l.rs
+++ b/embassy-stm32/src/rcc/l.rs
@@ -420,6 +420,8 @@ pub(crate) unsafe fn init(config: Config) {
420 sai2_extclk: None, 420 sai2_extclk: None,
421 lsi: None, 421 lsi: None,
422 lse: None, 422 lse: None,
423 #[cfg(stm32l4)]
424 dsi_phy: None,
423 ); 425 );
424} 426}
425 427
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 9533e16c4..4013d0a46 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -297,6 +297,7 @@ pub(crate) unsafe fn init(config: Config) {
297 msik: None, 297 msik: None,
298 shsi: None, 298 shsi: None,
299 shsi_div_2: None, 299 shsi_div_2: None,
300 dsi_phy: None,
300 ); 301 );
301} 302}
302 303
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs
index bab8cf4a3..77d89293d 100644
--- a/embassy-stm32/src/rtc/datetime.rs
+++ b/embassy-stm32/src/rtc/datetime.rs
@@ -148,9 +148,9 @@ impl DateTime {
148 ) -> Result<Self, Error> { 148 ) -> Result<Self, Error> {
149 if year > 4095 { 149 if year > 4095 {
150 Err(Error::InvalidYear) 150 Err(Error::InvalidYear)
151 } else if month < 1 || month > 12 { 151 } else if !(1..=12).contains(&month) {
152 Err(Error::InvalidMonth) 152 Err(Error::InvalidMonth)
153 } else if day < 1 || day > 31 { 153 } else if !(1..=31).contains(&day) {
154 Err(Error::InvalidDay) 154 Err(Error::InvalidDay)
155 } else if hour > 23 { 155 } else if hour > 23 {
156 Err(Error::InvalidHour) 156 Err(Error::InvalidHour)
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 00abe9356..b12a0db66 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -42,7 +42,7 @@ pub(crate) enum WakeupPrescaler {
42 Div16 = 16, 42 Div16 = 16,
43} 43}
44 44
45#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] 45#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
46impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { 46impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
47 fn from(val: WakeupPrescaler) -> Self { 47 fn from(val: WakeupPrescaler) -> Self {
48 use crate::pac::rtc::vals::Wucksel; 48 use crate::pac::rtc::vals::Wucksel;
@@ -56,7 +56,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
56 } 56 }
57} 57}
58 58
59#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] 59#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
60impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { 60impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
61 fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { 61 fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
62 use crate::pac::rtc::vals::Wucksel; 62 use crate::pac::rtc::vals::Wucksel;
@@ -81,8 +81,7 @@ impl WakeupPrescaler {
81 WakeupPrescaler::Div16, 81 WakeupPrescaler::Div16,
82 ] 82 ]
83 .iter() 83 .iter()
84 .skip_while(|psc| **psc as u32 <= val) 84 .find(|psc| **psc as u32 > val)
85 .next()
86 .unwrap_or(&WakeupPrescaler::Div16) 85 .unwrap_or(&WakeupPrescaler::Div16)
87 } 86 }
88} 87}
@@ -159,7 +158,7 @@ impl RtcTimeProvider {
159 } 158 }
160 } 159 }
161 160
162 return Err(RtcError::ReadFailure); 161 Err(RtcError::ReadFailure)
163 } 162 }
164} 163}
165 164
@@ -190,7 +189,7 @@ impl Default for RtcConfig {
190} 189}
191 190
192/// Calibration cycle period. 191/// Calibration cycle period.
193#[derive(Copy, Clone, Debug, PartialEq)] 192#[derive(Default, Copy, Clone, Debug, PartialEq)]
194#[repr(u8)] 193#[repr(u8)]
195pub enum RtcCalibrationCyclePeriod { 194pub enum RtcCalibrationCyclePeriod {
196 /// 8-second calibration period 195 /// 8-second calibration period
@@ -198,15 +197,10 @@ pub enum RtcCalibrationCyclePeriod {
198 /// 16-second calibration period 197 /// 16-second calibration period
199 Seconds16, 198 Seconds16,
200 /// 32-second calibration period 199 /// 32-second calibration period
200 #[default]
201 Seconds32, 201 Seconds32,
202} 202}
203 203
204impl Default for RtcCalibrationCyclePeriod {
205 fn default() -> Self {
206 RtcCalibrationCyclePeriod::Seconds32
207 }
208}
209
210impl Rtc { 204impl Rtc {
211 /// Create a new RTC instance. 205 /// Create a new RTC instance.
212 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 206 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
@@ -254,13 +248,13 @@ impl Rtc {
254 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. 248 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
255 pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { 249 pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> {
256 self.write(true, |rtc| { 250 self.write(true, |rtc| {
257 let (ht, hu) = byte_to_bcd2(t.hour() as u8); 251 let (ht, hu) = byte_to_bcd2(t.hour());
258 let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); 252 let (mnt, mnu) = byte_to_bcd2(t.minute());
259 let (st, su) = byte_to_bcd2(t.second() as u8); 253 let (st, su) = byte_to_bcd2(t.second());
260 254
261 let (dt, du) = byte_to_bcd2(t.day() as u8); 255 let (dt, du) = byte_to_bcd2(t.day());
262 let (mt, mu) = byte_to_bcd2(t.month() as u8); 256 let (mt, mu) = byte_to_bcd2(t.month());
263 let yr = t.year() as u16; 257 let yr = t.year();
264 let yr_offset = (yr - 2000_u16) as u8; 258 let yr_offset = (yr - 2000_u16) as u8;
265 let (yt, yu) = byte_to_bcd2(yr_offset); 259 let (yt, yu) = byte_to_bcd2(yr_offset);
266 260
@@ -338,7 +332,7 @@ impl Rtc {
338 } 332 }
339 333
340 #[cfg(feature = "low-power")] 334 #[cfg(feature = "low-power")]
341 /// start the wakeup alarm and wtih a duration that is as close to but less than 335 /// start the wakeup alarm and with a duration that is as close to but less than
342 /// the requested duration, and record the instant the wakeup alarm was started 336 /// the requested duration, and record the instant the wakeup alarm was started
343 pub(crate) fn start_wakeup_alarm( 337 pub(crate) fn start_wakeup_alarm(
344 &self, 338 &self,
@@ -422,20 +416,15 @@ impl Rtc {
422 #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] 416 #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
423 regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); 417 regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
424 418
425 #[cfg(all(stm32g0))] 419 // Check RM for EXTI and/or NVIC section, "Event event input mapping" or "EXTI interrupt/event mapping" or something similar,
426 crate::pac::EXTI 420 // there is a table for every "Event input" / "EXTI Line".
427 .rpr(0) 421 // If you find the EXTI line related to "RTC wakeup" marks as "Configurable" (not "Direct"),
428 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 422 // then write 1 to related field of Pending Register, to clean it's pending state.
429 #[cfg(all(not(stm32g0), not(stm32l5)))] 423 #[cfg(any(exti_v1, stm32h7, stm32wb))]
430 crate::pac::EXTI 424 crate::pac::EXTI
431 .pr(0) 425 .pr(0)
432 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 426 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
433 427
434 #[cfg(stm32l5)]
435 crate::pac::EXTI
436 .fpr(0)
437 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
438
439 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); 428 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
440 }); 429 });
441 } 430 }
@@ -465,7 +454,7 @@ pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) {
465 value -= 10; 454 value -= 10;
466 } 455 }
467 456
468 (bcd_high, ((bcd_high << 4) | value) as u8) 457 (bcd_high, ((bcd_high << 4) | value))
469} 458}
470 459
471pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 { 460pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 8a78d16e1..e51e09e7c 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -50,7 +50,7 @@ impl super::Rtc {
50 clock_drift = Self::RTC_CALR_MAX_PPM; 50 clock_drift = Self::RTC_CALR_MAX_PPM;
51 } 51 }
52 52
53 clock_drift = clock_drift / Self::RTC_CALR_RESOLUTION_PPM; 53 clock_drift /= Self::RTC_CALR_RESOLUTION_PPM;
54 54
55 self.write(false, |rtc| { 55 self.write(false, |rtc| {
56 rtc.calr().write(|w| { 56 rtc.calr().write(|w| {
@@ -129,29 +129,25 @@ impl super::Rtc {
129impl SealedInstance for crate::peripherals::RTC { 129impl SealedInstance for crate::peripherals::RTC {
130 const BACKUP_REGISTER_COUNT: usize = 32; 130 const BACKUP_REGISTER_COUNT: usize = 32;
131 131
132 #[cfg(all(feature = "low-power", stm32g4))] 132 #[cfg(feature = "low-power")]
133 const EXTI_WAKEUP_LINE: usize = 20; 133 cfg_if::cfg_if!(
134 134 if #[cfg(stm32g4)] {
135 #[cfg(all(feature = "low-power", stm32g0))] 135 const EXTI_WAKEUP_LINE: usize = 20;
136 const EXTI_WAKEUP_LINE: usize = 19; 136 type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
137 137 } else if #[cfg(stm32g0)] {
138 #[cfg(all(feature = "low-power", stm32g0))] 138 const EXTI_WAKEUP_LINE: usize = 19;
139 type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; 139 type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP;
140 140 } else if #[cfg(any(stm32l5, stm32h5))] {
141 #[cfg(all(feature = "low-power", stm32g4))] 141 const EXTI_WAKEUP_LINE: usize = 17;
142 type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; 142 type WakeupInterrupt = crate::interrupt::typelevel::RTC;
143 143 }
144 #[cfg(all(feature = "low-power", stm32l5))] 144 );
145 const EXTI_WAKEUP_LINE: usize = 17;
146
147 #[cfg(all(feature = "low-power", stm32l5))]
148 type WakeupInterrupt = crate::interrupt::typelevel::RTC;
149 145
150 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> { 146 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
151 #[allow(clippy::if_same_then_else)] 147 #[allow(clippy::if_same_then_else)]
152 if register < Self::BACKUP_REGISTER_COUNT { 148 if register < Self::BACKUP_REGISTER_COUNT {
153 //Some(rtc.bkpr()[register].read().bits()) 149 //Some(rtc.bkpr()[register].read().bits())
154 None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC 150 None // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
155 } else { 151 } else {
156 None 152 None
157 } 153 }
@@ -159,7 +155,7 @@ impl SealedInstance for crate::peripherals::RTC {
159 155
160 fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) { 156 fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) {
161 if register < Self::BACKUP_REGISTER_COUNT { 157 if register < Self::BACKUP_REGISTER_COUNT {
162 // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC 158 // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
163 //self.rtc.bkpr()[register].write(|w| w.bits(value)) 159 //self.rtc.bkpr()[register].write(|w| w.bits(value))
164 } 160 }
165 } 161 }
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 4527f4bcb..82760db64 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32h563zi to your chip name, if necessary. 8# Change stm32h563zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs
new file mode 100644
index 000000000..0d14c0668
--- /dev/null
+++ b/examples/stm32h5/src/bin/stop.rs
@@ -0,0 +1,71 @@
1// Notice:
2// the MCU might need an extra reset to make the code actually running
3
4#![no_std]
5#![no_main]
6
7use defmt::*;
8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
10use embassy_stm32::low_power::Executor;
11use embassy_stm32::rcc::{HSIPrescaler, LsConfig};
12use embassy_stm32::rtc::{Rtc, RtcConfig};
13use embassy_stm32::Config;
14use embassy_time::Timer;
15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _};
17
18#[cortex_m_rt::entry]
19fn main() -> ! {
20 Executor::take().run(|spawner| {
21 unwrap!(spawner.spawn(async_main(spawner)));
22 })
23}
24
25#[embassy_executor::task]
26async fn async_main(spawner: Spawner) {
27 defmt::info!("Program Start");
28
29 let mut config = Config::default();
30
31 // System Clock seems need to be equal or lower than 16 MHz
32 config.rcc.hsi = Some(HSIPrescaler::DIV4);
33
34 config.rcc.ls = LsConfig::default_lsi();
35 // when enabled the power-consumption is much higher during stop, but debugging and RTT is working
36 // if you wan't to measure the power-consumption, or for production: uncomment this line
37 // config.enable_debug_during_sleep = false;
38 let p = embassy_stm32::init(config);
39
40 // give the RTC to the executor...
41 let rtc = Rtc::new(p.RTC, RtcConfig::default());
42 static RTC: StaticCell<Rtc> = StaticCell::new();
43 let rtc = RTC.init(rtc);
44 embassy_stm32::low_power::stop_with_rtc(rtc);
45
46 unwrap!(spawner.spawn(blinky(p.PB4.into())));
47 unwrap!(spawner.spawn(timeout()));
48}
49
50#[embassy_executor::task]
51async fn blinky(led: AnyPin) {
52 let mut led = Output::new(led, Level::Low, Speed::Low);
53 loop {
54 info!("high");
55 led.set_high();
56 Timer::after_millis(300).await;
57
58 info!("low");
59 led.set_low();
60 Timer::after_millis(300).await;
61 }
62}
63
64// when enable_debug_during_sleep is false, it is more difficult to reprogram the MCU
65// therefore we block the MCU after 30s to be able to reprogram it easily
66#[embassy_executor::task]
67async fn timeout() -> ! {
68 Timer::after_secs(30).await;
69 #[allow(clippy::empty_loop)]
70 loop {}
71}
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 004846a9b..30669b88c 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -15,7 +15,7 @@ stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma"
15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] 15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"]
16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] 16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"]
17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] 17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"]
18stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "fdcan", "hash", "cordic"] 18stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"]
19stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] 19stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"]
20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] 20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"]
21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"] 21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"]
@@ -31,7 +31,7 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac"
31stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] 31stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"]
32stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] 32stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"]
33stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] 33stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
34stm32h503rb = ["embassy-stm32/stm32h503rb", "rng"] 34stm32h503rb = ["embassy-stm32/stm32h503rb", "rng", "stop"]
35 35
36cryp = [] 36cryp = []
37hash = [] 37hash = []
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 000296d46..c1106bb2f 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -51,6 +51,13 @@ async fn async_main(spawner: Spawner) {
51 let mut config = Config::default(); 51 let mut config = Config::default();
52 config.rcc.ls = LsConfig::default_lse(); 52 config.rcc.ls = LsConfig::default_lse();
53 53
54 // System Clock seems cannot be greater than 16 MHz
55 #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))]
56 {
57 use embassy_stm32::rcc::HSIPrescaler;
58 config.rcc.hsi = Some(HSIPrescaler::DIV4); // 64 MHz HSI will need a /4
59 }
60
54 let p = embassy_stm32::init(config); 61 let p = embassy_stm32::init(config);
55 info!("Hello World!"); 62 info!("Hello World!");
56 63