diff options
| author | xoviat <[email protected]> | 2023-09-14 18:53:27 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-09-14 18:53:27 -0500 |
| commit | 9fb14379c3d24f68a1f0715d61a54e31b7b53d2a (patch) | |
| tree | a9d7f7fe634105a4cd3a342eb444f9ebfaa9c2f8 | |
| parent | 309c3d6b472aa07bdf8b96f57eef5c0b5a686844 (diff) | |
stm32: add lp to l0
| -rw-r--r-- | embassy-stm32/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/low_power.rs | 15 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/bd.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/v2.rs | 25 |
5 files changed, 48 insertions, 6 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 24d0912f0..51909e43b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -21,7 +21,7 @@ flavors = [ | |||
| 21 | { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi" }, | 21 | { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi" }, |
| 22 | { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" }, | 22 | { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" }, |
| 23 | { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, | 23 | { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, |
| 24 | { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi" }, | 24 | { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, |
| 25 | { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, | 25 | { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, |
| 26 | { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, | 26 | { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, |
| 27 | { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" }, | 27 | { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" }, |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 7e678d323..b42b674e1 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -95,8 +95,21 @@ impl Executor { | |||
| 95 | 95 | ||
| 96 | self.time_driver.set_rtc(rtc); | 96 | self.time_driver.set_rtc(rtc); |
| 97 | 97 | ||
| 98 | #[cfg(not(stm32l0))] | ||
| 98 | crate::interrupt::typelevel::RTC_WKUP::unpend(); | 99 | crate::interrupt::typelevel::RTC_WKUP::unpend(); |
| 99 | unsafe { crate::interrupt::typelevel::RTC_WKUP::enable() }; | 100 | |
| 101 | #[cfg(not(stm32l0))] | ||
| 102 | unsafe { | ||
| 103 | crate::interrupt::typelevel::RTC_WKUP::enable() | ||
| 104 | }; | ||
| 105 | |||
| 106 | #[cfg(stm32l0)] | ||
| 107 | crate::interrupt::typelevel::RTC::unpend(); | ||
| 108 | |||
| 109 | #[cfg(stm32l0)] | ||
| 110 | unsafe { | ||
| 111 | crate::interrupt::typelevel::RTC::enable() | ||
| 112 | }; | ||
| 100 | 113 | ||
| 101 | rtc.enable_wakeup_line(); | 114 | rtc.enable_wakeup_line(); |
| 102 | } | 115 | } |
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 76d0f3a36..059a32116 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs | |||
| @@ -58,13 +58,13 @@ impl BackupDomain { | |||
| 58 | ))] | 58 | ))] |
| 59 | #[allow(dead_code, unused_variables)] | 59 | #[allow(dead_code, unused_variables)] |
| 60 | fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R { | 60 | fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R { |
| 61 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] | 61 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))] |
| 62 | let cr = crate::pac::PWR.cr(); | 62 | let cr = crate::pac::PWR.cr(); |
| 63 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | 63 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] |
| 64 | let cr = crate::pac::PWR.cr1(); | 64 | let cr = crate::pac::PWR.cr1(); |
| 65 | 65 | ||
| 66 | // TODO: Missing from PAC for l0 and f0? | 66 | // TODO: Missing from PAC for l0 and f0? |
| 67 | #[cfg(not(any(rtc_v2f0, rtc_v2l0, rtc_v3u5)))] | 67 | #[cfg(not(any(rtc_v2f0, rtc_v3u5)))] |
| 68 | { | 68 | { |
| 69 | cr.modify(|w| w.set_dbp(true)); | 69 | cr.modify(|w| w.set_dbp(true)); |
| 70 | while !cr.read().dbp() {} | 70 | while !cr.read().dbp() {} |
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 7f9ab01f1..3c8511ffd 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | use super::bd::BackupDomain; | ||
| 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; | 2 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 3 | use super::RtcClockSource; | ||
| 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 4 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; |
| 3 | use crate::pac::RCC; | 5 | use crate::pac::RCC; |
| 4 | #[cfg(crs)] | 6 | #[cfg(crs)] |
| @@ -135,6 +137,7 @@ pub struct Config { | |||
| 135 | pub apb2_pre: APBPrescaler, | 137 | pub apb2_pre: APBPrescaler, |
| 136 | #[cfg(crs)] | 138 | #[cfg(crs)] |
| 137 | pub enable_hsi48: bool, | 139 | pub enable_hsi48: bool, |
| 140 | pub rtc: Option<RtcClockSource>, | ||
| 138 | } | 141 | } |
| 139 | 142 | ||
| 140 | impl Default for Config { | 143 | impl Default for Config { |
| @@ -147,6 +150,7 @@ impl Default for Config { | |||
| 147 | apb2_pre: APBPrescaler::NotDivided, | 150 | apb2_pre: APBPrescaler::NotDivided, |
| 148 | #[cfg(crs)] | 151 | #[cfg(crs)] |
| 149 | enable_hsi48: false, | 152 | enable_hsi48: false, |
| 153 | rtc: None, | ||
| 150 | } | 154 | } |
| 151 | } | 155 | } |
| 152 | } | 156 | } |
| @@ -231,6 +235,10 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 231 | } | 235 | } |
| 232 | }; | 236 | }; |
| 233 | 237 | ||
| 238 | config.rtc.map(|rtc| { | ||
| 239 | BackupDomain::configure_ls(rtc, None); | ||
| 240 | }); | ||
| 241 | |||
| 234 | RCC.cfgr().modify(|w| { | 242 | RCC.cfgr().modify(|w| { |
| 235 | w.set_sw(sw); | 243 | w.set_sw(sw); |
| 236 | w.set_hpre(config.ahb_pre.into()); | 244 | w.set_hpre(config.ahb_pre.into()); |
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 9037389ec..1fa9f2fe3 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -15,7 +15,7 @@ pub(crate) enum WakeupPrescaler { | |||
| 15 | Div16 = 16, | 15 | Div16 = 16, |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | #[cfg(any(stm32wb, stm32f4))] | 18 | #[cfg(any(stm32wb, stm32f4, stm32l0))] |
| 19 | impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { | 19 | impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { |
| 20 | fn from(val: WakeupPrescaler) -> Self { | 20 | fn from(val: WakeupPrescaler) -> Self { |
| 21 | use crate::pac::rtc::vals::Wucksel; | 21 | use crate::pac::rtc::vals::Wucksel; |
| @@ -29,7 +29,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { | |||
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | #[cfg(any(stm32wb, stm32f4))] | 32 | #[cfg(any(stm32wb, stm32f4, stm32l0))] |
| 33 | impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { | 33 | impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { |
| 34 | fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { | 34 | fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { |
| 35 | use crate::pac::rtc::vals::Wucksel; | 35 | use crate::pac::rtc::vals::Wucksel; |
| @@ -67,10 +67,15 @@ impl super::Rtc { | |||
| 67 | pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) { | 67 | pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) { |
| 68 | use embassy_time::{Duration, TICK_HZ}; | 68 | use embassy_time::{Duration, TICK_HZ}; |
| 69 | 69 | ||
| 70 | #[cfg(not(stm32l0))] | ||
| 70 | use crate::rcc::get_freqs; | 71 | use crate::rcc::get_freqs; |
| 71 | 72 | ||
| 73 | #[cfg(not(stm32l0))] | ||
| 72 | let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64; | 74 | let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64; |
| 73 | 75 | ||
| 76 | #[cfg(stm32l0)] | ||
| 77 | let rtc_hz = 32_768u64; | ||
| 78 | |||
| 74 | let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ; | 79 | let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ; |
| 75 | let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); | 80 | let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); |
| 76 | 81 | ||
| @@ -109,7 +114,14 @@ impl super::Rtc { | |||
| 109 | pub(crate) fn enable_wakeup_line(&self) { | 114 | pub(crate) fn enable_wakeup_line(&self) { |
| 110 | use crate::pac::EXTI; | 115 | use crate::pac::EXTI; |
| 111 | 116 | ||
| 117 | #[cfg(stm32l0)] | ||
| 118 | EXTI.rtsr(0).modify(|w| w.set_line(20, true)); | ||
| 119 | #[cfg(stm32l0)] | ||
| 120 | EXTI.imr(0).modify(|w| w.set_line(20, true)); | ||
| 121 | |||
| 122 | #[cfg(not(stm32l0))] | ||
| 112 | EXTI.rtsr(0).modify(|w| w.set_line(22, true)); | 123 | EXTI.rtsr(0).modify(|w| w.set_line(22, true)); |
| 124 | #[cfg(not(stm32l0))] | ||
| 113 | EXTI.imr(0).modify(|w| w.set_line(22, true)); | 125 | EXTI.imr(0).modify(|w| w.set_line(22, true)); |
| 114 | } | 126 | } |
| 115 | 127 | ||
| @@ -126,8 +138,17 @@ impl super::Rtc { | |||
| 126 | regs.cr().modify(|w| w.set_wute(false)); | 138 | regs.cr().modify(|w| w.set_wute(false)); |
| 127 | regs.isr().modify(|w| w.set_wutf(false)); | 139 | regs.isr().modify(|w| w.set_wutf(false)); |
| 128 | 140 | ||
| 141 | #[cfg(not(stm32l0))] | ||
| 129 | crate::pac::EXTI.pr(0).modify(|w| w.set_line(22, true)); | 142 | crate::pac::EXTI.pr(0).modify(|w| w.set_line(22, true)); |
| 143 | |||
| 144 | #[cfg(stm32l0)] | ||
| 145 | crate::pac::EXTI.pr(0).modify(|w| w.set_line(20, true)); | ||
| 146 | |||
| 147 | #[cfg(not(stm32l0))] | ||
| 130 | crate::interrupt::typelevel::RTC_WKUP::unpend(); | 148 | crate::interrupt::typelevel::RTC_WKUP::unpend(); |
| 149 | |||
| 150 | #[cfg(stm32l0)] | ||
| 151 | crate::interrupt::typelevel::RTC::unpend(); | ||
| 131 | }); | 152 | }); |
| 132 | 153 | ||
| 133 | critical_section::with(|cs| { | 154 | critical_section::with(|cs| { |
