aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-mcxa/src/dma.rs2
-rw-r--r--embassy-mcxa/src/reset_reason.rs187
-rw-r--r--embassy-nrf/CHANGELOG.md2
-rw-r--r--embassy-nrf/src/time_driver.rs4
-rw-r--r--embassy-stm32/Cargo.toml2
-rw-r--r--embassy-stm32/src/rcc/l.rs5
-rw-r--r--embassy-stm32/src/rcc/u5.rs5
-rw-r--r--embassy-stm32/src/rcc/wba.rs5
-rw-r--r--embassy-stm32/src/rtc/low_power.rs94
-rw-r--r--embassy-stm32/src/rtc/mod.rs16
-rw-r--r--embassy-stm32/src/time_driver.rs23
-rw-r--r--examples/mcxa/src/bin/reset-reason.rs4
-rw-r--r--tests/stm32/src/bin/stop.rs2
13 files changed, 220 insertions, 131 deletions
diff --git a/embassy-mcxa/src/dma.rs b/embassy-mcxa/src/dma.rs
index 8d519d99b..b68f55e65 100644
--- a/embassy-mcxa/src/dma.rs
+++ b/embassy-mcxa/src/dma.rs
@@ -1924,7 +1924,7 @@ impl Iterator for TransferErrorRawIter {
1924 1924
1925 for (mask, var) in TransferErrorRaw::MAP { 1925 for (mask, var) in TransferErrorRaw::MAP {
1926 // If the bit is set... 1926 // If the bit is set...
1927 if self.0 | mask != 0 { 1927 if self.0 & mask != 0 {
1928 // clear the bit 1928 // clear the bit
1929 self.0 &= !mask; 1929 self.0 &= !mask;
1930 // and return the answer 1930 // and return the answer
diff --git a/embassy-mcxa/src/reset_reason.rs b/embassy-mcxa/src/reset_reason.rs
index f9a9ce096..1787690a7 100644
--- a/embassy-mcxa/src/reset_reason.rs
+++ b/embassy-mcxa/src/reset_reason.rs
@@ -6,45 +6,158 @@
6 6
7/// Reads the most recent reset reason from the Core Mode Controller 7/// Reads the most recent reset reason from the Core Mode Controller
8/// (CMC). 8/// (CMC).
9pub fn reset_reason() -> ResetReason { 9pub fn reset_reason() -> ResetReasonRaw {
10 let regs = unsafe { &*crate::pac::Cmc::steal() }; 10 let regs = unsafe { &*crate::pac::Cmc::steal() };
11 let srs = regs.srs().read().bits();
12 ResetReasonRaw(srs)
13}
14
15/// Raw reset reason bits. Can be queried or all reasons can be iterated over
16#[cfg_attr(feature = "defmt", derive(defmt::Format))]
17#[derive(Copy, Clone, Debug)]
18pub struct ResetReasonRaw(u32);
19
20#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21#[derive(Copy, Clone, Debug)]
22pub struct ResetReasonRawIter(u32);
23
24impl ResetReasonRaw {
25 const MAP: &[(u32, ResetReason)] = &[
26 (1 << 0, ResetReason::WakeUp),
27 (1 << 1, ResetReason::Por),
28 (1 << 2, ResetReason::VoltageDetect),
29 (1 << 4, ResetReason::Warm),
30 (1 << 5, ResetReason::Fatal),
31 (1 << 8, ResetReason::Pin),
32 (1 << 9, ResetReason::Dap),
33 (1 << 10, ResetReason::ResetAckTimeout),
34 (1 << 11, ResetReason::LowPowerAckTimeout),
35 (1 << 12, ResetReason::SystemClockGeneration),
36 (1 << 13, ResetReason::Wwdt0),
37 (1 << 14, ResetReason::Software),
38 (1 << 15, ResetReason::Lockup),
39 (1 << 26, ResetReason::Cdog0),
40 (1 << 27, ResetReason::Cdog1),
41 (1 << 28, ResetReason::Jtag),
42 ];
43
44 /// Convert to an iterator of contained reset reasons
45 pub fn into_iter(self) -> ResetReasonRawIter {
46 ResetReasonRawIter(self.0)
47 }
48
49 /// Wake up
50 #[inline]
51 pub fn is_wakeup(&self) -> bool {
52 (self.0 & (1 << 0)) != 0
53 }
54
55 /// Power-on Reset
56 #[inline]
57 pub fn is_por(&self) -> bool {
58 (self.0 & (1 << 1)) != 0
59 }
60
61 /// Voltage detect
62 #[inline]
63 pub fn is_voltage_detect(&self) -> bool {
64 (self.0 & (1 << 2)) != 0
65 }
66
67 /// Warm
68 #[inline]
69 pub fn is_warm(&self) -> bool {
70 (self.0 & (1 << 4)) != 0
71 }
72
73 /// Fatal
74 #[inline]
75 pub fn is_fatal(&self) -> bool {
76 (self.0 & (1 << 5)) != 0
77 }
78
79 /// Pin
80 #[inline]
81 pub fn is_pin(&self) -> bool {
82 (self.0 & (1 << 8)) != 0
83 }
84
85 /// DAP
86 #[inline]
87 pub fn is_dap(&self) -> bool {
88 (self.0 & (1 << 9)) != 0
89 }
90
91 /// Reset ack timeout
92 #[inline]
93 pub fn is_reset_ack_timeout(&self) -> bool {
94 (self.0 & (1 << 10)) != 0
95 }
96
97 /// Low power ack timeout
98 #[inline]
99 pub fn is_low_power_ack_timeout(&self) -> bool {
100 (self.0 & (1 << 11)) != 0
101 }
102
103 /// System clock generation
104 #[inline]
105 pub fn is_system_clock_generation(&self) -> bool {
106 (self.0 & (1 << 12)) != 0
107 }
108
109 /// Watchdog 0
110 #[inline]
111 pub fn is_watchdog0(&self) -> bool {
112 (self.0 & (1 << 13)) != 0
113 }
114
115 /// Software
116 pub fn is_software(&self) -> bool {
117 (self.0 & (1 << 14)) != 0
118 }
119
120 /// Lockup
121 pub fn is_lockup(&self) -> bool {
122 (self.0 & (1 << 15)) != 0
123 }
124
125 /// Code watchdog 0
126 pub fn is_code_watchdog0(&self) -> bool {
127 (self.0 & (1 << 26)) != 0
128 }
129
130 /// Code watchdog 1
131 pub fn is_code_watchdog1(&self) -> bool {
132 (self.0 & (1 << 27)) != 0
133 }
134
135 /// JTAG
136 pub fn is_jtag(&self) -> bool {
137 (self.0 & (1 << 28)) != 0
138 }
139}
11 140
12 let srs = regs.srs().read(); 141impl Iterator for ResetReasonRawIter {
13 142 type Item = ResetReason;
14 if srs.wakeup().is_enabled() { 143
15 ResetReason::WakeUp 144 fn next(&mut self) -> Option<Self::Item> {
16 } else if srs.por().bit_is_set() { 145 if self.0 == 0 {
17 ResetReason::Por 146 return None;
18 } else if srs.vd().bit_is_set() { 147 }
19 ResetReason::VoltageDetect 148
20 } else if srs.warm().bit_is_set() { 149 for (mask, var) in ResetReasonRaw::MAP {
21 ResetReason::Warm 150 // If the bit is set...
22 } else if srs.fatal().bit_is_set() { 151 if self.0 & mask != 0 {
23 ResetReason::Fatal 152 // clear the bit
24 } else if srs.pin().bit_is_set() { 153 self.0 &= !mask;
25 ResetReason::Pin 154 // and return the answer
26 } else if srs.dap().bit_is_set() { 155 return Some(*var);
27 ResetReason::Dap 156 }
28 } else if srs.rstack().bit_is_set() { 157 }
29 ResetReason::ResetAckTimeout 158
30 } else if srs.lpack().bit_is_set() { 159 // Shouldn't happen, but oh well.
31 ResetReason::LowPowerAckTimeout 160 None
32 } else if srs.scg().bit_is_set() {
33 ResetReason::SystemClockGeneration
34 } else if srs.wwdt0().bit_is_set() {
35 ResetReason::Wwdt0
36 } else if srs.sw().bit_is_set() {
37 ResetReason::Software
38 } else if srs.lockup().bit_is_set() {
39 ResetReason::Lockup
40 } else if srs.cdog0().bit_is_set() {
41 ResetReason::Cdog0
42 } else if srs.cdog1().bit_is_set() {
43 ResetReason::Cdog1
44 } else if srs.jtag().bit_is_set() {
45 ResetReason::Jtag
46 } else {
47 ResetReason::Tamper
48 } 161 }
49} 162}
50 163
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md
index 0d7bfb5f0..921835417 100644
--- a/embassy-nrf/CHANGELOG.md
+++ b/embassy-nrf/CHANGELOG.md
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8<!-- next-header --> 8<!-- next-header -->
9## Unreleased - ReleaseDate 9## Unreleased - ReleaseDate
10 10
11- bugfix: avoid hang if calling now() before syscounter is enabled on nrf54
12
11## 0.9.0 - 2025-12-15 13## 0.9.0 - 2025-12-15
12 14
13- changed: apply trimming values from FICR.TRIMCNF on nrf53/54l 15- changed: apply trimming values from FICR.TRIMCNF on nrf53/54l
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs
index 35f65bd64..21d94cc30 100644
--- a/embassy-nrf/src/time_driver.rs
+++ b/embassy-nrf/src/time_driver.rs
@@ -79,6 +79,10 @@ fn calc_now(period: u32, counter: u32) -> u64 {
79#[cfg(feature = "_grtc")] 79#[cfg(feature = "_grtc")]
80fn syscounter() -> u64 { 80fn syscounter() -> u64 {
81 let r = rtc(); 81 let r = rtc();
82 if !r.mode().read().syscounteren() {
83 return 0;
84 }
85
82 r.syscounter(0).active().write(|w| w.set_active(true)); 86 r.syscounter(0).active().write(|w| w.set_active(true));
83 loop { 87 loop {
84 let countl: u32 = r.syscounter(0).syscounterl().read(); 88 let countl: u32 = r.syscounter(0).syscounterl().read();
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 880df5f33..ce6fabc6b 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -241,7 +241,7 @@ log = ["dep:log"]
241chrono = ["dep:chrono"] 241chrono = ["dep:chrono"]
242 242
243exti = [] 243exti = []
244low-power = [ "dep:embassy-executor", "time" ] 244low-power = [ "dep:embassy-executor", "time", "chrono" ]
245low-power-pender = [ "low-power" ] 245low-power-pender = [ "low-power" ]
246low-power-debug-with-sleep = [ "low-power" ] 246low-power-debug-with-sleep = [ "low-power" ]
247 247
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs
index 0d668103c..a1dfefd15 100644
--- a/embassy-stm32/src/rcc/l.rs
+++ b/embassy-stm32/src/rcc/l.rs
@@ -385,6 +385,11 @@ pub(crate) unsafe fn init(config: Config) {
385 while !RCC.extcfgr().read().c2hpref() {} 385 while !RCC.extcfgr().read().c2hpref() {}
386 } 386 }
387 387
388 // Disable HSI if not used
389 if !config.hsi {
390 RCC.cr().modify(|w| w.set_hsion(false));
391 }
392
388 config.mux.init(); 393 config.mux.init();
389 394
390 set_clocks!( 395 set_clocks!(
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 47cc29c6f..c8c3e4adb 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -467,6 +467,11 @@ pub(crate) unsafe fn init(config: Config) {
467 let lse = config.ls.lse.map(|l| l.frequency); 467 let lse = config.ls.lse.map(|l| l.frequency);
468 let lsi = config.ls.lsi.then_some(LSI_FREQ); 468 let lsi = config.ls.lsi.then_some(LSI_FREQ);
469 469
470 // Disable HSI if not used
471 if !config.hsi {
472 RCC.cr().modify(|w| w.set_hsion(false));
473 }
474
470 config.mux.init(); 475 config.mux.init();
471 476
472 set_clocks!( 477 set_clocks!(
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
index 2528996d5..4ab3067bc 100644
--- a/embassy-stm32/src/rcc/wba.rs
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -269,6 +269,11 @@ pub(crate) unsafe fn init(config: Config) {
269 269
270 let lsi = config.ls.lsi.then_some(LSI_FREQ); 270 let lsi = config.ls.lsi.then_some(LSI_FREQ);
271 271
272 // Disable HSI if not used
273 if !config.hsi {
274 RCC.cr().modify(|w| w.set_hsion(false));
275 }
276
272 config.mux.init(); 277 config.mux.init();
273 278
274 set_clocks!( 279 set_clocks!(
diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs
index f049d6b12..cd5cea081 100644
--- a/embassy-stm32/src/rtc/low_power.rs
+++ b/embassy-stm32/src/rtc/low_power.rs
@@ -1,64 +1,12 @@
1#[cfg(feature = "time")] 1use chrono::{DateTime, NaiveDateTime, TimeDelta, Utc};
2use embassy_time::{Duration, TICK_HZ}; 2use embassy_time::{Duration, Instant, TICK_HZ};
3 3
4use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; 4use super::Rtc;
5use crate::interrupt::typelevel::Interrupt; 5use crate::interrupt::typelevel::Interrupt;
6use crate::pac::rtc::vals::Wucksel; 6use crate::pac::rtc::vals::Wucksel;
7use crate::peripherals::RTC; 7use crate::peripherals::RTC;
8use crate::rtc::{RtcTimeProvider, SealedInstance}; 8use crate::rtc::{RtcTimeProvider, SealedInstance};
9 9
10/// Represents an instant in time that can be substracted to compute a duration
11pub(super) struct RtcInstant {
12 /// 0..59
13 second: u8,
14 /// 0..256
15 subsecond: u16,
16}
17
18impl RtcInstant {
19 #[cfg(not(rtc_v2_f2))]
20 const fn from(second: u8, subsecond: u16) -> Result<Self, DateTimeError> {
21 if second > 59 {
22 Err(DateTimeError::InvalidSecond)
23 } else {
24 Ok(Self { second, subsecond })
25 }
26 }
27}
28
29#[cfg(feature = "defmt")]
30impl defmt::Format for RtcInstant {
31 fn format(&self, fmt: defmt::Formatter) {
32 defmt::write!(
33 fmt,
34 "{}:{}",
35 self.second,
36 RTC::regs().prer().read().prediv_s() - self.subsecond,
37 )
38 }
39}
40
41#[cfg(feature = "time")]
42impl core::ops::Sub for RtcInstant {
43 type Output = embassy_time::Duration;
44
45 fn sub(self, rhs: Self) -> Self::Output {
46 let second = if self.second < rhs.second {
47 self.second + 60
48 } else {
49 self.second
50 };
51
52 let psc = RTC::regs().prer().read().prediv_s() as u32;
53
54 let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32);
55 let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32);
56 let rtc_ticks = self_ticks - other_ticks;
57
58 Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64)
59 }
60}
61
62fn wucksel_compute_min(val: u32) -> (Wucksel, u32) { 10fn wucksel_compute_min(val: u32) -> (Wucksel, u32) {
63 *[ 11 *[
64 (Wucksel::DIV2, 2), 12 (Wucksel::DIV2, 2),
@@ -72,22 +20,15 @@ fn wucksel_compute_min(val: u32) -> (Wucksel, u32) {
72} 20}
73 21
74impl Rtc { 22impl Rtc {
75 /// Return the current instant. 23 pub(super) fn calc_epoch(&self) -> DateTime<Utc> {
76 fn instant(&self) -> Result<RtcInstant, RtcError> { 24 let now: NaiveDateTime = RtcTimeProvider::new().now().unwrap().into();
77 RtcTimeProvider::new().read(|_, tr, ss| {
78 let second = bcd2_to_byte((tr.st(), tr.su()));
79 25
80 RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) 26 now.and_utc() - TimeDelta::microseconds(Instant::now().as_micros().try_into().unwrap())
81 })
82 } 27 }
83 28
84 /// start the wakeup alarm and with a duration that is as close to but less than 29 /// start the wakeup alarm and with a duration that is as close to but less than
85 /// the requested duration, and record the instant the wakeup alarm was started 30 /// the requested duration, and record the instant the wakeup alarm was started
86 pub(crate) fn start_wakeup_alarm( 31 pub(crate) fn start_wakeup_alarm(&mut self, requested_duration: embassy_time::Duration) {
87 &mut self,
88 requested_duration: embassy_time::Duration,
89 cs: critical_section::CriticalSection,
90 ) {
91 // Panic if the rcc mod knows we're not using low-power rtc 32 // Panic if the rcc mod knows we're not using low-power rtc
92 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] 33 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
93 unsafe { crate::rcc::get_freqs() }.rtc.to_hertz().unwrap(); 34 unsafe { crate::rcc::get_freqs() }.rtc.to_hertz().unwrap();
@@ -122,27 +63,19 @@ impl Rtc {
122 regs.cr().modify(|w| w.set_wutie(true)); 63 regs.cr().modify(|w| w.set_wutie(true));
123 }); 64 });
124 65
125 let instant = self.instant().unwrap();
126 trace!( 66 trace!(
127 "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", 67 "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {})",
128 Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), 68 Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(),
129 prescaler as u32, 69 prescaler as u32,
130 rtc_ticks, 70 rtc_ticks,
131 instant,
132 ); 71 );
133
134 assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none())
135 } 72 }
136 73
137 /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` 74 /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm`
138 /// was called, otherwise none 75 /// was called, otherwise none
139 pub(crate) fn stop_wakeup_alarm( 76 pub(crate) fn stop_wakeup_alarm(&mut self) -> embassy_time::Instant {
140 &mut self,
141 cs: critical_section::CriticalSection,
142 ) -> Option<embassy_time::Duration> {
143 let instant = self.instant().unwrap();
144 if RTC::regs().cr().read().wute() { 77 if RTC::regs().cr().read().wute() {
145 trace!("rtc: stop wakeup alarm at {}", instant); 78 trace!("rtc: stop wakeup alarm");
146 79
147 self.write(false, |regs| { 80 self.write(false, |regs| {
148 regs.cr().modify(|w| w.set_wutie(false)); 81 regs.cr().modify(|w| w.set_wutie(false));
@@ -166,10 +99,13 @@ impl Rtc {
166 }); 99 });
167 } 100 }
168 101
169 self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) 102 let datetime: NaiveDateTime = RtcTimeProvider::new().now().expect("failed to read now").into();
103 let offset = datetime.and_utc() - self.epoch;
104
105 Instant::from_micros(offset.num_microseconds().unwrap().try_into().unwrap())
170 } 106 }
171 107
172 pub(crate) fn enable_wakeup_line(&self) { 108 pub(super) fn enable_wakeup_line(&mut self) {
173 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); 109 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
174 unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() }; 110 unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() };
175 111
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index e88bd7ab2..94ba13ae1 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -5,7 +5,7 @@ mod datetime;
5mod low_power; 5mod low_power;
6 6
7#[cfg(feature = "low-power")] 7#[cfg(feature = "low-power")]
8use core::cell::{Cell, RefCell, RefMut}; 8use core::cell::{RefCell, RefMut};
9#[cfg(feature = "low-power")] 9#[cfg(feature = "low-power")]
10use core::ops; 10use core::ops;
11 11
@@ -163,7 +163,7 @@ impl<'a> ops::DerefMut for RtcBorrow<'a> {
163/// RTC driver. 163/// RTC driver.
164pub struct Rtc { 164pub struct Rtc {
165 #[cfg(feature = "low-power")] 165 #[cfg(feature = "low-power")]
166 stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<low_power::RtcInstant>>>, 166 epoch: chrono::DateTime<chrono::Utc>,
167 _private: (), 167 _private: (),
168} 168}
169 169
@@ -225,7 +225,7 @@ impl Rtc {
225 225
226 let mut this = Self { 226 let mut this = Self {
227 #[cfg(feature = "low-power")] 227 #[cfg(feature = "low-power")]
228 stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), 228 epoch: chrono::DateTime::from_timestamp_secs(0).unwrap(),
229 _private: (), 229 _private: (),
230 }; 230 };
231 231
@@ -243,7 +243,10 @@ impl Rtc {
243 } 243 }
244 244
245 #[cfg(feature = "low-power")] 245 #[cfg(feature = "low-power")]
246 this.enable_wakeup_line(); 246 {
247 this.enable_wakeup_line();
248 this.epoch = this.calc_epoch();
249 }
247 250
248 this 251 this
249 } 252 }
@@ -293,6 +296,11 @@ impl Rtc {
293 }); 296 });
294 }); 297 });
295 298
299 #[cfg(feature = "low-power")]
300 {
301 self.epoch = self.calc_epoch();
302 }
303
296 Ok(()) 304 Ok(())
297 } 305 }
298 306
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index ed5d902bd..59ec58575 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -251,8 +251,8 @@ impl RtcDriver {
251 251
252 #[cfg(feature = "low-power")] 252 #[cfg(feature = "low-power")]
253 /// Add the given offset to the current time 253 /// Add the given offset to the current time
254 fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) { 254 fn set_time(&self, instant: u64, cs: CriticalSection) {
255 let (period, counter) = calc_period_counter(self.now() + offset.as_ticks()); 255 let (period, counter) = calc_period_counter(core::cmp::max(self.now(), instant));
256 256
257 self.period.store(period, Ordering::SeqCst); 257 self.period.store(period, Ordering::SeqCst);
258 regs_gp16().cnt().write(|w| w.set_cnt(counter)); 258 regs_gp16().cnt().write(|w| w.set_cnt(counter));
@@ -269,10 +269,17 @@ impl RtcDriver {
269 #[cfg(feature = "low-power")] 269 #[cfg(feature = "low-power")]
270 /// Stop the wakeup alarm, if enabled, and add the appropriate offset 270 /// Stop the wakeup alarm, if enabled, and add the appropriate offset
271 fn stop_wakeup_alarm(&self, cs: CriticalSection) { 271 fn stop_wakeup_alarm(&self, cs: CriticalSection) {
272 if !regs_gp16().cr1().read().cen() 272 if !regs_gp16().cr1().read().cen() {
273 && let Some(offset) = self.rtc.borrow(cs).borrow_mut().as_mut().unwrap().stop_wakeup_alarm(cs) 273 self.set_time(
274 { 274 self.rtc
275 self.add_time(offset, cs); 275 .borrow(cs)
276 .borrow_mut()
277 .as_mut()
278 .unwrap()
279 .stop_wakeup_alarm()
280 .as_ticks(),
281 cs,
282 );
276 } 283 }
277 } 284 }
278 285
@@ -287,7 +294,7 @@ impl RtcDriver {
287 #[cfg(feature = "low-power")] 294 #[cfg(feature = "low-power")]
288 /// Set the rtc but panic if it's already been set 295 /// Set the rtc but panic if it's already been set
289 pub(crate) fn set_rtc(&self, cs: CriticalSection, mut rtc: Rtc) { 296 pub(crate) fn set_rtc(&self, cs: CriticalSection, mut rtc: Rtc) {
290 rtc.stop_wakeup_alarm(cs); 297 rtc.stop_wakeup_alarm();
291 298
292 assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()); 299 assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none());
293 } 300 }
@@ -310,7 +317,7 @@ impl RtcDriver {
310 .borrow_mut() 317 .borrow_mut()
311 .as_mut() 318 .as_mut()
312 .unwrap() 319 .unwrap()
313 .start_wakeup_alarm(time_until_next_alarm, cs); 320 .start_wakeup_alarm(time_until_next_alarm);
314 321
315 regs_gp16().cr1().modify(|w| w.set_cen(false)); 322 regs_gp16().cr1().modify(|w| w.set_cen(false));
316 // save the count for the timer as its lost in STOP2 for stm32wlex 323 // save the count for the timer as its lost in STOP2 for stm32wlex
diff --git a/examples/mcxa/src/bin/reset-reason.rs b/examples/mcxa/src/bin/reset-reason.rs
index c244fbe04..2d48a92b1 100644
--- a/examples/mcxa/src/bin/reset-reason.rs
+++ b/examples/mcxa/src/bin/reset-reason.rs
@@ -11,5 +11,7 @@ async fn main(_spawner: Spawner) {
11 let config = Config::default(); 11 let config = Config::default();
12 let _p = hal::init(config); 12 let _p = hal::init(config);
13 13
14 defmt::info!("Reset Reason: '{}'", reset_reason()); 14 for reason in reset_reason().into_iter() {
15 defmt::info!("Reset Reason: '{}'", reason);
16 }
15} 17}
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 83c375bc5..75dacbe7e 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -60,10 +60,12 @@ async fn async_main(spawner: Spawner) {
60 60
61 let (rtc, _time_provider) = Rtc::new(p.RTC); 61 let (rtc, _time_provider) = Rtc::new(p.RTC);
62 62
63 info!("set datetime");
63 critical_section::with(|cs| { 64 critical_section::with(|cs| {
64 rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); 65 rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set");
65 }); 66 });
66 67
68 info!("spawn");
67 spawner.spawn(task_1().unwrap()); 69 spawner.spawn(task_1().unwrap());
68 spawner.spawn(task_2().unwrap()); 70 spawner.spawn(task_2().unwrap());
69} 71}