aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-08-20 00:05:08 +0200
committerGitHub <[email protected]>2021-08-20 00:05:08 +0200
commit8e5f1f4b5e8ff20897ac86ca81605d50c3dfa966 (patch)
tree588a2c2a0d7e533bfad6a928bf0c7bc70c5b6be0
parent39baff8775845895b67ff62ced66fb420b558c55 (diff)
parent174c51f09707b8a475382071f99e0d9c44f93ab7 (diff)
Merge pull request #367 from embassy-rs/metapac-cleanup
stm32-metapac cleanups
-rw-r--r--.gitignore1
-rw-r--r--embassy-stm32/build.rs73
-rw-r--r--embassy-stm32/gen.py88
-rw-r--r--embassy-stm32/src/exti.rs270
-rw-r--r--embassy-stm32/src/exti/mod.rs116
-rw-r--r--embassy-stm32/src/exti/v1.rs171
-rw-r--r--embassy-stm32/src/exti/v2.rs184
-rw-r--r--embassy-stm32/src/lib.rs6
-rw-r--r--embassy-stm32/src/rcc/f0/mod.rs20
-rw-r--r--embassy-stm32/src/rcc/f4/mod.rs10
-rw-r--r--embassy-stm32/src/rcc/h7/mod.rs21
-rw-r--r--embassy-stm32/src/rcc/l0/mod.rs20
-rw-r--r--embassy-stm32/src/rcc/mod.rs16
-rw-r--r--embassy-stm32/src/rcc/wb/mod.rs (renamed from embassy-stm32/src/rcc/wb55/mod.rs)0
-rw-r--r--embassy-stm32/src/rcc/wl5x/mod.rs4
-rw-r--r--examples/stm32f0/src/bin/hello.rs2
-rw-r--r--examples/stm32f0/src/example_common.rs7
-rw-r--r--examples/stm32f4/src/bin/blinky.rs5
-rw-r--r--examples/stm32f4/src/bin/button.rs5
-rw-r--r--examples/stm32f4/src/bin/button_exti.rs5
-rw-r--r--examples/stm32f4/src/bin/can.rs5
-rw-r--r--examples/stm32f4/src/bin/hello.rs1
-rw-r--r--examples/stm32f4/src/bin/spi.rs5
-rw-r--r--examples/stm32f4/src/bin/spi_dma.rs5
-rw-r--r--examples/stm32f4/src/bin/usart.rs5
-rw-r--r--examples/stm32f4/src/bin/usart_dma.rs5
-rw-r--r--examples/stm32h7/src/bin/blinky.rs3
-rw-r--r--examples/stm32h7/src/bin/button_exti.rs5
-rw-r--r--examples/stm32h7/src/bin/dac.rs5
-rw-r--r--examples/stm32h7/src/bin/eth.rs5
-rw-r--r--examples/stm32h7/src/bin/spi.rs5
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs5
-rw-r--r--examples/stm32h7/src/bin/usart.rs5
-rw-r--r--examples/stm32h7/src/bin/usart_dma.rs5
-rw-r--r--examples/stm32l0/Cargo.toml2
-rw-r--r--examples/stm32l0/src/bin/blinky.rs5
-rw-r--r--examples/stm32l0/src/bin/button.rs16
-rw-r--r--examples/stm32l0/src/bin/button_exti.rs1
-rw-r--r--examples/stm32l0/src/bin/spi.rs14
-rw-r--r--examples/stm32l0/src/bin/usart_dma.rs7
-rw-r--r--examples/stm32l0/src/bin/usart_irq.rs7
-rw-r--r--examples/stm32l4/Cargo.toml2
-rw-r--r--examples/stm32l4/src/bin/adc.rs3
-rw-r--r--examples/stm32l4/src/bin/blinky.rs5
-rw-r--r--examples/stm32l4/src/bin/button.rs5
-rw-r--r--examples/stm32l4/src/bin/button_exti.rs5
-rw-r--r--examples/stm32l4/src/bin/dac.rs3
-rw-r--r--examples/stm32l4/src/bin/spi.rs5
-rw-r--r--examples/stm32l4/src/bin/spi_dma.rs5
-rw-r--r--examples/stm32l4/src/bin/usart.rs5
-rw-r--r--examples/stm32l4/src/bin/usart_dma.rs5
-rw-r--r--examples/stm32wb55/src/bin/blinky.rs3
-rw-r--r--examples/stm32wb55/src/bin/button_exti.rs31
-rw-r--r--examples/stm32wl55/src/bin/blinky.rs3
-rw-r--r--examples/stm32wl55/src/bin/button.rs7
-rw-r--r--examples/stm32wl55/src/bin/button_exti.rs3
m---------stm32-data0
-rw-r--r--stm32-metapac-gen/src/lib.rs158
-rw-r--r--stm32-metapac-gen/src/main.rs26
59 files changed, 502 insertions, 912 deletions
diff --git a/.gitignore b/.gitignore
index 11781dc15..30628ed58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ target
2Cargo.lock 2Cargo.lock
3third_party 3third_party
4/Cargo.toml 4/Cargo.toml
5stm32-metapac-gen/out/ \ No newline at end of file
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index a6434a7e8..ed2b4c50e 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1,6 +1,6 @@
1use std::env; 1use std::env;
2use std::fs;
2use std::path::PathBuf; 3use std::path::PathBuf;
3use std::process::Command;
4 4
5fn main() { 5fn main() {
6 let chip_name = env::vars_os() 6 let chip_name = env::vars_os()
@@ -11,18 +11,73 @@ fn main() {
11 .unwrap() 11 .unwrap()
12 .to_ascii_lowercase(); 12 .to_ascii_lowercase();
13 13
14 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 14 struct Peripheral {
15 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string(); 15 kind: String,
16 name: String,
17 }
18
19 let mut peripherals: Vec<Peripheral> = Vec::new();
20 stm32_metapac::peripherals!(
21 ($kind:ident, $name:ident) => {
22 peripherals.push(Peripheral{
23 kind: stringify!($kind).to_string(),
24 name: stringify!($name).to_string(),
25 });
26 };
27 );
28
29 let mut singletons: Vec<String> = Vec::new();
30 for p in peripherals {
31 match p.kind.as_str() {
32 // Generate singletons per pin, not per port
33 "gpio" => {
34 println!("{}", p.name);
35 let port_letter = p.name.strip_prefix("GPIO").unwrap();
36 for pin_num in 0..16 {
37 singletons.push(format!("P{}{}", port_letter, pin_num));
38 }
39 }
40
41 // No singleton for these, the HAL handles them specially.
42 "exti" => {}
16 43
17 let exit_code = Command::new("python3") 44 // We *shouldn't* have singletons for these, but the HAL currently requires
18 .args(&["gen.py", &chip_name, &out_file]) 45 // singletons, for using with RccPeripheral to enable/disable clocks to them.
19 .status() 46 //"rcc" => {}
20 .expect("failed to execute gen.py"); 47 //"dbgmcu" => {}
48 //"syscfg" => {}
49 //"dma" => {}
50 //"bdma" => {}
51 //"dmamux" => {}
21 52
22 if !exit_code.success() { 53 // For other peripherals, one singleton per peri
23 panic!("gen.py exited with {:?}", exit_code) 54 _ => singletons.push(p.name.clone()),
55 }
24 } 56 }
25 57
58 // One singleton per EXTI line
59 for pin_num in 0..16 {
60 singletons.push(format!("EXTI{}", pin_num));
61 }
62
63 // One singleton per DMA channel
64 stm32_metapac::dma_channels! {
65 ($channel_peri:ident, $dma_peri:ident, $version:ident, $channel_num:expr, $ignore:tt) => {
66 singletons.push(stringify!($channel_peri).to_string());
67 };
68 }
69
70 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
71 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string();
72 fs::write(
73 out_file,
74 format!(
75 "embassy_hal_common::peripherals!({});",
76 singletons.join(",")
77 ),
78 )
79 .unwrap();
80
26 stm32_metapac::peripheral_versions!( 81 stm32_metapac::peripheral_versions!(
27 ($peri:ident, $version:ident) => { 82 ($peri:ident, $version:ident) => {
28 println!("cargo:rustc-cfg={}", stringify!($peri)); 83 println!("cargo:rustc-cfg={}", stringify!($peri));
diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py
deleted file mode 100644
index e589f2f06..000000000
--- a/embassy-stm32/gen.py
+++ /dev/null
@@ -1,88 +0,0 @@
1import sys
2import yaml
3import re
4import os
5import re
6
7try:
8 from yaml import CSafeLoader as SafeLoader
9except ImportError:
10 from yaml import SafeLoader
11
12
13abspath = os.path.abspath(__file__)
14dname = os.path.dirname(abspath)
15os.chdir(dname)
16
17data_path = '../stm32-data/data'
18
19try:
20 _, chip_name, output_file = sys.argv
21except:
22 raise Exception("Usage: gen.py STM32F429ZI_CM0 path/to/generated.rs")
23
24c = chip_name.split('_', 1)
25
26chip_name = c[0].upper()
27core_name = None
28
29if len(c) > 1:
30 core_name = c[1].lower()
31
32# ======= load chip
33with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f:
34 chip = yaml.load(f, Loader=SafeLoader)
35
36# ======= Generate!
37with open(output_file, 'w') as f:
38 singletons = [] # USART1, PA5, EXTI8
39 exti_interrupts = [] # EXTI IRQs, EXTI0, EXTI4_15 etc.
40 pins = set() # set of all present pins. PA4, PA5...
41
42 # ========= peripherals
43
44 singletons.extend((f'EXTI{x}' for x in range(16)))
45 num_dmas = 0
46
47 core = chip['cores'][0]
48 if core_name != None:
49 for c in chip['cores']:
50 if core_name == c['name']:
51 core = c
52
53 for (name, peri) in core['peripherals'].items():
54 if 'block' not in peri:
55 continue
56
57 block = peri['block']
58 block_mod, block_name_unparsed = block.rsplit('/')
59 block_mod, block_version = block_mod.rsplit('_')
60 block_name = ''
61 for b in block_name_unparsed.split('_'):
62 block_name += b.capitalize()
63
64 custom_singletons = False
65
66 if block_mod == 'gpio':
67 custom_singletons = True
68 port = name[4:]
69 port_num = ord(port) - ord('A')
70
71 for pin_num in range(16):
72 pin = f'P{port}{pin_num}'
73 pins.add(pin)
74 singletons.append(pin)
75
76 # if block_mod == 'dma':
77 # custom_singletons = True
78 # for ch_num in range(8):
79 # channel = f'{name}_CH{ch_num}'
80 # singletons.append(channel)
81
82 if not custom_singletons:
83 singletons.append(name)
84
85 for (channel_id, defn) in core['dma_channels'].items():
86 singletons.append( channel_id )
87
88 f.write(f"embassy_hal_common::peripherals!({','.join(singletons)});")
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
new file mode 100644
index 000000000..659daa377
--- /dev/null
+++ b/embassy-stm32/src/exti.rs
@@ -0,0 +1,270 @@
1use core::convert::Infallible;
2use core::future::Future;
3use core::marker::PhantomData;
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
7use embassy::util::{AtomicWaker, Unborrow};
8use embassy_hal_common::unsafe_impl_unborrow;
9use embedded_hal::digital::v2::InputPin;
10
11use crate::gpio::{AnyPin, Input, Pin as GpioPin};
12use crate::interrupt;
13use crate::pac;
14use crate::pac::{EXTI, SYSCFG};
15use crate::peripherals;
16
17const EXTI_COUNT: usize = 16;
18const NEW_AW: AtomicWaker = AtomicWaker::new();
19static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT];
20
21#[cfg(exti_w)]
22fn cpu_regs() -> pac::exti::Cpu {
23 EXTI.cpu(crate::pac::CORE_INDEX)
24}
25
26#[cfg(not(exti_w))]
27fn cpu_regs() -> pac::exti::Exti {
28 EXTI
29}
30
31pub unsafe fn on_irq() {
32 let bits = EXTI.pr(0).read();
33
34 // Mask all the channels that fired.
35 cpu_regs().imr(0).modify(|w| w.0 &= !bits.0);
36
37 // Wake the tasks
38 for pin in BitIter(bits.0) {
39 EXTI_WAKERS[pin as usize].wake();
40 }
41
42 // Clear pending
43 EXTI.pr(0).write_value(bits);
44}
45
46struct BitIter(u32);
47
48impl Iterator for BitIter {
49 type Item = u32;
50
51 fn next(&mut self) -> Option<Self::Item> {
52 match self.0.trailing_zeros() {
53 32 => None,
54 b => {
55 self.0 &= !(1 << b);
56 Some(b)
57 }
58 }
59 }
60}
61
62/// EXTI input driver
63pub struct ExtiInput<'d, T: GpioPin> {
64 pin: Input<'d, T>,
65}
66
67impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {}
68
69impl<'d, T: GpioPin> ExtiInput<'d, T> {
70 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
71 Self { pin }
72 }
73}
74
75impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
76 type Error = Infallible;
77
78 fn is_high(&self) -> Result<bool, Self::Error> {
79 self.pin.is_high()
80 }
81
82 fn is_low(&self) -> Result<bool, Self::Error> {
83 self.pin.is_low()
84 }
85}
86
87impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
88 type Future<'a> = ExtiInputFuture<'a>;
89
90 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
91 ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, false)
92 }
93}
94
95impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
96 type Future<'a> = ExtiInputFuture<'a>;
97
98 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
99 ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), false, true)
100 }
101}
102
103impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
104 type Future<'a> = ExtiInputFuture<'a>;
105
106 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
107 ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, true)
108 }
109}
110
111pub struct ExtiInputFuture<'a> {
112 pin: u8,
113 phantom: PhantomData<&'a mut AnyPin>,
114}
115
116impl<'a> ExtiInputFuture<'a> {
117 fn new(pin: u8, port: u8, rising: bool, falling: bool) -> Self {
118 cortex_m::interrupt::free(|_| unsafe {
119 let pin = pin as usize;
120 SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
121 EXTI.rtsr(0).modify(|w| w.set_line(pin, rising));
122 EXTI.ftsr(0).modify(|w| w.set_line(pin, falling));
123 EXTI.pr(0).write(|w| w.set_line(pin, true)); // clear pending bit
124 cpu_regs().imr(0).modify(|w| w.set_line(pin, true));
125 });
126
127 Self {
128 pin,
129 phantom: PhantomData,
130 }
131 }
132}
133
134impl<'a> Drop for ExtiInputFuture<'a> {
135 fn drop(&mut self) {
136 cortex_m::interrupt::free(|_| unsafe {
137 let pin = self.pin as _;
138 cpu_regs().imr(0).modify(|w| w.set_line(pin, false));
139 });
140 }
141}
142
143impl<'a> Future for ExtiInputFuture<'a> {
144 type Output = ();
145
146 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
147 EXTI_WAKERS[self.pin as usize].register(cx.waker());
148
149 let imr = unsafe { cpu_regs().imr(0).read() };
150 if !imr.line(self.pin as _) {
151 Poll::Ready(())
152 } else {
153 Poll::Pending
154 }
155 }
156}
157
158macro_rules! foreach_exti_irq {
159 ($action:ident) => {
160 crate::pac::interrupts!(
161 (EXTI0) => { $action!(EXTI0); };
162 (EXTI1) => { $action!(EXTI1); };
163 (EXTI2) => { $action!(EXTI2); };
164 (EXTI3) => { $action!(EXTI3); };
165 (EXTI4) => { $action!(EXTI4); };
166 (EXTI5) => { $action!(EXTI5); };
167 (EXTI6) => { $action!(EXTI6); };
168 (EXTI7) => { $action!(EXTI7); };
169 (EXTI8) => { $action!(EXTI8); };
170 (EXTI9) => { $action!(EXTI9); };
171 (EXTI10) => { $action!(EXTI10); };
172 (EXTI11) => { $action!(EXTI11); };
173 (EXTI12) => { $action!(EXTI12); };
174 (EXTI13) => { $action!(EXTI13); };
175 (EXTI14) => { $action!(EXTI14); };
176 (EXTI15) => { $action!(EXTI15); };
177
178 // plus the weird ones
179 (EXTI0_1) => { $action!( EXTI0_1 ); };
180 (EXTI15_10) => { $action!(EXTI15_10); };
181 (EXTI15_4) => { $action!(EXTI15_4); };
182 (EXTI1_0) => { $action!(EXTI1_0); };
183 (EXTI2_3) => { $action!(EXTI2_3); };
184 (EXTI2_TSC) => { $action!(EXTI2_TSC); };
185 (EXTI3_2) => { $action!(EXTI3_2); };
186 (EXTI4_15) => { $action!(EXTI4_15); };
187 (EXTI9_5) => { $action!(EXTI9_5); };
188 );
189 };
190}
191
192macro_rules! impl_irq {
193 ($e:ident) => {
194 #[interrupt]
195 unsafe fn $e() {
196 on_irq()
197 }
198 };
199}
200
201foreach_exti_irq!(impl_irq);
202
203pub(crate) mod sealed {
204 pub trait Channel {}
205}
206
207pub trait Channel: sealed::Channel + Sized {
208 fn number(&self) -> usize;
209 fn degrade(self) -> AnyChannel {
210 AnyChannel {
211 number: self.number() as u8,
212 }
213 }
214}
215
216pub struct AnyChannel {
217 number: u8,
218}
219unsafe_impl_unborrow!(AnyChannel);
220impl sealed::Channel for AnyChannel {}
221impl Channel for AnyChannel {
222 fn number(&self) -> usize {
223 self.number as usize
224 }
225}
226
227macro_rules! impl_exti {
228 ($type:ident, $number:expr) => {
229 impl sealed::Channel for peripherals::$type {}
230 impl Channel for peripherals::$type {
231 fn number(&self) -> usize {
232 $number as usize
233 }
234 }
235 };
236}
237
238impl_exti!(EXTI0, 0);
239impl_exti!(EXTI1, 1);
240impl_exti!(EXTI2, 2);
241impl_exti!(EXTI3, 3);
242impl_exti!(EXTI4, 4);
243impl_exti!(EXTI5, 5);
244impl_exti!(EXTI6, 6);
245impl_exti!(EXTI7, 7);
246impl_exti!(EXTI8, 8);
247impl_exti!(EXTI9, 9);
248impl_exti!(EXTI10, 10);
249impl_exti!(EXTI11, 11);
250impl_exti!(EXTI12, 12);
251impl_exti!(EXTI13, 13);
252impl_exti!(EXTI14, 14);
253impl_exti!(EXTI15, 15);
254
255macro_rules! enable_irq {
256 ($e:ident) => {
257 crate::interrupt::$e::steal().enable();
258 };
259}
260
261/// safety: must be called only once
262pub(crate) unsafe fn init() {
263 use embassy::interrupt::Interrupt;
264 use embassy::interrupt::InterruptExt;
265
266 foreach_exti_irq!(enable_irq);
267
268 #[cfg(not(any(rcc_wb, rcc_wl5)))]
269 <crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
270}
diff --git a/embassy-stm32/src/exti/mod.rs b/embassy-stm32/src/exti/mod.rs
deleted file mode 100644
index 3f43e0bc7..000000000
--- a/embassy-stm32/src/exti/mod.rs
+++ /dev/null
@@ -1,116 +0,0 @@
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_h7, path = "v1.rs")]
39#[cfg_attr(exti_wb55, path = "v2.rs")]
40#[cfg_attr(exti_wl5x, path = "v2.rs")]
41mod _version;
42
43#[allow(unused)]
44pub use _version::*;
45
46use crate::peripherals;
47use embassy_hal_common::unsafe_impl_unborrow;
48
49pub(crate) mod sealed {
50 pub trait Channel {}
51}
52
53pub trait Channel: sealed::Channel + Sized {
54 fn number(&self) -> usize;
55 fn degrade(self) -> AnyChannel {
56 AnyChannel {
57 number: self.number() as u8,
58 }
59 }
60}
61
62pub struct AnyChannel {
63 number: u8,
64}
65unsafe_impl_unborrow!(AnyChannel);
66impl sealed::Channel for AnyChannel {}
67impl Channel for AnyChannel {
68 fn number(&self) -> usize {
69 self.number as usize
70 }
71}
72
73macro_rules! impl_exti {
74 ($type:ident, $number:expr) => {
75 impl sealed::Channel for peripherals::$type {}
76 impl Channel for peripherals::$type {
77 fn number(&self) -> usize {
78 $number as usize
79 }
80 }
81 };
82}
83
84impl_exti!(EXTI0, 0);
85impl_exti!(EXTI1, 1);
86impl_exti!(EXTI2, 2);
87impl_exti!(EXTI3, 3);
88impl_exti!(EXTI4, 4);
89impl_exti!(EXTI5, 5);
90impl_exti!(EXTI6, 6);
91impl_exti!(EXTI7, 7);
92impl_exti!(EXTI8, 8);
93impl_exti!(EXTI9, 9);
94impl_exti!(EXTI10, 10);
95impl_exti!(EXTI11, 11);
96impl_exti!(EXTI12, 12);
97impl_exti!(EXTI13, 13);
98impl_exti!(EXTI14, 14);
99impl_exti!(EXTI15, 15);
100
101macro_rules! enable_irq {
102 ($e:ident) => {
103 crate::interrupt::$e::steal().enable();
104 };
105}
106
107/// safety: must be called only once
108pub(crate) unsafe fn init() {
109 use embassy::interrupt::Interrupt;
110 use embassy::interrupt::InterruptExt;
111
112 foreach_exti_irq!(enable_irq);
113
114 #[cfg(not(any(rcc_wb55, rcc_wl5x)))]
115 <crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
116}
diff --git a/embassy-stm32/src/exti/v1.rs b/embassy-stm32/src/exti/v1.rs
deleted file mode 100644
index caf457605..000000000
--- a/embassy-stm32/src/exti/v1.rs
+++ /dev/null
@@ -1,171 +0,0 @@
1use core::convert::Infallible;
2use core::future::Future;
3use core::marker::PhantomData;
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
7use embassy::util::{AtomicWaker, Unborrow};
8use embedded_hal::digital::v2::InputPin;
9use pac::exti::{regs, vals};
10
11use crate::gpio::{AnyPin, Input, Pin as GpioPin};
12use crate::pac;
13use crate::pac::{EXTI, SYSCFG};
14
15const EXTI_COUNT: usize = 16;
16const NEW_AW: AtomicWaker = AtomicWaker::new();
17static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT];
18
19pub unsafe fn on_irq() {
20 let bits = EXTI.pr().read().0;
21
22 // Mask all the channels that fired.
23 EXTI.imr().modify(|w| w.0 &= !bits);
24
25 // Wake the tasks
26 for pin in BitIter(bits) {
27 EXTI_WAKERS[pin as usize].wake();
28 }
29
30 // Clear pending
31 EXTI.pr().write_value(regs::Pr(bits));
32}
33
34struct BitIter(u32);
35
36impl Iterator for BitIter {
37 type Item = u32;
38
39 fn next(&mut self) -> Option<Self::Item> {
40 match self.0.trailing_zeros() {
41 32 => None,
42 b => {
43 self.0 &= !(1 << b);
44 Some(b)
45 }
46 }
47 }
48}
49
50/// EXTI input driver
51pub struct ExtiInput<'d, T: GpioPin> {
52 pin: Input<'d, T>,
53}
54
55impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {}
56
57impl<'d, T: GpioPin> ExtiInput<'d, T> {
58 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
59 Self { pin }
60 }
61}
62
63impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
64 type Error = Infallible;
65
66 fn is_high(&self) -> Result<bool, Self::Error> {
67 self.pin.is_high()
68 }
69
70 fn is_low(&self) -> Result<bool, Self::Error> {
71 self.pin.is_low()
72 }
73}
74
75impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
76 type Future<'a> = ExtiInputFuture<'a>;
77
78 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
79 ExtiInputFuture::new(
80 self.pin.pin.pin(),
81 self.pin.pin.port(),
82 vals::Tr::ENABLED,
83 vals::Tr::DISABLED,
84 )
85 }
86}
87
88impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
89 type Future<'a> = ExtiInputFuture<'a>;
90
91 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
92 ExtiInputFuture::new(
93 self.pin.pin.pin(),
94 self.pin.pin.port(),
95 vals::Tr::DISABLED,
96 vals::Tr::ENABLED,
97 )
98 }
99}
100
101impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
102 type Future<'a> = ExtiInputFuture<'a>;
103
104 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
105 ExtiInputFuture::new(
106 self.pin.pin.pin(),
107 self.pin.pin.port(),
108 vals::Tr::ENABLED,
109 vals::Tr::ENABLED,
110 )
111 }
112}
113
114pub struct ExtiInputFuture<'a> {
115 pin: u8,
116 phantom: PhantomData<&'a mut AnyPin>,
117}
118
119impl<'a> ExtiInputFuture<'a> {
120 fn new(pin: u8, port: u8, rising: vals::Tr, falling: vals::Tr) -> Self {
121 cortex_m::interrupt::free(|_| unsafe {
122 let pin = pin as usize;
123 SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
124 EXTI.rtsr().modify(|w| w.set_tr(pin, rising));
125 EXTI.ftsr().modify(|w| w.set_tr(pin, falling));
126 EXTI.pr().write(|w| w.set_pr(pin, true)); // clear pending bit
127 EXTI.imr().modify(|w| w.set_mr(pin, vals::Mr::UNMASKED));
128 });
129
130 Self {
131 pin,
132 phantom: PhantomData,
133 }
134 }
135}
136
137impl<'a> Drop for ExtiInputFuture<'a> {
138 fn drop(&mut self) {
139 cortex_m::interrupt::free(|_| unsafe {
140 let pin = self.pin as _;
141 EXTI.imr().modify(|w| w.set_mr(pin, vals::Mr::MASKED));
142 });
143 }
144}
145
146impl<'a> Future for ExtiInputFuture<'a> {
147 type Output = ();
148
149 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
150 EXTI_WAKERS[self.pin as usize].register(cx.waker());
151
152 if unsafe { EXTI.imr().read().mr(self.pin as _) == vals::Mr::MASKED } {
153 Poll::Ready(())
154 } else {
155 Poll::Pending
156 }
157 }
158}
159
160use crate::interrupt;
161
162macro_rules! impl_irq {
163 ($e:ident) => {
164 #[interrupt]
165 unsafe fn $e() {
166 on_irq()
167 }
168 };
169}
170
171foreach_exti_irq!(impl_irq);
diff --git a/embassy-stm32/src/exti/v2.rs b/embassy-stm32/src/exti/v2.rs
deleted file mode 100644
index 2e62331fe..000000000
--- a/embassy-stm32/src/exti/v2.rs
+++ /dev/null
@@ -1,184 +0,0 @@
1use core::convert::Infallible;
2use core::future::Future;
3use core::marker::PhantomData;
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
7use embassy::util::{AtomicWaker, Unborrow};
8use embedded_hal::digital::v2::InputPin;
9use pac::exti::{regs, vals};
10
11use crate::gpio::{AnyPin, Input, Pin as GpioPin};
12use crate::pac;
13use crate::pac::CORE_INDEX;
14use crate::pac::{EXTI, SYSCFG};
15
16const EXTI_COUNT: usize = 16;
17const NEW_AW: AtomicWaker = AtomicWaker::new();
18static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT];
19
20pub unsafe fn on_irq() {
21 let bits = EXTI.pr(0).read().0;
22
23 // Mask all the channels that fired.
24 EXTI.cpu(CORE_INDEX)
25 .imr(CORE_INDEX)
26 .modify(|w| w.0 &= !bits);
27
28 // Wake the tasks
29 for pin in BitIter(bits) {
30 EXTI_WAKERS[pin as usize].wake();
31 }
32
33 // Clear pending
34 EXTI.pr(0).write_value(regs::Pr(bits));
35}
36
37struct BitIter(u32);
38
39impl Iterator for BitIter {
40 type Item = u32;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 match self.0.trailing_zeros() {
44 32 => None,
45 b => {
46 self.0 &= !(1 << b);
47 Some(b)
48 }
49 }
50 }
51}
52
53/// EXTI input driver
54pub struct ExtiInput<'d, T: GpioPin> {
55 pin: Input<'d, T>,
56}
57
58impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {}
59
60impl<'d, T: GpioPin> ExtiInput<'d, T> {
61 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
62 Self { pin }
63 }
64}
65
66impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
67 type Error = Infallible;
68
69 fn is_high(&self) -> Result<bool, Self::Error> {
70 self.pin.is_high()
71 }
72
73 fn is_low(&self) -> Result<bool, Self::Error> {
74 self.pin.is_low()
75 }
76}
77
78impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
79 type Future<'a> = ExtiInputFuture<'a>;
80
81 fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
82 ExtiInputFuture::new(
83 self.pin.pin.pin(),
84 self.pin.pin.port(),
85 vals::Rt::ENABLED,
86 vals::Ft::DISABLED,
87 )
88 }
89}
90
91impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
92 type Future<'a> = ExtiInputFuture<'a>;
93
94 fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
95 ExtiInputFuture::new(
96 self.pin.pin.pin(),
97 self.pin.pin.port(),
98 vals::Rt::DISABLED,
99 vals::Ft::ENABLED,
100 )
101 }
102}
103
104impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
105 type Future<'a> = ExtiInputFuture<'a>;
106
107 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
108 ExtiInputFuture::new(
109 self.pin.pin.pin(),
110 self.pin.pin.port(),
111 vals::Rt::ENABLED,
112 vals::Ft::ENABLED,
113 )
114 }
115}
116
117pub struct ExtiInputFuture<'a> {
118 pin: u8,
119 phantom: PhantomData<&'a mut AnyPin>,
120}
121
122impl<'a> ExtiInputFuture<'a> {
123 fn new(pin: u8, port: u8, rising: vals::Rt, falling: vals::Ft) -> Self {
124 cortex_m::interrupt::free(|_| unsafe {
125 let pin = pin as usize;
126 SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
127 EXTI.rtsr(CORE_INDEX).modify(|w| w.set_rt(pin, rising));
128 EXTI.ftsr(CORE_INDEX).modify(|w| w.set_ft(pin, falling));
129 EXTI.pr(CORE_INDEX).write(|w| w.set_pif(pin, true)); // clear pending bit
130 EXTI.cpu(CORE_INDEX)
131 .imr(CORE_INDEX)
132 .modify(|w| w.set_im(pin, vals::Mr::UNMASKED));
133 });
134
135 Self {
136 pin,
137 phantom: PhantomData,
138 }
139 }
140}
141
142impl<'a> Drop for ExtiInputFuture<'a> {
143 fn drop(&mut self) {
144 cortex_m::interrupt::free(|_| unsafe {
145 let pin = self.pin as _;
146 EXTI.cpu(CORE_INDEX)
147 .imr(CORE_INDEX)
148 .modify(|w| w.set_im(pin, vals::Mr::MASKED));
149 });
150 }
151}
152
153impl<'a> Future for ExtiInputFuture<'a> {
154 type Output = ();
155
156 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
157 EXTI_WAKERS[self.pin as usize].register(cx.waker());
158
159 if unsafe {
160 EXTI.cpu(CORE_INDEX)
161 .imr(CORE_INDEX)
162 .read()
163 .im(self.pin as _)
164 == vals::Mr::MASKED
165 } {
166 Poll::Ready(())
167 } else {
168 Poll::Pending
169 }
170 }
171}
172
173use crate::interrupt;
174
175macro_rules! impl_irq {
176 ($e:ident) => {
177 #[interrupt]
178 unsafe fn $e() {
179 on_irq()
180 }
181 };
182}
183
184foreach_exti_irq!(impl_irq);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index af4ab95fd..503d10f57 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -68,12 +68,14 @@ pub use generated::{peripherals, Peripherals};
68#[non_exhaustive] 68#[non_exhaustive]
69pub struct Config { 69pub struct Config {
70 pub rcc: rcc::Config, 70 pub rcc: rcc::Config,
71 pub enable_debug_during_sleep: bool,
71} 72}
72 73
73impl Default for Config { 74impl Default for Config {
74 fn default() -> Self { 75 fn default() -> Self {
75 Self { 76 Self {
76 rcc: Default::default(), 77 rcc: Default::default(),
78 enable_debug_during_sleep: true,
77 } 79 }
78 } 80 }
79} 81}
@@ -83,6 +85,10 @@ pub fn init(config: Config) -> Peripherals {
83 let p = Peripherals::take(); 85 let p = Peripherals::take();
84 86
85 unsafe { 87 unsafe {
88 if config.enable_debug_during_sleep {
89 dbgmcu::Dbgmcu::enable_all();
90 }
91
86 gpio::init(); 92 gpio::init();
87 dma::init(); 93 dma::init();
88 #[cfg(exti)] 94 #[cfg(exti)]
diff --git a/embassy-stm32/src/rcc/f0/mod.rs b/embassy-stm32/src/rcc/f0/mod.rs
index 6600a1e28..916ed39fc 100644
--- a/embassy-stm32/src/rcc/f0/mod.rs
+++ b/embassy-stm32/src/rcc/f0/mod.rs
@@ -2,7 +2,6 @@ use core::marker::PhantomData;
2 2
3use embassy::util::Unborrow; 3use embassy::util::Unborrow;
4 4
5use crate::dbgmcu::Dbgmcu;
6use crate::pac::{FLASH, RCC}; 5use crate::pac::{FLASH, RCC};
7use crate::peripherals; 6use crate::peripherals;
8use crate::time::Hertz; 7use crate::time::Hertz;
@@ -27,7 +26,6 @@ pub struct Config {
27 pub sys_ck: Option<Hertz>, 26 pub sys_ck: Option<Hertz>,
28 pub hclk: Option<Hertz>, 27 pub hclk: Option<Hertz>,
29 pub pclk: Option<Hertz>, 28 pub pclk: Option<Hertz>,
30 pub enable_debug_wfe: bool,
31} 29}
32 30
33pub struct Rcc<'d> { 31pub struct Rcc<'d> {
@@ -190,12 +188,6 @@ impl<'d> Rcc<'d> {
190 } 188 }
191 }) 189 })
192 } 190 }
193
194 if self.config.enable_debug_wfe {
195 RCC.ahbenr().modify(|w| w.set_dmaen(true));
196
197 critical_section::with(|_| Dbgmcu::enable_all());
198 }
199 } 191 }
200 192
201 Clocks { 193 Clocks {
@@ -210,18 +202,6 @@ impl<'d> Rcc<'d> {
210} 202}
211 203
212pub unsafe fn init(config: Config) { 204pub unsafe fn init(config: Config) {
213 RCC.ahbenr().modify(|w| {
214 w.set_iopaen(true);
215 w.set_iopben(true);
216 w.set_iopcen(true);
217 w.set_iopden(true);
218
219 #[cfg(rcc_f0)]
220 w.set_iopeen(true);
221
222 w.set_iopfen(true);
223 });
224
225 let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config); 205 let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config);
226 let clocks = rcc.freeze(); 206 let clocks = rcc.freeze();
227 set_freqs(clocks); 207 set_freqs(clocks);
diff --git a/embassy-stm32/src/rcc/f4/mod.rs b/embassy-stm32/src/rcc/f4/mod.rs
index eab98daf8..04083dfa1 100644
--- a/embassy-stm32/src/rcc/f4/mod.rs
+++ b/embassy-stm32/src/rcc/f4/mod.rs
@@ -21,7 +21,6 @@ pub struct Config {
21 pub hclk: Option<Hertz>, 21 pub hclk: Option<Hertz>,
22 pub pclk1: Option<Hertz>, 22 pub pclk1: Option<Hertz>,
23 pub pclk2: Option<Hertz>, 23 pub pclk2: Option<Hertz>,
24 pub enable_debug_wfe: bool,
25} 24}
26 25
27/// RCC peripheral 26/// RCC peripheral
@@ -176,15 +175,6 @@ impl<'d> Rcc<'d> {
176 }); 175 });
177 } 176 }
178 177
179 if self.config.enable_debug_wfe {
180 unsafe {
181 RCC.ahb1enr().modify(|w| w.set_dma1en(true));
182 critical_section::with(|_| {
183 crate::dbgmcu::Dbgmcu::enable_all();
184 });
185 }
186 }
187
188 Clocks { 178 Clocks {
189 sys: Hertz(sysclk), 179 sys: Hertz(sysclk),
190 apb1: Hertz(pclk1), 180 apb1: Hertz(pclk1),
diff --git a/embassy-stm32/src/rcc/h7/mod.rs b/embassy-stm32/src/rcc/h7/mod.rs
index d6a55c3b4..5567a478b 100644
--- a/embassy-stm32/src/rcc/h7/mod.rs
+++ b/embassy-stm32/src/rcc/h7/mod.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3use embassy::util::Unborrow; 3use embassy::util::Unborrow;
4 4
5use crate::pac::rcc::vals::Timpre; 5use crate::pac::rcc::vals::Timpre;
6use crate::pac::{DBGMCU, RCC, SYSCFG}; 6use crate::pac::{RCC, SYSCFG};
7use crate::peripherals; 7use crate::peripherals;
8use crate::pwr::{Power, VoltageScale}; 8use crate::pwr::{Power, VoltageScale};
9use crate::rcc::{set_freqs, Clocks}; 9use crate::rcc::{set_freqs, Clocks};
@@ -363,25 +363,6 @@ impl<'d> Rcc<'d> {
363 } 363 }
364 } 364 }
365 365
366 /// Enables debugging during WFI/WFE
367 ///
368 /// Set `enable_dma1` to true if you do not have at least one bus master (other than the CPU)
369 /// enable during WFI/WFE
370 pub fn enable_debug_wfe(&mut self, _dbg: &mut peripherals::DBGMCU, enable_dma1: bool) {
371 // NOTE(unsafe) We have exclusive access to the RCC and DBGMCU
372 unsafe {
373 if enable_dma1 {
374 RCC.ahb1enr().modify(|w| w.set_dma1en(true));
375 }
376
377 DBGMCU.cr().modify(|w| {
378 w.set_dbgsleep_d1(true);
379 w.set_dbgstby_d1(true);
380 w.set_dbgstop_d1(true);
381 });
382 }
383 }
384
385 /// Setup traceclk 366 /// Setup traceclk
386 /// Returns a pll1_r_ck 367 /// Returns a pll1_r_ck
387 fn traceclk_setup(&mut self, sys_use_pll1_p: bool) { 368 fn traceclk_setup(&mut self, sys_use_pll1_p: bool) {
diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs
index 290449e19..e65faaa2c 100644
--- a/embassy-stm32/src/rcc/l0/mod.rs
+++ b/embassy-stm32/src/rcc/l0/mod.rs
@@ -1,5 +1,4 @@
1pub use super::types::*; 1pub use super::types::*;
2use crate::dbgmcu::Dbgmcu;
3use crate::pac; 2use crate::pac;
4use crate::peripherals::{self, CRS, RCC, SYSCFG}; 3use crate::peripherals::{self, CRS, RCC, SYSCFG};
5use crate::rcc::{get_freqs, set_freqs, Clocks}; 4use crate::rcc::{get_freqs, set_freqs, Clocks};
@@ -168,15 +167,6 @@ impl<'d> Rcc<'d> {
168 unsafe { get_freqs() } 167 unsafe { get_freqs() }
169 } 168 }
170 169
171 pub fn enable_debug_wfe(&mut self, _dbg: &mut peripherals::DBGMCU, enable_dma: bool) {
172 // NOTE(unsafe) We have exclusive access to the RCC and DBGMCU
173 unsafe {
174 pac::RCC.ahbenr().modify(|w| w.set_dma1en(enable_dma));
175
176 Dbgmcu::enable_all();
177 }
178 }
179
180 pub fn enable_hsi48(&mut self, _syscfg: &mut SYSCFG, _crs: CRS) -> HSI48 { 170 pub fn enable_hsi48(&mut self, _syscfg: &mut SYSCFG, _crs: CRS) -> HSI48 {
181 let rcc = pac::RCC; 171 let rcc = pac::RCC;
182 unsafe { 172 unsafe {
@@ -387,16 +377,6 @@ impl RccExt for RCC {
387pub struct HSI48(()); 377pub struct HSI48(());
388 378
389pub unsafe fn init(config: Config) { 379pub unsafe fn init(config: Config) {
390 let rcc = pac::RCC;
391 rcc.iopenr().write(|w| {
392 w.set_iopaen(true);
393 w.set_iopben(true);
394 w.set_iopcen(true);
395 w.set_iopden(true);
396 w.set_iopeen(true);
397 w.set_iophen(true);
398 });
399
400 let r = <peripherals::RCC as embassy::util::Steal>::steal(); 380 let r = <peripherals::RCC as embassy::util::Steal>::steal();
401 let clocks = r.freeze(config); 381 let clocks = r.freeze(config);
402 set_freqs(clocks); 382 set_freqs(clocks);
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 87be0a5b3..9c8da4a98 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -10,6 +10,8 @@ pub struct Clocks {
10 pub sys: Hertz, 10 pub sys: Hertz,
11 pub apb1: Hertz, 11 pub apb1: Hertz,
12 pub apb2: Hertz, 12 pub apb2: Hertz,
13 #[cfg(rcc_wl5)]
14 pub apb3: Hertz,
13 15
14 pub apb1_tim: Hertz, 16 pub apb1_tim: Hertz,
15 pub apb2_tim: Hertz, 17 pub apb2_tim: Hertz,
@@ -17,13 +19,13 @@ pub struct Clocks {
17 #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))] 19 #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))]
18 pub ahb: Hertz, 20 pub ahb: Hertz,
19 21
20 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] 22 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))]
21 pub ahb1: Hertz, 23 pub ahb1: Hertz,
22 24
23 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] 25 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))]
24 pub ahb2: Hertz, 26 pub ahb2: Hertz,
25 27
26 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] 28 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))]
27 pub ahb3: Hertz, 29 pub ahb3: Hertz,
28 30
29 #[cfg(any(rcc_h7))] 31 #[cfg(any(rcc_h7))]
@@ -66,10 +68,10 @@ cfg_if::cfg_if! {
66 } else if #[cfg(rcc_f4)] { 68 } else if #[cfg(rcc_f4)] {
67 mod f4; 69 mod f4;
68 pub use f4::*; 70 pub use f4::*;
69 } else if #[cfg(rcc_wb55)] { 71 } else if #[cfg(rcc_wb)] {
70 mod wb55; 72 mod wb;
71 pub use wb55::*; 73 pub use wb::*;
72 } else if #[cfg(rcc_wl5x)] { 74 } else if #[cfg(rcc_wl5)] {
73 mod wl5x; 75 mod wl5x;
74 pub use wl5x::*; 76 pub use wl5x::*;
75 } else if #[cfg(any(rcc_f0, rcc_f0x0))] { 77 } else if #[cfg(any(rcc_f0, rcc_f0x0))] {
diff --git a/embassy-stm32/src/rcc/wb55/mod.rs b/embassy-stm32/src/rcc/wb/mod.rs
index 4247d8ffb..4247d8ffb 100644
--- a/embassy-stm32/src/rcc/wb55/mod.rs
+++ b/embassy-stm32/src/rcc/wb/mod.rs
diff --git a/embassy-stm32/src/rcc/wl5x/mod.rs b/embassy-stm32/src/rcc/wl5x/mod.rs
index 72caad2ec..e1e001c7b 100644
--- a/embassy-stm32/src/rcc/wl5x/mod.rs
+++ b/embassy-stm32/src/rcc/wl5x/mod.rs
@@ -190,6 +190,9 @@ impl RccExt for RCC {
190 } 190 }
191 }; 191 };
192 192
193 // TODO: completely untested
194 let apb3_freq = ahb_freq;
195
193 Clocks { 196 Clocks {
194 sys: sys_clk.hz(), 197 sys: sys_clk.hz(),
195 ahb1: ahb_freq.hz(), 198 ahb1: ahb_freq.hz(),
@@ -197,6 +200,7 @@ impl RccExt for RCC {
197 ahb3: ahb_freq.hz(), 200 ahb3: ahb_freq.hz(),
198 apb1: apb1_freq.hz(), 201 apb1: apb1_freq.hz(),
199 apb2: apb2_freq.hz(), 202 apb2: apb2_freq.hz(),
203 apb3: apb3_freq.hz(),
200 apb1_tim: apb1_tim_freq.hz(), 204 apb1_tim: apb1_tim_freq.hz(),
201 apb2_tim: apb2_tim_freq.hz(), 205 apb2_tim: apb2_tim_freq.hz(),
202 } 206 }
diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs
index 8429cc603..418f27943 100644
--- a/examples/stm32f0/src/bin/hello.rs
+++ b/examples/stm32f0/src/bin/hello.rs
@@ -12,7 +12,7 @@ use embassy_stm32::Peripherals;
12#[path = "../example_common.rs"] 12#[path = "../example_common.rs"]
13mod example_common; 13mod example_common;
14 14
15#[embassy::main(config = "example_common::config()")] 15#[embassy::main]
16async fn main(_spawner: Spawner, _p: Peripherals) -> ! { 16async fn main(_spawner: Spawner, _p: Peripherals) -> ! {
17 loop { 17 loop {
18 Timer::after(Duration::from_secs(1)).await; 18 Timer::after(Duration::from_secs(1)).await;
diff --git a/examples/stm32f0/src/example_common.rs b/examples/stm32f0/src/example_common.rs
index f50119653..54d633837 100644
--- a/examples/stm32f0/src/example_common.rs
+++ b/examples/stm32f0/src/example_common.rs
@@ -6,13 +6,6 @@ use panic_probe as _;
6pub use defmt::*; 6pub use defmt::*;
7 7
8use core::sync::atomic::{AtomicUsize, Ordering}; 8use core::sync::atomic::{AtomicUsize, Ordering};
9use embassy_stm32::Config;
10
11pub fn config() -> Config {
12 let mut config = Config::default();
13 config.rcc.enable_debug_wfe = true;
14 config
15}
16 9
17defmt::timestamp! {"{=u64}", { 10defmt::timestamp! {"{=u64}", {
18 static COUNT: AtomicUsize = AtomicUsize::new(0); 11 static COUNT: AtomicUsize = AtomicUsize::new(0);
diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs
index b3a0ffb8e..a30887f7d 100644
--- a/examples/stm32f4/src/bin/blinky.rs
+++ b/examples/stm32f4/src/bin/blinky.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
14use embedded_hal::digital::v2::OutputPin; 13use embedded_hal::digital::v2::OutputPin;
@@ -18,10 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let mut led = Output::new(p.PB7, Level::High, Speed::Low); 20 let mut led = Output::new(p.PB7, Level::High, Speed::Low);
26 21
27 loop { 22 loop {
diff --git a/examples/stm32f4/src/bin/button.rs b/examples/stm32f4/src/bin/button.rs
index 90998cf46..04fcfcc21 100644
--- a/examples/stm32f4/src/bin/button.rs
+++ b/examples/stm32f4/src/bin/button.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use cortex_m_rt::entry; 9use cortex_m_rt::entry;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 10use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
12use embedded_hal::digital::v2::{InputPin, OutputPin}; 11use embedded_hal::digital::v2::{InputPin, OutputPin};
13use example_common::*; 12use example_common::*;
@@ -16,10 +15,6 @@ use example_common::*;
16fn main() -> ! { 15fn main() -> ! {
17 info!("Hello World!"); 16 info!("Hello World!");
18 17
19 unsafe {
20 Dbgmcu::enable_all();
21 }
22
23 let p = embassy_stm32::init(Default::default()); 18 let p = embassy_stm32::init(Default::default());
24 19
25 let button = Input::new(p.PC13, Pull::Down); 20 let button = Input::new(p.PC13, Pull::Down);
diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs
index ee43fa7d9..49c23ca3b 100644
--- a/examples/stm32f4/src/bin/button_exti.rs
+++ b/examples/stm32f4/src/bin/button_exti.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
@@ -18,10 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let button = Input::new(p.PC13, Pull::Down); 20 let button = Input::new(p.PC13, Pull::Down);
26 let mut button = ExtiInput::new(button, p.EXTI13); 21 let mut button = ExtiInput::new(button, p.EXTI13);
27 22
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index 2bb24f045..29dff5510 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -10,7 +10,6 @@ mod example_common;
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use embassy_stm32::can::filter::Mask32; 11use embassy_stm32::can::filter::Mask32;
12use embassy_stm32::can::{Can, Frame, StandardId}; 12use embassy_stm32::can::{Can, Frame, StandardId};
13use embassy_stm32::dbgmcu::Dbgmcu;
14use embassy_stm32::gpio::{Input, Pull}; 13use embassy_stm32::gpio::{Input, Pull};
15use example_common::*; 14use example_common::*;
16 15
@@ -18,10 +17,6 @@ use example_common::*;
18fn main() -> ! { 17fn main() -> ! {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let mut p = embassy_stm32::init(Default::default()); 20 let mut p = embassy_stm32::init(Default::default());
26 21
27 // The next two lines are a workaround for testing without transceiver. 22 // The next two lines are a workaround for testing without transceiver.
diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs
index 1b8730aea..8059f4b5a 100644
--- a/examples/stm32f4/src/bin/hello.rs
+++ b/examples/stm32f4/src/bin/hello.rs
@@ -17,7 +17,6 @@ mod example_common;
17fn config() -> Config { 17fn config() -> Config {
18 let mut config = Config::default(); 18 let mut config = Config::default();
19 config.rcc.sys_ck = Some(Hertz(84_000_000)); 19 config.rcc.sys_ck = Some(Hertz(84_000_000));
20 config.rcc.enable_debug_wfe = true;
21 config 20 config
22} 21}
23 22
diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs
index bb130a2e2..19b6c62aa 100644
--- a/examples/stm32f4/src/bin/spi.rs
+++ b/examples/stm32f4/src/bin/spi.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9 9
10use cortex_m_rt::entry; 10use cortex_m_rt::entry;
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::dma::NoDma; 11use embassy_stm32::dma::NoDma;
13use embassy_stm32::gpio::{Level, Output, Speed}; 12use embassy_stm32::gpio::{Level, Output, Speed};
14use embassy_stm32::spi::{Config, Spi}; 13use embassy_stm32::spi::{Config, Spi};
@@ -21,10 +20,6 @@ use example_common::*;
21fn main() -> ! { 20fn main() -> ! {
22 info!("Hello World, dude!"); 21 info!("Hello World, dude!");
23 22
24 unsafe {
25 Dbgmcu::enable_all();
26 }
27
28 let p = embassy_stm32::init(Default::default()); 23 let p = embassy_stm32::init(Default::default());
29 24
30 let mut spi = Spi::new( 25 let mut spi = Spi::new(
diff --git a/examples/stm32f4/src/bin/spi_dma.rs b/examples/stm32f4/src/bin/spi_dma.rs
index a965bef70..ef88fbb9e 100644
--- a/examples/stm32f4/src/bin/spi_dma.rs
+++ b/examples/stm32f4/src/bin/spi_dma.rs
@@ -9,7 +9,6 @@ mod example_common;
9use core::fmt::Write; 9use core::fmt::Write;
10use core::str::from_utf8; 10use core::str::from_utf8;
11use embassy::executor::Spawner; 11use embassy::executor::Spawner;
12use embassy_stm32::dbgmcu::Dbgmcu;
13use embassy_stm32::spi::{Config, Spi}; 12use embassy_stm32::spi::{Config, Spi};
14use embassy_stm32::time::Hertz; 13use embassy_stm32::time::Hertz;
15use embassy_stm32::Peripherals; 14use embassy_stm32::Peripherals;
@@ -21,10 +20,6 @@ use heapless::String;
21async fn main(_spawner: Spawner, p: Peripherals) { 20async fn main(_spawner: Spawner, p: Peripherals) {
22 info!("Hello World!"); 21 info!("Hello World!");
23 22
24 unsafe {
25 Dbgmcu::enable_all();
26 }
27
28 let mut spi = Spi::new( 23 let mut spi = Spi::new(
29 p.SPI1, 24 p.SPI1,
30 p.PB3, 25 p.PB3,
diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs
index 781c6a958..8bb2ada9e 100644
--- a/examples/stm32f4/src/bin/usart.rs
+++ b/examples/stm32f4/src/bin/usart.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use cortex_m_rt::entry; 9use cortex_m_rt::entry;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
12use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
13use embedded_hal::blocking::serial::Write; 12use embedded_hal::blocking::serial::Write;
@@ -17,10 +16,6 @@ use example_common::*;
17fn main() -> ! { 16fn main() -> ! {
18 info!("Hello World!"); 17 info!("Hello World!");
19 18
20 unsafe {
21 Dbgmcu::enable_all();
22 }
23
24 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
25 20
26 let config = Config::default(); 21 let config = Config::default();
diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs
index bf50b8ad9..3cfa6219c 100644
--- a/examples/stm32f4/src/bin/usart_dma.rs
+++ b/examples/stm32f4/src/bin/usart_dma.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use core::fmt::Write; 9use core::fmt::Write;
10use embassy::executor::Spawner; 10use embassy::executor::Spawner;
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::dma::NoDma; 11use embassy_stm32::dma::NoDma;
13use embassy_stm32::usart::{Config, Uart}; 12use embassy_stm32::usart::{Config, Uart};
14use embassy_stm32::Peripherals; 13use embassy_stm32::Peripherals;
@@ -20,10 +19,6 @@ use heapless::String;
20async fn main(_spawner: Spawner, p: Peripherals) { 19async fn main(_spawner: Spawner, p: Peripherals) {
21 info!("Hello World!"); 20 info!("Hello World!");
22 21
23 unsafe {
24 Dbgmcu::enable_all();
25 }
26
27 let config = Config::default(); 22 let config = Config::default();
28 let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, p.DMA1_CH3, NoDma, config); 23 let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, p.DMA1_CH3, NoDma, config);
29 24
diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs
index 09b34eacb..3784fba84 100644
--- a/examples/stm32h7/src/bin/blinky.rs
+++ b/examples/stm32h7/src/bin/blinky.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
14use embedded_hal::digital::v2::OutputPin; 13use embedded_hal::digital::v2::OutputPin;
@@ -18,8 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe { Dbgmcu::enable_all() };
22
23 let mut led = Output::new(p.PB14, Level::High, Speed::Low); 20 let mut led = Output::new(p.PB14, Level::High, Speed::Low);
24 21
25 loop { 22 loop {
diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs
index ee43fa7d9..49c23ca3b 100644
--- a/examples/stm32h7/src/bin/button_exti.rs
+++ b/examples/stm32h7/src/bin/button_exti.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
@@ -18,10 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let button = Input::new(p.PC13, Pull::Down); 20 let button = Input::new(p.PC13, Pull::Down);
26 let mut button = ExtiInput::new(button, p.EXTI13); 21 let mut button = ExtiInput::new(button, p.EXTI13);
27 22
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index 8816f63c2..e4c3a7312 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -19,10 +19,6 @@ fn main() -> ! {
19 19
20 let p = embassy_stm32::init(config()); 20 let p = embassy_stm32::init(config());
21 21
22 unsafe {
23 Dbgmcu::enable_all();
24 }
25
26 let mut dac = Dac::new(p.DAC1, p.PA4, NoPin); 22 let mut dac = Dac::new(p.DAC1, p.PA4, NoPin);
27 23
28 loop { 24 loop {
@@ -33,7 +29,6 @@ fn main() -> ! {
33 } 29 }
34} 30}
35 31
36use embassy_stm32::dbgmcu::Dbgmcu;
37use micromath::F32Ext; 32use micromath::F32Ext;
38 33
39fn to_sine_wave(v: u8) -> u8 { 34fn to_sine_wave(v: u8) -> u8 {
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index e8d13876a..4a9f261c2 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -19,7 +19,6 @@ use embassy_macros::interrupt_take;
19use embassy_net::{ 19use embassy_net::{
20 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, 20 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
21}; 21};
22use embassy_stm32::dbgmcu::Dbgmcu;
23use embassy_stm32::eth::lan8742a::LAN8742A; 22use embassy_stm32::eth::lan8742a::LAN8742A;
24use embassy_stm32::eth::{Ethernet, State}; 23use embassy_stm32::eth::{Ethernet, State};
25use embassy_stm32::rng::Random; 24use embassy_stm32::rng::Random;
@@ -96,10 +95,6 @@ fn main() -> ! {
96 95
97 info!("Setup RCC..."); 96 info!("Setup RCC...");
98 97
99 unsafe {
100 Dbgmcu::enable_all();
101 }
102
103 let p = embassy_stm32::init(config()); 98 let p = embassy_stm32::init(config());
104 99
105 let rng = Random::new(p.RNG); 100 let rng = Random::new(p.RNG);
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index 047b65849..5514b0d3d 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -17,7 +17,6 @@ use example_common::*;
17 17
18use core::str::from_utf8; 18use core::str::from_utf8;
19use cortex_m_rt::entry; 19use cortex_m_rt::entry;
20use embassy_stm32::dbgmcu::Dbgmcu;
21use embassy_stm32::peripherals::SPI3; 20use embassy_stm32::peripherals::SPI3;
22use embassy_stm32::time::U32Ext; 21use embassy_stm32::time::U32Ext;
23use heapless::String; 22use heapless::String;
@@ -43,10 +42,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
43fn main() -> ! { 42fn main() -> ! {
44 info!("Hello World!"); 43 info!("Hello World!");
45 44
46 unsafe {
47 Dbgmcu::enable_all();
48 }
49
50 let p = embassy_stm32::init(config()); 45 let p = embassy_stm32::init(config());
51 46
52 let spi = spi::Spi::new( 47 let spi = spi::Spi::new(
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index f11b7eb45..ea1605903 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -16,7 +16,6 @@ use example_common::*;
16 16
17use core::str::from_utf8; 17use core::str::from_utf8;
18use cortex_m_rt::entry; 18use cortex_m_rt::entry;
19use embassy_stm32::dbgmcu::Dbgmcu;
20use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; 19use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3};
21use embassy_stm32::spi; 20use embassy_stm32::spi;
22use heapless::String; 21use heapless::String;
@@ -39,10 +38,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
39fn main() -> ! { 38fn main() -> ! {
40 info!("Hello World!"); 39 info!("Hello World!");
41 40
42 unsafe {
43 Dbgmcu::enable_all();
44 }
45
46 let p = embassy_stm32::init(config()); 41 let p = embassy_stm32::init(config());
47 42
48 let spi = spi::Spi::new( 43 let spi = spi::Spi::new(
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs
index a3fcc6d3f..10bf7813d 100644
--- a/examples/stm32h7/src/bin/usart.rs
+++ b/examples/stm32h7/src/bin/usart.rs
@@ -14,7 +14,6 @@ use embassy_stm32::usart::{Config, Uart};
14use example_common::*; 14use example_common::*;
15 15
16use cortex_m_rt::entry; 16use cortex_m_rt::entry;
17use embassy_stm32::dbgmcu::Dbgmcu;
18 17
19#[embassy::task] 18#[embassy::task]
20async fn main_task() { 19async fn main_task() {
@@ -39,10 +38,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
39fn main() -> ! { 38fn main() -> ! {
40 info!("Hello World!"); 39 info!("Hello World!");
41 40
42 unsafe {
43 Dbgmcu::enable_all();
44 }
45
46 let executor = EXECUTOR.put(Executor::new()); 41 let executor = EXECUTOR.put(Executor::new());
47 42
48 executor.run(|spawner| { 43 executor.run(|spawner| {
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index 3f70a82b0..eb71a72cf 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -9,7 +9,6 @@ mod example_common;
9use core::fmt::Write; 9use core::fmt::Write;
10use embassy::executor::Executor; 10use embassy::executor::Executor;
11use embassy::util::Forever; 11use embassy::util::Forever;
12use embassy_stm32::dbgmcu::Dbgmcu;
13use embassy_stm32::dma::NoDma; 12use embassy_stm32::dma::NoDma;
14use embassy_stm32::usart::{Config, Uart}; 13use embassy_stm32::usart::{Config, Uart};
15use embassy_traits::uart::Write as _Write; 14use embassy_traits::uart::Write as _Write;
@@ -41,10 +40,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
41fn main() -> ! { 40fn main() -> ! {
42 info!("Hello World!"); 41 info!("Hello World!");
43 42
44 unsafe {
45 Dbgmcu::enable_all();
46 }
47
48 let executor = EXECUTOR.put(Executor::new()); 43 let executor = EXECUTOR.put(Executor::new());
49 44
50 executor.run(|spawner| { 45 executor.run(|spawner| {
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 9b3166154..07b033c1e 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -27,7 +27,7 @@ defmt = "0.2.0"
27defmt-rtt = "0.2.0" 27defmt-rtt = "0.2.0"
28 28
29cortex-m = "0.7.1" 29cortex-m = "0.7.1"
30cortex-m-rt = "0.6.14" 30cortex-m-rt = "0.7.0"
31embedded-hal = { version = "0.2.4" } 31embedded-hal = { version = "0.2.4" }
32panic-probe = { version = "0.2.0", features= ["print-defmt"] } 32panic-probe = { version = "0.2.0", features= ["print-defmt"] }
33futures = { version = "0.3.8", default-features = false, features = ["async-await"] } 33futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs
index 29f5d7c74..d8513bc7c 100644
--- a/examples/stm32l0/src/bin/blinky.rs
+++ b/examples/stm32l0/src/bin/blinky.rs
@@ -10,17 +10,14 @@ mod example_common;
10use embassy::executor::Spawner; 10use embassy::executor::Spawner;
11use embassy::time::{Duration, Timer}; 11use embassy::time::{Duration, Timer};
12use embassy_stm32::gpio::{Level, Output, Speed}; 12use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::rcc::Rcc;
14use embassy_stm32::Peripherals; 13use embassy_stm32::Peripherals;
15use embedded_hal::digital::v2::OutputPin; 14use embedded_hal::digital::v2::OutputPin;
16use example_common::*; 15use example_common::*;
17 16
18#[embassy::main] 17#[embassy::main]
19async fn main(_spawner: Spawner, mut p: Peripherals) { 18async fn main(_spawner: Spawner, p: Peripherals) {
20 info!("Hello World!"); 19 info!("Hello World!");
21 20
22 Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true);
23
24 let mut led = Output::new(p.PB5, Level::High, Speed::Low); 21 let mut led = Output::new(p.PB5, Level::High, Speed::Low);
25 22
26 loop { 23 loop {
diff --git a/examples/stm32l0/src/bin/button.rs b/examples/stm32l0/src/bin/button.rs
index e37d3f26d..a7e82e37e 100644
--- a/examples/stm32l0/src/bin/button.rs
+++ b/examples/stm32l0/src/bin/button.rs
@@ -6,22 +6,16 @@
6 6
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy_stm32::{ 9use embassy::executor::Spawner;
10 gpio::{Input, Level, Output, Pull, Speed}, 10use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
11 rcc::*, 11use embassy_stm32::Peripherals;
12};
13use embedded_hal::digital::v2::{InputPin, OutputPin}; 12use embedded_hal::digital::v2::{InputPin, OutputPin};
14use example_common::*; 13use example_common::*;
15 14
16use cortex_m_rt::entry; 15#[embassy::main]
17 16async fn main(_spawner: Spawner, p: Peripherals) {
18#[entry]
19fn main() -> ! {
20 info!("Hello World!"); 17 info!("Hello World!");
21 18
22 let mut p = embassy_stm32::init(Default::default());
23 Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true);
24
25 let button = Input::new(p.PB2, Pull::Up); 19 let button = Input::new(p.PB2, Pull::Up);
26 let mut led1 = Output::new(p.PA5, Level::High, Speed::Low); 20 let mut led1 = Output::new(p.PA5, Level::High, Speed::Low);
27 let mut led2 = Output::new(p.PB5, Level::High, Speed::Low); 21 let mut led2 = Output::new(p.PB5, Level::High, Speed::Low);
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs
index 40e25b088..13ce99907 100644
--- a/examples/stm32l0/src/bin/button_exti.rs
+++ b/examples/stm32l0/src/bin/button_exti.rs
@@ -17,7 +17,6 @@ use example_common::*;
17#[embassy::main] 17#[embassy::main]
18async fn main(_spawner: Spawner, mut p: Peripherals) { 18async fn main(_spawner: Spawner, mut p: Peripherals) {
19 let mut rcc = rcc::Rcc::new(p.RCC); 19 let mut rcc = rcc::Rcc::new(p.RCC);
20 rcc.enable_debug_wfe(&mut p.DBGMCU, true);
21 // Enables SYSCFG 20 // Enables SYSCFG
22 let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS); 21 let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS);
23 22
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs
index 43ffb5539..83c4fe322 100644
--- a/examples/stm32l0/src/bin/spi.rs
+++ b/examples/stm32l0/src/bin/spi.rs
@@ -7,25 +7,21 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9 9
10use embassy::executor::Spawner;
10use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
11use embedded_hal::digital::v2::OutputPin; 12use embedded_hal::digital::v2::OutputPin;
12use example_common::*; 13use example_common::*;
13 14
14use cortex_m_rt::entry;
15use embassy_stm32::dma::NoDma; 15use embassy_stm32::dma::NoDma;
16use embassy_stm32::rcc;
17use embassy_stm32::spi::{Config, Spi}; 16use embassy_stm32::spi::{Config, Spi};
18use embassy_stm32::time::Hertz; 17use embassy_stm32::time::Hertz;
18use embassy_stm32::Peripherals;
19use embedded_hal::blocking::spi::Transfer; 19use embedded_hal::blocking::spi::Transfer;
20 20
21#[entry] 21#[embassy::main]
22fn main() -> ! { 22async fn main(_spawner: Spawner, p: Peripherals) {
23 info!("Hello World, folks!"); 23 info!("Hello World, folks!");
24 24
25 let mut p = embassy_stm32::init(Default::default());
26 let mut rcc = rcc::Rcc::new(p.RCC);
27 rcc.enable_debug_wfe(&mut p.DBGMCU, true);
28
29 let mut spi = Spi::new( 25 let mut spi = Spi::new(
30 p.SPI1, 26 p.SPI1,
31 p.PB3, 27 p.PB3,
@@ -40,7 +36,7 @@ fn main() -> ! {
40 let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); 36 let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh);
41 37
42 loop { 38 loop {
43 let mut buf = [0x0A; 4]; 39 let mut buf = [0x0Au8; 4];
44 unwrap!(cs.set_low()); 40 unwrap!(cs.set_low());
45 unwrap!(spi.transfer(&mut buf)); 41 unwrap!(spi.transfer(&mut buf));
46 unwrap!(cs.set_high()); 42 unwrap!(cs.set_high());
diff --git a/examples/stm32l0/src/bin/usart_dma.rs b/examples/stm32l0/src/bin/usart_dma.rs
index 39a605174..2b2424e97 100644
--- a/examples/stm32l0/src/bin/usart_dma.rs
+++ b/examples/stm32l0/src/bin/usart_dma.rs
@@ -11,14 +11,11 @@ use example_common::*;
11 11
12use embassy::executor::Spawner; 12use embassy::executor::Spawner;
13use embassy_stm32::usart::{Config, Uart}; 13use embassy_stm32::usart::{Config, Uart};
14use embassy_stm32::{rcc, Peripherals}; 14use embassy_stm32::Peripherals;
15use embassy_traits::uart::{Read, Write}; 15use embassy_traits::uart::{Read, Write};
16 16
17#[embassy::main] 17#[embassy::main]
18async fn main(_spawner: Spawner, mut p: Peripherals) { 18async fn main(_spawner: Spawner, p: Peripherals) {
19 let mut rcc = rcc::Rcc::new(p.RCC);
20 rcc.enable_debug_wfe(&mut p.DBGMCU, true);
21
22 let mut usart = Uart::new( 19 let mut usart = Uart::new(
23 p.USART1, 20 p.USART1,
24 p.PB7, 21 p.PB7,
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index 5c79d0671..66a00f41b 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -15,13 +15,10 @@ use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
15use embassy_stm32::dma::NoDma; 15use embassy_stm32::dma::NoDma;
16use embassy_stm32::interrupt; 16use embassy_stm32::interrupt;
17use embassy_stm32::usart::{BufferedUart, Config, State, Uart}; 17use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
18use embassy_stm32::{rcc, Peripherals}; 18use embassy_stm32::Peripherals;
19 19
20#[embassy::main] 20#[embassy::main]
21async fn main(_spawner: Spawner, mut p: Peripherals) { 21async fn main(_spawner: Spawner, p: Peripherals) {
22 let mut rcc = rcc::Rcc::new(p.RCC);
23 rcc.enable_debug_wfe(&mut p.DBGMCU, true);
24
25 static mut TX_BUFFER: [u8; 8] = [0; 8]; 22 static mut TX_BUFFER: [u8; 8] = [0; 8];
26 static mut RX_BUFFER: [u8; 256] = [0; 256]; 23 static mut RX_BUFFER: [u8; 256] = [0; 256];
27 24
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 3f6b34679..3fa6fa467 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -26,7 +26,7 @@ defmt = "0.2.0"
26defmt-rtt = "0.2.0" 26defmt-rtt = "0.2.0"
27 27
28cortex-m = "0.7.1" 28cortex-m = "0.7.1"
29cortex-m-rt = "0.6.14" 29cortex-m-rt = "0.7.0"
30embedded-hal = { version = "0.2.4" } 30embedded-hal = { version = "0.2.4" }
31panic-probe = { version = "0.2.0", features= ["print-defmt"] } 31panic-probe = { version = "0.2.0", features= ["print-defmt"] }
32futures = { version = "0.3.8", default-features = false, features = ["async-await"] } 32futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index c778d9c3f..14b4e5ecf 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -9,7 +9,6 @@ mod example_common;
9 9
10use embassy::time::Delay; 10use embassy::time::Delay;
11use embassy_stm32::adc::{Adc, Resolution}; 11use embassy_stm32::adc::{Adc, Resolution};
12use embassy_stm32::dbgmcu::Dbgmcu;
13use embassy_stm32::pac; 12use embassy_stm32::pac;
14use example_common::*; 13use example_common::*;
15 14
@@ -18,8 +17,6 @@ fn main() -> ! {
18 info!("Hello World!"); 17 info!("Hello World!");
19 18
20 unsafe { 19 unsafe {
21 Dbgmcu::enable_all();
22
23 pac::RCC.ccipr().modify(|w| { 20 pac::RCC.ccipr().modify(|w| {
24 w.set_adcsel(0b11); 21 w.set_adcsel(0b11);
25 }); 22 });
diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs
index c9ba587e4..9c983bc6c 100644
--- a/examples/stm32l4/src/bin/blinky.rs
+++ b/examples/stm32l4/src/bin/blinky.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
14use embedded_hal::digital::v2::OutputPin; 13use embedded_hal::digital::v2::OutputPin;
@@ -18,10 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let mut led = Output::new(p.PB14, Level::High, Speed::Low); 20 let mut led = Output::new(p.PB14, Level::High, Speed::Low);
26 21
27 loop { 22 loop {
diff --git a/examples/stm32l4/src/bin/button.rs b/examples/stm32l4/src/bin/button.rs
index 883a0d6c8..be6e2d2f3 100644
--- a/examples/stm32l4/src/bin/button.rs
+++ b/examples/stm32l4/src/bin/button.rs
@@ -6,7 +6,6 @@
6 6
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy_stm32::dbgmcu::Dbgmcu;
10use embassy_stm32::gpio::{Input, Pull}; 9use embassy_stm32::gpio::{Input, Pull};
11use embedded_hal::digital::v2::InputPin; 10use embedded_hal::digital::v2::InputPin;
12use example_common::*; 11use example_common::*;
@@ -15,10 +14,6 @@ use example_common::*;
15fn main() -> ! { 14fn main() -> ! {
16 info!("Hello World!"); 15 info!("Hello World!");
17 16
18 unsafe {
19 Dbgmcu::enable_all();
20 }
21
22 let p = embassy_stm32::init(Default::default()); 17 let p = embassy_stm32::init(Default::default());
23 18
24 let button = Input::new(p.PC13, Pull::Up); 19 let button = Input::new(p.PC13, Pull::Up);
diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs
index 8a78b2589..c55d6408c 100644
--- a/examples/stm32l4/src/bin/button_exti.rs
+++ b/examples/stm32l4/src/bin/button_exti.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
@@ -18,10 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe {
22 Dbgmcu::enable_all();
23 }
24
25 let button = Input::new(p.PC13, Pull::Up); 20 let button = Input::new(p.PC13, Pull::Up);
26 let mut button = ExtiInput::new(button, p.EXTI13); 21 let mut button = ExtiInput::new(button, p.EXTI13);
27 22
diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs
index c479f86c7..e03fbc955 100644
--- a/examples/stm32l4/src/bin/dac.rs
+++ b/examples/stm32l4/src/bin/dac.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9 9
10use embassy_stm32::dac::{Channel, Dac, Value}; 10use embassy_stm32::dac::{Channel, Dac, Value};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::NoPin; 11use embassy_stm32::gpio::NoPin;
13use embassy_stm32::pac; 12use embassy_stm32::pac;
14use example_common::*; 13use example_common::*;
@@ -18,8 +17,6 @@ fn main() -> ! {
18 info!("Hello World!"); 17 info!("Hello World!");
19 18
20 unsafe { 19 unsafe {
21 Dbgmcu::enable_all();
22
23 pac::RCC.apb1enr1().modify(|w| { 20 pac::RCC.apb1enr1().modify(|w| {
24 w.set_dac1en(true); 21 w.set_dac1en(true);
25 }); 22 });
diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs
index ef6e2fcad..376537e91 100644
--- a/examples/stm32l4/src/bin/spi.rs
+++ b/examples/stm32l4/src/bin/spi.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9 9
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::spi::{Config, Spi}; 12use embassy_stm32::spi::{Config, Spi};
@@ -20,10 +19,6 @@ use example_common::*;
20fn main() -> ! { 19fn main() -> ! {
21 info!("Hello World!"); 20 info!("Hello World!");
22 21
23 unsafe {
24 Dbgmcu::enable_all();
25 }
26
27 let p = embassy_stm32::init(Default::default()); 22 let p = embassy_stm32::init(Default::default());
28 23
29 let mut spi = Spi::new( 24 let mut spi = Spi::new(
diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs
index d626a1290..75c19a3bf 100644
--- a/examples/stm32l4/src/bin/spi_dma.rs
+++ b/examples/stm32l4/src/bin/spi_dma.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9 9
10use embassy::executor::Spawner; 10use embassy::executor::Spawner;
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_stm32::spi::{Config, Spi}; 12use embassy_stm32::spi::{Config, Spi};
14use embassy_stm32::time::Hertz; 13use embassy_stm32::time::Hertz;
@@ -21,10 +20,6 @@ use example_common::*;
21async fn main(_spawner: Spawner, p: Peripherals) { 20async fn main(_spawner: Spawner, p: Peripherals) {
22 info!("Hello World!"); 21 info!("Hello World!");
23 22
24 unsafe {
25 Dbgmcu::enable_all();
26 }
27
28 let mut spi = Spi::new( 23 let mut spi = Spi::new(
29 p.SPI3, 24 p.SPI3,
30 p.PC10, 25 p.PC10,
diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs
index 95ac84b23..09b62f680 100644
--- a/examples/stm32l4/src/bin/usart.rs
+++ b/examples/stm32l4/src/bin/usart.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9 9
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
12use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
13use embedded_hal::blocking::serial::Write; 12use embedded_hal::blocking::serial::Write;
@@ -17,10 +16,6 @@ use example_common::*;
17fn main() -> ! { 16fn main() -> ! {
18 info!("Hello World!"); 17 info!("Hello World!");
19 18
20 unsafe {
21 Dbgmcu::enable_all();
22 }
23
24 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
25 20
26 let config = Config::default(); 21 let config = Config::default();
diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs
index f74a0e06b..d307dc13c 100644
--- a/examples/stm32l4/src/bin/usart_dma.rs
+++ b/examples/stm32l4/src/bin/usart_dma.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use core::fmt::Write; 9use core::fmt::Write;
10use embassy::executor::Spawner; 10use embassy::executor::Spawner;
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::dma::NoDma; 11use embassy_stm32::dma::NoDma;
13use embassy_stm32::usart::{Config, Uart}; 12use embassy_stm32::usart::{Config, Uart};
14use embassy_stm32::Peripherals; 13use embassy_stm32::Peripherals;
@@ -20,10 +19,6 @@ use heapless::String;
20async fn main(_spawner: Spawner, p: Peripherals) { 19async fn main(_spawner: Spawner, p: Peripherals) {
21 info!("Hello World!"); 20 info!("Hello World!");
22 21
23 unsafe {
24 Dbgmcu::enable_all();
25 }
26
27 let config = Config::default(); 22 let config = Config::default();
28 let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_CH3, NoDma, config); 23 let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_CH3, NoDma, config);
29 24
diff --git a/examples/stm32wb55/src/bin/blinky.rs b/examples/stm32wb55/src/bin/blinky.rs
index 2deaf5f55..ea5f872d7 100644
--- a/examples/stm32wb55/src/bin/blinky.rs
+++ b/examples/stm32wb55/src/bin/blinky.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
14use embedded_hal::digital::v2::OutputPin; 13use embedded_hal::digital::v2::OutputPin;
@@ -18,8 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe { Dbgmcu::enable_all() };
22
23 let mut led = Output::new(p.PB0, Level::High, Speed::Low); 20 let mut led = Output::new(p.PB0, Level::High, Speed::Low);
24 21
25 loop { 22 loop {
diff --git a/examples/stm32wb55/src/bin/button_exti.rs b/examples/stm32wb55/src/bin/button_exti.rs
new file mode 100644
index 000000000..1c070833d
--- /dev/null
+++ b/examples/stm32wb55/src/bin/button_exti.rs
@@ -0,0 +1,31 @@
1#![no_std]
2#![no_main]
3#![feature(trait_alias)]
4#![feature(type_alias_impl_trait)]
5#![allow(incomplete_features)]
6
7#[path = "../example_common.rs"]
8mod example_common;
9use embassy::executor::Spawner;
10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::gpio::{Input, Pull};
12use embassy_stm32::Peripherals;
13use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge};
14use example_common::*;
15
16#[embassy::main]
17async fn main(_spawner: Spawner, p: Peripherals) {
18 info!("Hello World!");
19
20 let button = Input::new(p.PC4, Pull::Up);
21 let mut button = ExtiInput::new(button, p.EXTI4);
22
23 info!("Press the USER button...");
24
25 loop {
26 button.wait_for_falling_edge().await;
27 info!("Pressed!");
28 button.wait_for_rising_edge().await;
29 info!("Released!");
30 }
31}
diff --git a/examples/stm32wl55/src/bin/blinky.rs b/examples/stm32wl55/src/bin/blinky.rs
index b5e5ffcf9..b13b66e0e 100644
--- a/examples/stm32wl55/src/bin/blinky.rs
+++ b/examples/stm32wl55/src/bin/blinky.rs
@@ -8,7 +8,6 @@
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_stm32::dbgmcu::Dbgmcu;
12use embassy_stm32::gpio::{Level, Output, Speed}; 11use embassy_stm32::gpio::{Level, Output, Speed};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
14use embedded_hal::digital::v2::OutputPin; 13use embedded_hal::digital::v2::OutputPin;
@@ -18,8 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe { Dbgmcu::enable_all() };
22
23 let mut led = Output::new(p.PB15, Level::High, Speed::Low); 20 let mut led = Output::new(p.PB15, Level::High, Speed::Low);
24 21
25 loop { 22 loop {
diff --git a/examples/stm32wl55/src/bin/button.rs b/examples/stm32wl55/src/bin/button.rs
index 84e1f599f..ca1625a64 100644
--- a/examples/stm32wl55/src/bin/button.rs
+++ b/examples/stm32wl55/src/bin/button.rs
@@ -6,10 +6,7 @@
6 6
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy_stm32::{ 9use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
10 dbgmcu::Dbgmcu,
11 gpio::{Input, Level, Output, Pull, Speed},
12};
13use embedded_hal::digital::v2::{InputPin, OutputPin}; 10use embedded_hal::digital::v2::{InputPin, OutputPin};
14use example_common::*; 11use example_common::*;
15 12
@@ -21,8 +18,6 @@ fn main() -> ! {
21 18
22 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(Default::default());
23 20
24 unsafe { Dbgmcu::enable_all() };
25
26 let button = Input::new(p.PA0, Pull::Up); 21 let button = Input::new(p.PA0, Pull::Up);
27 let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); 22 let mut led1 = Output::new(p.PB15, Level::High, Speed::Low);
28 let mut led2 = Output::new(p.PB9, Level::High, Speed::Low); 23 let mut led2 = Output::new(p.PB9, Level::High, Speed::Low);
diff --git a/examples/stm32wl55/src/bin/button_exti.rs b/examples/stm32wl55/src/bin/button_exti.rs
index 2f6e55115..b34e54574 100644
--- a/examples/stm32wl55/src/bin/button_exti.rs
+++ b/examples/stm32wl55/src/bin/button_exti.rs
@@ -7,7 +7,6 @@
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy_stm32::dbgmcu::Dbgmcu;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
13use embassy_stm32::Peripherals; 12use embassy_stm32::Peripherals;
@@ -18,8 +17,6 @@ use example_common::*;
18async fn main(_spawner: Spawner, p: Peripherals) { 17async fn main(_spawner: Spawner, p: Peripherals) {
19 info!("Hello World!"); 18 info!("Hello World!");
20 19
21 unsafe { Dbgmcu::enable_all() };
22
23 let button = Input::new(p.PA0, Pull::Up); 20 let button = Input::new(p.PA0, Pull::Up);
24 let mut button = ExtiInput::new(button, p.EXTI0); 21 let mut button = ExtiInput::new(button, p.EXTI0);
25 22
diff --git a/stm32-data b/stm32-data
Subproject bfd4797d1278c3e0b4611bc79e12346dedbde7c Subproject 12be5f3da4ba38850d94ab865d2b920bd936300
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index b1980d84e..8646accfa 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -1,4 +1,5 @@
1use chiptool::generate::CommonModule; 1use chiptool::generate::CommonModule;
2use chiptool::ir::IR;
2use regex::Regex; 3use regex::Regex;
3use serde::Deserialize; 4use serde::Deserialize;
4use std::collections::{BTreeMap, HashMap, HashSet}; 5use std::collections::{BTreeMap, HashMap, HashSet};
@@ -116,11 +117,7 @@ impl BlockInfo {
116 } 117 }
117} 118}
118 119
119fn find_reg_for_field<'c>( 120fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> {
120 rcc: &'c ir::IR,
121 reg_regex: &str,
122 field_name: &str,
123) -> Option<(&'c str, &'c str)> {
124 let reg_regex = Regex::new(reg_regex).unwrap(); 121 let reg_regex = Regex::new(reg_regex).unwrap();
125 122
126 for (name, fieldset) in &rcc.fieldsets { 123 for (name, fieldset) in &rcc.fieldsets {
@@ -273,19 +270,18 @@ pub fn gen(options: Options) {
273 }); 270 });
274 271
275 // Load RCC register for chip 272 // Load RCC register for chip
276 let rcc = core.peripherals.iter().find_map(|(name, p)| { 273 let (_, rcc) = core
277 if name == "RCC" { 274 .peripherals
278 p.block.as_ref().map(|block| { 275 .iter()
279 let bi = BlockInfo::parse(block); 276 .find(|(name, _)| name == &"RCC")
280 let rcc_reg_path = data_dir 277 .expect("RCC peripheral missing");
281 .join("registers") 278
282 .join(&format!("{}_{}.yaml", bi.module, bi.version)); 279 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
283 serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap() 280 let bi = BlockInfo::parse(&rcc_block);
284 }) 281 let rcc_reg_path = data_dir
285 } else { 282 .join("registers")
286 None 283 .join(&format!("{}_{}.yaml", bi.module, bi.version));
287 } 284 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
288 });
289 285
290 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new(); 286 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
291 let mut pin_table: Vec<Vec<String>> = Vec::new(); 287 let mut pin_table: Vec<Vec<String>> = Vec::new();
@@ -424,74 +420,72 @@ pub fn gen(options: Options) {
424 _ => {} 420 _ => {}
425 } 421 }
426 422
427 if let Some(rcc) = &rcc { 423 // Workaround for clock registers being split on some chip families. Assume fields are
428 // Workaround for clock registers being split on some chip families. Assume fields are 424 // named after peripheral and look for first field matching and use that register.
429 // named after peripheral and look for first field matching and use that register. 425 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
430 let mut en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); 426 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
431 let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); 427
432 428 if en.is_none() && name.ends_with("1") {
433 if en.is_none() && name.ends_with("1") { 429 en = find_reg(
434 en = find_reg_for_field( 430 &rcc,
435 &rcc, 431 "^.+ENR\\d*$",
436 "^.+ENR\\d*$", 432 &format!("{}EN", &name[..name.len() - 1]),
437 &format!("{}EN", &name[..name.len() - 1]), 433 );
438 ); 434 rst = find_reg(
439 rst = find_reg_for_field( 435 &rcc,
440 &rcc, 436 "^.+RSTR\\d*$",
441 "^.+RSTR\\d*$", 437 &format!("{}RST", &name[..name.len() - 1]),
442 &format!("{}RST", &name[..name.len() - 1]), 438 );
443 ); 439 }
444 }
445 440
446 match (en, rst) { 441 match (en, rst) {
447 (Some((enable_reg, enable_field)), reset_reg_field) => { 442 (Some((enable_reg, enable_field)), reset_reg_field) => {
448 let clock = match &p.clock { 443 let clock = match &p.clock {
449 Some(clock) => clock.as_str(), 444 Some(clock) => clock.as_str(),
450 None => { 445 None => {
451 // No clock was specified, derive the clock name from the enable register name. 446 // No clock was specified, derive the clock name from the enable register name.
452 Regex::new("([A-Z]+\\d*).*") 447 Regex::new("([A-Z]+\\d*).*")
453 .unwrap() 448 .unwrap()
454 .captures(enable_reg) 449 .captures(enable_reg)
455 .unwrap() 450 .unwrap()
456 .get(1) 451 .get(1)
457 .unwrap() 452 .unwrap()
458 .as_str() 453 .as_str()
459 }
460 };
461
462 let clock = if name.starts_with("TIM") {
463 format!("{}_tim", clock.to_ascii_lowercase())
464 } else {
465 clock.to_ascii_lowercase()
466 };
467
468 let mut row = Vec::with_capacity(6);
469 row.push(name.clone());
470 row.push(clock);
471 row.push(enable_reg.to_ascii_lowercase());
472
473 if let Some((reset_reg, reset_field)) = reset_reg_field {
474 row.push(reset_reg.to_ascii_lowercase());
475 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
476 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
477 } else {
478 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
479 } 454 }
455 };
480 456
481 if !name.starts_with("GPIO") { 457 let clock = if name.starts_with("TIM") {
482 peripheral_rcc_table.push(row); 458 format!("{}_tim", clock.to_ascii_lowercase())
483 } else { 459 } else {
484 gpio_rcc_table.push(row); 460 clock.to_ascii_lowercase()
485 gpio_regs.insert(enable_reg.to_ascii_lowercase()); 461 };
486 } 462
487 } 463 let mut row = Vec::with_capacity(6);
488 (None, Some(_)) => { 464 row.push(name.clone());
489 println!("Unable to find enable register for {}", name) 465 row.push(clock);
466 row.push(enable_reg.to_ascii_lowercase());
467
468 if let Some((reset_reg, reset_field)) = reset_reg_field {
469 row.push(reset_reg.to_ascii_lowercase());
470 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
471 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
472 } else {
473 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
490 } 474 }
491 (None, None) => { 475
492 println!("Unable to find enable and reset register for {}", name) 476 if !name.starts_with("GPIO") {
477 peripheral_rcc_table.push(row);
478 } else {
479 gpio_rcc_table.push(row);
480 gpio_regs.insert(enable_reg.to_ascii_lowercase());
493 } 481 }
494 } 482 }
483 (None, Some(_)) => {
484 println!("Unable to find enable register for {}", name)
485 }
486 (None, None) => {
487 println!("Unable to find enable and reset register for {}", name)
488 }
495 } 489 }
496 } 490 }
497 491
@@ -502,6 +496,10 @@ pub fn gen(options: Options) {
502 gpio_rcc_table.push(vec![reg]); 496 gpio_rcc_table.push(vec![reg]);
503 } 497 }
504 498
499 // We should always find GPIO RCC regs. If not, it means something
500 // is broken and GPIO won't work because it's not enabled.
501 assert!(!gpio_rcc_table.is_empty());
502
505 for (id, channel_info) in &core.dma_channels { 503 for (id, channel_info) in &core.dma_channels {
506 let mut row = Vec::new(); 504 let mut row = Vec::new();
507 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap(); 505 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
diff --git a/stm32-metapac-gen/src/main.rs b/stm32-metapac-gen/src/main.rs
index 31f684046..0380affc2 100644
--- a/stm32-metapac-gen/src/main.rs
+++ b/stm32-metapac-gen/src/main.rs
@@ -1,3 +1,4 @@
1use std::env::args;
1use std::path::PathBuf; 2use std::path::PathBuf;
2use stm32_metapac_gen::*; 3use stm32_metapac_gen::*;
3 4
@@ -5,13 +6,24 @@ fn main() {
5 let out_dir = PathBuf::from("out"); 6 let out_dir = PathBuf::from("out");
6 let data_dir = PathBuf::from("../stm32-data/data"); 7 let data_dir = PathBuf::from("../stm32-data/data");
7 8
8 let chips = std::fs::read_dir(data_dir.join("chips")) 9 let args: Vec<String> = args().collect();
9 .unwrap() 10
10 .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) 11 let chips = match &args[..] {
11 .filter(|s| s.ends_with(".yaml")) 12 [_, chip] => {
12 .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride 13 vec![chip.clone()]
13 .map(|s| s.strip_suffix(".yaml").unwrap().to_string()) 14 }
14 .collect(); 15 [_] => {
16 std::fs::read_dir(data_dir.join("chips"))
17 .unwrap()
18 .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string()))
19 .filter(|s| s.ends_with(".yaml"))
20 .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride
21 .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4
22 .map(|s| s.strip_suffix(".yaml").unwrap().to_string())
23 .collect()
24 }
25 _ => panic!("usage: stm32-metapac-gen [chip?]"),
26 };
15 27
16 gen(Options { 28 gen(Options {
17 out_dir, 29 out_dir,