aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales <[email protected]>2021-06-24 20:39:51 -0300
committerGitHub <[email protected]>2021-06-24 20:39:51 -0300
commite1880a19df2f91757aa34a21b670da22ccb81440 (patch)
tree6dc183d0885fb65a07e636ee18a5ca60702b056e
parent9e5406f761a5a71e8a634796a60f1148b7d96ec1 (diff)
parent013792b9442b4ef6ca4d6ddc6ee631d4491dbfbd (diff)
Merge pull request #254 from thalesfragoso/f0-rcc
F0 rcc
-rw-r--r--embassy-stm32/Cargo.toml73
-rw-r--r--embassy-stm32/gen.py4
-rw-r--r--embassy-stm32/gen_features.py1
-rw-r--r--embassy-stm32/src/exti/mod.rs111
-rw-r--r--embassy-stm32/src/exti/v1.rs (renamed from embassy-stm32/src/exti.rs)103
-rw-r--r--embassy-stm32/src/exti/v2.rs1
-rw-r--r--embassy-stm32/src/lib.rs6
-rw-r--r--embassy-stm32/src/rcc/f0/mod.rs231
-rw-r--r--embassy-stm32/src/rcc/mod.rs8
m---------stm32-data0
-rw-r--r--stm32-metapac/gen/src/lib.rs1
11 files changed, 427 insertions, 112 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 8163624f3..4e37c94fe 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -45,6 +45,79 @@ net = ["embassy-net", "vcell"]
45 45
46# BEGIN GENERATED FEATURES 46# BEGIN GENERATED FEATURES
47# Generated by gen_features.py. DO NOT EDIT. 47# Generated by gen_features.py. DO NOT EDIT.
48stm32f030c6 = [ "stm32-metapac/stm32f030c6",]
49stm32f030c8 = [ "stm32-metapac/stm32f030c8",]
50stm32f030cc = [ "stm32-metapac/stm32f030cc",]
51stm32f030f4 = [ "stm32-metapac/stm32f030f4",]
52stm32f030k6 = [ "stm32-metapac/stm32f030k6",]
53stm32f030r8 = [ "stm32-metapac/stm32f030r8",]
54stm32f030rc = [ "stm32-metapac/stm32f030rc",]
55stm32f031c4 = [ "stm32-metapac/stm32f031c4",]
56stm32f031c6 = [ "stm32-metapac/stm32f031c6",]
57stm32f031e6 = [ "stm32-metapac/stm32f031e6",]
58stm32f031f4 = [ "stm32-metapac/stm32f031f4",]
59stm32f031f6 = [ "stm32-metapac/stm32f031f6",]
60stm32f031g4 = [ "stm32-metapac/stm32f031g4",]
61stm32f031g6 = [ "stm32-metapac/stm32f031g6",]
62stm32f031k4 = [ "stm32-metapac/stm32f031k4",]
63stm32f031k6 = [ "stm32-metapac/stm32f031k6",]
64stm32f038c6 = [ "stm32-metapac/stm32f038c6",]
65stm32f038e6 = [ "stm32-metapac/stm32f038e6",]
66stm32f038f6 = [ "stm32-metapac/stm32f038f6",]
67stm32f038g6 = [ "stm32-metapac/stm32f038g6",]
68stm32f038k6 = [ "stm32-metapac/stm32f038k6",]
69stm32f042c4 = [ "stm32-metapac/stm32f042c4",]
70stm32f042c6 = [ "stm32-metapac/stm32f042c6",]
71stm32f042f4 = [ "stm32-metapac/stm32f042f4",]
72stm32f042f6 = [ "stm32-metapac/stm32f042f6",]
73stm32f042g4 = [ "stm32-metapac/stm32f042g4",]
74stm32f042g6 = [ "stm32-metapac/stm32f042g6",]
75stm32f042k4 = [ "stm32-metapac/stm32f042k4",]
76stm32f042k6 = [ "stm32-metapac/stm32f042k6",]
77stm32f042t6 = [ "stm32-metapac/stm32f042t6",]
78stm32f048c6 = [ "stm32-metapac/stm32f048c6",]
79stm32f048g6 = [ "stm32-metapac/stm32f048g6",]
80stm32f048t6 = [ "stm32-metapac/stm32f048t6",]
81stm32f051c4 = [ "stm32-metapac/stm32f051c4",]
82stm32f051c6 = [ "stm32-metapac/stm32f051c6",]
83stm32f051c8 = [ "stm32-metapac/stm32f051c8",]
84stm32f051k4 = [ "stm32-metapac/stm32f051k4",]
85stm32f051k6 = [ "stm32-metapac/stm32f051k6",]
86stm32f051k8 = [ "stm32-metapac/stm32f051k8",]
87stm32f051r4 = [ "stm32-metapac/stm32f051r4",]
88stm32f051r6 = [ "stm32-metapac/stm32f051r6",]
89stm32f051r8 = [ "stm32-metapac/stm32f051r8",]
90stm32f051t8 = [ "stm32-metapac/stm32f051t8",]
91stm32f058c8 = [ "stm32-metapac/stm32f058c8",]
92stm32f058r8 = [ "stm32-metapac/stm32f058r8",]
93stm32f058t8 = [ "stm32-metapac/stm32f058t8",]
94stm32f070c6 = [ "stm32-metapac/stm32f070c6",]
95stm32f070cb = [ "stm32-metapac/stm32f070cb",]
96stm32f070f6 = [ "stm32-metapac/stm32f070f6",]
97stm32f070rb = [ "stm32-metapac/stm32f070rb",]
98stm32f071c8 = [ "stm32-metapac/stm32f071c8",]
99stm32f071cb = [ "stm32-metapac/stm32f071cb",]
100stm32f071rb = [ "stm32-metapac/stm32f071rb",]
101stm32f071v8 = [ "stm32-metapac/stm32f071v8",]
102stm32f071vb = [ "stm32-metapac/stm32f071vb",]
103stm32f072c8 = [ "stm32-metapac/stm32f072c8",]
104stm32f072cb = [ "stm32-metapac/stm32f072cb",]
105stm32f072r8 = [ "stm32-metapac/stm32f072r8",]
106stm32f072rb = [ "stm32-metapac/stm32f072rb",]
107stm32f072v8 = [ "stm32-metapac/stm32f072v8",]
108stm32f072vb = [ "stm32-metapac/stm32f072vb",]
109stm32f078cb = [ "stm32-metapac/stm32f078cb",]
110stm32f078rb = [ "stm32-metapac/stm32f078rb",]
111stm32f078vb = [ "stm32-metapac/stm32f078vb",]
112stm32f091cb = [ "stm32-metapac/stm32f091cb",]
113stm32f091cc = [ "stm32-metapac/stm32f091cc",]
114stm32f091rb = [ "stm32-metapac/stm32f091rb",]
115stm32f091rc = [ "stm32-metapac/stm32f091rc",]
116stm32f091vb = [ "stm32-metapac/stm32f091vb",]
117stm32f091vc = [ "stm32-metapac/stm32f091vc",]
118stm32f098cc = [ "stm32-metapac/stm32f098cc",]
119stm32f098rc = [ "stm32-metapac/stm32f098rc",]
120stm32f098vc = [ "stm32-metapac/stm32f098vc",]
48stm32f401cb = [ "stm32-metapac/stm32f401cb",] 121stm32f401cb = [ "stm32-metapac/stm32f401cb",]
49stm32f401cc = [ "stm32-metapac/stm32f401cc",] 122stm32f401cc = [ "stm32-metapac/stm32f401cc",]
50stm32f401cd = [ "stm32-metapac/stm32f401cd",] 123stm32f401cd = [ "stm32-metapac/stm32f401cd",]
diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py
index b9391d309..386c5ce17 100644
--- a/embassy-stm32/gen.py
+++ b/embassy-stm32/gen.py
@@ -33,10 +33,6 @@ if len(c) > 1:
33with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f: 33with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f:
34 chip = yaml.load(f, Loader=SafeLoader) 34 chip = yaml.load(f, Loader=SafeLoader)
35 35
36# ======= load GPIO AF
37with open(f'{data_path}/gpio_af/{chip["gpio_af"]}.yaml', 'r') as f:
38 af = yaml.load(f, Loader=SafeLoader)
39
40# ======= Generate! 36# ======= Generate!
41with open(output_file, 'w') as f: 37with open(output_file, 'w') as f:
42 singletons = [] # USART1, PA5, EXTI8 38 singletons = [] # USART1, PA5, EXTI8
diff --git a/embassy-stm32/gen_features.py b/embassy-stm32/gen_features.py
index 10dfd7884..4eb57e2a3 100644
--- a/embassy-stm32/gen_features.py
+++ b/embassy-stm32/gen_features.py
@@ -13,6 +13,7 @@ dname = os.path.dirname(abspath)
13os.chdir(dname) 13os.chdir(dname)
14 14
15supported_families = [ 15supported_families = [
16 "STM32F0",
16 'STM32F4', 17 'STM32F4',
17 'STM32L0', 18 'STM32L0',
18 'STM32L4', 19 'STM32L4',
diff --git a/embassy-stm32/src/exti/mod.rs b/embassy-stm32/src/exti/mod.rs
new file mode 100644
index 000000000..126a6fb64
--- /dev/null
+++ b/embassy-stm32/src/exti/mod.rs
@@ -0,0 +1,111 @@
1#![macro_use]
2
3macro_rules! foreach_exti_irq {
4 ($action:ident) => {
5 crate::pac::interrupts!(
6 (EXTI0) => { $action!(EXTI0); };
7 (EXTI1) => { $action!(EXTI1); };
8 (EXTI2) => { $action!(EXTI2); };
9 (EXTI3) => { $action!(EXTI3); };
10 (EXTI4) => { $action!(EXTI4); };
11 (EXTI5) => { $action!(EXTI5); };
12 (EXTI6) => { $action!(EXTI6); };
13 (EXTI7) => { $action!(EXTI7); };
14 (EXTI8) => { $action!(EXTI8); };
15 (EXTI9) => { $action!(EXTI9); };
16 (EXTI10) => { $action!(EXTI10); };
17 (EXTI11) => { $action!(EXTI11); };
18 (EXTI12) => { $action!(EXTI12); };
19 (EXTI13) => { $action!(EXTI13); };
20 (EXTI14) => { $action!(EXTI14); };
21 (EXTI15) => { $action!(EXTI15); };
22
23 // plus the weird ones
24 (EXTI0_1) => { $action!( EXTI0_1 ); };
25 (EXTI15_10) => { $action!(EXTI15_10); };
26 (EXTI15_4) => { $action!(EXTI15_4); };
27 (EXTI1_0) => { $action!(EXTI1_0); };
28 (EXTI2_3) => { $action!(EXTI2_3); };
29 (EXTI2_TSC) => { $action!(EXTI2_TSC); };
30 (EXTI3_2) => { $action!(EXTI3_2); };
31 (EXTI4_15) => { $action!(EXTI4_15); };
32 (EXTI9_5) => { $action!(EXTI9_5); };
33 );
34 };
35}
36
37#[cfg_attr(exti_v1, path = "v1.rs")]
38#[cfg_attr(exti_wb55, path = "v2.rs")]
39mod _version;
40
41#[allow(unused)]
42pub use _version::*;
43
44use crate::peripherals;
45use embassy_extras::unsafe_impl_unborrow;
46
47pub(crate) mod sealed {
48 pub trait Channel {}
49}
50
51pub trait Channel: sealed::Channel + Sized {
52 fn number(&self) -> usize;
53 fn degrade(self) -> AnyChannel {
54 AnyChannel {
55 number: self.number() as u8,
56 }
57 }
58}
59
60pub struct AnyChannel {
61 number: u8,
62}
63unsafe_impl_unborrow!(AnyChannel);
64impl sealed::Channel for AnyChannel {}
65impl Channel for AnyChannel {
66 fn number(&self) -> usize {
67 self.number as usize
68 }
69}
70
71macro_rules! impl_exti {
72 ($type:ident, $number:expr) => {
73 impl sealed::Channel for peripherals::$type {}
74 impl Channel for peripherals::$type {
75 fn number(&self) -> usize {
76 $number as usize
77 }
78 }
79 };
80}
81
82impl_exti!(EXTI0, 0);
83impl_exti!(EXTI1, 1);
84impl_exti!(EXTI2, 2);
85impl_exti!(EXTI3, 3);
86impl_exti!(EXTI4, 4);
87impl_exti!(EXTI5, 5);
88impl_exti!(EXTI6, 6);
89impl_exti!(EXTI7, 7);
90impl_exti!(EXTI8, 8);
91impl_exti!(EXTI9, 9);
92impl_exti!(EXTI10, 10);
93impl_exti!(EXTI11, 11);
94impl_exti!(EXTI12, 12);
95impl_exti!(EXTI13, 13);
96impl_exti!(EXTI14, 14);
97impl_exti!(EXTI15, 15);
98
99macro_rules! enable_irq {
100 ($e:ident) => {
101 crate::interrupt::$e::steal().enable();
102 };
103}
104
105/// safety: must be called only once
106pub(crate) unsafe fn init() {
107 use embassy::interrupt::Interrupt;
108 use embassy::interrupt::InterruptExt;
109
110 foreach_exti_irq!(enable_irq);
111}
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti/v1.rs
index 90d4afd56..caf457605 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti/v1.rs
@@ -1,4 +1,3 @@
1#![macro_use]
2use core::convert::Infallible; 1use core::convert::Infallible;
3use core::future::Future; 2use core::future::Future;
4use core::marker::PhantomData; 3use core::marker::PhantomData;
@@ -6,14 +5,12 @@ use core::pin::Pin;
6use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
7use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; 6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
8use embassy::util::{AtomicWaker, Unborrow}; 7use embassy::util::{AtomicWaker, Unborrow};
9use embassy_extras::unsafe_impl_unborrow;
10use embedded_hal::digital::v2::InputPin; 8use embedded_hal::digital::v2::InputPin;
11use pac::exti::{regs, vals}; 9use pac::exti::{regs, vals};
12 10
13use crate::gpio::{AnyPin, Input, Pin as GpioPin}; 11use crate::gpio::{AnyPin, Input, Pin as GpioPin};
14use crate::pac; 12use crate::pac;
15use crate::pac::{EXTI, SYSCFG}; 13use crate::pac::{EXTI, SYSCFG};
16use crate::peripherals;
17 14
18const EXTI_COUNT: usize = 16; 15const EXTI_COUNT: usize = 16;
19const NEW_AW: AtomicWaker = AtomicWaker::new(); 16const NEW_AW: AtomicWaker = AtomicWaker::new();
@@ -160,106 +157,6 @@ impl<'a> Future for ExtiInputFuture<'a> {
160 } 157 }
161} 158}
162 159
163pub(crate) mod sealed {
164 pub trait Channel {}
165}
166
167pub trait Channel: sealed::Channel + Sized {
168 fn number(&self) -> usize;
169 fn degrade(self) -> AnyChannel {
170 AnyChannel {
171 number: self.number() as u8,
172 }
173 }
174}
175
176pub struct AnyChannel {
177 number: u8,
178}
179unsafe_impl_unborrow!(AnyChannel);
180impl sealed::Channel for AnyChannel {}
181impl Channel for AnyChannel {
182 fn number(&self) -> usize {
183 self.number as usize
184 }
185}
186
187macro_rules! impl_exti {
188 ($type:ident, $number:expr) => {
189 impl sealed::Channel for peripherals::$type {}
190 impl Channel for peripherals::$type {
191 fn number(&self) -> usize {
192 $number as usize
193 }
194 }
195 };
196}
197
198impl_exti!(EXTI0, 0);
199impl_exti!(EXTI1, 1);
200impl_exti!(EXTI2, 2);
201impl_exti!(EXTI3, 3);
202impl_exti!(EXTI4, 4);
203impl_exti!(EXTI5, 5);
204impl_exti!(EXTI6, 6);
205impl_exti!(EXTI7, 7);
206impl_exti!(EXTI8, 8);
207impl_exti!(EXTI9, 9);
208impl_exti!(EXTI10, 10);
209impl_exti!(EXTI11, 11);
210impl_exti!(EXTI12, 12);
211impl_exti!(EXTI13, 13);
212impl_exti!(EXTI14, 14);
213impl_exti!(EXTI15, 15);
214
215macro_rules! foreach_exti_irq {
216 ($action:ident) => {
217 crate::pac::interrupts!(
218 (EXTI0) => { $action!(EXTI0); };
219 (EXTI1) => { $action!(EXTI1); };
220 (EXTI2) => { $action!(EXTI2); };
221 (EXTI3) => { $action!(EXTI3); };
222 (EXTI4) => { $action!(EXTI4); };
223 (EXTI5) => { $action!(EXTI5); };
224 (EXTI6) => { $action!(EXTI6); };
225 (EXTI7) => { $action!(EXTI7); };
226 (EXTI8) => { $action!(EXTI8); };
227 (EXTI9) => { $action!(EXTI9); };
228 (EXTI10) => { $action!(EXTI10); };
229 (EXTI11) => { $action!(EXTI11); };
230 (EXTI12) => { $action!(EXTI12); };
231 (EXTI13) => { $action!(EXTI13); };
232 (EXTI14) => { $action!(EXTI14); };
233 (EXTI15) => { $action!(EXTI15); };
234
235 // plus the weird ones
236 (EXTI0_1) => { $action!( EXTI0_1 ); };
237 (EXTI15_10) => { $action!(EXTI15_10); };
238 (EXTI15_4) => { $action!(EXTI15_4); };
239 (EXTI1_0) => { $action!(EXTI1_0); };
240 (EXTI2_3) => { $action!(EXTI2_3); };
241 (EXTI2_TSC) => { $action!(EXTI2_TSC); };
242 (EXTI3_2) => { $action!(EXTI3_2); };
243 (EXTI4_15) => { $action!(EXTI4_15); };
244 (EXTI9_5) => { $action!(EXTI9_5); };
245 );
246 };
247}
248
249macro_rules! enable_irq {
250 ($e:ident) => {
251 crate::interrupt::$e::steal().enable();
252 };
253}
254
255/// safety: must be called only once
256pub(crate) unsafe fn init() {
257 use embassy::interrupt::Interrupt;
258 use embassy::interrupt::InterruptExt;
259
260 foreach_exti_irq!(enable_irq);
261}
262
263use crate::interrupt; 160use crate::interrupt;
264 161
265macro_rules! impl_irq { 162macro_rules! impl_irq {
diff --git a/embassy-stm32/src/exti/v2.rs b/embassy-stm32/src/exti/v2.rs
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/embassy-stm32/src/exti/v2.rs
@@ -0,0 +1 @@
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 39ccd54f0..9ba7bbe4c 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -16,7 +16,6 @@ pub mod interrupt;
16pub mod time; 16pub mod time;
17 17
18// Always-present hardware 18// Always-present hardware
19pub mod exti;
20pub mod gpio; 19pub mod gpio;
21pub mod rcc; 20pub mod rcc;
22 21
@@ -31,6 +30,8 @@ pub mod dac;
31pub mod dma; 30pub mod dma;
32#[cfg(all(eth, feature = "net"))] 31#[cfg(all(eth, feature = "net"))]
33pub mod eth; 32pub mod eth;
33#[cfg(exti)]
34pub mod exti;
34#[cfg(i2c)] 35#[cfg(i2c)]
35pub mod i2c; 36pub mod i2c;
36#[cfg(pwr)] 37#[cfg(pwr)]
@@ -83,10 +84,9 @@ pub fn init(config: Config) -> Peripherals {
83 let p = Peripherals::take(); 84 let p = Peripherals::take();
84 85
85 unsafe { 86 unsafe {
86 exti::init();
87
88 #[cfg(dma)] 87 #[cfg(dma)]
89 dma::init(); 88 dma::init();
89 #[cfg(exti)]
90 exti::init(); 90 exti::init();
91 rcc::init(config.rcc); 91 rcc::init(config.rcc);
92 } 92 }
diff --git a/embassy-stm32/src/rcc/f0/mod.rs b/embassy-stm32/src/rcc/f0/mod.rs
new file mode 100644
index 000000000..8ddacb8ef
--- /dev/null
+++ b/embassy-stm32/src/rcc/f0/mod.rs
@@ -0,0 +1,231 @@
1use core::marker::PhantomData;
2
3use embassy::util::Unborrow;
4
5use crate::pac::{DBGMCU, FLASH, RCC};
6use crate::peripherals;
7use crate::time::Hertz;
8
9use super::{set_freqs, Clocks};
10
11const HSI: u32 = 8_000_000;
12
13/// Configuration of the clocks
14///
15/// hse takes precedence over hsi48 if both are enabled
16#[non_exhaustive]
17#[derive(Default)]
18pub struct Config {
19 pub hse: Option<Hertz>,
20 pub bypass_hse: bool,
21 pub usb_pll: bool,
22
23 #[cfg(rcc_f0)]
24 pub hsi48: bool,
25
26 pub sys_ck: Option<Hertz>,
27 pub hclk: Option<Hertz>,
28 pub pclk: Option<Hertz>,
29 pub enable_debug_wfe: bool,
30}
31
32pub struct Rcc<'d> {
33 inner: PhantomData<&'d ()>,
34 config: Config,
35}
36
37impl<'d> Rcc<'d> {
38 pub fn new(_rcc: impl Unborrow<Target = peripherals::RCC> + 'd, config: Config) -> Self {
39 Self {
40 inner: PhantomData,
41 config,
42 }
43 }
44
45 pub fn freeze(self) -> Clocks {
46 use crate::pac::rcc::vals::{Hpre, Hsebyp, Pllmul, Pllsrc, Ppre, Sw, Usbsw};
47
48 let sysclk = self.config.sys_ck.map(|v| v.0).unwrap_or(HSI);
49
50 let (src_clk, use_hsi48) = self.config.hse.map(|v| (v.0, false)).unwrap_or_else(|| {
51 #[cfg(rcc_f0)]
52 if self.config.hsi48 {
53 return (48_000_000, true);
54 }
55 (HSI, false)
56 });
57
58 let (pllmul_bits, real_sysclk) = if sysclk == src_clk {
59 (None, sysclk)
60 } else {
61 let prediv = if self.config.hse.is_some() { 1 } else { 2 };
62 let pllmul = (2 * prediv * sysclk + src_clk) / src_clk / 2;
63 let pllmul = pllmul.max(2).min(16);
64
65 let pllmul_bits = pllmul as u8 - 2;
66 let real_sysclk = pllmul * src_clk / prediv;
67 (Some(pllmul_bits), real_sysclk)
68 };
69
70 let hpre_bits = self
71 .config
72 .hclk
73 .map(|hclk| match real_sysclk / hclk.0 {
74 0 => unreachable!(),
75 1 => 0b0111,
76 2 => 0b1000,
77 3..=5 => 0b1001,
78 6..=11 => 0b1010,
79 12..=39 => 0b1011,
80 40..=95 => 0b1100,
81 96..=191 => 0b1101,
82 192..=383 => 0b1110,
83 _ => 0b1111,
84 })
85 .unwrap_or(0b0111);
86 let hclk = real_sysclk / (1 << (hpre_bits - 0b0111));
87
88 let ppre_bits = self
89 .config
90 .pclk
91 .map(|pclk| match hclk / pclk.0 {
92 0 => unreachable!(),
93 1 => 0b011,
94 2 => 0b100,
95 3..=5 => 0b101,
96 6..=11 => 0b110,
97 _ => 0b111,
98 })
99 .unwrap_or(0b011);
100
101 let ppre: u8 = 1 << (ppre_bits - 0b011);
102 let pclk = hclk / u32::from(ppre);
103
104 let timer_mul = if ppre == 1 { 1 } else { 2 };
105
106 // NOTE(safety) Atomic write
107 unsafe {
108 FLASH.acr().write(|w| {
109 let latency = if real_sysclk <= 24_000_000 {
110 0
111 } else if real_sysclk <= 48_000_000 {
112 1
113 } else {
114 2
115 };
116 w.latency().0 = latency;
117 });
118 }
119
120 // NOTE(unsafe) We have exclusive access to the RCC
121 unsafe {
122 match (self.config.hse.is_some(), use_hsi48) {
123 (true, _) => {
124 RCC.cr().modify(|w| {
125 w.set_csson(true);
126 w.set_hseon(true);
127
128 if self.config.bypass_hse {
129 w.set_hsebyp(Hsebyp::BYPASSED);
130 }
131 });
132 while !RCC.cr().read().hserdy() {}
133
134 if pllmul_bits.is_some() {
135 RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSE_DIV_PREDIV))
136 }
137 }
138 (false, true) => {
139 // use_hsi48 will always be false for rcc_f0x0
140 #[cfg(rcc_f0)]
141 RCC.cr2().modify(|w| w.set_hsi48on(true));
142 #[cfg(rcc_f0)]
143 while !RCC.cr2().read().hsi48rdy() {}
144
145 #[cfg(rcc_f0)]
146 if pllmul_bits.is_some() {
147 RCC.cfgr()
148 .modify(|w| w.set_pllsrc(Pllsrc::HSI48_DIV_PREDIV))
149 }
150 }
151 _ => {
152 RCC.cr().modify(|w| w.set_hsion(true));
153 while !RCC.cr().read().hsirdy() {}
154
155 if pllmul_bits.is_some() {
156 RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSI_DIV2))
157 }
158 }
159 }
160
161 if self.config.usb_pll {
162 RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLLCLK));
163 }
164 // TODO: Option to use CRS (Clock Recovery)
165
166 if let Some(pllmul_bits) = pllmul_bits {
167 RCC.cfgr().modify(|w| w.set_pllmul(Pllmul(pllmul_bits)));
168
169 RCC.cr().modify(|w| w.set_pllon(true));
170 while !RCC.cr().read().pllrdy() {}
171
172 RCC.cfgr().modify(|w| {
173 w.set_ppre(Ppre(ppre_bits));
174 w.set_hpre(Hpre(hpre_bits));
175 w.set_sw(Sw::PLL)
176 });
177 } else {
178 RCC.cfgr().modify(|w| {
179 w.set_ppre(Ppre(ppre_bits));
180 w.set_hpre(Hpre(hpre_bits));
181
182 if self.config.hse.is_some() {
183 w.set_sw(Sw::HSE);
184 } else if use_hsi48 {
185 #[cfg(rcc_f0)]
186 w.set_sw(Sw::HSI48);
187 } else {
188 w.set_sw(Sw::HSI)
189 }
190 })
191 }
192
193 if self.config.enable_debug_wfe {
194 RCC.ahbenr().modify(|w| w.set_dmaen(true));
195
196 critical_section::with(|_| {
197 DBGMCU.cr().modify(|w| {
198 w.set_dbg_standby(true);
199 w.set_dbg_stop(true);
200 });
201 });
202 }
203 }
204
205 Clocks {
206 sys: Hertz(real_sysclk),
207 apb1: Hertz(pclk),
208 apb1_tim: Hertz(pclk * timer_mul),
209 apb2_tim: Hertz(0),
210 ahb: Hertz(hclk),
211 }
212 }
213}
214
215pub unsafe fn init(config: Config) {
216 RCC.ahbenr().modify(|w| {
217 w.set_iopaen(true);
218 w.set_iopben(true);
219 w.set_iopcen(true);
220 w.set_iopden(true);
221
222 #[cfg(rcc_f0)]
223 w.set_iopeen(true);
224
225 w.set_iopfen(true);
226 });
227
228 let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config);
229 let clocks = rcc.freeze();
230 set_freqs(clocks);
231}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index e84021272..91e8b5bef 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -9,11 +9,14 @@ mod types;
9pub struct Clocks { 9pub struct Clocks {
10 pub sys: Hertz, 10 pub sys: Hertz,
11 pub apb1: Hertz, 11 pub apb1: Hertz,
12
13 #[cfg(not(any(rcc_f0, rcc_f0x0)))]
12 pub apb2: Hertz, 14 pub apb2: Hertz,
15
13 pub apb1_tim: Hertz, 16 pub apb1_tim: Hertz,
14 pub apb2_tim: Hertz, 17 pub apb2_tim: Hertz,
15 18
16 #[cfg(any(rcc_l0))] 19 #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))]
17 pub ahb: Hertz, 20 pub ahb: Hertz,
18 21
19 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] 22 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))]
@@ -65,6 +68,9 @@ cfg_if::cfg_if! {
65 } else if #[cfg(rcc_wl5x)] { 68 } else if #[cfg(rcc_wl5x)] {
66 mod wl5x; 69 mod wl5x;
67 pub use wl5x::*; 70 pub use wl5x::*;
71 } else if #[cfg(any(rcc_f0, rcc_f0x0))] {
72 mod f0;
73 pub use f0::*;
68 } 74 }
69} 75}
70 76
diff --git a/stm32-data b/stm32-data
Subproject 18f86c83123771048f971350c99c4f810385d7d Subproject eb76ee900ac67b51497196572250323e82666b4
diff --git a/stm32-metapac/gen/src/lib.rs b/stm32-metapac/gen/src/lib.rs
index a5c061009..9e7add452 100644
--- a/stm32-metapac/gen/src/lib.rs
+++ b/stm32-metapac/gen/src/lib.rs
@@ -19,7 +19,6 @@ pub struct Chip {
19 pub cores: Vec<Core>, 19 pub cores: Vec<Core>,
20 pub flash: u32, 20 pub flash: u32,
21 pub ram: u32, 21 pub ram: u32,
22 pub gpio_af: String,
23 pub packages: Vec<Package>, 22 pub packages: Vec<Package>,
24} 23}
25 24