aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-07-31 11:08:46 +0200
committerGitHub <[email protected]>2021-07-31 11:08:46 +0200
commit3835278567e05014158eeede15d62a57ee105518 (patch)
treedf0617979c36f81c5f8f68d1d7244a186d8b5ce6
parente9885a61f88e3746275297a6d0ea7f837b302757 (diff)
parent21e3acaa00f405397811c3abf71dbb26ea932896 (diff)
Merge pull request #321 from thalesfragoso/f4-pll
F4 PLL
-rw-r--r--embassy-stm32/build.rs11
-rw-r--r--embassy-stm32/src/pwr/f4.rs1
-rw-r--r--embassy-stm32/src/pwr/mod.rs1
-rw-r--r--embassy-stm32/src/rcc/f4/max.rs21
-rw-r--r--embassy-stm32/src/rcc/f4/mod.rs432
-rw-r--r--embassy-stm32/src/rcc/mod.rs3
-rw-r--r--examples/stm32f4/src/bin/hello.rs34
m---------stm32-data0
-rw-r--r--stm32-metapac-gen/src/lib.rs8
9 files changed, 348 insertions, 163 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index df8af660b..a6434a7e8 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -9,7 +9,7 @@ fn main() {
9 .expect("No stm32xx Cargo feature enabled") 9 .expect("No stm32xx Cargo feature enabled")
10 .strip_prefix("CARGO_FEATURE_") 10 .strip_prefix("CARGO_FEATURE_")
11 .unwrap() 11 .unwrap()
12 .to_ascii_uppercase(); 12 .to_ascii_lowercase();
13 13
14 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 14 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
15 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string(); 15 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string();
@@ -30,6 +30,15 @@ fn main() {
30 }; 30 };
31 ); 31 );
32 32
33 let mut chip_and_core = chip_name.split('_');
34 let chip = chip_and_core.next().expect("Unexpected stm32xx feature");
35
36 if let Some(core) = chip_and_core.next() {
37 println!("cargo:rustc-cfg={}_{}", &chip[..(chip.len() - 2)], core);
38 } else {
39 println!("cargo:rustc-cfg={}", &chip[..(chip.len() - 2)]);
40 }
41
33 println!("cargo:rerun-if-changed=build.rs"); 42 println!("cargo:rerun-if-changed=build.rs");
34 println!("cargo:rerun-if-changed=gen.py"); 43 println!("cargo:rerun-if-changed=gen.py");
35} 44}
diff --git a/embassy-stm32/src/pwr/f4.rs b/embassy-stm32/src/pwr/f4.rs
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/embassy-stm32/src/pwr/f4.rs
@@ -0,0 +1 @@
diff --git a/embassy-stm32/src/pwr/mod.rs b/embassy-stm32/src/pwr/mod.rs
index 5b563d725..1bb104bd3 100644
--- a/embassy-stm32/src/pwr/mod.rs
+++ b/embassy-stm32/src/pwr/mod.rs
@@ -1,4 +1,5 @@
1#[cfg_attr(any(pwr_h7, pwr_h7smps), path = "h7.rs")] 1#[cfg_attr(any(pwr_h7, pwr_h7smps), path = "h7.rs")]
2#[cfg_attr(pwr_f4, path = "f4.rs")]
2mod _version; 3mod _version;
3 4
4pub use _version::*; 5pub use _version::*;
diff --git a/embassy-stm32/src/rcc/f4/max.rs b/embassy-stm32/src/rcc/f4/max.rs
new file mode 100644
index 000000000..dd8de3da9
--- /dev/null
+++ b/embassy-stm32/src/rcc/f4/max.rs
@@ -0,0 +1,21 @@
1#[cfg(stm32f401)]
2pub(crate) const SYSCLK_MAX: u32 = 84_000_000;
3
4#[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))]
5pub(crate) const SYSCLK_MAX: u32 = 168_000_000;
6
7#[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
8pub(crate) const SYSCLK_MAX: u32 = 100_000_000;
9
10#[cfg(any(
11 stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,
12))]
13pub(crate) const SYSCLK_MAX: u32 = 180_000_000;
14
15#[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
16pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX;
17
18#[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))]
19pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2;
20
21pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2;
diff --git a/embassy-stm32/src/rcc/f4/mod.rs b/embassy-stm32/src/rcc/f4/mod.rs
index d47510da7..1cf3e5bd9 100644
--- a/embassy-stm32/src/rcc/f4/mod.rs
+++ b/embassy-stm32/src/rcc/f4/mod.rs
@@ -1,207 +1,325 @@
1pub use super::types::*; 1use crate::pac::{FLASH, PWR, RCC};
2use crate::pac; 2use crate::peripherals;
3use crate::peripherals::{self, RCC};
4use crate::rcc::{get_freqs, set_freqs, Clocks}; 3use crate::rcc::{get_freqs, set_freqs, Clocks};
5use crate::time::Hertz; 4use crate::time::Hertz;
6use crate::time::U32Ext;
7use core::marker::PhantomData; 5use core::marker::PhantomData;
8use embassy::util::Unborrow; 6use embassy::util::Unborrow;
9use embassy_hal_common::unborrow;
10use pac::rcc::vals::{Hpre, Ppre, Sw};
11 7
12/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, 8mod max;
13/// and with the addition of the init function to configure a system clock. 9use max::{PCLK1_MAX, PCLK2_MAX};
14 10
15/// Only the basic setup using the HSE and HSI clocks are supported as of now. 11const HSI: u32 = 16_000_000;
16 12
17/// HSI speed 13/// Clocks configutation
18pub const HSI_FREQ: u32 = 16_000_000; 14#[non_exhaustive]
19 15#[derive(Default)]
20/// System clock mux source 16pub struct Config {
21#[derive(Clone, Copy)] 17 pub hse: Option<Hertz>,
22pub enum ClockSrc { 18 pub bypass_hse: bool,
23 HSE(Hertz), 19 pub pll48: bool,
24 HSI16, 20 pub sys_ck: Option<Hertz>,
21 pub hclk: Option<Hertz>,
22 pub pclk1: Option<Hertz>,
23 pub pclk2: Option<Hertz>,
24 pub enable_debug_wfe: bool,
25} 25}
26 26
27impl Into<Ppre> for APBPrescaler { 27/// RCC peripheral
28 fn into(self) -> Ppre { 28pub struct Rcc<'d> {
29 match self { 29 config: Config,
30 APBPrescaler::NotDivided => Ppre::DIV1, 30 phantom: PhantomData<&'d mut peripherals::RCC>,
31 APBPrescaler::Div2 => Ppre::DIV2,
32 APBPrescaler::Div4 => Ppre::DIV4,
33 APBPrescaler::Div8 => Ppre::DIV8,
34 APBPrescaler::Div16 => Ppre::DIV16,
35 }
36 }
37} 31}
38 32
39impl Into<Hpre> for AHBPrescaler { 33impl<'d> Rcc<'d> {
40 fn into(self) -> Hpre { 34 pub fn new(_rcc: impl Unborrow<Target = peripherals::RCC> + 'd, config: Config) -> Self {
41 match self { 35 Self {
42 AHBPrescaler::NotDivided => Hpre::DIV1, 36 config,
43 AHBPrescaler::Div2 => Hpre::DIV2, 37 phantom: PhantomData,
44 AHBPrescaler::Div4 => Hpre::DIV4,
45 AHBPrescaler::Div8 => Hpre::DIV8,
46 AHBPrescaler::Div16 => Hpre::DIV16,
47 AHBPrescaler::Div64 => Hpre::DIV64,
48 AHBPrescaler::Div128 => Hpre::DIV128,
49 AHBPrescaler::Div256 => Hpre::DIV256,
50 AHBPrescaler::Div512 => Hpre::DIV512,
51 } 38 }
52 } 39 }
53}
54 40
55/// Clocks configutation 41 fn freeze(mut self) -> Clocks {
56pub struct Config { 42 use super::sealed::RccPeripheral;
57 mux: ClockSrc, 43 use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw};
58 ahb_pre: AHBPrescaler,
59 apb1_pre: APBPrescaler,
60 apb2_pre: APBPrescaler,
61}
62 44
63impl Default for Config { 45 let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
64 #[inline] 46 let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
65 fn default() -> Config { 47 let sysclk_on_pll = sysclk != pllsrcclk;
66 Config { 48
67 mux: ClockSrc::HSI16, 49 let plls = self.setup_pll(
68 ahb_pre: AHBPrescaler::NotDivided, 50 pllsrcclk,
69 apb1_pre: APBPrescaler::NotDivided, 51 self.config.hse.is_some(),
70 apb2_pre: APBPrescaler::NotDivided, 52 if sysclk_on_pll { Some(sysclk) } else { None },
53 self.config.pll48,
54 );
55
56 if self.config.pll48 {
57 assert!(
58 // USB specification allows +-0.25%
59 plls.pll48clk
60 .map(|freq| (48_000_000 - freq as i32).abs() <= 120_000)
61 .unwrap_or(false)
62 );
71 } 63 }
72 }
73}
74 64
75impl Config { 65 let sysclk = if sysclk_on_pll {
76 #[inline] 66 plls.pllsysclk.unwrap()
77 pub fn clock_src(mut self, mux: ClockSrc) -> Self { 67 } else {
78 self.mux = mux; 68 sysclk
79 self 69 };
80 }
81 70
82 #[inline] 71 let hclk = self.config.hclk.map(|h| h.0).unwrap_or(sysclk);
83 pub fn ahb_pre(mut self, pre: AHBPrescaler) -> Self { 72 let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk {
84 self.ahb_pre = pre; 73 0 => unreachable!(),
85 self 74 1 => (Hpre::DIV1, 1),
86 } 75 2 => (Hpre::DIV2, 2),
76 3..=5 => (Hpre::DIV4, 4),
77 6..=11 => (Hpre::DIV8, 8),
78 12..=39 => (Hpre::DIV16, 16),
79 40..=95 => (Hpre::DIV64, 64),
80 96..=191 => (Hpre::DIV128, 128),
81 192..=383 => (Hpre::DIV256, 256),
82 _ => (Hpre::DIV512, 512),
83 };
87 84
88 #[inline] 85 // Calculate real AHB clock
89 pub fn apb1_pre(mut self, pre: APBPrescaler) -> Self { 86 let hclk = sysclk / hpre_div;
90 self.apb1_pre = pre;
91 self
92 }
93 87
94 #[inline] 88 let pclk1 = self
95 pub fn apb2_pre(mut self, pre: APBPrescaler) -> Self { 89 .config
96 self.apb2_pre = pre; 90 .pclk1
97 self 91 .map(|p| p.0)
98 } 92 .unwrap_or_else(|| core::cmp::min(PCLK1_MAX, hclk));
99} 93 let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 {
94 0 => unreachable!(),
95 1 => (0b000, 1),
96 2 => (0b100, 2),
97 3..=5 => (0b101, 4),
98 6..=11 => (0b110, 8),
99 _ => (0b111, 16),
100 };
101 let timer_mul1 = if ppre1 == 1 { 1 } else { 2 };
100 102
101/// RCC peripheral 103 // Calculate real APB1 clock
102pub struct Rcc<'d> { 104 let pclk1 = hclk / ppre1;
103 _rb: peripherals::RCC, 105 assert!(pclk1 <= PCLK1_MAX);
104 phantom: PhantomData<&'d mut peripherals::RCC>,
105}
106 106
107impl<'d> Rcc<'d> { 107 let pclk2 = self
108 pub fn new(rcc: impl Unborrow<Target = peripherals::RCC> + 'd) -> Self { 108 .config
109 unborrow!(rcc); 109 .pclk2
110 Self { 110 .map(|p| p.0)
111 _rb: rcc, 111 .unwrap_or_else(|| core::cmp::min(PCLK2_MAX, hclk));
112 phantom: PhantomData, 112 let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 {
113 0 => unreachable!(),
114 1 => (0b000, 1),
115 2 => (0b100, 2),
116 3..=5 => (0b101, 4),
117 6..=11 => (0b110, 8),
118 _ => (0b111, 16),
119 };
120 let timer_mul2 = if ppre2 == 1 { 1 } else { 2 };
121
122 // Calculate real APB2 clock
123 let pclk2 = hclk / ppre2;
124 assert!(pclk2 <= PCLK2_MAX);
125
126 Self::flash_setup(sysclk);
127
128 if self.config.hse.is_some() {
129 // NOTE(unsafe) We own the peripheral block
130 unsafe {
131 RCC.cr().modify(|w| {
132 w.set_hsebyp(Hsebyp(self.config.bypass_hse as u8));
133 w.set_hseon(true);
134 });
135 while !RCC.cr().read().hserdy() {}
136 }
113 } 137 }
114 }
115 138
116 // Safety: RCC init must have been called 139 if plls.use_pll {
117 pub fn clocks(&self) -> &'static Clocks { 140 unsafe {
118 unsafe { get_freqs() } 141 RCC.cr().modify(|w| w.set_pllon(true));
119 }
120}
121 142
122/// Extension trait that freezes the `RCC` peripheral with provided clocks configuration 143 if hclk > 168_000_000 {
123pub trait RccExt { 144 peripherals::PWR::enable();
124 fn freeze(self, config: Config) -> Clocks;
125}
126 145
127impl RccExt for RCC { 146 PWR.cr().modify(|w| w.set_oden(true));
128 #[inline] 147 while !PWR.csr().read().odrdy() {}
129 fn freeze(self, cfgr: Config) -> Clocks {
130 let rcc = pac::RCC;
131 let (sys_clk, sw) = match cfgr.mux {
132 ClockSrc::HSI16 => {
133 // Enable HSI16
134 unsafe {
135 rcc.cr().modify(|w| w.set_hsion(true));
136 while !rcc.cr().read().hsirdy() {}
137 }
138 148
139 (HSI_FREQ, Sw::HSI) 149 PWR.cr().modify(|w| w.set_odswen(true));
140 } 150 while !PWR.csr().read().odswrdy() {}
141 ClockSrc::HSE(freq) => {
142 // Enable HSE
143 unsafe {
144 rcc.cr().modify(|w| w.set_hseon(true));
145 while !rcc.cr().read().hserdy() {}
146 } 151 }
147 152
148 (freq.0, Sw::HSE) 153 while !RCC.cr().read().pllrdy() {}
149 } 154 }
150 }; 155 }
151 156
152 unsafe { 157 unsafe {
153 rcc.cfgr().modify(|w| { 158 RCC.cfgr().modify(|w| {
154 w.set_sw(sw.into()); 159 w.set_ppre2(Ppre(ppre2_bits));
155 w.set_hpre(cfgr.ahb_pre.into()); 160 w.set_ppre1(Ppre(ppre1_bits));
156 w.set_ppre1(cfgr.apb1_pre.into()); 161 w.set_hpre(hpre_bits);
157 w.set_ppre2(cfgr.apb2_pre.into()); 162 });
163
164 // Wait for the new prescalers to kick in
165 // "The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after write"
166 cortex_m::asm::delay(16);
167
168 RCC.cfgr().modify(|w| {
169 w.set_sw(if sysclk_on_pll {
170 Sw::PLL
171 } else if self.config.hse.is_some() {
172 Sw::HSE
173 } else {
174 Sw::HSI
175 })
158 }); 176 });
159 } 177 }
160 178
161 let ahb_freq: u32 = match cfgr.ahb_pre { 179 if self.config.enable_debug_wfe {
162 AHBPrescaler::NotDivided => sys_clk, 180 unsafe {
163 pre => { 181 RCC.ahb1enr().modify(|w| w.set_dma1en(true));
164 let pre: Hpre = pre.into(); 182 critical_section::with(|_| {
165 let pre = 1 << (pre.0 as u32 - 7); 183 crate::dbgmcu::Dbgmcu::enable_all();
166 sys_clk / pre 184 });
167 } 185 }
168 }; 186 }
187
188 Clocks {
189 sys: Hertz(sysclk),
190 apb1: Hertz(pclk1),
191 apb2: Hertz(pclk2),
192
193 apb1_tim: Hertz(pclk1 * timer_mul1),
194 apb2_tim: Hertz(pclk2 * timer_mul2),
195
196 ahb1: Hertz(hclk),
197 ahb2: Hertz(hclk),
198 ahb3: Hertz(hclk),
199
200 pll48: plls.pll48clk.map(Hertz),
201 }
202 }
203
204 // Safety: RCC init must have been called
205 pub fn clocks(&self) -> &'static Clocks {
206 unsafe { get_freqs() }
207 }
169 208
170 let (apb1_freq, apb1_tim_freq) = match cfgr.apb1_pre { 209 fn setup_pll(
171 APBPrescaler::NotDivided => (ahb_freq, ahb_freq), 210 &mut self,
172 pre => { 211 pllsrcclk: u32,
173 let pre: Ppre = pre.into(); 212 use_hse: bool,
174 let pre: u8 = 1 << (pre.0 - 3); 213 pllsysclk: Option<u32>,
175 let freq = ahb_freq / pre as u32; 214 pll48clk: bool,
176 (freq, freq * 2) 215 ) -> PllResults {
216 use crate::pac::rcc::vals::{Pllp, Pllsrc};
217
218 let sysclk = pllsysclk.unwrap_or(pllsrcclk);
219 if pllsysclk.is_none() && !pll48clk {
220 // NOTE(unsafe) We have a mutable borrow to the owner of the RegBlock
221 unsafe {
222 RCC.pllcfgr()
223 .modify(|w| w.set_pllsrc(Pllsrc(use_hse as u8)));
177 } 224 }
225
226 return PllResults {
227 use_pll: false,
228 pllsysclk: None,
229 pll48clk: None,
230 };
231 }
232 // Input divisor from PLL source clock, must result to frequency in
233 // the range from 1 to 2 MHz
234 let pllm_min = (pllsrcclk + 1_999_999) / 2_000_000;
235 let pllm_max = pllsrcclk / 1_000_000;
236
237 // Sysclk output divisor must be one of 2, 4, 6 or 8
238 let sysclk_div = core::cmp::min(8, (432_000_000 / sysclk) & !1);
239
240 let target_freq = if pll48clk {
241 48_000_000
242 } else {
243 sysclk * sysclk_div
178 }; 244 };
179 245
180 let (apb2_freq, apb2_tim_freq) = match cfgr.apb2_pre { 246 // Find the lowest pllm value that minimize the difference between
181 APBPrescaler::NotDivided => (ahb_freq, ahb_freq), 247 // target frequency and the real vco_out frequency.
182 pre => { 248 let pllm = (pllm_min..=pllm_max)
183 let pre: Ppre = pre.into(); 249 .min_by_key(|pllm| {
184 let pre: u8 = 1 << (pre.0 - 3); 250 let vco_in = pllsrcclk / pllm;
185 let freq = ahb_freq / (1 << (pre as u8 - 3)); 251 let plln = target_freq / vco_in;
186 (freq, freq * 2) 252 target_freq - vco_in * plln
187 } 253 })
254 .unwrap();
255
256 let vco_in = pllsrcclk / pllm;
257 assert!((1_000_000..=2_000_000).contains(&vco_in));
258
259 // Main scaler, must result in >= 100MHz (>= 192MHz for F401)
260 // and <= 432MHz, min 50, max 432
261 let plln = if pll48clk {
262 // try the different valid pllq according to the valid
263 // main scaller values, and take the best
264 let pllq = (4..=9)
265 .min_by_key(|pllq| {
266 let plln = 48_000_000 * pllq / vco_in;
267 let pll48_diff = 48_000_000 - vco_in * plln / pllq;
268 let sysclk_diff = (sysclk as i32 - (vco_in * plln / sysclk_div) as i32).abs();
269 (pll48_diff, sysclk_diff)
270 })
271 .unwrap();
272 48_000_000 * pllq / vco_in
273 } else {
274 sysclk * sysclk_div / vco_in
188 }; 275 };
189 276
190 Clocks { 277 let pllp = (sysclk_div / 2) - 1;
191 sys: sys_clk.hz(), 278
192 ahb1: ahb_freq.hz(), 279 let pllq = (vco_in * plln + 47_999_999) / 48_000_000;
193 ahb2: ahb_freq.hz(), 280 let real_pll48clk = vco_in * plln / pllq;
194 ahb3: ahb_freq.hz(), 281
195 apb1: apb1_freq.hz(), 282 unsafe {
196 apb2: apb2_freq.hz(), 283 RCC.pllcfgr().modify(|w| {
197 apb1_tim: apb1_tim_freq.hz(), 284 w.set_pllm(pllm as u8);
198 apb2_tim: apb2_tim_freq.hz(), 285 w.set_plln(plln as u16);
286 w.set_pllp(Pllp(pllp as u8));
287 w.set_pllq(pllq as u8);
288 w.set_pllsrc(Pllsrc(use_hse as u8));
289 });
290 }
291
292 let real_pllsysclk = vco_in * plln / sysclk_div;
293
294 PllResults {
295 use_pll: true,
296 pllsysclk: Some(real_pllsysclk),
297 pll48clk: if pll48clk { Some(real_pll48clk) } else { None },
199 } 298 }
200 } 299 }
300
301 fn flash_setup(sysclk: u32) {
302 use crate::pac::flash::vals::Latency;
303
304 // Be conservative with voltage ranges
305 const FLASH_LATENCY_STEP: u32 = 30_000_000;
306
307 critical_section::with(|_| unsafe {
308 FLASH
309 .acr()
310 .modify(|w| w.set_latency(Latency(((sysclk - 1) / FLASH_LATENCY_STEP) as u8)));
311 });
312 }
201} 313}
202 314
203pub unsafe fn init(config: Config) { 315pub unsafe fn init(config: Config) {
204 let r = <peripherals::RCC as embassy::util::Steal>::steal(); 316 let r = <peripherals::RCC as embassy::util::Steal>::steal();
205 let clocks = r.freeze(config); 317 let clocks = Rcc::new(r, config).freeze();
206 set_freqs(clocks); 318 set_freqs(clocks);
207} 319}
320
321struct PllResults {
322 use_pll: bool,
323 pllsysclk: Option<u32>,
324 pll48clk: Option<u32>,
325}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index c02db58fe..87be0a5b3 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -31,6 +31,9 @@ pub struct Clocks {
31 31
32 #[cfg(any(rcc_h7))] 32 #[cfg(any(rcc_h7))]
33 pub apb4: Hertz, 33 pub apb4: Hertz,
34
35 #[cfg(rcc_f4)]
36 pub pll48: Option<Hertz>,
34} 37}
35 38
36/// Frozen clock frequencies 39/// Frozen clock frequencies
diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs
new file mode 100644
index 000000000..8ee6c1ef8
--- /dev/null
+++ b/examples/stm32f4/src/bin/hello.rs
@@ -0,0 +1,34 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(min_type_alias_impl_trait)]
5#![feature(impl_trait_in_bindings)]
6#![feature(type_alias_impl_trait)]
7#![allow(incomplete_features)]
8
9use defmt::{info, panic};
10use embassy::executor::Spawner;
11use embassy::time::{Duration, Timer};
12use embassy_stm32::rcc::Config as RccConfig;
13use embassy_stm32::time::Hertz;
14use embassy_stm32::Config;
15use embassy_stm32::Peripherals;
16
17#[path = "../example_common.rs"]
18mod example_common;
19
20fn config() -> Config {
21 let mut rcc_config = RccConfig::default();
22 rcc_config.sys_ck = Some(Hertz(84_000_000));
23 rcc_config.enable_debug_wfe = true;
24
25 Config::default().rcc(rcc_config)
26}
27
28#[embassy::main(config = "config()")]
29async fn main(_spawner: Spawner, _p: Peripherals) -> ! {
30 loop {
31 info!("Hello World!");
32 Timer::after(Duration::from_secs(1)).await;
33 }
34}
diff --git a/stm32-data b/stm32-data
Subproject 62c8985228186a02a623d1acfb59b75a4865d30 Subproject 0ad27b2fd1126c6c9d9f4602d1331f5d82f4aa2
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 83f4dcfb3..f508b3658 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -1,5 +1,4 @@
1use chiptool::generate::CommonModule; 1use chiptool::generate::CommonModule;
2use proc_macro2::TokenStream;
3use regex::Regex; 2use regex::Regex;
4use serde::Deserialize; 3use serde::Deserialize;
5use std::collections::{HashMap, HashSet}; 4use std::collections::{HashMap, HashSet};
@@ -10,7 +9,6 @@ use std::fs::File;
10use std::io::Write; 9use std::io::Write;
11use std::path::Path; 10use std::path::Path;
12use std::path::PathBuf; 11use std::path::PathBuf;
13use std::str::FromStr;
14 12
15use chiptool::util::ToSanitizedSnakeCase; 13use chiptool::util::ToSanitizedSnakeCase;
16use chiptool::{generate, ir, transform}; 14use chiptool::{generate, ir, transform};
@@ -54,7 +52,7 @@ pub struct Peripheral {
54 #[serde(default)] 52 #[serde(default)]
55 pub dma_channels: HashMap<String, Vec<PeripheralDmaChannel>>, 53 pub dma_channels: HashMap<String, Vec<PeripheralDmaChannel>>,
56 #[serde(default)] 54 #[serde(default)]
57 pub interrupts: HashMap<String, String> 55 pub interrupts: HashMap<String, String>,
58} 56}
59 57
60#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] 58#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
@@ -353,8 +351,8 @@ pub fn gen(options: Options) {
353 row.push(name.clone()); 351 row.push(name.clone());
354 row.push(bi.module.clone()); 352 row.push(bi.module.clone());
355 row.push(bi.block.clone()); 353 row.push(bi.block.clone());
356 row.push( signal.clone() ); 354 row.push(signal.clone());
357 row.push( irq_name.to_ascii_uppercase() ); 355 row.push(irq_name.to_ascii_uppercase());
358 interrupt_table.push(row) 356 interrupt_table.push(row)
359 } 357 }
360 358