aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/rcc/bd.rs83
-rw-r--r--embassy-stm32/src/rcc/f2.rs30
-rw-r--r--embassy-stm32/src/rcc/f4.rs14
-rw-r--r--embassy-stm32/src/rcc/l4.rs2
-rw-r--r--embassy-stm32/src/rcc/wb.rs19
-rw-r--r--embassy-stm32/src/rcc/wl.rs23
-rw-r--r--embassy-stm32/src/rtc/mod.rs2
-rw-r--r--embassy-stm32/src/rtc/v2.rs9
-rw-r--r--embassy-stm32/src/rtc/v3.rs17
-rw-r--r--examples/stm32wl/src/bin/lora_lorawan.rs2
-rw-r--r--examples/stm32wl/src/bin/random.rs2
-rw-r--r--examples/stm32wl/src/bin/rtc.rs1
12 files changed, 84 insertions, 120 deletions
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index 34b88458f..76d0f3a36 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -94,36 +94,49 @@ impl BackupDomain {
94 r 94 r
95 } 95 }
96 96
97 #[cfg(any(
98 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
99 rtc_v3u5
100 ))]
97 #[allow(dead_code, unused_variables)] 101 #[allow(dead_code, unused_variables)]
98 #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))] 102 pub fn configure_ls(clock_source: RtcClockSource, lse_drive: Option<LseDrive>) {
99 pub fn enable_lse(lse_drive: LseDrive) { 103 match clock_source {
100 Self::modify(|w| { 104 RtcClockSource::LSI => {
101 #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] 105 #[cfg(rtc_v3u5)]
102 w.set_lsedrv(lse_drive.into()); 106 let csr = crate::pac::RCC.bdcr();
103 w.set_lseon(true); 107
104 }); 108 #[cfg(not(rtc_v3u5))]
105 109 let csr = crate::pac::RCC.csr();
106 while !Self::read().lserdy() {} 110
107 } 111 Self::modify(|_| {
108 112 #[cfg(not(rtc_v2wb))]
109 #[allow(dead_code)] 113 csr.modify(|w| w.set_lsion(true));
110 #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))] 114
111 pub fn enable_lsi() { 115 #[cfg(rtc_v2wb)]
112 let csr = crate::pac::RCC.csr(); 116 csr.modify(|w| w.set_lsi1on(true));
113 117 });
114 Self::modify(|_| { 118
115 #[cfg(not(rtc_v2wb))] 119 #[cfg(not(rtc_v2wb))]
116 csr.modify(|w| w.set_lsion(true)); 120 while !csr.read().lsirdy() {}
117 121
118 #[cfg(rtc_v2wb)] 122 #[cfg(rtc_v2wb)]
119 csr.modify(|w| w.set_lsi1on(true)); 123 while !csr.read().lsi1rdy() {}
120 }); 124 }
121 125 RtcClockSource::LSE => {
122 #[cfg(not(rtc_v2wb))] 126 let lse_drive = lse_drive.unwrap_or_default();
123 while !csr.read().lsirdy() {} 127
128 Self::modify(|w| {
129 #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
130 w.set_lsedrv(lse_drive.into());
131 w.set_lseon(true);
132 });
133
134 while !Self::read().lserdy() {}
135 }
136 _ => {}
137 };
124 138
125 #[cfg(rtc_v2wb)] 139 Self::configure_rtc(clock_source);
126 while !csr.read().lsi1rdy() {}
127 } 140 }
128 141
129 #[cfg(any( 142 #[cfg(any(
@@ -131,7 +144,7 @@ impl BackupDomain {
131 rtc_v3u5 144 rtc_v3u5
132 ))] 145 ))]
133 #[allow(dead_code, unused_variables)] 146 #[allow(dead_code, unused_variables)]
134 pub fn set_rtc_clock_source(clock_source: RtcClockSource) { 147 pub fn configure_rtc(clock_source: RtcClockSource) {
135 let clock_source = clock_source as u8; 148 let clock_source = clock_source as u8;
136 #[cfg(any( 149 #[cfg(any(
137 not(any(rtc_v3, rtc_v3u5, rtc_v2wb)), 150 not(any(rtc_v3, rtc_v3u5, rtc_v2wb)),
@@ -146,18 +159,6 @@ impl BackupDomain {
146 }); 159 });
147 } 160 }
148 161
149 #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))]
150 #[allow(dead_code, unused_variables)]
151 pub fn configure_rtc(clock_source: RtcClockSource, lse_drive: Option<LseDrive>) {
152 match clock_source {
153 RtcClockSource::LSI => Self::enable_lsi(),
154 RtcClockSource::LSE => Self::enable_lse(lse_drive.unwrap_or_default()),
155 _ => {}
156 };
157
158 Self::set_rtc_clock_source(clock_source);
159 }
160
161 #[cfg(any( 162 #[cfg(any(
162 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, 163 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
163 rtc_v3u5 164 rtc_v3u5
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs
index 8b6556249..b821f9585 100644
--- a/embassy-stm32/src/rcc/f2.rs
+++ b/embassy-stm32/src/rcc/f2.rs
@@ -421,33 +421,9 @@ pub(crate) unsafe fn init(config: Config) {
421 RCC.apb1enr().modify(|w| w.set_pwren(true)); 421 RCC.apb1enr().modify(|w| w.set_pwren(true));
422 PWR.cr().read(); 422 PWR.cr().read();
423 423
424 match config.rtc { 424 config
425 Some(RtcClockSource::LSE) => { 425 .rtc
426 // 1. Unlock the backup domain 426 .map(|clock_source| BackupDomain::configure_ls(clock_source, None));
427 PWR.cr().modify(|w| w.set_dbp(true));
428
429 // 2. Setup the LSE
430 RCC.bdcr().modify(|w| {
431 // Enable LSE
432 w.set_lseon(true);
433 });
434
435 // Wait until LSE is running
436 while !RCC.bdcr().read().lserdy() {}
437
438 BackupDomain::set_rtc_clock_source(RtcClockSource::LSE);
439 }
440 Some(RtcClockSource::LSI) => {
441 // Turn on the internal 32 kHz LSI oscillator
442 RCC.csr().modify(|w| w.set_lsion(true));
443
444 // Wait until LSI is running
445 while !RCC.csr().read().lsirdy() {}
446
447 BackupDomain::set_rtc_clock_source(RtcClockSource::LSI);
448 }
449 _ => todo!(),
450 }
451 427
452 set_freqs(Clocks { 428 set_freqs(Clocks {
453 sys: sys_clk, 429 sys: sys_clk,
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index c2c78a45e..f7bc0d99a 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -461,17 +461,9 @@ pub(crate) unsafe fn init(config: Config) {
461 }) 461 })
462 }); 462 });
463 463
464 match config.rtc { 464 config
465 Some(RtcClockSource::LSI) => { 465 .rtc
466 RCC.csr().modify(|w| w.set_lsion(true)); 466 .map(|clock_source| BackupDomain::configure_ls(clock_source, None));
467 while !RCC.csr().read().lsirdy() {}
468 }
469 _ => {}
470 }
471
472 config.rtc.map(|clock_source| {
473 BackupDomain::set_rtc_clock_source(clock_source);
474 });
475 467
476 let rtc = match config.rtc { 468 let rtc = match config.rtc {
477 Some(RtcClockSource::LSI) => Some(LSI_FREQ), 469 Some(RtcClockSource::LSI) => Some(LSI_FREQ),
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 0083ae5bb..41dbff01e 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -407,7 +407,7 @@ pub(crate) unsafe fn init(config: Config) {
407 407
408 RCC.apb1enr1().modify(|w| w.set_pwren(true)); 408 RCC.apb1enr1().modify(|w| w.set_pwren(true));
409 409
410 BackupDomain::configure_rtc(config.rtc_mux, None); 410 BackupDomain::configure_ls(config.rtc_mux, None);
411 411
412 let (sys_clk, sw) = match config.mux { 412 let (sys_clk, sw) = match config.mux {
413 ClockSrc::MSI(range) => { 413 ClockSrc::MSI(range) => {
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index efd964642..d90a50cf4 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -276,7 +276,6 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks {
276} 276}
277 277
278pub(crate) fn configure_clocks(config: &Config) { 278pub(crate) fn configure_clocks(config: &Config) {
279 let pwr = crate::pac::PWR;
280 let rcc = crate::pac::RCC; 279 let rcc = crate::pac::RCC;
281 280
282 let needs_hsi = if let Some(pll_mux) = &config.mux { 281 let needs_hsi = if let Some(pll_mux) = &config.mux {
@@ -293,17 +292,11 @@ pub(crate) fn configure_clocks(config: &Config) {
293 while !rcc.cr().read().hsirdy() {} 292 while !rcc.cr().read().hsirdy() {}
294 } 293 }
295 294
296 match &config.lse { 295 rcc.cfgr().modify(|w| w.set_stopwuck(true));
297 Some(_) => {
298 rcc.cfgr().modify(|w| w.set_stopwuck(true));
299 296
300 pwr.cr1().modify(|w| w.set_dbp(true)); 297 config
301 pwr.cr1().modify(|w| w.set_dbp(true)); 298 .rtc
302 299 .map(|clock_source| BackupDomain::configure_ls(clock_source, None));
303 rcc.bdcr().modify(|w| w.set_lseon(true));
304 }
305 _ => {}
306 }
307 300
308 match &config.hse { 301 match &config.hse {
309 Some(hse) => { 302 Some(hse) => {
@@ -363,8 +356,4 @@ pub(crate) fn configure_clocks(config: &Config) {
363 w.set_c2hpre(config.ahb2_pre.into()); 356 w.set_c2hpre(config.ahb2_pre.into());
364 w.set_shdhpre(config.ahb3_pre.into()); 357 w.set_shdhpre(config.ahb3_pre.into());
365 }); 358 });
366
367 config
368 .rtc
369 .map(|clock_source| BackupDomain::configure_rtc(clock_source, None));
370} 359}
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs
index 7a03d9060..6035f50b0 100644
--- a/embassy-stm32/src/rcc/wl.rs
+++ b/embassy-stm32/src/rcc/wl.rs
@@ -137,8 +137,6 @@ pub struct Config {
137 pub shd_ahb_pre: AHBPrescaler, 137 pub shd_ahb_pre: AHBPrescaler,
138 pub apb1_pre: APBPrescaler, 138 pub apb1_pre: APBPrescaler,
139 pub apb2_pre: APBPrescaler, 139 pub apb2_pre: APBPrescaler,
140 pub enable_lsi: bool,
141 pub enable_rtc_apb: bool,
142 pub rtc_mux: RtcClockSource, 140 pub rtc_mux: RtcClockSource,
143 pub adc_clock_source: AdcClockSource, 141 pub adc_clock_source: AdcClockSource,
144} 142}
@@ -152,8 +150,6 @@ impl Default for Config {
152 shd_ahb_pre: AHBPrescaler::NotDivided, 150 shd_ahb_pre: AHBPrescaler::NotDivided,
153 apb1_pre: APBPrescaler::NotDivided, 151 apb1_pre: APBPrescaler::NotDivided,
154 apb2_pre: APBPrescaler::NotDivided, 152 apb2_pre: APBPrescaler::NotDivided,
155 enable_lsi: false,
156 enable_rtc_apb: false,
157 rtc_mux: RtcClockSource::LSI, 153 rtc_mux: RtcClockSource::LSI,
158 adc_clock_source: AdcClockSource::default(), 154 adc_clock_source: AdcClockSource::default(),
159 } 155 }
@@ -234,7 +230,8 @@ pub(crate) unsafe fn init(config: Config) {
234 230
235 while FLASH.acr().read().latency() != ws {} 231 while FLASH.acr().read().latency() != ws {}
236 232
237 BackupDomain::configure_rtc(config.rtc_mux, None); 233 // Enables the LSI if configured
234 BackupDomain::configure_ls(config.rtc_mux, None);
238 235
239 match config.mux { 236 match config.mux {
240 ClockSrc::HSI16 => { 237 ClockSrc::HSI16 => {
@@ -269,14 +266,6 @@ pub(crate) unsafe fn init(config: Config) {
269 } 266 }
270 } 267 }
271 268
272 if config.enable_rtc_apb {
273 // enable peripheral clock for communication
274 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
275
276 // read to allow the pwr clock to enable
277 crate::pac::PWR.cr1().read();
278 }
279
280 RCC.extcfgr().modify(|w| { 269 RCC.extcfgr().modify(|w| {
281 if config.shd_ahb_pre == AHBPrescaler::NotDivided { 270 if config.shd_ahb_pre == AHBPrescaler::NotDivided {
282 w.set_shdhpre(0); 271 w.set_shdhpre(0);
@@ -301,14 +290,6 @@ pub(crate) unsafe fn init(config: Config) {
301 290
302 // TODO: switch voltage range 291 // TODO: switch voltage range
303 292
304 if config.enable_lsi {
305 let csr = RCC.csr().read();
306 if !csr.lsion() {
307 RCC.csr().modify(|w| w.set_lsion(true));
308 while !RCC.csr().read().lsirdy() {}
309 }
310 }
311
312 set_freqs(Clocks { 293 set_freqs(Clocks {
313 sys: Hertz(sys_clk), 294 sys: Hertz(sys_clk),
314 ahb1: Hertz(ahb_freq), 295 ahb1: Hertz(ahb_freq),
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 9db4f69c5..a1133a80b 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -268,7 +268,7 @@ pub(crate) mod sealed {
268 crate::pac::RTC 268 crate::pac::RTC
269 } 269 }
270 270
271 fn enable_peripheral_clk() {} 271 fn enable_peripheral_clk();
272 272
273 /// Read content of the backup register. 273 /// Read content of the backup register.
274 /// 274 ///
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs
index 62d8d4f9c..9037389ec 100644
--- a/embassy-stm32/src/rtc/v2.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -270,9 +270,18 @@ impl sealed::Instance for crate::peripherals::RTC {
270 } 270 }
271 #[cfg(any(rtc_v2f2))] 271 #[cfg(any(rtc_v2f2))]
272 { 272 {
273 // enable peripheral clock for communication
273 crate::pac::RCC.apb1enr().modify(|w| w.set_pwren(true)); 274 crate::pac::RCC.apb1enr().modify(|w| w.set_pwren(true));
275
276 // read to allow the pwr clock to enable
274 crate::pac::PWR.cr().read(); 277 crate::pac::PWR.cr().read();
275 } 278 }
279
280 #[cfg(any(rtc_v2f0))]
281 {
282 // enable peripheral clock for communication
283 crate::pac::RCC.apb1enr().modify(|w| w.set_pwren(true));
284 }
276 } 285 }
277 286
278 fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> { 287 fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> {
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index a6b2655d8..9ac9f9f85 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -128,6 +128,23 @@ impl super::Rtc {
128impl sealed::Instance for crate::peripherals::RTC { 128impl sealed::Instance for crate::peripherals::RTC {
129 const BACKUP_REGISTER_COUNT: usize = 32; 129 const BACKUP_REGISTER_COUNT: usize = 32;
130 130
131 fn enable_peripheral_clk() {
132 #[cfg(any(rcc_wle, rcc_wl5, rcc_g4))]
133 {
134 // enable peripheral clock for communication
135 crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
136 }
137
138 #[cfg(rcc_g0)]
139 {
140 // enable peripheral clock for communication
141 crate::pac::RCC.apbenr1().modify(|w| w.set_rtcapben(true));
142 }
143
144 // read to allow the pwr clock to enable
145 crate::pac::PWR.cr1().read();
146 }
147
131 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> { 148 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
132 #[allow(clippy::if_same_then_else)] 149 #[allow(clippy::if_same_then_else)]
133 if register < Self::BACKUP_REGISTER_COUNT { 150 if register < Self::BACKUP_REGISTER_COUNT {
diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs
index 2c9c98861..230df4752 100644
--- a/examples/stm32wl/src/bin/lora_lorawan.rs
+++ b/examples/stm32wl/src/bin/lora_lorawan.rs
@@ -33,7 +33,7 @@ bind_interrupts!(struct Irqs{
33async fn main(_spawner: Spawner) { 33async fn main(_spawner: Spawner) {
34 let mut config = embassy_stm32::Config::default(); 34 let mut config = embassy_stm32::Config::default();
35 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; 35 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32;
36 config.rcc.enable_lsi = true; // enable RNG 36 config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
37 let p = embassy_stm32::init(config); 37 let p = embassy_stm32::init(config);
38 38
39 pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); 39 pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01));
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs
index 592e65f40..18eeac4fa 100644
--- a/examples/stm32wl/src/bin/random.rs
+++ b/examples/stm32wl/src/bin/random.rs
@@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs{
16async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
17 let mut config = embassy_stm32::Config::default(); 17 let mut config = embassy_stm32::Config::default();
18 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; 18 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32;
19 config.rcc.enable_lsi = true; //Needed for RNG to work 19 config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
20 20
21 let p = embassy_stm32::init(config); 21 let p = embassy_stm32::init(config);
22 pac::RCC.ccipr().modify(|w| { 22 pac::RCC.ccipr().modify(|w| {
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs
index 2be6c7b93..e123425a0 100644
--- a/examples/stm32wl/src/bin/rtc.rs
+++ b/examples/stm32wl/src/bin/rtc.rs
@@ -17,7 +17,6 @@ async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 17 let mut config = Config::default();
18 config.rcc.mux = ClockSrc::HSE32; 18 config.rcc.mux = ClockSrc::HSE32;
19 config.rcc.rtc_mux = RtcClockSource::LSE; 19 config.rcc.rtc_mux = RtcClockSource::LSE;
20 config.rcc.enable_rtc_apb = true;
21 embassy_stm32::init(config) 20 embassy_stm32::init(config)
22 }; 21 };
23 info!("Hello World!"); 22 info!("Hello World!");