aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-07-10 21:45:34 +0000
committerGitHub <[email protected]>2022-07-10 21:45:34 +0000
commitc6a11db39ef829adfb8b4903065446c4bb7a2ef4 (patch)
tree68294655fd3326356a5d3ab2ba1d1eacfe3a997f
parent93e7d53e393a8f79be1c4a5c0e1fd8497305fc50 (diff)
parent5a208d28d011761d88e12881a69ab9c0663149e2 (diff)
Merge #854
854: Implement IWDG timeout calculation r=Dirbaio a=chemicstry Allow specifying `IndependentWatchdog` timeout as `Duration` instead of prescaler value. Since IWDG is clocked from LSI, which differs between families, I standardized HSI/LSI definitions in RCC and used that. Co-authored-by: chemicstry <[email protected]>
-rw-r--r--embassy-stm32/src/rcc/f0.rs10
-rw-r--r--embassy-stm32/src/rcc/f1.rs10
-rw-r--r--embassy-stm32/src/rcc/f2.rs9
-rw-r--r--embassy-stm32/src/rcc/f3.rs16
-rw-r--r--embassy-stm32/src/rcc/f4.rs8
-rw-r--r--embassy-stm32/src/rcc/f7.rs8
-rw-r--r--embassy-stm32/src/rcc/g0.rs10
-rw-r--r--embassy-stm32/src/rcc/g4.rs6
-rw-r--r--embassy-stm32/src/rcc/h7.rs31
-rw-r--r--embassy-stm32/src/rcc/l0.rs11
-rw-r--r--embassy-stm32/src/rcc/l1.rs9
-rw-r--r--embassy-stm32/src/rcc/l4.rs11
-rw-r--r--embassy-stm32/src/rcc/l5.rs11
-rw-r--r--embassy-stm32/src/rcc/u5.rs11
-rw-r--r--embassy-stm32/src/rcc/wb.rs7
-rw-r--r--embassy-stm32/src/rcc/wl.rs14
-rw-r--r--embassy-stm32/src/wdg/mod.rs44
-rw-r--r--examples/stm32f4/src/bin/wdt.rs46
m---------stm32-data0
19 files changed, 203 insertions, 69 deletions
diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs
index 10b075da4..eb62ab661 100644
--- a/embassy-stm32/src/rcc/f0.rs
+++ b/embassy-stm32/src/rcc/f0.rs
@@ -3,7 +3,11 @@ use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Sw, Usbsw};
3use crate::pac::{FLASH, RCC}; 3use crate::pac::{FLASH, RCC};
4use crate::time::Hertz; 4use crate::time::Hertz;
5 5
6const HSI: u32 = 8_000_000; 6/// HSI speed
7pub const HSI_FREQ: Hertz = Hertz(8_000_000);
8
9/// LSI speed
10pub const LSI_FREQ: Hertz = Hertz(40_000);
7 11
8/// Configuration of the clocks 12/// Configuration of the clocks
9/// 13///
@@ -24,14 +28,14 @@ pub struct Config {
24} 28}
25 29
26pub(crate) unsafe fn init(config: Config) { 30pub(crate) unsafe fn init(config: Config) {
27 let sysclk = config.sys_ck.map(|v| v.0).unwrap_or(HSI); 31 let sysclk = config.sys_ck.map(|v| v.0).unwrap_or(HSI_FREQ.0);
28 32
29 let (src_clk, use_hsi48) = config.hse.map(|v| (v.0, false)).unwrap_or_else(|| { 33 let (src_clk, use_hsi48) = config.hse.map(|v| (v.0, false)).unwrap_or_else(|| {
30 #[cfg(not(stm32f0x0))] 34 #[cfg(not(stm32f0x0))]
31 if config.hsi48 { 35 if config.hsi48 {
32 return (48_000_000, true); 36 return (48_000_000, true);
33 } 37 }
34 (HSI, false) 38 (HSI_FREQ.0, false)
35 }); 39 });
36 40
37 let (pllmul_bits, real_sysclk) = if sysclk == src_clk { 41 let (pllmul_bits, real_sysclk) = if sysclk == src_clk {
diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs
index 8e2e6684a..e667dbf90 100644
--- a/embassy-stm32/src/rcc/f1.rs
+++ b/embassy-stm32/src/rcc/f1.rs
@@ -6,7 +6,11 @@ use crate::pac::rcc::vals::*;
6use crate::pac::{FLASH, RCC}; 6use crate::pac::{FLASH, RCC};
7use crate::time::Hertz; 7use crate::time::Hertz;
8 8
9const HSI: u32 = 8_000_000; 9/// HSI speed
10pub const HSI_FREQ: Hertz = Hertz(8_000_000);
11
12/// LSI speed
13pub const LSI_FREQ: Hertz = Hertz(40_000);
10 14
11/// Configuration of the clocks 15/// Configuration of the clocks
12/// 16///
@@ -23,12 +27,12 @@ pub struct Config {
23} 27}
24 28
25pub(crate) unsafe fn init(config: Config) { 29pub(crate) unsafe fn init(config: Config) {
26 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI / 2); 30 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0 / 2);
27 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); 31 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
28 let pllmul = sysclk / pllsrcclk; 32 let pllmul = sysclk / pllsrcclk;
29 33
30 let (pllmul_bits, real_sysclk) = if pllmul == 1 { 34 let (pllmul_bits, real_sysclk) = if pllmul == 1 {
31 (None, config.hse.map(|hse| hse.0).unwrap_or(HSI)) 35 (None, config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0))
32 } else { 36 } else {
33 let pllmul = core::cmp::min(core::cmp::max(pllmul, 1), 16); 37 let pllmul = core::cmp::min(core::cmp::max(pllmul, 1), 16);
34 (Some(pllmul as u8 - 2), pllsrcclk * pllmul) 38 (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs
index 65fa78f82..d543888c1 100644
--- a/embassy-stm32/src/rcc/f2.rs
+++ b/embassy-stm32/src/rcc/f2.rs
@@ -8,7 +8,10 @@ use crate::rcc::{set_freqs, Clocks};
8use crate::time::Hertz; 8use crate::time::Hertz;
9 9
10/// HSI speed 10/// HSI speed
11pub const HSI: Hertz = Hertz(16_000_000); 11pub const HSI_FREQ: Hertz = Hertz(16_000_000);
12
13/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(32_000);
12 15
13#[derive(Clone, Copy)] 16#[derive(Clone, Copy)]
14pub struct HSEConfig { 17pub struct HSEConfig {
@@ -429,7 +432,7 @@ pub(crate) unsafe fn init(config: Config) {
429 .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); 432 .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input"));
430 hse_config.frequency 433 hse_config.frequency
431 } 434 }
432 PLLSrc::HSI => HSI, 435 PLLSrc::HSI => HSI_FREQ,
433 }; 436 };
434 437
435 // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics 438 // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics
@@ -451,7 +454,7 @@ pub(crate) unsafe fn init(config: Config) {
451 let (sys_clk, sw) = match config.mux { 454 let (sys_clk, sw) = match config.mux {
452 ClockSrc::HSI => { 455 ClockSrc::HSI => {
453 assert!(config.hsi, "HSI must be enabled to be used as system clock"); 456 assert!(config.hsi, "HSI must be enabled to be used as system clock");
454 (HSI, Sw::HSI) 457 (HSI_FREQ, Sw::HSI)
455 } 458 }
456 ClockSrc::HSE => { 459 ClockSrc::HSE => {
457 let hse_config = config 460 let hse_config = config
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs
index c2aec04c4..2deee80d6 100644
--- a/embassy-stm32/src/rcc/f3.rs
+++ b/embassy-stm32/src/rcc/f3.rs
@@ -4,7 +4,11 @@ use crate::pac::{FLASH, RCC};
4use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
5use crate::time::Hertz; 5use crate::time::Hertz;
6 6
7const HSI: u32 = 8_000_000; 7/// HSI speed
8pub const HSI_FREQ: Hertz = Hertz(8_000_000);
9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(40_000);
8 12
9/// Clocks configutation 13/// Clocks configutation
10#[non_exhaustive] 14#[non_exhaustive]
@@ -180,7 +184,7 @@ pub(crate) unsafe fn init(config: Config) {
180fn get_sysclk(config: &Config) -> (Hertz, Option<PllConfig>) { 184fn get_sysclk(config: &Config) -> (Hertz, Option<PllConfig>) {
181 match (config.sysclk, config.hse) { 185 match (config.sysclk, config.hse) {
182 (Some(sysclk), Some(hse)) if sysclk == hse => (hse, None), 186 (Some(sysclk), Some(hse)) if sysclk == hse => (hse, None),
183 (Some(sysclk), None) if sysclk.0 == HSI => (Hertz(HSI), None), 187 (Some(sysclk), None) if sysclk == HSI_FREQ => (HSI_FREQ, None),
184 // If the user selected System clock is different from HSI or HSE 188 // If the user selected System clock is different from HSI or HSE
185 // we will have to setup PLL clock source 189 // we will have to setup PLL clock source
186 (Some(sysclk), _) => { 190 (Some(sysclk), _) => {
@@ -188,7 +192,7 @@ fn get_sysclk(config: &Config) -> (Hertz, Option<PllConfig>) {
188 (sysclk, Some(pll_config)) 192 (sysclk, Some(pll_config))
189 } 193 }
190 (None, Some(hse)) => (hse, None), 194 (None, Some(hse)) => (hse, None),
191 (None, None) => (Hertz(HSI), None), 195 (None, None) => (HSI_FREQ, None),
192 } 196 }
193} 197}
194 198
@@ -228,15 +232,15 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) {
228 stm32f302xd, stm32f302xe, stm32f303xd, 232 stm32f302xd, stm32f302xe, stm32f303xd,
229 stm32f303xe, stm32f398xe 233 stm32f303xe, stm32f398xe
230 ))] { 234 ))] {
231 let (multiplier, divisor) = get_mul_div(sysclk, HSI); 235 let (multiplier, divisor) = get_mul_div(sysclk, HSI_FREQ.0);
232 ( 236 (
233 Hertz((HSI / divisor) * multiplier), 237 Hertz((HSI_FREQ.0 / divisor) * multiplier),
234 Pllsrc::HSI_DIV_PREDIV, 238 Pllsrc::HSI_DIV_PREDIV,
235 into_pll_mul(multiplier), 239 into_pll_mul(multiplier),
236 Some(into_pre_div(divisor)), 240 Some(into_pre_div(divisor)),
237 ) 241 )
238 } else { 242 } else {
239 let pllsrcclk = HSI / 2; 243 let pllsrcclk = HSI_FREQ.0 / 2;
240 let multiplier = sysclk / pllsrcclk; 244 let multiplier = sysclk / pllsrcclk;
241 assert!(multiplier <= 16); 245 assert!(multiplier <= 16);
242 ( 246 (
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index 21f3ad15d..200bcce9c 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -4,7 +4,11 @@ use crate::pac::{FLASH, PWR, RCC};
4use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
5use crate::time::Hertz; 5use crate::time::Hertz;
6 6
7const HSI: u32 = 16_000_000; 7/// HSI speed
8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(32_000);
8 12
9/// Clocks configuration 13/// Clocks configuration
10#[non_exhaustive] 14#[non_exhaustive]
@@ -108,7 +112,7 @@ unsafe fn flash_setup(sysclk: u32) {
108pub(crate) unsafe fn init(config: Config) { 112pub(crate) unsafe fn init(config: Config) {
109 crate::peripherals::PWR::enable(); 113 crate::peripherals::PWR::enable();
110 114
111 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI); 115 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0);
112 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); 116 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
113 let sysclk_on_pll = sysclk != pllsrcclk; 117 let sysclk_on_pll = sysclk != pllsrcclk;
114 118
diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs
index d98aa4018..2d21326a3 100644
--- a/embassy-stm32/src/rcc/f7.rs
+++ b/embassy-stm32/src/rcc/f7.rs
@@ -5,7 +5,11 @@ use crate::pac::{FLASH, PWR, RCC};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
6use crate::time::Hertz; 6use crate::time::Hertz;
7 7
8const HSI: u32 = 16_000_000; 8/// HSI speed
9pub const HSI_FREQ: Hertz = Hertz(16_000_000);
10
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(32_000);
9 13
10/// Clocks configuration 14/// Clocks configuration
11#[non_exhaustive] 15#[non_exhaustive]
@@ -117,7 +121,7 @@ pub(crate) unsafe fn init(config: Config) {
117 } 121 }
118 } 122 }
119 123
120 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI); 124 let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0);
121 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); 125 let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
122 let sysclk_on_pll = sysclk != pllsrcclk; 126 let sysclk_on_pll = sysclk != pllsrcclk;
123 127
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index 36b49c711..6bfae46bd 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -5,10 +5,10 @@ use crate::rcc::{set_freqs, Clocks};
5use crate::time::{Hertz, U32Ext}; 5use crate::time::{Hertz, U32Ext};
6 6
7/// HSI speed 7/// HSI speed
8pub const HSI_FREQ: u32 = 16_000_000; 8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9 9
10/// LSI speed 10/// LSI speed
11pub const LSI_FREQ: u32 = 32_000; 11pub const LSI_FREQ: Hertz = Hertz(32_000);
12 12
13/// System clock mux source 13/// System clock mux source
14#[derive(Clone, Copy)] 14#[derive(Clone, Copy)]
@@ -248,7 +248,7 @@ impl PllConfig {
248 pub(crate) unsafe fn init(self) -> u32 { 248 pub(crate) unsafe fn init(self) -> u32 {
249 assert!(self.n >= 8 && self.n <= 86); 249 assert!(self.n >= 8 && self.n <= 86);
250 let (src, input_freq) = match self.source { 250 let (src, input_freq) = match self.source {
251 PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ), 251 PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ.0),
252 PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq.0), 252 PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq.0),
253 }; 253 };
254 254
@@ -344,7 +344,7 @@ pub(crate) unsafe fn init(config: Config) {
344 }); 344 });
345 while !RCC.cr().read().hsirdy() {} 345 while !RCC.cr().read().hsirdy() {}
346 346
347 (HSI_FREQ >> div.0, Sw::HSI) 347 (HSI_FREQ.0 >> div.0, Sw::HSI)
348 } 348 }
349 ClockSrc::HSE(freq) => { 349 ClockSrc::HSE(freq) => {
350 // Enable HSE 350 // Enable HSE
@@ -361,7 +361,7 @@ pub(crate) unsafe fn init(config: Config) {
361 // Enable LSI 361 // Enable LSI
362 RCC.csr().write(|w| w.set_lsion(true)); 362 RCC.csr().write(|w| w.set_lsion(true));
363 while !RCC.csr().read().lsirdy() {} 363 while !RCC.csr().read().lsirdy() {}
364 (LSI_FREQ, Sw::LSI) 364 (LSI_FREQ.0, Sw::LSI)
365 } 365 }
366 }; 366 };
367 367
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 2b8c2b576..d9c15727b 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -3,10 +3,10 @@ use crate::rcc::{set_freqs, Clocks};
3use crate::time::{Hertz, U32Ext}; 3use crate::time::{Hertz, U32Ext};
4 4
5/// HSI speed 5/// HSI speed
6pub const HSI_FREQ: u32 = 16_000_000; 6pub const HSI_FREQ: Hertz = Hertz(16_000_000);
7 7
8/// LSI speed 8/// LSI speed
9pub const LSI_FREQ: u32 = 32_000; 9pub const LSI_FREQ: Hertz = Hertz(32_000);
10 10
11/// System clock mux source 11/// System clock mux source
12#[derive(Clone, Copy)] 12#[derive(Clone, Copy)]
@@ -96,7 +96,7 @@ pub(crate) unsafe fn init(config: Config) {
96 RCC.cr().write(|w| w.set_hsion(true)); 96 RCC.cr().write(|w| w.set_hsion(true));
97 while !RCC.cr().read().hsirdy() {} 97 while !RCC.cr().read().hsirdy() {}
98 98
99 (HSI_FREQ, 0x01) 99 (HSI_FREQ.0, 0x01)
100 } 100 }
101 ClockSrc::HSE(freq) => { 101 ClockSrc::HSE(freq) => {
102 // Enable HSE 102 // Enable HSE
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs
index 4fa01ade4..6b1014312 100644
--- a/embassy-stm32/src/rcc/h7.rs
+++ b/embassy-stm32/src/rcc/h7.rs
@@ -12,10 +12,17 @@ use crate::rcc::{set_freqs, Clocks};
12use crate::time::Hertz; 12use crate::time::Hertz;
13use crate::{peripherals, Unborrow}; 13use crate::{peripherals, Unborrow};
14 14
15const HSI: Hertz = Hertz(64_000_000); 15/// HSI speed
16const CSI: Hertz = Hertz(4_000_000); 16pub const HSI_FREQ: Hertz = Hertz(64_000_000);
17const HSI48: Hertz = Hertz(48_000_000); 17
18const LSI: Hertz = Hertz(32_000); 18/// CSI speed
19pub const CSI_FREQ: Hertz = Hertz(4_000_000);
20
21/// HSI48 speed
22pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
23
24/// LSI speed
25pub const LSI_FREQ: Hertz = Hertz(32_000);
19 26
20/// Voltage Scale 27/// Voltage Scale
21/// 28///
@@ -461,7 +468,7 @@ pub(crate) unsafe fn init(mut config: Config) {
461 // achieved, but the mechanism for doing so is not yet 468 // achieved, but the mechanism for doing so is not yet
462 // implemented here. 469 // implemented here.
463 470
464 let srcclk = config.hse.unwrap_or(HSI); // Available clocks 471 let srcclk = config.hse.unwrap_or(HSI_FREQ); // Available clocks
465 let (sys_ck, sys_use_pll1_p) = sys_ck_setup(&mut config, srcclk); 472 let (sys_ck, sys_use_pll1_p) = sys_ck_setup(&mut config, srcclk);
466 473
467 // Configure traceclk from PLL if needed 474 // Configure traceclk from PLL if needed
@@ -490,9 +497,9 @@ pub(crate) unsafe fn init(mut config: Config) {
490 497
491 // per_ck from HSI by default 498 // per_ck from HSI by default
492 let (per_ck, ckpersel) = match (config.per_ck == config.hse, config.per_ck) { 499 let (per_ck, ckpersel) = match (config.per_ck == config.hse, config.per_ck) {
493 (true, Some(hse)) => (hse, Ckpersel::HSE), // HSE 500 (true, Some(hse)) => (hse, Ckpersel::HSE), // HSE
494 (_, Some(CSI)) => (CSI, Ckpersel::CSI), // CSI 501 (_, Some(CSI_FREQ)) => (CSI_FREQ, Ckpersel::CSI), // CSI
495 _ => (HSI, Ckpersel::HSI), // HSI 502 _ => (HSI_FREQ, Ckpersel::HSI), // HSI
496 }; 503 };
497 504
498 // D1 Core Prescaler 505 // D1 Core Prescaler
@@ -664,10 +671,10 @@ pub(crate) unsafe fn init(mut config: Config) {
664 ppre2, 671 ppre2,
665 ppre3, 672 ppre3,
666 ppre4, 673 ppre4,
667 csi_ck: Some(CSI), 674 csi_ck: Some(CSI_FREQ),
668 hsi_ck: Some(HSI), 675 hsi_ck: Some(HSI_FREQ),
669 hsi48_ck: Some(HSI48), 676 hsi48_ck: Some(HSI48_FREQ),
670 lsi_ck: Some(LSI), 677 lsi_ck: Some(LSI_FREQ),
671 per_ck: Some(per_ck), 678 per_ck: Some(per_ck),
672 hse_ck, 679 hse_ck,
673 pll1_p_ck: pll1_p_ck.map(Hertz), 680 pll1_p_ck: pll1_p_ck.map(Hertz),
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs
index 2e23833ca..2ca25aa2d 100644
--- a/embassy-stm32/src/rcc/l0.rs
+++ b/embassy-stm32/src/rcc/l0.rs
@@ -5,8 +5,11 @@ use crate::pac::{CRS, SYSCFG};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
6use crate::time::{Hertz, U32Ext}; 6use crate::time::{Hertz, U32Ext};
7 7
8/// HSI16 speed 8/// HSI speed
9pub const HSI16_FREQ: u32 = 16_000_000; 9pub const HSI_FREQ: Hertz = Hertz(16_000_000);
10
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(32_000);
10 13
11/// System clock mux source 14/// System clock mux source
12#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
@@ -217,7 +220,7 @@ pub(crate) unsafe fn init(config: Config) {
217 RCC.cr().write(|w| w.set_hsi16on(true)); 220 RCC.cr().write(|w| w.set_hsi16on(true));
218 while !RCC.cr().read().hsi16rdyf() {} 221 while !RCC.cr().read().hsi16rdyf() {}
219 222
220 (HSI16_FREQ, Sw::HSI16) 223 (HSI_FREQ.0, Sw::HSI16)
221 } 224 }
222 ClockSrc::HSE(freq) => { 225 ClockSrc::HSE(freq) => {
223 // Enable HSE 226 // Enable HSE
@@ -238,7 +241,7 @@ pub(crate) unsafe fn init(config: Config) {
238 // Enable HSI 241 // Enable HSI
239 RCC.cr().write(|w| w.set_hsi16on(true)); 242 RCC.cr().write(|w| w.set_hsi16on(true));
240 while !RCC.cr().read().hsi16rdyf() {} 243 while !RCC.cr().read().hsi16rdyf() {}
241 HSI16_FREQ 244 HSI_FREQ.0
242 } 245 }
243 }; 246 };
244 247
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs
index 80290632e..8c315f293 100644
--- a/embassy-stm32/src/rcc/l1.rs
+++ b/embassy-stm32/src/rcc/l1.rs
@@ -4,7 +4,10 @@ use crate::rcc::{set_freqs, Clocks};
4use crate::time::{Hertz, U32Ext}; 4use crate::time::{Hertz, U32Ext};
5 5
6/// HSI speed 6/// HSI speed
7pub const HSI_FREQ: u32 = 16_000_000; 7pub const HSI_FREQ: Hertz = Hertz(16_000_000);
8
9/// LSI speed
10pub const LSI_FREQ: Hertz = Hertz(32_000);
8 11
9/// System clock mux source 12/// System clock mux source
10#[derive(Clone, Copy)] 13#[derive(Clone, Copy)]
@@ -211,7 +214,7 @@ pub(crate) unsafe fn init(config: Config) {
211 RCC.cr().write(|w| w.set_hsion(true)); 214 RCC.cr().write(|w| w.set_hsion(true));
212 while !RCC.cr().read().hsirdy() {} 215 while !RCC.cr().read().hsirdy() {}
213 216
214 (HSI_FREQ, Sw::HSI) 217 (HSI_FREQ.0, Sw::HSI)
215 } 218 }
216 ClockSrc::HSE(freq) => { 219 ClockSrc::HSE(freq) => {
217 // Enable HSE 220 // Enable HSE
@@ -232,7 +235,7 @@ pub(crate) unsafe fn init(config: Config) {
232 // Enable HSI 235 // Enable HSI
233 RCC.cr().write(|w| w.set_hsion(true)); 236 RCC.cr().write(|w| w.set_hsion(true));
234 while !RCC.cr().read().hsirdy() {} 237 while !RCC.cr().read().hsirdy() {}
235 HSI_FREQ 238 HSI_FREQ.0
236 } 239 }
237 }; 240 };
238 241
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 71a938550..fedfb0edc 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -3,8 +3,11 @@ use crate::pac::{FLASH, RCC};
3use crate::rcc::{set_freqs, Clocks}; 3use crate::rcc::{set_freqs, Clocks};
4use crate::time::{Hertz, U32Ext}; 4use crate::time::{Hertz, U32Ext};
5 5
6/// HSI16 speed 6/// HSI speed
7pub const HSI16_FREQ: u32 = 16_000_000; 7pub const HSI_FREQ: Hertz = Hertz(16_000_000);
8
9/// LSI speed
10pub const LSI_FREQ: Hertz = Hertz(32_000);
8 11
9/// System clock mux source 12/// System clock mux source
10#[derive(Clone, Copy)] 13#[derive(Clone, Copy)]
@@ -321,7 +324,7 @@ pub(crate) unsafe fn init(config: Config) {
321 RCC.cr().write(|w| w.set_hsion(true)); 324 RCC.cr().write(|w| w.set_hsion(true));
322 while !RCC.cr().read().hsirdy() {} 325 while !RCC.cr().read().hsirdy() {}
323 326
324 (HSI16_FREQ, Sw::HSI16) 327 (HSI_FREQ.0, Sw::HSI16)
325 } 328 }
326 ClockSrc::HSE(freq) => { 329 ClockSrc::HSE(freq) => {
327 // Enable HSE 330 // Enable HSE
@@ -342,7 +345,7 @@ pub(crate) unsafe fn init(config: Config) {
342 // Enable HSI 345 // Enable HSI
343 RCC.cr().write(|w| w.set_hsion(true)); 346 RCC.cr().write(|w| w.set_hsion(true));
344 while !RCC.cr().read().hsirdy() {} 347 while !RCC.cr().read().hsirdy() {}
345 HSI16_FREQ 348 HSI_FREQ.0
346 } 349 }
347 PLLSource::MSI(range) => { 350 PLLSource::MSI(range) => {
348 // Enable MSI 351 // Enable MSI
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs
index 60e1dadea..edcdafe08 100644
--- a/embassy-stm32/src/rcc/l5.rs
+++ b/embassy-stm32/src/rcc/l5.rs
@@ -5,8 +5,11 @@ use crate::pac::{FLASH, RCC};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
6use crate::time::{Hertz, U32Ext}; 6use crate::time::{Hertz, U32Ext};
7 7
8/// HSI16 speed 8/// HSI speed
9pub const HSI16_FREQ: u32 = 16_000_000; 9pub const HSI_FREQ: Hertz = Hertz(16_000_000);
10
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(32_000);
10 13
11/// System clock mux source 14/// System clock mux source
12#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
@@ -322,7 +325,7 @@ pub(crate) unsafe fn init(config: Config) {
322 RCC.cr().write(|w| w.set_hsion(true)); 325 RCC.cr().write(|w| w.set_hsion(true));
323 while !RCC.cr().read().hsirdy() {} 326 while !RCC.cr().read().hsirdy() {}
324 327
325 (HSI16_FREQ, Sw::HSI16) 328 (HSI_FREQ.0, Sw::HSI16)
326 } 329 }
327 ClockSrc::HSE(freq) => { 330 ClockSrc::HSE(freq) => {
328 // Enable HSE 331 // Enable HSE
@@ -343,7 +346,7 @@ pub(crate) unsafe fn init(config: Config) {
343 // Enable HSI 346 // Enable HSI
344 RCC.cr().write(|w| w.set_hsion(true)); 347 RCC.cr().write(|w| w.set_hsion(true));
345 while !RCC.cr().read().hsirdy() {} 348 while !RCC.cr().read().hsirdy() {}
346 HSI16_FREQ 349 HSI_FREQ.0
347 } 350 }
348 PLLSource::MSI(range) => { 351 PLLSource::MSI(range) => {
349 // Enable MSI 352 // Enable MSI
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index f09e467c6..701eeb893 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -4,8 +4,11 @@ use crate::pac::{FLASH, RCC};
4use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
5use crate::time::{Hertz, U32Ext}; 5use crate::time::{Hertz, U32Ext};
6 6
7/// HSI16 speed 7/// HSI speed
8pub const HSI16_FREQ: u32 = 16_000_000; 8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(32_000);
9 12
10/// Voltage Scale 13/// Voltage Scale
11/// 14///
@@ -333,13 +336,13 @@ pub(crate) unsafe fn init(config: Config) {
333 RCC.cr().write(|w| w.set_hsion(true)); 336 RCC.cr().write(|w| w.set_hsion(true));
334 while !RCC.cr().read().hsirdy() {} 337 while !RCC.cr().read().hsirdy() {}
335 338
336 HSI16_FREQ 339 HSI_FREQ.0
337 } 340 }
338 ClockSrc::PLL1R(src, m, n, div) => { 341 ClockSrc::PLL1R(src, m, n, div) => {
339 let freq = match src { 342 let freq = match src {
340 PllSrc::MSI(_) => MSIRange::default().into(), 343 PllSrc::MSI(_) => MSIRange::default().into(),
341 PllSrc::HSE(hertz) => hertz.0, 344 PllSrc::HSE(hertz) => hertz.0,
342 PllSrc::HSI16 => HSI16_FREQ, 345 PllSrc::HSI16 => HSI_FREQ.0,
343 }; 346 };
344 347
345 // disable 348 // disable
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index d950e28f8..aec74c4b0 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -8,7 +8,10 @@ use crate::time::{Hertz, U32Ext};
8/// Only the basic setup using the HSE and HSI clocks are supported as of now. 8/// Only the basic setup using the HSE and HSI clocks are supported as of now.
9 9
10/// HSI speed 10/// HSI speed
11pub const HSI_FREQ: u32 = 16_000_000; 11pub const HSI_FREQ: Hertz = Hertz(16_000_000);
12
13/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(32_000);
12 15
13/// System clock mux source 16/// System clock mux source
14#[derive(Clone, Copy)] 17#[derive(Clone, Copy)]
@@ -106,7 +109,7 @@ pub(crate) unsafe fn init(config: Config) {
106 RCC.cr().write(|w| w.set_hsion(true)); 109 RCC.cr().write(|w| w.set_hsion(true));
107 while !RCC.cr().read().hsirdy() {} 110 while !RCC.cr().read().hsirdy() {}
108 111
109 (HSI_FREQ, 0x01) 112 (HSI_FREQ.0, 0x01)
110 } 113 }
111 ClockSrc::HSE(freq) => { 114 ClockSrc::HSE(freq) => {
112 // Enable HSE 115 // Enable HSE
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs
index 1f2fbaf87..33ecaa361 100644
--- a/embassy-stm32/src/rcc/wl.rs
+++ b/embassy-stm32/src/rcc/wl.rs
@@ -1,6 +1,6 @@
1use crate::pac::{FLASH, RCC}; 1use crate::pac::{FLASH, RCC};
2use crate::rcc::{set_freqs, Clocks}; 2use crate::rcc::{set_freqs, Clocks};
3use crate::time::U32Ext; 3use crate::time::{Hertz, U32Ext};
4 4
5/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, 5/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
6/// and with the addition of the init function to configure a system clock. 6/// and with the addition of the init function to configure a system clock.
@@ -8,9 +8,13 @@ use crate::time::U32Ext;
8/// Only the basic setup using the HSE and HSI clocks are supported as of now. 8/// Only the basic setup using the HSE and HSI clocks are supported as of now.
9 9
10/// HSI speed 10/// HSI speed
11pub const HSI_FREQ: u32 = 16_000_000; 11pub const HSI_FREQ: Hertz = Hertz(16_000_000);
12 12
13pub const HSE32_FREQ: u32 = 32_000_000; 13/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(32_000);
15
16/// HSE32 speed
17pub const HSE32_FREQ: Hertz = Hertz(32_000_000);
14 18
15/// System clock mux source 19/// System clock mux source
16#[derive(Clone, Copy)] 20#[derive(Clone, Copy)]
@@ -203,7 +207,7 @@ pub(crate) unsafe fn init(config: Config) {
203 RCC.cr().write(|w| w.set_hsion(true)); 207 RCC.cr().write(|w| w.set_hsion(true));
204 while !RCC.cr().read().hsirdy() {} 208 while !RCC.cr().read().hsirdy() {}
205 209
206 (HSI_FREQ, 0x01, VoltageScale::Range2) 210 (HSI_FREQ.0, 0x01, VoltageScale::Range2)
207 } 211 }
208 ClockSrc::HSE32 => { 212 ClockSrc::HSE32 => {
209 // Enable HSE32 213 // Enable HSE32
@@ -213,7 +217,7 @@ pub(crate) unsafe fn init(config: Config) {
213 }); 217 });
214 while !RCC.cr().read().hserdy() {} 218 while !RCC.cr().read().hserdy() {}
215 219
216 (HSE32_FREQ, 0x02, VoltageScale::Range1) 220 (HSE32_FREQ.0, 0x02, VoltageScale::Range1)
217 } 221 }
218 ClockSrc::MSI(range) => { 222 ClockSrc::MSI(range) => {
219 RCC.cr().write(|w| { 223 RCC.cr().write(|w| {
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index da25692ab..c4b2609b1 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -1,21 +1,57 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::{unborrow, Unborrow}; 3use embassy_hal_common::{unborrow, Unborrow};
4use stm32_metapac::iwdg::vals::Key; 4use stm32_metapac::iwdg::vals::{Key, Pr};
5pub use stm32_metapac::iwdg::vals::Pr as Prescaler; 5
6use crate::rcc::LSI_FREQ;
6 7
7pub struct IndependentWatchdog<'d, T: Instance> { 8pub struct IndependentWatchdog<'d, T: Instance> {
8 wdg: PhantomData<&'d mut T>, 9 wdg: PhantomData<&'d mut T>,
9} 10}
10 11
12// 12-bit counter
13const MAX_RL: u16 = 0xFFF;
14
15/// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler
16const fn max_timeout(prescaler: u8) -> u32 {
17 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32)
18}
19
20/// Calculates watchdog reload value for the given prescaler and desired timeout
21const fn reload_value(prescaler: u8, timeout_us: u32) -> u16 {
22 (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16
23}
24
11impl<'d, T: Instance> IndependentWatchdog<'d, T> { 25impl<'d, T: Instance> IndependentWatchdog<'d, T> {
12 pub fn new(_instance: impl Unborrow<Target = T> + 'd, presc: Prescaler) -> Self { 26 /// Creates an IWDG (Independent Watchdog) instance with a given timeout value in microseconds.
27 ///
28 /// [Self] has to be started with [Self::unleash()].
29 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval.
30 pub fn new(_instance: impl Unborrow<Target = T> + 'd, timeout_us: u32) -> Self {
13 unborrow!(_instance); 31 unborrow!(_instance);
14 32
33 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
34 // This iterates from 4 (2^2) to 256 (2^8).
35 let psc_power = unwrap!((2..=8).find(|psc_power| {
36 let psc = 2u8.pow(*psc_power);
37 timeout_us <= max_timeout(psc)
38 }));
39
40 // Prescaler value
41 let psc = 2u8.pow(psc_power);
42
43 // Convert prescaler power to PR register value
44 let pr = psc_power as u8 - 2;
45 assert!(pr <= 0b110);
46
47 // Reload value
48 let rl = reload_value(psc, timeout_us);
49
15 let wdg = T::regs(); 50 let wdg = T::regs();
16 unsafe { 51 unsafe {
17 wdg.kr().write(|w| w.set_key(Key::ENABLE)); 52 wdg.kr().write(|w| w.set_key(Key::ENABLE));
18 wdg.pr().write(|w| w.set_pr(presc)); 53 wdg.pr().write(|w| w.set_pr(Pr(pr)));
54 wdg.rlr().write(|w| w.set_rl(rl));
19 } 55 }
20 56
21 IndependentWatchdog { 57 IndependentWatchdog {
diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs
new file mode 100644
index 000000000..bfc487c31
--- /dev/null
+++ b/examples/stm32f4/src/bin/wdt.rs
@@ -0,0 +1,46 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy::executor::Spawner;
7use embassy::time::{Duration, Timer};
8use embassy_stm32::gpio::{Level, Output, Speed};
9use embassy_stm32::wdg::IndependentWatchdog;
10use embassy_stm32::Peripherals;
11use {defmt_rtt as _, panic_probe as _};
12
13#[embassy::main]
14async fn main(_spawner: Spawner, p: Peripherals) {
15 info!("Hello World!");
16
17 let mut led = Output::new(p.PB7, Level::High, Speed::Low);
18
19 let mut wdt = IndependentWatchdog::new(p.IWDG, 1_000_000);
20 unsafe {
21 wdt.unleash();
22 }
23
24 let mut i = 0;
25
26 loop {
27 info!("high");
28 led.set_high();
29 Timer::after(Duration::from_millis(300)).await;
30
31 info!("low");
32 led.set_low();
33 Timer::after(Duration::from_millis(300)).await;
34
35 // Pet watchdog for 5 iterations and then stop.
36 // MCU should restart in 1 second after the last pet.
37 if i < 5 {
38 info!("Petting watchdog");
39 unsafe {
40 wdt.pet();
41 }
42 }
43
44 i += 1;
45 }
46}
diff --git a/stm32-data b/stm32-data
Subproject 56d5b8b2aee7026b4f9bcffc427bb8f9d48afeb Subproject b90d7cf8cb0610e333e4eef7127ae8c51955860