aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-10-11 01:08:01 +0200
committerDario Nieuwenhuis <[email protected]>2023-10-11 01:22:27 +0200
commit21915a9a3fed5390c9f505fff29f49ee32d55e78 (patch)
tree26c8cb8e04229a9012bfe21c76a5910fe5972ba9
parentd0d0ceec6acc0bae8a16f0ebdffaf24b40a018cd (diff)
stm32/rcc: unify L0 and L1.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/bd.rs2
-rw-r--r--embassy-stm32/src/rcc/l0l1.rs (renamed from embassy-stm32/src/rcc/l0.rs)28
-rw-r--r--embassy-stm32/src/rcc/l1.rs198
-rw-r--r--embassy-stm32/src/rcc/mod.rs3
-rw-r--r--tests/stm32/src/common.rs2
6 files changed, 17 insertions, 220 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index b6641d71d..6137e3c02 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -59,7 +59,7 @@ sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" }
63vcell = "0.1.3" 63vcell = "0.1.3"
64bxcan = "0.7.0" 64bxcan = "0.7.0"
65nb = "1.0.0" 65nb = "1.0.0"
@@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] }
77[build-dependencies] 77[build-dependencies]
78proc-macro2 = "1.0.36" 78proc-macro2 = "1.0.36"
79quote = "1.0.15" 79quote = "1.0.15"
80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d", default-features = false, features = ["metadata"]} 80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]}
81 81
82 82
83[features] 83[features]
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index 9c784c3a3..c18e92bc8 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -163,7 +163,7 @@ impl BackupDomain {
163 } 163 }
164 164
165 // If not OK, reset backup domain and configure it. 165 // If not OK, reset backup domain and configure it.
166 #[cfg(not(any(rcc_l0, rcc_l1)))] 166 #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))]
167 { 167 {
168 Self::modify(|w| w.set_bdrst(true)); 168 Self::modify(|w| w.set_bdrst(true));
169 Self::modify(|w| w.set_bdrst(false)); 169 Self::modify(|w| w.set_bdrst(false));
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0l1.rs
index 3fd8074d7..4b1acae5d 100644
--- a/embassy-stm32/src/rcc/l0.rs
+++ b/embassy-stm32/src/rcc/l0l1.rs
@@ -95,7 +95,7 @@ pub(crate) unsafe fn init(config: Config) {
95 ClockSrc::HSI16 => { 95 ClockSrc::HSI16 => {
96 // Enable HSI16 96 // Enable HSI16
97 RCC.cr().write(|w| w.set_hsi16on(true)); 97 RCC.cr().write(|w| w.set_hsi16on(true));
98 while !RCC.cr().read().hsi16rdyf() {} 98 while !RCC.cr().read().hsi16rdy() {}
99 99
100 (HSI_FREQ, Sw::HSI16) 100 (HSI_FREQ, Sw::HSI16)
101 } 101 }
@@ -117,7 +117,7 @@ pub(crate) unsafe fn init(config: Config) {
117 PLLSource::HSI16 => { 117 PLLSource::HSI16 => {
118 // Enable HSI 118 // Enable HSI
119 RCC.cr().write(|w| w.set_hsi16on(true)); 119 RCC.cr().write(|w| w.set_hsi16on(true));
120 while !RCC.cr().read().hsi16rdyf() {} 120 while !RCC.cr().read().hsi16rdy() {}
121 HSI_FREQ 121 HSI_FREQ
122 } 122 }
123 }; 123 };
@@ -150,21 +150,17 @@ pub(crate) unsafe fn init(config: Config) {
150 config.lse.map(|_| Default::default()), 150 config.lse.map(|_| Default::default()),
151 ); 151 );
152 152
153 let wait_states = match config.voltage_scale { 153 let wait_states = match (config.voltage_scale, sys_clk.0) {
154 VoltageScale::RANGE1 => match sys_clk.0 { 154 (VoltageScale::RANGE1, ..=16_000_000) => 0,
155 ..=16_000_000 => 0, 155 (VoltageScale::RANGE2, ..=8_000_000) => 0,
156 _ => 1, 156 (VoltageScale::RANGE3, ..=4_200_000) => 0,
157 }, 157 _ => 1,
158 VoltageScale::RANGE2 => match sys_clk.0 {
159 ..=8_000_000 => 0,
160 _ => 1,
161 },
162 VoltageScale::RANGE3 => 0,
163 _ => unreachable!(),
164 }; 158 };
165 FLASH.acr().modify(|w| { 159
166 w.set_latency(wait_states != 0); 160 #[cfg(stm32l1)]
167 }); 161 FLASH.acr().write(|w| w.set_acc64(true));
162 FLASH.acr().modify(|w| w.set_prften(true));
163 FLASH.acr().modify(|w| w.set_latency(wait_states != 0));
168 164
169 RCC.cfgr().modify(|w| { 165 RCC.cfgr().modify(|w| {
170 w.set_sw(sw); 166 w.set_sw(sw);
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs
deleted file mode 100644
index 7c75b888d..000000000
--- a/embassy-stm32/src/rcc/l1.rs
+++ /dev/null
@@ -1,198 +0,0 @@
1pub use crate::pac::rcc::vals::{
2 Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler,
3};
4use crate::pac::rcc::vals::{Pllsrc, Sw};
5use crate::pac::{FLASH, RCC};
6use crate::rcc::{set_freqs, Clocks};
7use crate::time::Hertz;
8
9/// HSI speed
10pub const HSI_FREQ: Hertz = Hertz(16_000_000);
11
12/// LSI speed
13pub const LSI_FREQ: Hertz = Hertz(32_000);
14
15/// System clock mux source
16#[derive(Clone, Copy)]
17pub enum ClockSrc {
18 MSI(MSIRange),
19 PLL(PLLSource, PLLMul, PLLDiv),
20 HSE(Hertz),
21 HSI,
22}
23
24/// PLL clock input source
25#[derive(Clone, Copy)]
26pub enum PLLSource {
27 HSI,
28 HSE(Hertz),
29}
30
31impl From<PLLSource> for Pllsrc {
32 fn from(val: PLLSource) -> Pllsrc {
33 match val {
34 PLLSource::HSI => Pllsrc::HSI,
35 PLLSource::HSE(_) => Pllsrc::HSE,
36 }
37 }
38}
39
40/// Clocks configutation
41pub struct Config {
42 pub mux: ClockSrc,
43 pub ahb_pre: AHBPrescaler,
44 pub apb1_pre: APBPrescaler,
45 pub apb2_pre: APBPrescaler,
46}
47
48impl Default for Config {
49 #[inline]
50 fn default() -> Config {
51 Config {
52 mux: ClockSrc::MSI(MSIRange::RANGE5),
53 ahb_pre: AHBPrescaler::DIV1,
54 apb1_pre: APBPrescaler::DIV1,
55 apb2_pre: APBPrescaler::DIV1,
56 }
57 }
58}
59
60pub(crate) unsafe fn init(config: Config) {
61 let (sys_clk, sw) = match config.mux {
62 ClockSrc::MSI(range) => {
63 // Set MSI range
64 RCC.icscr().write(|w| w.set_msirange(range));
65
66 // Enable MSI
67 RCC.cr().write(|w| w.set_msion(true));
68 while !RCC.cr().read().msirdy() {}
69
70 let freq = 32_768 * (1 << (range as u8 + 1));
71 (Hertz(freq), Sw::MSI)
72 }
73 ClockSrc::HSI => {
74 // Enable HSI
75 RCC.cr().write(|w| w.set_hsion(true));
76 while !RCC.cr().read().hsirdy() {}
77
78 (HSI_FREQ, Sw::HSI)
79 }
80 ClockSrc::HSE(freq) => {
81 // Enable HSE
82 RCC.cr().write(|w| w.set_hseon(true));
83 while !RCC.cr().read().hserdy() {}
84
85 (freq, Sw::HSE)
86 }
87 ClockSrc::PLL(src, mul, div) => {
88 let freq = match src {
89 PLLSource::HSE(freq) => {
90 // Enable HSE
91 RCC.cr().write(|w| w.set_hseon(true));
92 while !RCC.cr().read().hserdy() {}
93 freq
94 }
95 PLLSource::HSI => {
96 // Enable HSI
97 RCC.cr().write(|w| w.set_hsion(true));
98 while !RCC.cr().read().hsirdy() {}
99 HSI_FREQ
100 }
101 };
102
103 // Disable PLL
104 RCC.cr().modify(|w| w.set_pllon(false));
105 while RCC.cr().read().pllrdy() {}
106
107 let freq = freq * mul / div;
108
109 assert!(freq <= Hertz(32_000_000));
110
111 RCC.cfgr().write(move |w| {
112 w.set_pllmul(mul);
113 w.set_plldiv(div);
114 w.set_pllsrc(src.into());
115 });
116
117 // Enable PLL
118 RCC.cr().modify(|w| w.set_pllon(true));
119 while !RCC.cr().read().pllrdy() {}
120
121 (freq, Sw::PLL)
122 }
123 };
124
125 // Set flash 64-bit access, prefetch and wait states
126 if sys_clk >= Hertz(16_000_000) {
127 FLASH.acr().write(|w| w.set_acc64(true));
128 FLASH.acr().modify(|w| w.set_prften(true));
129 FLASH.acr().modify(|w| w.set_latency(true));
130 }
131
132 RCC.cfgr().modify(|w| {
133 w.set_sw(sw);
134 w.set_hpre(config.ahb_pre);
135 w.set_ppre1(config.apb1_pre);
136 w.set_ppre2(config.apb2_pre);
137 });
138
139 let ahb_freq = sys_clk / config.ahb_pre;
140
141 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
142 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
143 pre => {
144 let freq = ahb_freq / pre;
145 (freq, freq * 2u32)
146 }
147 };
148
149 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
150 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
151 pre => {
152 let freq = ahb_freq / pre;
153 (freq, freq * 2u32)
154 }
155 };
156
157 #[cfg(crs)]
158 if config.enable_hsi48 {
159 // Reset CRS peripheral
160 RCC.apb1rstr().modify(|w| w.set_crsrst(true));
161 RCC.apb1rstr().modify(|w| w.set_crsrst(false));
162
163 // Enable CRS peripheral
164 RCC.apb1enr().modify(|w| w.set_crsen(true));
165
166 // Initialize CRS
167 CRS.cfgr().write(|w|
168
169 // Select LSE as synchronization source
170 w.set_syncsrc(crs::vals::Syncsrc::LSE));
171 CRS.cr().modify(|w| {
172 w.set_autotrimen(true);
173 w.set_cen(true);
174 });
175
176 // Enable VREFINT reference for HSI48 oscillator
177 SYSCFG.cfgr3().modify(|w| {
178 w.set_enref_hsi48(true);
179 w.set_en_vrefint(true);
180 });
181
182 // Select HSI48 as USB clock
183 RCC.ccipr().modify(|w| w.set_hsi48msel(true));
184
185 // Enable dedicated USB clock
186 RCC.crrcr().modify(|w| w.set_hsi48on(true));
187 while !RCC.crrcr().read().hsi48rdy() {}
188 }
189
190 set_freqs(Clocks {
191 sys: sys_clk,
192 ahb1: ahb_freq,
193 apb1: apb1_freq,
194 apb2: apb2_freq,
195 apb1_tim: apb1_tim_freq,
196 apb2_tim: apb2_tim_freq,
197 });
198}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 52dc386b4..3d4de0e6e 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -19,8 +19,7 @@ pub use mco::*;
19#[cfg_attr(rcc_g0, path = "g0.rs")] 19#[cfg_attr(rcc_g0, path = "g0.rs")]
20#[cfg_attr(rcc_g4, path = "g4.rs")] 20#[cfg_attr(rcc_g4, path = "g4.rs")]
21#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] 21#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")]
22#[cfg_attr(rcc_l0, path = "l0.rs")] 22#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
23#[cfg_attr(rcc_l1, path = "l1.rs")]
24#[cfg_attr(rcc_l4, path = "l4.rs")] 23#[cfg_attr(rcc_l4, path = "l4.rs")]
25#[cfg_attr(rcc_l5, path = "l5.rs")] 24#[cfg_attr(rcc_l5, path = "l5.rs")]
26#[cfg_attr(rcc_u5, path = "u5.rs")] 25#[cfg_attr(rcc_u5, path = "u5.rs")]
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index f2ba5f7fc..2bf500798 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -332,7 +332,7 @@ pub fn config() -> Config {
332 use embassy_stm32::rcc::*; 332 use embassy_stm32::rcc::*;
333 config.rcc.mux = ClockSrc::PLL( 333 config.rcc.mux = ClockSrc::PLL(
334 // 32Mhz clock (16 * 4 / 2) 334 // 32Mhz clock (16 * 4 / 2)
335 PLLSource::HSI, 335 PLLSource::HSI16,
336 PLLMul::MUL4, 336 PLLMul::MUL4,
337 PLLDiv::DIV2, 337 PLLDiv::DIV2,
338 ); 338 );