aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/rcc/l4.rs379
-rw-r--r--examples/stm32l4/src/bin/rng.rs20
-rw-r--r--examples/stm32l4/src/bin/rtc.rs28
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs19
-rw-r--r--examples/stm32l4/src/bin/usb_serial.rs11
-rw-r--r--tests/stm32/src/common.rs20
6 files changed, 279 insertions, 198 deletions
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 1e5733d31..020f4e200 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -1,9 +1,8 @@
1use crate::pac::rcc::regs::Cfgr; 1use crate::pac::rcc::regs::Cfgr;
2pub use crate::pac::rcc::vals::{ 2pub use crate::pac::rcc::vals::{
3 Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, 3 Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
4 Pllr as PllRDiv, Ppre as APBPrescaler, 4 Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
5}; 5};
6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
7use crate::pac::{FLASH, RCC}; 6use crate::pac::{FLASH, RCC};
8use crate::rcc::{set_freqs, Clocks}; 7use crate::rcc::{set_freqs, Clocks};
9use crate::time::Hertz; 8use crate::time::Hertz;
@@ -11,42 +10,47 @@ use crate::time::Hertz;
11/// HSI speed 10/// HSI speed
12pub const HSI_FREQ: Hertz = Hertz(16_000_000); 11pub const HSI_FREQ: Hertz = Hertz(16_000_000);
13 12
14/// System clock mux source
15#[derive(Clone, Copy)] 13#[derive(Clone, Copy)]
16pub enum ClockSrc { 14pub struct Pll {
17 MSI(MSIRange), 15 /// PLL pre-divider (DIVM).
18 PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>), 16 pub prediv: PllPreDiv,
19 HSE(Hertz), 17
20 HSI16, 18 /// PLL multiplication factor.
21} 19 pub mul: PllMul,
22 20
23/// PLL clock input source 21 /// PLL P division factor. If None, PLL P output is disabled.
24#[derive(Clone, Copy)] 22 pub divp: Option<PllPDiv>,
25pub enum PLLSource { 23 /// PLL Q division factor. If None, PLL Q output is disabled.
26 HSI16, 24 pub divq: Option<PllQDiv>,
27 HSE(Hertz), 25 /// PLL R division factor. If None, PLL R output is disabled.
28 MSI(MSIRange), 26 pub divr: Option<PllRDiv>,
29}
30
31impl From<PLLSource> for Pllsrc {
32 fn from(val: PLLSource) -> Pllsrc {
33 match val {
34 PLLSource::HSI16 => Pllsrc::HSI16,
35 PLLSource::HSE(_) => Pllsrc::HSE,
36 PLLSource::MSI(_) => Pllsrc::MSI,
37 }
38 }
39} 27}
40 28
41/// Clocks configutation 29/// Clocks configutation
42pub struct Config { 30pub struct Config {
31 // base clock sources
32 pub msi: Option<MSIRange>,
33 pub hsi16: bool,
34 pub hse: Option<Hertz>,
35 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
36 pub hsi48: bool,
37
38 // pll
39 pub pll_src: PLLSource,
40 pub pll: Option<Pll>,
41 pub pllsai1: Option<Pll>,
42 #[cfg(any(
43 stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
44 ))]
45 pub pllsai2: Option<Pll>,
46
47 // sysclk, buses.
43 pub mux: ClockSrc, 48 pub mux: ClockSrc,
44 pub ahb_pre: AHBPrescaler, 49 pub ahb_pre: AHBPrescaler,
45 pub apb1_pre: APBPrescaler, 50 pub apb1_pre: APBPrescaler,
46 pub apb2_pre: APBPrescaler, 51 pub apb2_pre: APBPrescaler,
47 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>, 52
48 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 53 // low speed LSI/LSE/RTC
49 pub hsi48: bool,
50 pub ls: super::LsConfig, 54 pub ls: super::LsConfig,
51} 55}
52 56
@@ -54,11 +58,20 @@ impl Default for Config {
54 #[inline] 58 #[inline]
55 fn default() -> Config { 59 fn default() -> Config {
56 Config { 60 Config {
57 mux: ClockSrc::MSI(MSIRange::RANGE4M), 61 hse: None,
62 hsi16: false,
63 msi: Some(MSIRange::RANGE4M),
64 mux: ClockSrc::MSI,
58 ahb_pre: AHBPrescaler::DIV1, 65 ahb_pre: AHBPrescaler::DIV1,
59 apb1_pre: APBPrescaler::DIV1, 66 apb1_pre: APBPrescaler::DIV1,
60 apb2_pre: APBPrescaler::DIV1, 67 apb2_pre: APBPrescaler::DIV1,
68 pll_src: PLLSource::NONE,
69 pll: None,
61 pllsai1: None, 70 pllsai1: None,
71 #[cfg(any(
72 stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
73 ))]
74 pllsai2: None,
62 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 75 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
63 hsi48: false, 76 hsi48: false,
64 ls: Default::default(), 77 ls: Default::default(),
@@ -80,154 +93,204 @@ pub(crate) unsafe fn init(config: Config) {
80 // Wait until MSI is running 93 // Wait until MSI is running
81 while !RCC.cr().read().msirdy() {} 94 while !RCC.cr().read().msirdy() {}
82 } 95 }
83 if RCC.cfgr().read().sws() != Sw::MSI { 96 if RCC.cfgr().read().sws() != ClockSrc::MSI {
84 // Set MSI as a clock source, reset prescalers. 97 // Set MSI as a clock source, reset prescalers.
85 RCC.cfgr().write_value(Cfgr::default()); 98 RCC.cfgr().write_value(Cfgr::default());
86 // Wait for clock switch status bits to change. 99 // Wait for clock switch status bits to change.
87 while RCC.cfgr().read().sws() != Sw::MSI {} 100 while RCC.cfgr().read().sws() != ClockSrc::MSI {}
88 } 101 }
89 102
90 let rtc = config.ls.init(); 103 let rtc = config.ls.init();
91 104
92 let (sys_clk, sw) = match config.mux { 105 let msi = config.msi.map(|range| {
93 ClockSrc::MSI(range) => { 106 // Enable MSI
94 // Enable MSI 107 RCC.cr().write(|w| {
95 RCC.cr().write(|w| { 108 w.set_msirange(range);
96 w.set_msirange(range); 109 w.set_msirgsel(true);
97 w.set_msirgsel(true); 110 w.set_msion(true);
98 w.set_msion(true);
99
100 // If LSE is enabled, enable calibration of MSI
101 w.set_msipllen(config.ls.lse.is_some());
102 });
103 while !RCC.cr().read().msirdy() {}
104
105 // Enable as clock source for USB, RNG if running at 48 MHz
106 if range == MSIRange::RANGE48M {
107 RCC.ccipr().modify(|w| {
108 w.set_clk48sel(0b11);
109 });
110 }
111 (msirange_to_hertz(range), Sw::MSI)
112 }
113 ClockSrc::HSI16 => {
114 // Enable HSI16
115 RCC.cr().write(|w| w.set_hsion(true));
116 while !RCC.cr().read().hsirdy() {}
117 111
118 (HSI_FREQ, Sw::HSI16) 112 // If LSE is enabled, enable calibration of MSI
119 } 113 w.set_msipllen(config.ls.lse.is_some());
120 ClockSrc::HSE(freq) => { 114 });
121 // Enable HSE 115 while !RCC.cr().read().msirdy() {}
122 RCC.cr().write(|w| w.set_hseon(true));
123 while !RCC.cr().read().hserdy() {}
124 116
125 (freq, Sw::HSE) 117 // Enable as clock source for USB, RNG if running at 48 MHz
118 if range == MSIRange::RANGE48M {
119 RCC.ccipr().modify(|w| w.set_clk48sel(0b11));
126 } 120 }
127 ClockSrc::PLL(src, divr, prediv, mul, divq) => {
128 let src_freq = match src {
129 PLLSource::HSE(freq) => {
130 // Enable HSE
131 RCC.cr().write(|w| w.set_hseon(true));
132 while !RCC.cr().read().hserdy() {}
133 freq
134 }
135 PLLSource::HSI16 => {
136 // Enable HSI
137 RCC.cr().write(|w| w.set_hsion(true));
138 while !RCC.cr().read().hsirdy() {}
139 HSI_FREQ
140 }
141 PLLSource::MSI(range) => {
142 // Enable MSI
143 RCC.cr().write(|w| {
144 w.set_msirange(range);
145 w.set_msipllen(false); // should be turned on if LSE is started
146 w.set_msirgsel(true);
147 w.set_msion(true);
148 });
149 while !RCC.cr().read().msirdy() {}
150
151 msirange_to_hertz(range)
152 }
153 };
154
155 // Disable PLL
156 RCC.cr().modify(|w| w.set_pllon(false));
157 while RCC.cr().read().pllrdy() {}
158
159 let freq = src_freq / prediv * mul / divr;
160
161 #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
162 assert!(freq.0 <= 120_000_000);
163 #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))]
164 assert!(freq.0 <= 80_000_000);
165
166 RCC.pllcfgr().write(move |w| {
167 w.set_plln(mul);
168 w.set_pllm(prediv);
169 w.set_pllr(divr);
170 if let Some(divq) = divq {
171 w.set_pllq(divq);
172 w.set_pllqen(true);
173 }
174 w.set_pllsrc(src.into());
175 });
176
177 // Enable as clock source for USB, RNG if PLL48 divisor is provided
178 if let Some(divq) = divq {
179 let freq = src_freq / prediv * mul / divq;
180 assert!(freq.0 == 48_000_000);
181 RCC.ccipr().modify(|w| {
182 w.set_clk48sel(0b10);
183 });
184 }
185 121
186 if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { 122 msirange_to_hertz(range)
187 RCC.pllsai1cfgr().write(move |w| { 123 });
188 w.set_plln(mul);
189 w.set_pllm(prediv);
190 if let Some(r_div) = r_div {
191 w.set_pllr(r_div);
192 w.set_pllren(true);
193 }
194 if let Some(q_div) = q_div {
195 w.set_pllq(q_div);
196 w.set_pllqen(true);
197 let freq = src_freq / prediv * mul / q_div;
198 if freq.0 == 48_000_000 {
199 RCC.ccipr().modify(|w| {
200 w.set_clk48sel(0b1);
201 });
202 }
203 }
204 if let Some(p_div) = p_div {
205 w.set_pllp(p_div);
206 w.set_pllpen(true);
207 }
208 });
209
210 RCC.cr().modify(|w| w.set_pllsai1on(true));
211 }
212 124
213 // Enable PLL 125 let hsi16 = config.hsi16.then(|| {
214 RCC.cr().modify(|w| w.set_pllon(true)); 126 RCC.cr().write(|w| w.set_hsion(true));
215 while !RCC.cr().read().pllrdy() {} 127 while !RCC.cr().read().hsirdy() {}
216 RCC.pllcfgr().modify(|w| w.set_pllren(true));
217 128
218 (freq, Sw::PLL) 129 HSI_FREQ
219 } 130 });
220 }; 131
132 let hse = config.hse.map(|freq| {
133 RCC.cr().write(|w| w.set_hseon(true));
134 while !RCC.cr().read().hserdy() {}
135
136 freq
137 });
221 138
222 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 139 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
223 if config.hsi48 { 140 let _hsi48 = config.hsi48.then(|| {
224 RCC.crrcr().modify(|w| w.set_hsi48on(true)); 141 RCC.crrcr().modify(|w| w.set_hsi48on(true));
225 while !RCC.crrcr().read().hsi48rdy() {} 142 while !RCC.crrcr().read().hsi48rdy() {}
226 143
227 // Enable as clock source for USB, RNG and SDMMC 144 // Enable as clock source for USB, RNG and SDMMC
228 RCC.ccipr().modify(|w| w.set_clk48sel(0)); 145 RCC.ccipr().modify(|w| w.set_clk48sel(0));
146
147 Hertz(48_000_000)
148 });
149
150 let pll_src = match config.pll_src {
151 PLLSource::NONE => None,
152 PLLSource::HSE => hse,
153 PLLSource::HSI16 => hsi16,
154 PLLSource::MSI => msi,
155 };
156
157 let mut _pllp = None;
158 let mut _pllq = None;
159 let mut _pllr = None;
160 if let Some(pll) = config.pll {
161 let pll_src = pll_src.unwrap();
162
163 // Disable PLL
164 RCC.cr().modify(|w| w.set_pllon(false));
165 while RCC.cr().read().pllrdy() {}
166
167 let vco_freq = pll_src / pll.prediv * pll.mul;
168
169 _pllp = pll.divp.map(|div| vco_freq / div);
170 _pllq = pll.divq.map(|div| vco_freq / div);
171 _pllr = pll.divr.map(|div| vco_freq / div);
172
173 RCC.pllcfgr().write(move |w| {
174 w.set_plln(pll.mul);
175 w.set_pllm(pll.prediv);
176 w.set_pllsrc(config.pll_src);
177 if let Some(divp) = pll.divp {
178 w.set_pllp(divp);
179 w.set_pllpen(true);
180 }
181 if let Some(divq) = pll.divq {
182 w.set_pllq(divq);
183 w.set_pllqen(true);
184 }
185 if let Some(divr) = pll.divr {
186 w.set_pllr(divr);
187 w.set_pllren(true);
188 }
189 });
190
191 if _pllq == Some(Hertz(48_000_000)) {
192 RCC.ccipr().modify(|w| w.set_clk48sel(0b10));
193 }
194
195 // Enable PLL
196 RCC.cr().modify(|w| w.set_pllon(true));
197 while !RCC.cr().read().pllrdy() {}
198 } else {
199 // even if we're not using the main pll, set the source for pllsai
200 RCC.pllcfgr().write(move |w| {
201 w.set_pllsrc(config.pll_src);
202 });
203 }
204
205 if let Some(pll) = config.pllsai1 {
206 let pll_src = pll_src.unwrap();
207
208 // Disable PLL
209 RCC.cr().modify(|w| w.set_pllsai1on(false));
210 while RCC.cr().read().pllsai1rdy() {}
211
212 let vco_freq = pll_src / pll.prediv * pll.mul;
213
214 let _pllp = pll.divp.map(|div| vco_freq / div);
215 let _pllq = pll.divq.map(|div| vco_freq / div);
216 let _pllr = pll.divr.map(|div| vco_freq / div);
217
218 RCC.pllsai1cfgr().write(move |w| {
219 w.set_plln(pll.mul);
220 w.set_pllm(pll.prediv);
221 if let Some(divp) = pll.divp {
222 w.set_pllp(divp);
223 w.set_pllpen(true);
224 }
225 if let Some(divq) = pll.divq {
226 w.set_pllq(divq);
227 w.set_pllqen(true);
228 }
229 if let Some(divr) = pll.divr {
230 w.set_pllr(divr);
231 w.set_pllren(true);
232 }
233 });
234
235 if _pllq == Some(Hertz(48_000_000)) {
236 RCC.ccipr().modify(|w| w.set_clk48sel(0b01));
237 }
238
239 // Enable PLL
240 RCC.cr().modify(|w| w.set_pllsai1on(true));
241 while !RCC.cr().read().pllsai1rdy() {}
242 }
243
244 #[cfg(any(
245 stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx
246 ))]
247 if let Some(pll) = config.pllsai2 {
248 let pll_src = pll_src.unwrap();
249
250 // Disable PLL
251 RCC.cr().modify(|w| w.set_pllsai2on(false));
252 while RCC.cr().read().pllsai2rdy() {}
253
254 let vco_freq = pll_src / pll.prediv * pll.mul;
255
256 let _pllp = pll.divp.map(|div| vco_freq / div);
257 let _pllq = pll.divq.map(|div| vco_freq / div);
258 let _pllr = pll.divr.map(|div| vco_freq / div);
259
260 RCC.pllsai2cfgr().write(move |w| {
261 w.set_plln(pll.mul);
262 w.set_pllm(pll.prediv);
263 if let Some(divp) = pll.divp {
264 w.set_pllp(divp);
265 w.set_pllpen(true);
266 }
267 if let Some(divq) = pll.divq {
268 w.set_pllq(divq);
269 w.set_pllqen(true);
270 }
271 if let Some(divr) = pll.divr {
272 w.set_pllr(divr);
273 w.set_pllren(true);
274 }
275 });
276
277 // Enable PLL
278 RCC.cr().modify(|w| w.set_pllsai2on(true));
279 while !RCC.cr().read().pllsai2rdy() {}
229 } 280 }
230 281
282 let sys_clk = match config.mux {
283 ClockSrc::HSE => hse.unwrap(),
284 ClockSrc::HSI16 => hsi16.unwrap(),
285 ClockSrc::MSI => msi.unwrap(),
286 ClockSrc::PLL => _pllr.unwrap(),
287 };
288
289 #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
290 assert!(sys_clk.0 <= 120_000_000);
291 #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))]
292 assert!(sys_clk.0 <= 80_000_000);
293
231 // Set flash wait states 294 // Set flash wait states
232 FLASH.acr().modify(|w| { 295 FLASH.acr().modify(|w| {
233 w.set_latency(match sys_clk.0 { 296 w.set_latency(match sys_clk.0 {
@@ -240,7 +303,7 @@ pub(crate) unsafe fn init(config: Config) {
240 }); 303 });
241 304
242 RCC.cfgr().modify(|w| { 305 RCC.cfgr().modify(|w| {
243 w.set_sw(sw); 306 w.set_sw(config.mux);
244 w.set_hpre(config.ahb_pre); 307 w.set_hpre(config.ahb_pre);
245 w.set_ppre1(config.apb1_pre); 308 w.set_ppre1(config.apb1_pre);
246 w.set_ppre2(config.apb2_pre); 309 w.set_ppre2(config.apb2_pre);
@@ -277,7 +340,7 @@ pub(crate) unsafe fn init(config: Config) {
277 }); 340 });
278} 341}
279 342
280fn msirange_to_hertz(range: Msirange) -> Hertz { 343fn msirange_to_hertz(range: MSIRange) -> Hertz {
281 match range { 344 match range {
282 MSIRange::RANGE100K => Hertz(100_000), 345 MSIRange::RANGE100K => Hertz(100_000),
283 MSIRange::RANGE200K => Hertz(200_000), 346 MSIRange::RANGE200K => Hertz(200_000),
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs
index d0208d8a3..94251c12c 100644
--- a/examples/stm32l4/src/bin/rng.rs
+++ b/examples/stm32l4/src/bin/rng.rs
@@ -4,7 +4,7 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; 7use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv};
8use embassy_stm32::rng::Rng; 8use embassy_stm32::rng::Rng;
9use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; 9use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -16,14 +16,16 @@ bind_interrupts!(struct Irqs {
16#[embassy_executor::main] 16#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 17async fn main(_spawner: Spawner) {
18 let mut config = Config::default(); 18 let mut config = Config::default();
19 // 72Mhz clock (16 / 1 * 18 / 4) 19 config.rcc.mux = ClockSrc::PLL;
20 config.rcc.mux = ClockSrc::PLL( 20 config.rcc.hsi16 = true;
21 PLLSource::HSI16, 21 config.rcc.pll_src = PLLSource::HSI16;
22 PllRDiv::DIV4, 22 config.rcc.pll = Some(Pll {
23 PllPreDiv::DIV1, 23 prediv: PllPreDiv::DIV1,
24 PllMul::MUL18, 24 mul: PllMul::MUL18,
25 Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) 25 divp: None,
26 ); 26 divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6)
27 divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4)
28 });
27 let p = embassy_stm32::init(config); 29 let p = embassy_stm32::init(config);
28 30
29 info!("Hello World!"); 31 info!("Hello World!");
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs
index f5d46e95f..cd9f72ff3 100644
--- a/examples/stm32l4/src/bin/rtc.rs
+++ b/examples/stm32l4/src/bin/rtc.rs
@@ -5,7 +5,7 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv}; 8use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv};
9use embassy_stm32::rtc::{Rtc, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::Config; 11use embassy_stm32::Config;
@@ -14,18 +14,20 @@ use {defmt_rtt as _, panic_probe as _};
14 14
15#[embassy_executor::main] 15#[embassy_executor::main]
16async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
17 let p = { 17 let mut config = Config::default();
18 let mut config = Config::default(); 18 config.rcc.mux = ClockSrc::PLL;
19 config.rcc.mux = ClockSrc::PLL( 19 config.rcc.hse = Some(Hertz::mhz(8));
20 PLLSource::HSE(Hertz::mhz(8)), 20 config.rcc.pll_src = PLLSource::HSE;
21 PllRDiv::DIV2, 21 config.rcc.pll = Some(Pll {
22 PllPreDiv::DIV1, 22 prediv: PllPreDiv::DIV1,
23 PllMul::MUL20, 23 mul: PllMul::MUL20,
24 None, 24 divp: None,
25 ); 25 divq: None,
26 config.rcc.ls = LsConfig::default_lse(); 26 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2)
27 embassy_stm32::init(config) 27 });
28 }; 28 config.rcc.ls = LsConfig::default_lse();
29 let p = embassy_stm32::init(config);
30
29 info!("Hello World!"); 31 info!("Hello World!");
30 32
31 let now = NaiveDate::from_ymd_opt(2020, 5, 15) 33 let now = NaiveDate::from_ymd_opt(2020, 5, 15)
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index e2ac22d09..c1a27cf83 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -48,7 +48,7 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110};
48use embedded_hal_bus::spi::ExclusiveDevice; 48use embedded_hal_bus::spi::ExclusiveDevice;
49use hal::gpio::Pull; 49use hal::gpio::Pull;
50use hal::i2c::Config as I2C_Config; 50use hal::i2c::Config as I2C_Config;
51use hal::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; 51use hal::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv};
52use hal::spi::{Config as SPI_Config, Spi}; 52use hal::spi::{Config as SPI_Config, Spi};
53use hal::time::Hertz; 53use hal::time::Hertz;
54 54
@@ -77,13 +77,16 @@ async fn main(spawner: Spawner) {
77 77
78 // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) 78 // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2)
79 // 80MHz highest frequency for flash 0 wait. 79 // 80MHz highest frequency for flash 0 wait.
80 config.rcc.mux = ClockSrc::PLL( 80 config.rcc.mux = ClockSrc::PLL;
81 PLLSource::HSE(Hertz(8_000_000)), 81 config.rcc.hse = Some(Hertz::mhz(8));
82 PllRDiv::DIV2, 82 config.rcc.pll_src = PLLSource::HSE;
83 PllPreDiv::DIV1, 83 config.rcc.pll = Some(Pll {
84 PllMul::MUL20, 84 prediv: PllPreDiv::DIV1,
85 None, 85 mul: PllMul::MUL20,
86 ); 86 divp: None,
87 divq: None,
88 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2)
89 });
87 config.rcc.hsi48 = true; // needed for rng 90 config.rcc.hsi48 = true; // needed for rng
88 91
89 let dp = embassy_stm32::init(config); 92 let dp = embassy_stm32::init(config);
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs
index dc0d98ad4..8f6eeef32 100644
--- a/examples/stm32l4/src/bin/usb_serial.rs
+++ b/examples/stm32l4/src/bin/usb_serial.rs
@@ -23,8 +23,17 @@ async fn main(_spawner: Spawner) {
23 info!("Hello World!"); 23 info!("Hello World!");
24 24
25 let mut config = Config::default(); 25 let mut config = Config::default();
26 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
27 config.rcc.hsi48 = true; 26 config.rcc.hsi48 = true;
27 config.rcc.mux = ClockSrc::PLL;
28 config.rcc.hsi16 = true;
29 config.rcc.pll_src = PLLSource::HSI16;
30 config.rcc.pll = Some(Pll {
31 prediv: PllPreDiv::DIV1,
32 mul: PllMul::MUL10,
33 divp: None,
34 divq: None,
35 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2)
36 });
28 37
29 let p = embassy_stm32::init(config); 38 let p = embassy_stm32::init(config);
30 39
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 2bf500798..e1d7855fc 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -284,17 +284,19 @@ pub fn config() -> Config {
284 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 284 config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
285 } 285 }
286 286
287 #[cfg(any(feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] 287 #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))]
288 { 288 {
289 use embassy_stm32::rcc::*; 289 use embassy_stm32::rcc::*;
290 config.rcc.mux = ClockSrc::PLL( 290 config.rcc.mux = ClockSrc::PLL;
291 // 72Mhz clock (16 / 1 * 18 / 4) 291 config.rcc.hsi16 = true;
292 PLLSource::HSI16, 292 config.rcc.pll_src = PLLSource::HSI16;
293 PllRDiv::DIV4, 293 config.rcc.pll = Some(Pll {
294 PllPreDiv::DIV1, 294 prediv: PllPreDiv::DIV1,
295 PllMul::MUL18, 295 mul: PllMul::MUL18,
296 Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) 296 divp: None,
297 ); 297 divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6)
298 divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4)
299 });
298 } 300 }
299 301
300 #[cfg(any(feature = "stm32l552ze"))] 302 #[cfg(any(feature = "stm32l552ze"))]