stm32: add low power for g4
This commit is contained in:
		
							parent
							
								
									3bccb67231
								
							
						
					
					
						commit
						4b4c28d875
					
				@ -18,7 +18,7 @@ flavors = [
 | 
				
			|||||||
    { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" },
 | 
					    { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" },
 | 
				
			||||||
    { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" },
 | 
					    { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" },
 | 
				
			||||||
    { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" },
 | 
					    { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" },
 | 
				
			||||||
    { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi" },
 | 
					    { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] },
 | 
				
			||||||
    { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" },
 | 
					    { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" },
 | 
				
			||||||
    { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" },
 | 
					    { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" },
 | 
				
			||||||
    { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] },
 | 
					    { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] },
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,60 @@ use embassy_hal_internal::Peripheral;
 | 
				
			|||||||
use crate::peripherals::RTC;
 | 
					use crate::peripherals::RTC;
 | 
				
			||||||
use crate::rtc::sealed::Instance;
 | 
					use crate::rtc::sealed::Instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[repr(u8)]
 | 
				
			||||||
 | 
					#[derive(Clone, Copy, Debug)]
 | 
				
			||||||
 | 
					pub(crate) enum WakeupPrescaler {
 | 
				
			||||||
 | 
					    Div2 = 2,
 | 
				
			||||||
 | 
					    Div4 = 4,
 | 
				
			||||||
 | 
					    Div8 = 8,
 | 
				
			||||||
 | 
					    Div16 = 16,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))]
 | 
				
			||||||
 | 
					impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
 | 
				
			||||||
 | 
					    fn from(val: WakeupPrescaler) -> Self {
 | 
				
			||||||
 | 
					        use crate::pac::rtc::vals::Wucksel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        match val {
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div2 => Wucksel::DIV2,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div4 => Wucksel::DIV4,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div8 => Wucksel::DIV8,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div16 => Wucksel::DIV16,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))]
 | 
				
			||||||
 | 
					impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
 | 
				
			||||||
 | 
					    fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
 | 
				
			||||||
 | 
					        use crate::pac::rtc::vals::Wucksel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        match val {
 | 
				
			||||||
 | 
					            Wucksel::DIV2 => WakeupPrescaler::Div2,
 | 
				
			||||||
 | 
					            Wucksel::DIV4 => WakeupPrescaler::Div4,
 | 
				
			||||||
 | 
					            Wucksel::DIV8 => WakeupPrescaler::Div8,
 | 
				
			||||||
 | 
					            Wucksel::DIV16 => WakeupPrescaler::Div16,
 | 
				
			||||||
 | 
					            _ => unreachable!(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(feature = "low-power")]
 | 
				
			||||||
 | 
					impl WakeupPrescaler {
 | 
				
			||||||
 | 
					    pub fn compute_min(val: u32) -> Self {
 | 
				
			||||||
 | 
					        *[
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div2,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div4,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div8,
 | 
				
			||||||
 | 
					            WakeupPrescaler::Div16,
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .skip_while(|psc| **psc as u32 <= val)
 | 
				
			||||||
 | 
					        .next()
 | 
				
			||||||
 | 
					        .unwrap_or(&WakeupPrescaler::Div16)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Errors that can occur on methods on [RtcClock]
 | 
					/// Errors that can occur on methods on [RtcClock]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
#[derive(Clone, Debug, PartialEq, Eq)]
 | 
					#[derive(Clone, Debug, PartialEq, Eq)]
 | 
				
			||||||
@ -277,6 +331,114 @@ impl Rtc {
 | 
				
			|||||||
    pub fn write_backup_register(&self, register: usize, value: u32) {
 | 
					    pub fn write_backup_register(&self, register: usize, value: u32) {
 | 
				
			||||||
        RTC::write_backup_register(&RTC::regs(), register, value)
 | 
					        RTC::write_backup_register(&RTC::regs(), register, value)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(feature = "low-power")]
 | 
				
			||||||
 | 
					    /// start the wakeup alarm and wtih a duration that is as close to but less than
 | 
				
			||||||
 | 
					    /// the requested duration, and record the instant the wakeup alarm was started
 | 
				
			||||||
 | 
					    pub(crate) fn start_wakeup_alarm(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        requested_duration: embassy_time::Duration,
 | 
				
			||||||
 | 
					        cs: critical_section::CriticalSection,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        use embassy_time::{Duration, TICK_HZ};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
				
			||||||
 | 
					        use crate::pac::rtc::vals::Calrf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Panic if the rcc mod knows we're not using low-power rtc
 | 
				
			||||||
 | 
					        #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
 | 
				
			||||||
 | 
					        unsafe { crate::rcc::get_freqs() }.rtc.unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let requested_duration = requested_duration.as_ticks().clamp(0, u32::MAX as u64);
 | 
				
			||||||
 | 
					        let rtc_hz = Self::frequency().0 as u64;
 | 
				
			||||||
 | 
					        let rtc_ticks = requested_duration * rtc_hz / TICK_HZ;
 | 
				
			||||||
 | 
					        let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // adjust the rtc ticks to the prescaler and subtract one rtc tick
 | 
				
			||||||
 | 
					        let rtc_ticks = rtc_ticks / prescaler as u64;
 | 
				
			||||||
 | 
					        let rtc_ticks = rtc_ticks.clamp(0, (u16::MAX - 1) as u64).saturating_sub(1) as u16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.write(false, |regs| {
 | 
				
			||||||
 | 
					            regs.cr().modify(|w| w.set_wute(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #[cfg(any(
 | 
				
			||||||
 | 
					                rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb
 | 
				
			||||||
 | 
					            ))]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                regs.isr().modify(|w| w.set_wutf(false));
 | 
				
			||||||
 | 
					                while !regs.isr().read().wutwf() {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
				
			||||||
 | 
					                while !regs.icsr().read().wutwf() {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            regs.cr().modify(|w| w.set_wucksel(prescaler.into()));
 | 
				
			||||||
 | 
					            regs.wutr().write(|w| w.set_wut(rtc_ticks));
 | 
				
			||||||
 | 
					            regs.cr().modify(|w| w.set_wute(true));
 | 
				
			||||||
 | 
					            regs.cr().modify(|w| w.set_wutie(true));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let instant = self.instant().unwrap();
 | 
				
			||||||
 | 
					        trace!(
 | 
				
			||||||
 | 
					            "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
 | 
				
			||||||
 | 
					            Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(),
 | 
				
			||||||
 | 
					            prescaler as u32,
 | 
				
			||||||
 | 
					            rtc_ticks,
 | 
				
			||||||
 | 
					            instant,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(feature = "low-power")]
 | 
				
			||||||
 | 
					    /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm`
 | 
				
			||||||
 | 
					    /// was called, otherwise none
 | 
				
			||||||
 | 
					    pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> {
 | 
				
			||||||
 | 
					        use crate::interrupt::typelevel::Interrupt;
 | 
				
			||||||
 | 
					        #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
				
			||||||
 | 
					        use crate::pac::rtc::vals::Calrf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let instant = self.instant().unwrap();
 | 
				
			||||||
 | 
					        if RTC::regs().cr().read().wute() {
 | 
				
			||||||
 | 
					            trace!("rtc: stop wakeup alarm at {}", instant);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.write(false, |regs| {
 | 
				
			||||||
 | 
					                regs.cr().modify(|w| w.set_wutie(false));
 | 
				
			||||||
 | 
					                regs.cr().modify(|w| w.set_wute(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                #[cfg(any(
 | 
				
			||||||
 | 
					                    rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb
 | 
				
			||||||
 | 
					                ))]
 | 
				
			||||||
 | 
					                regs.isr().modify(|w| w.set_wutf(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
				
			||||||
 | 
					                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                crate::pac::EXTI
 | 
				
			||||||
 | 
					                    .pr(0)
 | 
				
			||||||
 | 
					                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(feature = "low-power")]
 | 
				
			||||||
 | 
					    pub(crate) fn enable_wakeup_line(&self) {
 | 
				
			||||||
 | 
					        use crate::interrupt::typelevel::Interrupt;
 | 
				
			||||||
 | 
					        use crate::pac::EXTI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
				
			||||||
 | 
					        unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
				
			||||||
 | 
					        EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) {
 | 
					pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,145 +6,7 @@ use crate::peripherals::RTC;
 | 
				
			|||||||
use crate::rtc::sealed::Instance;
 | 
					use crate::rtc::sealed::Instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[allow(dead_code)]
 | 
					#[allow(dead_code)]
 | 
				
			||||||
#[repr(u8)]
 | 
					 | 
				
			||||||
#[derive(Clone, Copy, Debug)]
 | 
					 | 
				
			||||||
pub(crate) enum WakeupPrescaler {
 | 
					 | 
				
			||||||
    Div2 = 2,
 | 
					 | 
				
			||||||
    Div4 = 4,
 | 
					 | 
				
			||||||
    Div8 = 8,
 | 
					 | 
				
			||||||
    Div16 = 16,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(any(stm32wb, stm32f4, stm32l0))]
 | 
					 | 
				
			||||||
impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
 | 
					 | 
				
			||||||
    fn from(val: WakeupPrescaler) -> Self {
 | 
					 | 
				
			||||||
        use crate::pac::rtc::vals::Wucksel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match val {
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div2 => Wucksel::DIV2,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div4 => Wucksel::DIV4,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div8 => Wucksel::DIV8,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div16 => Wucksel::DIV16,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(any(stm32wb, stm32f4, stm32l0))]
 | 
					 | 
				
			||||||
impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
 | 
					 | 
				
			||||||
    fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
 | 
					 | 
				
			||||||
        use crate::pac::rtc::vals::Wucksel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match val {
 | 
					 | 
				
			||||||
            Wucksel::DIV2 => WakeupPrescaler::Div2,
 | 
					 | 
				
			||||||
            Wucksel::DIV4 => WakeupPrescaler::Div4,
 | 
					 | 
				
			||||||
            Wucksel::DIV8 => WakeupPrescaler::Div8,
 | 
					 | 
				
			||||||
            Wucksel::DIV16 => WakeupPrescaler::Div16,
 | 
					 | 
				
			||||||
            _ => unreachable!(),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[allow(dead_code)]
 | 
					 | 
				
			||||||
impl WakeupPrescaler {
 | 
					 | 
				
			||||||
    pub fn compute_min(val: u32) -> Self {
 | 
					 | 
				
			||||||
        *[
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div2,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div4,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div8,
 | 
					 | 
				
			||||||
            WakeupPrescaler::Div16,
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
        .iter()
 | 
					 | 
				
			||||||
        .skip_while(|psc| **psc as u32 <= val)
 | 
					 | 
				
			||||||
        .next()
 | 
					 | 
				
			||||||
        .unwrap_or(&WakeupPrescaler::Div16)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl super::Rtc {
 | 
					impl super::Rtc {
 | 
				
			||||||
    #[cfg(feature = "low-power")]
 | 
					 | 
				
			||||||
    /// start the wakeup alarm and wtih a duration that is as close to but less than
 | 
					 | 
				
			||||||
    /// the requested duration, and record the instant the wakeup alarm was started
 | 
					 | 
				
			||||||
    pub(crate) fn start_wakeup_alarm(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        requested_duration: embassy_time::Duration,
 | 
					 | 
				
			||||||
        cs: critical_section::CriticalSection,
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
        use embassy_time::{Duration, TICK_HZ};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Panic if the rcc mod knows we're not using low-power rtc
 | 
					 | 
				
			||||||
        #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
 | 
					 | 
				
			||||||
        unsafe { crate::rcc::get_freqs() }.rtc.unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let requested_duration = requested_duration.as_ticks().clamp(0, u32::MAX as u64);
 | 
					 | 
				
			||||||
        let rtc_hz = Self::frequency().0 as u64;
 | 
					 | 
				
			||||||
        let rtc_ticks = requested_duration * rtc_hz / TICK_HZ;
 | 
					 | 
				
			||||||
        let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // adjust the rtc ticks to the prescaler and subtract one rtc tick
 | 
					 | 
				
			||||||
        let rtc_ticks = rtc_ticks / prescaler as u64;
 | 
					 | 
				
			||||||
        let rtc_ticks = rtc_ticks.clamp(0, (u16::MAX - 1) as u64).saturating_sub(1) as u16;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.write(false, |regs| {
 | 
					 | 
				
			||||||
            regs.cr().modify(|w| w.set_wute(false));
 | 
					 | 
				
			||||||
            regs.isr().modify(|w| w.set_wutf(false));
 | 
					 | 
				
			||||||
            while !regs.isr().read().wutwf() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            regs.cr().modify(|w| w.set_wucksel(prescaler.into()));
 | 
					 | 
				
			||||||
            regs.wutr().write(|w| w.set_wut(rtc_ticks));
 | 
					 | 
				
			||||||
            regs.cr().modify(|w| w.set_wute(true));
 | 
					 | 
				
			||||||
            regs.cr().modify(|w| w.set_wutie(true));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let instant = self.instant().unwrap();
 | 
					 | 
				
			||||||
        trace!(
 | 
					 | 
				
			||||||
            "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
 | 
					 | 
				
			||||||
            Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(),
 | 
					 | 
				
			||||||
            prescaler as u32,
 | 
					 | 
				
			||||||
            rtc_ticks,
 | 
					 | 
				
			||||||
            instant,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(feature = "low-power")]
 | 
					 | 
				
			||||||
    /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm`
 | 
					 | 
				
			||||||
    /// was called, otherwise none
 | 
					 | 
				
			||||||
    pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> {
 | 
					 | 
				
			||||||
        use crate::interrupt::typelevel::Interrupt;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let instant = self.instant().unwrap();
 | 
					 | 
				
			||||||
        if RTC::regs().cr().read().wute() {
 | 
					 | 
				
			||||||
            trace!("rtc: stop wakeup alarm at {}", instant);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.write(false, |regs| {
 | 
					 | 
				
			||||||
                regs.cr().modify(|w| w.set_wutie(false));
 | 
					 | 
				
			||||||
                regs.cr().modify(|w| w.set_wute(false));
 | 
					 | 
				
			||||||
                regs.isr().modify(|w| w.set_wutf(false));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                crate::pac::EXTI
 | 
					 | 
				
			||||||
                    .pr(0)
 | 
					 | 
				
			||||||
                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(feature = "low-power")]
 | 
					 | 
				
			||||||
    pub(crate) fn enable_wakeup_line(&self) {
 | 
					 | 
				
			||||||
        use crate::interrupt::typelevel::Interrupt;
 | 
					 | 
				
			||||||
        use crate::pac::EXTI;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
					 | 
				
			||||||
        unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
					 | 
				
			||||||
        EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Applies the RTC config
 | 
					    /// Applies the RTC config
 | 
				
			||||||
    /// It this changes the RTC clock source the time will be reset
 | 
					    /// It this changes the RTC clock source the time will be reset
 | 
				
			||||||
    pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
 | 
					    pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
 | 
				
			||||||
 | 
				
			|||||||
@ -95,7 +95,7 @@ impl super::Rtc {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(super) fn write<F, R>(&mut self, init_mode: bool, f: F) -> R
 | 
					    pub(super) fn write<F, R>(&self, init_mode: bool, f: F) -> R
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        F: FnOnce(&crate::pac::rtc::Rtc) -> R,
 | 
					        F: FnOnce(&crate::pac::rtc::Rtc) -> R,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -129,6 +129,12 @@ impl super::Rtc {
 | 
				
			|||||||
impl sealed::Instance for crate::peripherals::RTC {
 | 
					impl sealed::Instance for crate::peripherals::RTC {
 | 
				
			||||||
    const BACKUP_REGISTER_COUNT: usize = 32;
 | 
					    const BACKUP_REGISTER_COUNT: usize = 32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(all(feature = "low-power", stm32g4))]
 | 
				
			||||||
 | 
					    const EXTI_WAKEUP_LINE: usize = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(all(feature = "low-power", stm32g4))]
 | 
				
			||||||
 | 
					    type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
 | 
					    fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
 | 
				
			||||||
        #[allow(clippy::if_same_then_else)]
 | 
					        #[allow(clippy::if_same_then_else)]
 | 
				
			||||||
        if register < Self::BACKUP_REGISTER_COUNT {
 | 
					        if register < Self::BACKUP_REGISTER_COUNT {
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"]
 | 
				
			|||||||
stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"]
 | 
					stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"]
 | 
				
			||||||
stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac-adc-pin"]
 | 
					stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac-adc-pin"]
 | 
				
			||||||
stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
 | 
					stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
 | 
				
			||||||
stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"]
 | 
					stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng"]
 | 
				
			||||||
stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"]
 | 
					stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"]
 | 
				
			||||||
stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"]
 | 
					stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"]
 | 
				
			||||||
stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"]
 | 
					stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user