diff --git a/.gitignore b/.gitignore index 11781dc1..30628ed5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target Cargo.lock third_party /Cargo.toml +stm32-metapac-gen/out/ \ No newline at end of file diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index a6434a7e..ed2b4c50 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1,6 +1,6 @@ use std::env; +use std::fs; use std::path::PathBuf; -use std::process::Command; fn main() { let chip_name = env::vars_os() @@ -11,17 +11,72 @@ fn main() { .unwrap() .to_ascii_lowercase(); + struct Peripheral { + kind: String, + name: String, + } + + let mut peripherals: Vec = Vec::new(); + stm32_metapac::peripherals!( + ($kind:ident, $name:ident) => { + peripherals.push(Peripheral{ + kind: stringify!($kind).to_string(), + name: stringify!($name).to_string(), + }); + }; + ); + + let mut singletons: Vec = Vec::new(); + for p in peripherals { + match p.kind.as_str() { + // Generate singletons per pin, not per port + "gpio" => { + println!("{}", p.name); + let port_letter = p.name.strip_prefix("GPIO").unwrap(); + for pin_num in 0..16 { + singletons.push(format!("P{}{}", port_letter, pin_num)); + } + } + + // No singleton for these, the HAL handles them specially. + "exti" => {} + + // We *shouldn't* have singletons for these, but the HAL currently requires + // singletons, for using with RccPeripheral to enable/disable clocks to them. + //"rcc" => {} + //"dbgmcu" => {} + //"syscfg" => {} + //"dma" => {} + //"bdma" => {} + //"dmamux" => {} + + // For other peripherals, one singleton per peri + _ => singletons.push(p.name.clone()), + } + } + + // One singleton per EXTI line + for pin_num in 0..16 { + singletons.push(format!("EXTI{}", pin_num)); + } + + // One singleton per DMA channel + stm32_metapac::dma_channels! { + ($channel_peri:ident, $dma_peri:ident, $version:ident, $channel_num:expr, $ignore:tt) => { + singletons.push(stringify!($channel_peri).to_string()); + }; + } + let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_file = out_dir.join("generated.rs").to_string_lossy().to_string(); - - let exit_code = Command::new("python3") - .args(&["gen.py", &chip_name, &out_file]) - .status() - .expect("failed to execute gen.py"); - - if !exit_code.success() { - panic!("gen.py exited with {:?}", exit_code) - } + fs::write( + out_file, + format!( + "embassy_hal_common::peripherals!({});", + singletons.join(",") + ), + ) + .unwrap(); stm32_metapac::peripheral_versions!( ($peri:ident, $version:ident) => { diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py deleted file mode 100644 index e589f2f0..00000000 --- a/embassy-stm32/gen.py +++ /dev/null @@ -1,88 +0,0 @@ -import sys -import yaml -import re -import os -import re - -try: - from yaml import CSafeLoader as SafeLoader -except ImportError: - from yaml import SafeLoader - - -abspath = os.path.abspath(__file__) -dname = os.path.dirname(abspath) -os.chdir(dname) - -data_path = '../stm32-data/data' - -try: - _, chip_name, output_file = sys.argv -except: - raise Exception("Usage: gen.py STM32F429ZI_CM0 path/to/generated.rs") - -c = chip_name.split('_', 1) - -chip_name = c[0].upper() -core_name = None - -if len(c) > 1: - core_name = c[1].lower() - -# ======= load chip -with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f: - chip = yaml.load(f, Loader=SafeLoader) - -# ======= Generate! -with open(output_file, 'w') as f: - singletons = [] # USART1, PA5, EXTI8 - exti_interrupts = [] # EXTI IRQs, EXTI0, EXTI4_15 etc. - pins = set() # set of all present pins. PA4, PA5... - - # ========= peripherals - - singletons.extend((f'EXTI{x}' for x in range(16))) - num_dmas = 0 - - core = chip['cores'][0] - if core_name != None: - for c in chip['cores']: - if core_name == c['name']: - core = c - - for (name, peri) in core['peripherals'].items(): - if 'block' not in peri: - continue - - block = peri['block'] - block_mod, block_name_unparsed = block.rsplit('/') - block_mod, block_version = block_mod.rsplit('_') - block_name = '' - for b in block_name_unparsed.split('_'): - block_name += b.capitalize() - - custom_singletons = False - - if block_mod == 'gpio': - custom_singletons = True - port = name[4:] - port_num = ord(port) - ord('A') - - for pin_num in range(16): - pin = f'P{port}{pin_num}' - pins.add(pin) - singletons.append(pin) - - # if block_mod == 'dma': - # custom_singletons = True - # for ch_num in range(8): - # channel = f'{name}_CH{ch_num}' - # singletons.append(channel) - - if not custom_singletons: - singletons.append(name) - - for (channel_id, defn) in core['dma_channels'].items(): - singletons.append( channel_id ) - - 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 00000000..659daa37 --- /dev/null +++ b/embassy-stm32/src/exti.rs @@ -0,0 +1,270 @@ +use core::convert::Infallible; +use core::future::Future; +use core::marker::PhantomData; +use core::pin::Pin; +use core::task::{Context, Poll}; +use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; +use embassy::util::{AtomicWaker, Unborrow}; +use embassy_hal_common::unsafe_impl_unborrow; +use embedded_hal::digital::v2::InputPin; + +use crate::gpio::{AnyPin, Input, Pin as GpioPin}; +use crate::interrupt; +use crate::pac; +use crate::pac::{EXTI, SYSCFG}; +use crate::peripherals; + +const EXTI_COUNT: usize = 16; +const NEW_AW: AtomicWaker = AtomicWaker::new(); +static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT]; + +#[cfg(exti_w)] +fn cpu_regs() -> pac::exti::Cpu { + EXTI.cpu(crate::pac::CORE_INDEX) +} + +#[cfg(not(exti_w))] +fn cpu_regs() -> pac::exti::Exti { + EXTI +} + +pub unsafe fn on_irq() { + let bits = EXTI.pr(0).read(); + + // Mask all the channels that fired. + cpu_regs().imr(0).modify(|w| w.0 &= !bits.0); + + // Wake the tasks + for pin in BitIter(bits.0) { + EXTI_WAKERS[pin as usize].wake(); + } + + // Clear pending + EXTI.pr(0).write_value(bits); +} + +struct BitIter(u32); + +impl Iterator for BitIter { + type Item = u32; + + fn next(&mut self) -> Option { + match self.0.trailing_zeros() { + 32 => None, + b => { + self.0 &= !(1 << b); + Some(b) + } + } + } +} + +/// EXTI input driver +pub struct ExtiInput<'d, T: GpioPin> { + pin: Input<'d, T>, +} + +impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {} + +impl<'d, T: GpioPin> ExtiInput<'d, T> { + pub fn new(pin: Input<'d, T>, _ch: impl Unborrow + 'd) -> Self { + Self { pin } + } +} + +impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { + type Error = Infallible; + + fn is_high(&self) -> Result { + self.pin.is_high() + } + + fn is_low(&self) -> Result { + self.pin.is_low() + } +} + +impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> { + type Future<'a> = ExtiInputFuture<'a>; + + fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> { + ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, false) + } +} + +impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> { + type Future<'a> = ExtiInputFuture<'a>; + + fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> { + ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), false, true) + } +} + +impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> { + type Future<'a> = ExtiInputFuture<'a>; + + fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> { + ExtiInputFuture::new(self.pin.pin.pin(), self.pin.pin.port(), true, true) + } +} + +pub struct ExtiInputFuture<'a> { + pin: u8, + phantom: PhantomData<&'a mut AnyPin>, +} + +impl<'a> ExtiInputFuture<'a> { + fn new(pin: u8, port: u8, rising: bool, falling: bool) -> Self { + cortex_m::interrupt::free(|_| unsafe { + let pin = pin as usize; + SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port)); + EXTI.rtsr(0).modify(|w| w.set_line(pin, rising)); + EXTI.ftsr(0).modify(|w| w.set_line(pin, falling)); + EXTI.pr(0).write(|w| w.set_line(pin, true)); // clear pending bit + cpu_regs().imr(0).modify(|w| w.set_line(pin, true)); + }); + + Self { + pin, + phantom: PhantomData, + } + } +} + +impl<'a> Drop for ExtiInputFuture<'a> { + fn drop(&mut self) { + cortex_m::interrupt::free(|_| unsafe { + let pin = self.pin as _; + cpu_regs().imr(0).modify(|w| w.set_line(pin, false)); + }); + } +} + +impl<'a> Future for ExtiInputFuture<'a> { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + EXTI_WAKERS[self.pin as usize].register(cx.waker()); + + let imr = unsafe { cpu_regs().imr(0).read() }; + if !imr.line(self.pin as _) { + Poll::Ready(()) + } else { + Poll::Pending + } + } +} + +macro_rules! foreach_exti_irq { + ($action:ident) => { + crate::pac::interrupts!( + (EXTI0) => { $action!(EXTI0); }; + (EXTI1) => { $action!(EXTI1); }; + (EXTI2) => { $action!(EXTI2); }; + (EXTI3) => { $action!(EXTI3); }; + (EXTI4) => { $action!(EXTI4); }; + (EXTI5) => { $action!(EXTI5); }; + (EXTI6) => { $action!(EXTI6); }; + (EXTI7) => { $action!(EXTI7); }; + (EXTI8) => { $action!(EXTI8); }; + (EXTI9) => { $action!(EXTI9); }; + (EXTI10) => { $action!(EXTI10); }; + (EXTI11) => { $action!(EXTI11); }; + (EXTI12) => { $action!(EXTI12); }; + (EXTI13) => { $action!(EXTI13); }; + (EXTI14) => { $action!(EXTI14); }; + (EXTI15) => { $action!(EXTI15); }; + + // plus the weird ones + (EXTI0_1) => { $action!( EXTI0_1 ); }; + (EXTI15_10) => { $action!(EXTI15_10); }; + (EXTI15_4) => { $action!(EXTI15_4); }; + (EXTI1_0) => { $action!(EXTI1_0); }; + (EXTI2_3) => { $action!(EXTI2_3); }; + (EXTI2_TSC) => { $action!(EXTI2_TSC); }; + (EXTI3_2) => { $action!(EXTI3_2); }; + (EXTI4_15) => { $action!(EXTI4_15); }; + (EXTI9_5) => { $action!(EXTI9_5); }; + ); + }; +} + +macro_rules! impl_irq { + ($e:ident) => { + #[interrupt] + unsafe fn $e() { + on_irq() + } + }; +} + +foreach_exti_irq!(impl_irq); + +pub(crate) mod sealed { + pub trait Channel {} +} + +pub trait Channel: sealed::Channel + Sized { + fn number(&self) -> usize; + fn degrade(self) -> AnyChannel { + AnyChannel { + number: self.number() as u8, + } + } +} + +pub struct AnyChannel { + number: u8, +} +unsafe_impl_unborrow!(AnyChannel); +impl sealed::Channel for AnyChannel {} +impl Channel for AnyChannel { + fn number(&self) -> usize { + self.number as usize + } +} + +macro_rules! impl_exti { + ($type:ident, $number:expr) => { + impl sealed::Channel for peripherals::$type {} + impl Channel for peripherals::$type { + fn number(&self) -> usize { + $number as usize + } + } + }; +} + +impl_exti!(EXTI0, 0); +impl_exti!(EXTI1, 1); +impl_exti!(EXTI2, 2); +impl_exti!(EXTI3, 3); +impl_exti!(EXTI4, 4); +impl_exti!(EXTI5, 5); +impl_exti!(EXTI6, 6); +impl_exti!(EXTI7, 7); +impl_exti!(EXTI8, 8); +impl_exti!(EXTI9, 9); +impl_exti!(EXTI10, 10); +impl_exti!(EXTI11, 11); +impl_exti!(EXTI12, 12); +impl_exti!(EXTI13, 13); +impl_exti!(EXTI14, 14); +impl_exti!(EXTI15, 15); + +macro_rules! enable_irq { + ($e:ident) => { + crate::interrupt::$e::steal().enable(); + }; +} + +/// safety: must be called only once +pub(crate) unsafe fn init() { + use embassy::interrupt::Interrupt; + use embassy::interrupt::InterruptExt; + + foreach_exti_irq!(enable_irq); + + #[cfg(not(any(rcc_wb, rcc_wl5)))] + ::enable(); +} diff --git a/embassy-stm32/src/exti/mod.rs b/embassy-stm32/src/exti/mod.rs deleted file mode 100644 index 3f43e0bc..00000000 --- a/embassy-stm32/src/exti/mod.rs +++ /dev/null @@ -1,116 +0,0 @@ -#![macro_use] - -macro_rules! foreach_exti_irq { - ($action:ident) => { - crate::pac::interrupts!( - (EXTI0) => { $action!(EXTI0); }; - (EXTI1) => { $action!(EXTI1); }; - (EXTI2) => { $action!(EXTI2); }; - (EXTI3) => { $action!(EXTI3); }; - (EXTI4) => { $action!(EXTI4); }; - (EXTI5) => { $action!(EXTI5); }; - (EXTI6) => { $action!(EXTI6); }; - (EXTI7) => { $action!(EXTI7); }; - (EXTI8) => { $action!(EXTI8); }; - (EXTI9) => { $action!(EXTI9); }; - (EXTI10) => { $action!(EXTI10); }; - (EXTI11) => { $action!(EXTI11); }; - (EXTI12) => { $action!(EXTI12); }; - (EXTI13) => { $action!(EXTI13); }; - (EXTI14) => { $action!(EXTI14); }; - (EXTI15) => { $action!(EXTI15); }; - - // plus the weird ones - (EXTI0_1) => { $action!( EXTI0_1 ); }; - (EXTI15_10) => { $action!(EXTI15_10); }; - (EXTI15_4) => { $action!(EXTI15_4); }; - (EXTI1_0) => { $action!(EXTI1_0); }; - (EXTI2_3) => { $action!(EXTI2_3); }; - (EXTI2_TSC) => { $action!(EXTI2_TSC); }; - (EXTI3_2) => { $action!(EXTI3_2); }; - (EXTI4_15) => { $action!(EXTI4_15); }; - (EXTI9_5) => { $action!(EXTI9_5); }; - ); - }; -} - -#[cfg_attr(exti_v1, path = "v1.rs")] -#[cfg_attr(exti_h7, path = "v1.rs")] -#[cfg_attr(exti_wb55, path = "v2.rs")] -#[cfg_attr(exti_wl5x, path = "v2.rs")] -mod _version; - -#[allow(unused)] -pub use _version::*; - -use crate::peripherals; -use embassy_hal_common::unsafe_impl_unborrow; - -pub(crate) mod sealed { - pub trait Channel {} -} - -pub trait Channel: sealed::Channel + Sized { - fn number(&self) -> usize; - fn degrade(self) -> AnyChannel { - AnyChannel { - number: self.number() as u8, - } - } -} - -pub struct AnyChannel { - number: u8, -} -unsafe_impl_unborrow!(AnyChannel); -impl sealed::Channel for AnyChannel {} -impl Channel for AnyChannel { - fn number(&self) -> usize { - self.number as usize - } -} - -macro_rules! impl_exti { - ($type:ident, $number:expr) => { - impl sealed::Channel for peripherals::$type {} - impl Channel for peripherals::$type { - fn number(&self) -> usize { - $number as usize - } - } - }; -} - -impl_exti!(EXTI0, 0); -impl_exti!(EXTI1, 1); -impl_exti!(EXTI2, 2); -impl_exti!(EXTI3, 3); -impl_exti!(EXTI4, 4); -impl_exti!(EXTI5, 5); -impl_exti!(EXTI6, 6); -impl_exti!(EXTI7, 7); -impl_exti!(EXTI8, 8); -impl_exti!(EXTI9, 9); -impl_exti!(EXTI10, 10); -impl_exti!(EXTI11, 11); -impl_exti!(EXTI12, 12); -impl_exti!(EXTI13, 13); -impl_exti!(EXTI14, 14); -impl_exti!(EXTI15, 15); - -macro_rules! enable_irq { - ($e:ident) => { - crate::interrupt::$e::steal().enable(); - }; -} - -/// safety: must be called only once -pub(crate) unsafe fn init() { - use embassy::interrupt::Interrupt; - use embassy::interrupt::InterruptExt; - - foreach_exti_irq!(enable_irq); - - #[cfg(not(any(rcc_wb55, rcc_wl5x)))] - ::enable(); -} diff --git a/embassy-stm32/src/exti/v1.rs b/embassy-stm32/src/exti/v1.rs deleted file mode 100644 index caf45760..00000000 --- a/embassy-stm32/src/exti/v1.rs +++ /dev/null @@ -1,171 +0,0 @@ -use core::convert::Infallible; -use core::future::Future; -use core::marker::PhantomData; -use core::pin::Pin; -use core::task::{Context, Poll}; -use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; -use embassy::util::{AtomicWaker, Unborrow}; -use embedded_hal::digital::v2::InputPin; -use pac::exti::{regs, vals}; - -use crate::gpio::{AnyPin, Input, Pin as GpioPin}; -use crate::pac; -use crate::pac::{EXTI, SYSCFG}; - -const EXTI_COUNT: usize = 16; -const NEW_AW: AtomicWaker = AtomicWaker::new(); -static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT]; - -pub unsafe fn on_irq() { - let bits = EXTI.pr().read().0; - - // Mask all the channels that fired. - EXTI.imr().modify(|w| w.0 &= !bits); - - // Wake the tasks - for pin in BitIter(bits) { - EXTI_WAKERS[pin as usize].wake(); - } - - // Clear pending - EXTI.pr().write_value(regs::Pr(bits)); -} - -struct BitIter(u32); - -impl Iterator for BitIter { - type Item = u32; - - fn next(&mut self) -> Option { - match self.0.trailing_zeros() { - 32 => None, - b => { - self.0 &= !(1 << b); - Some(b) - } - } - } -} - -/// EXTI input driver -pub struct ExtiInput<'d, T: GpioPin> { - pin: Input<'d, T>, -} - -impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {} - -impl<'d, T: GpioPin> ExtiInput<'d, T> { - pub fn new(pin: Input<'d, T>, _ch: impl Unborrow + 'd) -> Self { - Self { pin } - } -} - -impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { - type Error = Infallible; - - fn is_high(&self) -> Result { - self.pin.is_high() - } - - fn is_low(&self) -> Result { - self.pin.is_low() - } -} - -impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Tr::ENABLED, - vals::Tr::DISABLED, - ) - } -} - -impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Tr::DISABLED, - vals::Tr::ENABLED, - ) - } -} - -impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Tr::ENABLED, - vals::Tr::ENABLED, - ) - } -} - -pub struct ExtiInputFuture<'a> { - pin: u8, - phantom: PhantomData<&'a mut AnyPin>, -} - -impl<'a> ExtiInputFuture<'a> { - fn new(pin: u8, port: u8, rising: vals::Tr, falling: vals::Tr) -> Self { - cortex_m::interrupt::free(|_| unsafe { - let pin = pin as usize; - SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port)); - EXTI.rtsr().modify(|w| w.set_tr(pin, rising)); - EXTI.ftsr().modify(|w| w.set_tr(pin, falling)); - EXTI.pr().write(|w| w.set_pr(pin, true)); // clear pending bit - EXTI.imr().modify(|w| w.set_mr(pin, vals::Mr::UNMASKED)); - }); - - Self { - pin, - phantom: PhantomData, - } - } -} - -impl<'a> Drop for ExtiInputFuture<'a> { - fn drop(&mut self) { - cortex_m::interrupt::free(|_| unsafe { - let pin = self.pin as _; - EXTI.imr().modify(|w| w.set_mr(pin, vals::Mr::MASKED)); - }); - } -} - -impl<'a> Future for ExtiInputFuture<'a> { - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - EXTI_WAKERS[self.pin as usize].register(cx.waker()); - - if unsafe { EXTI.imr().read().mr(self.pin as _) == vals::Mr::MASKED } { - Poll::Ready(()) - } else { - Poll::Pending - } - } -} - -use crate::interrupt; - -macro_rules! impl_irq { - ($e:ident) => { - #[interrupt] - unsafe fn $e() { - on_irq() - } - }; -} - -foreach_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 2e62331f..00000000 --- a/embassy-stm32/src/exti/v2.rs +++ /dev/null @@ -1,184 +0,0 @@ -use core::convert::Infallible; -use core::future::Future; -use core::marker::PhantomData; -use core::pin::Pin; -use core::task::{Context, Poll}; -use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; -use embassy::util::{AtomicWaker, Unborrow}; -use embedded_hal::digital::v2::InputPin; -use pac::exti::{regs, vals}; - -use crate::gpio::{AnyPin, Input, Pin as GpioPin}; -use crate::pac; -use crate::pac::CORE_INDEX; -use crate::pac::{EXTI, SYSCFG}; - -const EXTI_COUNT: usize = 16; -const NEW_AW: AtomicWaker = AtomicWaker::new(); -static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [NEW_AW; EXTI_COUNT]; - -pub unsafe fn on_irq() { - let bits = EXTI.pr(0).read().0; - - // Mask all the channels that fired. - EXTI.cpu(CORE_INDEX) - .imr(CORE_INDEX) - .modify(|w| w.0 &= !bits); - - // Wake the tasks - for pin in BitIter(bits) { - EXTI_WAKERS[pin as usize].wake(); - } - - // Clear pending - EXTI.pr(0).write_value(regs::Pr(bits)); -} - -struct BitIter(u32); - -impl Iterator for BitIter { - type Item = u32; - - fn next(&mut self) -> Option { - match self.0.trailing_zeros() { - 32 => None, - b => { - self.0 &= !(1 << b); - Some(b) - } - } - } -} - -/// EXTI input driver -pub struct ExtiInput<'d, T: GpioPin> { - pin: Input<'d, T>, -} - -impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {} - -impl<'d, T: GpioPin> ExtiInput<'d, T> { - pub fn new(pin: Input<'d, T>, _ch: impl Unborrow + 'd) -> Self { - Self { pin } - } -} - -impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { - type Error = Infallible; - - fn is_high(&self) -> Result { - self.pin.is_high() - } - - fn is_low(&self) -> Result { - self.pin.is_low() - } -} - -impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Rt::ENABLED, - vals::Ft::DISABLED, - ) - } -} - -impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Rt::DISABLED, - vals::Ft::ENABLED, - ) - } -} - -impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> { - type Future<'a> = ExtiInputFuture<'a>; - - fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> { - ExtiInputFuture::new( - self.pin.pin.pin(), - self.pin.pin.port(), - vals::Rt::ENABLED, - vals::Ft::ENABLED, - ) - } -} - -pub struct ExtiInputFuture<'a> { - pin: u8, - phantom: PhantomData<&'a mut AnyPin>, -} - -impl<'a> ExtiInputFuture<'a> { - fn new(pin: u8, port: u8, rising: vals::Rt, falling: vals::Ft) -> Self { - cortex_m::interrupt::free(|_| unsafe { - let pin = pin as usize; - SYSCFG.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port)); - EXTI.rtsr(CORE_INDEX).modify(|w| w.set_rt(pin, rising)); - EXTI.ftsr(CORE_INDEX).modify(|w| w.set_ft(pin, falling)); - EXTI.pr(CORE_INDEX).write(|w| w.set_pif(pin, true)); // clear pending bit - EXTI.cpu(CORE_INDEX) - .imr(CORE_INDEX) - .modify(|w| w.set_im(pin, vals::Mr::UNMASKED)); - }); - - Self { - pin, - phantom: PhantomData, - } - } -} - -impl<'a> Drop for ExtiInputFuture<'a> { - fn drop(&mut self) { - cortex_m::interrupt::free(|_| unsafe { - let pin = self.pin as _; - EXTI.cpu(CORE_INDEX) - .imr(CORE_INDEX) - .modify(|w| w.set_im(pin, vals::Mr::MASKED)); - }); - } -} - -impl<'a> Future for ExtiInputFuture<'a> { - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - EXTI_WAKERS[self.pin as usize].register(cx.waker()); - - if unsafe { - EXTI.cpu(CORE_INDEX) - .imr(CORE_INDEX) - .read() - .im(self.pin as _) - == vals::Mr::MASKED - } { - Poll::Ready(()) - } else { - Poll::Pending - } - } -} - -use crate::interrupt; - -macro_rules! impl_irq { - ($e:ident) => { - #[interrupt] - unsafe fn $e() { - on_irq() - } - }; -} - -foreach_exti_irq!(impl_irq); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index af4ab95f..503d10f5 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -68,12 +68,14 @@ pub use generated::{peripherals, Peripherals}; #[non_exhaustive] pub struct Config { pub rcc: rcc::Config, + pub enable_debug_during_sleep: bool, } impl Default for Config { fn default() -> Self { Self { rcc: Default::default(), + enable_debug_during_sleep: true, } } } @@ -83,6 +85,10 @@ pub fn init(config: Config) -> Peripherals { let p = Peripherals::take(); unsafe { + if config.enable_debug_during_sleep { + dbgmcu::Dbgmcu::enable_all(); + } + gpio::init(); dma::init(); #[cfg(exti)] diff --git a/embassy-stm32/src/rcc/f0/mod.rs b/embassy-stm32/src/rcc/f0/mod.rs index 6600a1e2..916ed39f 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; use embassy::util::Unborrow; -use crate::dbgmcu::Dbgmcu; use crate::pac::{FLASH, RCC}; use crate::peripherals; use crate::time::Hertz; @@ -27,7 +26,6 @@ pub struct Config { pub sys_ck: Option, pub hclk: Option, pub pclk: Option, - pub enable_debug_wfe: bool, } pub struct Rcc<'d> { @@ -190,12 +188,6 @@ impl<'d> Rcc<'d> { } }) } - - if self.config.enable_debug_wfe { - RCC.ahbenr().modify(|w| w.set_dmaen(true)); - - critical_section::with(|_| Dbgmcu::enable_all()); - } } Clocks { @@ -210,18 +202,6 @@ impl<'d> Rcc<'d> { } pub unsafe fn init(config: Config) { - RCC.ahbenr().modify(|w| { - w.set_iopaen(true); - w.set_iopben(true); - w.set_iopcen(true); - w.set_iopden(true); - - #[cfg(rcc_f0)] - w.set_iopeen(true); - - w.set_iopfen(true); - }); - let rcc = Rcc::new(::steal(), config); let clocks = rcc.freeze(); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/f4/mod.rs b/embassy-stm32/src/rcc/f4/mod.rs index eab98daf..04083dfa 100644 --- a/embassy-stm32/src/rcc/f4/mod.rs +++ b/embassy-stm32/src/rcc/f4/mod.rs @@ -21,7 +21,6 @@ pub struct Config { pub hclk: Option, pub pclk1: Option, pub pclk2: Option, - pub enable_debug_wfe: bool, } /// RCC peripheral @@ -176,15 +175,6 @@ impl<'d> Rcc<'d> { }); } - if self.config.enable_debug_wfe { - unsafe { - RCC.ahb1enr().modify(|w| w.set_dma1en(true)); - critical_section::with(|_| { - crate::dbgmcu::Dbgmcu::enable_all(); - }); - } - } - Clocks { sys: Hertz(sysclk), apb1: Hertz(pclk1), diff --git a/embassy-stm32/src/rcc/h7/mod.rs b/embassy-stm32/src/rcc/h7/mod.rs index d6a55c3b..5567a478 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; use embassy::util::Unborrow; use crate::pac::rcc::vals::Timpre; -use crate::pac::{DBGMCU, RCC, SYSCFG}; +use crate::pac::{RCC, SYSCFG}; use crate::peripherals; use crate::pwr::{Power, VoltageScale}; use crate::rcc::{set_freqs, Clocks}; @@ -363,25 +363,6 @@ impl<'d> Rcc<'d> { } } - /// Enables debugging during WFI/WFE - /// - /// Set `enable_dma1` to true if you do not have at least one bus master (other than the CPU) - /// enable during WFI/WFE - pub fn enable_debug_wfe(&mut self, _dbg: &mut peripherals::DBGMCU, enable_dma1: bool) { - // NOTE(unsafe) We have exclusive access to the RCC and DBGMCU - unsafe { - if enable_dma1 { - RCC.ahb1enr().modify(|w| w.set_dma1en(true)); - } - - DBGMCU.cr().modify(|w| { - w.set_dbgsleep_d1(true); - w.set_dbgstby_d1(true); - w.set_dbgstop_d1(true); - }); - } - } - /// Setup traceclk /// Returns a pll1_r_ck 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 290449e1..e65faaa2 100644 --- a/embassy-stm32/src/rcc/l0/mod.rs +++ b/embassy-stm32/src/rcc/l0/mod.rs @@ -1,5 +1,4 @@ pub use super::types::*; -use crate::dbgmcu::Dbgmcu; use crate::pac; use crate::peripherals::{self, CRS, RCC, SYSCFG}; use crate::rcc::{get_freqs, set_freqs, Clocks}; @@ -168,15 +167,6 @@ impl<'d> Rcc<'d> { unsafe { get_freqs() } } - pub fn enable_debug_wfe(&mut self, _dbg: &mut peripherals::DBGMCU, enable_dma: bool) { - // NOTE(unsafe) We have exclusive access to the RCC and DBGMCU - unsafe { - pac::RCC.ahbenr().modify(|w| w.set_dma1en(enable_dma)); - - Dbgmcu::enable_all(); - } - } - pub fn enable_hsi48(&mut self, _syscfg: &mut SYSCFG, _crs: CRS) -> HSI48 { let rcc = pac::RCC; unsafe { @@ -387,16 +377,6 @@ impl RccExt for RCC { pub struct HSI48(()); pub unsafe fn init(config: Config) { - let rcc = pac::RCC; - rcc.iopenr().write(|w| { - w.set_iopaen(true); - w.set_iopben(true); - w.set_iopcen(true); - w.set_iopden(true); - w.set_iopeen(true); - w.set_iophen(true); - }); - let r = ::steal(); let clocks = r.freeze(config); set_freqs(clocks); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 87be0a5b..9c8da4a9 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -10,6 +10,8 @@ pub struct Clocks { pub sys: Hertz, pub apb1: Hertz, pub apb2: Hertz, + #[cfg(rcc_wl5)] + pub apb3: Hertz, pub apb1_tim: Hertz, pub apb2_tim: Hertz, @@ -17,13 +19,13 @@ pub struct Clocks { #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))] pub ahb: Hertz, - #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] + #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))] pub ahb1: Hertz, - #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] + #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))] pub ahb2: Hertz, - #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] + #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))] pub ahb3: Hertz, #[cfg(any(rcc_h7))] @@ -66,10 +68,10 @@ cfg_if::cfg_if! { } else if #[cfg(rcc_f4)] { mod f4; pub use f4::*; - } else if #[cfg(rcc_wb55)] { - mod wb55; - pub use wb55::*; - } else if #[cfg(rcc_wl5x)] { + } else if #[cfg(rcc_wb)] { + mod wb; + pub use wb::*; + } else if #[cfg(rcc_wl5)] { mod wl5x; pub use wl5x::*; } 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 similarity index 100% rename from embassy-stm32/src/rcc/wb55/mod.rs rename to 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 72caad2e..e1e001c7 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 { } }; + // TODO: completely untested + let apb3_freq = ahb_freq; + Clocks { sys: sys_clk.hz(), ahb1: ahb_freq.hz(), @@ -197,6 +200,7 @@ impl RccExt for RCC { ahb3: ahb_freq.hz(), apb1: apb1_freq.hz(), apb2: apb2_freq.hz(), + apb3: apb3_freq.hz(), apb1_tim: apb1_tim_freq.hz(), apb2_tim: apb2_tim_freq.hz(), } diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs index 8429cc60..418f2794 100644 --- a/examples/stm32f0/src/bin/hello.rs +++ b/examples/stm32f0/src/bin/hello.rs @@ -12,7 +12,7 @@ use embassy_stm32::Peripherals; #[path = "../example_common.rs"] mod example_common; -#[embassy::main(config = "example_common::config()")] +#[embassy::main] async fn main(_spawner: Spawner, _p: Peripherals) -> ! { loop { Timer::after(Duration::from_secs(1)).await; diff --git a/examples/stm32f0/src/example_common.rs b/examples/stm32f0/src/example_common.rs index f5011965..54d63383 100644 --- a/examples/stm32f0/src/example_common.rs +++ b/examples/stm32f0/src/example_common.rs @@ -6,13 +6,6 @@ use panic_probe as _; pub use defmt::*; use core::sync::atomic::{AtomicUsize, Ordering}; -use embassy_stm32::Config; - -pub fn config() -> Config { - let mut config = Config::default(); - config.rcc.enable_debug_wfe = true; - config -} defmt::timestamp! {"{=u64}", { static COUNT: AtomicUsize = AtomicUsize::new(0); diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs index b3a0ffb8..a30887f7 100644 --- a/examples/stm32f4/src/bin/blinky.rs +++ b/examples/stm32f4/src/bin/blinky.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; @@ -18,10 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let mut led = Output::new(p.PB7, Level::High, Speed::Low); loop { diff --git a/examples/stm32f4/src/bin/button.rs b/examples/stm32f4/src/bin/button.rs index 90998cf4..04fcfcc2 100644 --- a/examples/stm32f4/src/bin/button.rs +++ b/examples/stm32f4/src/bin/button.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embedded_hal::digital::v2::{InputPin, OutputPin}; use example_common::*; @@ -16,10 +15,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); 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 ee43fa7d..49c23ca3 100644 --- a/examples/stm32f4/src/bin/button_exti.rs +++ b/examples/stm32f4/src/bin/button_exti.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{Input, Pull}; use embassy_stm32::Peripherals; @@ -18,10 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let button = Input::new(p.PC13, Pull::Down); let mut button = ExtiInput::new(button, p.EXTI13); diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs index 2bb24f04..29dff551 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs @@ -10,7 +10,6 @@ mod example_common; use cortex_m_rt::entry; use embassy_stm32::can::filter::Mask32; use embassy_stm32::can::{Can, Frame, StandardId}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Input, Pull}; use example_common::*; @@ -18,10 +17,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let mut p = embassy_stm32::init(Default::default()); // 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 1b8730ae..8059f4b5 100644 --- a/examples/stm32f4/src/bin/hello.rs +++ b/examples/stm32f4/src/bin/hello.rs @@ -17,7 +17,6 @@ mod example_common; fn config() -> Config { let mut config = Config::default(); config.rcc.sys_ck = Some(Hertz(84_000_000)); - config.rcc.enable_debug_wfe = true; config } diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs index bb130a2e..19b6c62a 100644 --- a/examples/stm32f4/src/bin/spi.rs +++ b/examples/stm32f4/src/bin/spi.rs @@ -8,7 +8,6 @@ mod example_common; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; @@ -21,10 +20,6 @@ use example_common::*; fn main() -> ! { info!("Hello World, dude!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); let mut spi = Spi::new( diff --git a/examples/stm32f4/src/bin/spi_dma.rs b/examples/stm32f4/src/bin/spi_dma.rs index a965bef7..ef88fbb9 100644 --- a/examples/stm32f4/src/bin/spi_dma.rs +++ b/examples/stm32f4/src/bin/spi_dma.rs @@ -9,7 +9,6 @@ mod example_common; use core::fmt::Write; use core::str::from_utf8; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; use embassy_stm32::Peripherals; @@ -21,10 +20,6 @@ use heapless::String; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let mut spi = Spi::new( p.SPI1, p.PB3, diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs index 781c6a95..8bb2ada9 100644 --- a/examples/stm32f4/src/bin/usart.rs +++ b/examples/stm32f4/src/bin/usart.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embedded_hal::blocking::serial::Write; @@ -17,10 +16,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); let config = Config::default(); diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs index bf50b8ad..3cfa6219 100644 --- a/examples/stm32f4/src/bin/usart_dma.rs +++ b/examples/stm32f4/src/bin/usart_dma.rs @@ -8,7 +8,6 @@ mod example_common; use core::fmt::Write; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::Peripherals; @@ -20,10 +19,6 @@ use heapless::String; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let config = Config::default(); let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, p.DMA1_CH3, NoDma, config); diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs index 09b34eac..3784fba8 100644 --- a/examples/stm32h7/src/bin/blinky.rs +++ b/examples/stm32h7/src/bin/blinky.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; @@ -18,8 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { Dbgmcu::enable_all() }; - let mut led = Output::new(p.PB14, Level::High, Speed::Low); loop { diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs index ee43fa7d..49c23ca3 100644 --- a/examples/stm32h7/src/bin/button_exti.rs +++ b/examples/stm32h7/src/bin/button_exti.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{Input, Pull}; use embassy_stm32::Peripherals; @@ -18,10 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let button = Input::new(p.PC13, Pull::Down); let mut button = ExtiInput::new(button, p.EXTI13); diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 8816f63c..e4c3a731 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -19,10 +19,6 @@ fn main() -> ! { let p = embassy_stm32::init(config()); - unsafe { - Dbgmcu::enable_all(); - } - let mut dac = Dac::new(p.DAC1, p.PA4, NoPin); loop { @@ -33,7 +29,6 @@ fn main() -> ! { } } -use embassy_stm32::dbgmcu::Dbgmcu; use micromath::F32Ext; fn to_sine_wave(v: u8) -> u8 { diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index e8d13876..4a9f261c 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -19,7 +19,6 @@ use embassy_macros::interrupt_take; use embassy_net::{ Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, }; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::eth::lan8742a::LAN8742A; use embassy_stm32::eth::{Ethernet, State}; use embassy_stm32::rng::Random; @@ -96,10 +95,6 @@ fn main() -> ! { info!("Setup RCC..."); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(config()); let rng = Random::new(p.RNG); diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index 047b6584..5514b0d3 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -17,7 +17,6 @@ use example_common::*; use core::str::from_utf8; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::peripherals::SPI3; use embassy_stm32::time::U32Ext; use heapless::String; @@ -43,10 +42,6 @@ static EXECUTOR: Forever = Forever::new(); fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(config()); let spi = spi::Spi::new( diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index f11b7eb4..ea160590 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -16,7 +16,6 @@ use example_common::*; use core::str::from_utf8; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; use embassy_stm32::spi; use heapless::String; @@ -39,10 +38,6 @@ static EXECUTOR: Forever = Forever::new(); fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(config()); let spi = spi::Spi::new( diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index a3fcc6d3..10bf7813 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}; use example_common::*; use cortex_m_rt::entry; -use embassy_stm32::dbgmcu::Dbgmcu; #[embassy::task] async fn main_task() { @@ -39,10 +38,6 @@ static EXECUTOR: Forever = Forever::new(); fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let executor = EXECUTOR.put(Executor::new()); executor.run(|spawner| { diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs index 3f70a82b..eb71a72c 100644 --- a/examples/stm32h7/src/bin/usart_dma.rs +++ b/examples/stm32h7/src/bin/usart_dma.rs @@ -9,7 +9,6 @@ mod example_common; use core::fmt::Write; use embassy::executor::Executor; use embassy::util::Forever; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_traits::uart::Write as _Write; @@ -41,10 +40,6 @@ static EXECUTOR: Forever = Forever::new(); fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let executor = EXECUTOR.put(Executor::new()); executor.run(|spawner| { diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 9b316615..07b033c1 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -27,7 +27,7 @@ defmt = "0.2.0" defmt-rtt = "0.2.0" cortex-m = "0.7.1" -cortex-m-rt = "0.6.14" +cortex-m-rt = "0.7.0" embedded-hal = { version = "0.2.4" } panic-probe = { version = "0.2.0", features= ["print-defmt"] } futures = { 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 29f5d7c7..d8513bc7 100644 --- a/examples/stm32l0/src/bin/blinky.rs +++ b/examples/stm32l0/src/bin/blinky.rs @@ -10,17 +10,14 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_stm32::rcc::Rcc; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; use example_common::*; #[embassy::main] -async fn main(_spawner: Spawner, mut p: Peripherals) { +async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true); - let mut led = Output::new(p.PB5, Level::High, Speed::Low); loop { diff --git a/examples/stm32l0/src/bin/button.rs b/examples/stm32l0/src/bin/button.rs index e37d3f26..a7e82e37 100644 --- a/examples/stm32l0/src/bin/button.rs +++ b/examples/stm32l0/src/bin/button.rs @@ -6,22 +6,16 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_stm32::{ - gpio::{Input, Level, Output, Pull, Speed}, - rcc::*, -}; +use embassy::executor::Spawner; +use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; +use embassy_stm32::Peripherals; use embedded_hal::digital::v2::{InputPin, OutputPin}; use example_common::*; -use cortex_m_rt::entry; - -#[entry] -fn main() -> ! { +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - let mut p = embassy_stm32::init(Default::default()); - Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true); - let button = Input::new(p.PB2, Pull::Up); let mut led1 = Output::new(p.PA5, Level::High, Speed::Low); 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 40e25b08..13ce9990 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -17,7 +17,6 @@ use example_common::*; #[embassy::main] async fn main(_spawner: Spawner, mut p: Peripherals) { let mut rcc = rcc::Rcc::new(p.RCC); - rcc.enable_debug_wfe(&mut p.DBGMCU, true); // Enables SYSCFG let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS); diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs index 43ffb553..83c4fe32 100644 --- a/examples/stm32l0/src/bin/spi.rs +++ b/examples/stm32l0/src/bin/spi.rs @@ -7,25 +7,21 @@ #[path = "../example_common.rs"] mod example_common; +use embassy::executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embedded_hal::digital::v2::OutputPin; use example_common::*; -use cortex_m_rt::entry; use embassy_stm32::dma::NoDma; -use embassy_stm32::rcc; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; +use embassy_stm32::Peripherals; use embedded_hal::blocking::spi::Transfer; -#[entry] -fn main() -> ! { +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World, folks!"); - let mut p = embassy_stm32::init(Default::default()); - let mut rcc = rcc::Rcc::new(p.RCC); - rcc.enable_debug_wfe(&mut p.DBGMCU, true); - let mut spi = Spi::new( p.SPI1, p.PB3, @@ -40,7 +36,7 @@ fn main() -> ! { let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); loop { - let mut buf = [0x0A; 4]; + let mut buf = [0x0Au8; 4]; unwrap!(cs.set_low()); unwrap!(spi.transfer(&mut buf)); unwrap!(cs.set_high()); diff --git a/examples/stm32l0/src/bin/usart_dma.rs b/examples/stm32l0/src/bin/usart_dma.rs index 39a60517..2b2424e9 100644 --- a/examples/stm32l0/src/bin/usart_dma.rs +++ b/examples/stm32l0/src/bin/usart_dma.rs @@ -11,14 +11,11 @@ use example_common::*; use embassy::executor::Spawner; use embassy_stm32::usart::{Config, Uart}; -use embassy_stm32::{rcc, Peripherals}; +use embassy_stm32::Peripherals; use embassy_traits::uart::{Read, Write}; #[embassy::main] -async fn main(_spawner: Spawner, mut p: Peripherals) { - let mut rcc = rcc::Rcc::new(p.RCC); - rcc.enable_debug_wfe(&mut p.DBGMCU, true); - +async fn main(_spawner: Spawner, p: Peripherals) { let mut usart = Uart::new( p.USART1, p.PB7, diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs index 5c79d067..66a00f41 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}; use embassy_stm32::dma::NoDma; use embassy_stm32::interrupt; use embassy_stm32::usart::{BufferedUart, Config, State, Uart}; -use embassy_stm32::{rcc, Peripherals}; +use embassy_stm32::Peripherals; #[embassy::main] -async fn main(_spawner: Spawner, mut p: Peripherals) { - let mut rcc = rcc::Rcc::new(p.RCC); - rcc.enable_debug_wfe(&mut p.DBGMCU, true); - +async fn main(_spawner: Spawner, p: Peripherals) { static mut TX_BUFFER: [u8; 8] = [0; 8]; static mut RX_BUFFER: [u8; 256] = [0; 256]; diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 3f6b3467..3fa6fa46 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -26,7 +26,7 @@ defmt = "0.2.0" defmt-rtt = "0.2.0" cortex-m = "0.7.1" -cortex-m-rt = "0.6.14" +cortex-m-rt = "0.7.0" embedded-hal = { version = "0.2.4" } panic-probe = { version = "0.2.0", features= ["print-defmt"] } futures = { 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 c778d9c3..14b4e5ec 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -9,7 +9,6 @@ mod example_common; use embassy::time::Delay; use embassy_stm32::adc::{Adc, Resolution}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::pac; use example_common::*; @@ -18,8 +17,6 @@ fn main() -> ! { info!("Hello World!"); unsafe { - Dbgmcu::enable_all(); - pac::RCC.ccipr().modify(|w| { w.set_adcsel(0b11); }); diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs index c9ba587e..9c983bc6 100644 --- a/examples/stm32l4/src/bin/blinky.rs +++ b/examples/stm32l4/src/bin/blinky.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; @@ -18,10 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let mut led = Output::new(p.PB14, Level::High, Speed::Low); loop { diff --git a/examples/stm32l4/src/bin/button.rs b/examples/stm32l4/src/bin/button.rs index 883a0d6c..be6e2d2f 100644 --- a/examples/stm32l4/src/bin/button.rs +++ b/examples/stm32l4/src/bin/button.rs @@ -6,7 +6,6 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Input, Pull}; use embedded_hal::digital::v2::InputPin; use example_common::*; @@ -15,10 +14,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); 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 8a78b258..c55d6408 100644 --- a/examples/stm32l4/src/bin/button_exti.rs +++ b/examples/stm32l4/src/bin/button_exti.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{Input, Pull}; use embassy_stm32::Peripherals; @@ -18,10 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let button = Input::new(p.PC13, Pull::Up); let mut button = ExtiInput::new(button, p.EXTI13); diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs index c479f86c..e03fbc95 100644 --- a/examples/stm32l4/src/bin/dac.rs +++ b/examples/stm32l4/src/bin/dac.rs @@ -8,7 +8,6 @@ mod example_common; use embassy_stm32::dac::{Channel, Dac, Value}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::NoPin; use embassy_stm32::pac; use example_common::*; @@ -18,8 +17,6 @@ fn main() -> ! { info!("Hello World!"); unsafe { - Dbgmcu::enable_all(); - pac::RCC.apb1enr1().modify(|w| { w.set_dac1en(true); }); diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs index ef6e2fca..376537e9 100644 --- a/examples/stm32l4/src/bin/spi.rs +++ b/examples/stm32l4/src/bin/spi.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::spi::{Config, Spi}; @@ -20,10 +19,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); let mut spi = Spi::new( diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs index d626a129..75c19a3b 100644 --- a/examples/stm32l4/src/bin/spi_dma.rs +++ b/examples/stm32l4/src/bin/spi_dma.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; @@ -21,10 +20,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let mut spi = Spi::new( p.SPI3, p.PC10, diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs index 95ac84b2..09b62f68 100644 --- a/examples/stm32l4/src/bin/usart.rs +++ b/examples/stm32l4/src/bin/usart.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embedded_hal::blocking::serial::Write; @@ -17,10 +16,6 @@ use example_common::*; fn main() -> ! { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let p = embassy_stm32::init(Default::default()); let config = Config::default(); diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs index f74a0e06..d307dc13 100644 --- a/examples/stm32l4/src/bin/usart_dma.rs +++ b/examples/stm32l4/src/bin/usart_dma.rs @@ -8,7 +8,6 @@ mod example_common; use core::fmt::Write; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::Peripherals; @@ -20,10 +19,6 @@ use heapless::String; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { - Dbgmcu::enable_all(); - } - let config = Config::default(); let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_CH3, NoDma, config); diff --git a/examples/stm32wb55/src/bin/blinky.rs b/examples/stm32wb55/src/bin/blinky.rs index 2deaf5f5..ea5f872d 100644 --- a/examples/stm32wb55/src/bin/blinky.rs +++ b/examples/stm32wb55/src/bin/blinky.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; @@ -18,8 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { Dbgmcu::enable_all() }; - let mut led = Output::new(p.PB0, Level::High, Speed::Low); loop { diff --git a/examples/stm32wb55/src/bin/button_exti.rs b/examples/stm32wb55/src/bin/button_exti.rs new file mode 100644 index 00000000..1c070833 --- /dev/null +++ b/examples/stm32wb55/src/bin/button_exti.rs @@ -0,0 +1,31 @@ +#![no_std] +#![no_main] +#![feature(trait_alias)] +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +#[path = "../example_common.rs"] +mod example_common; +use embassy::executor::Spawner; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::{Input, Pull}; +use embassy_stm32::Peripherals; +use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; +use example_common::*; + +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { + info!("Hello World!"); + + let button = Input::new(p.PC4, Pull::Up); + let mut button = ExtiInput::new(button, p.EXTI4); + + info!("Press the USER button..."); + + loop { + button.wait_for_falling_edge().await; + info!("Pressed!"); + button.wait_for_rising_edge().await; + info!("Released!"); + } +} diff --git a/examples/stm32wl55/src/bin/blinky.rs b/examples/stm32wl55/src/bin/blinky.rs index b5e5ffcf..b13b66e0 100644 --- a/examples/stm32wl55/src/bin/blinky.rs +++ b/examples/stm32wl55/src/bin/blinky.rs @@ -8,7 +8,6 @@ mod example_common; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::Peripherals; use embedded_hal::digital::v2::OutputPin; @@ -18,8 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { Dbgmcu::enable_all() }; - let mut led = Output::new(p.PB15, Level::High, Speed::Low); loop { diff --git a/examples/stm32wl55/src/bin/button.rs b/examples/stm32wl55/src/bin/button.rs index 84e1f599..ca1625a6 100644 --- a/examples/stm32wl55/src/bin/button.rs +++ b/examples/stm32wl55/src/bin/button.rs @@ -6,10 +6,7 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_stm32::{ - dbgmcu::Dbgmcu, - gpio::{Input, Level, Output, Pull, Speed}, -}; +use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embedded_hal::digital::v2::{InputPin, OutputPin}; use example_common::*; @@ -21,8 +18,6 @@ fn main() -> ! { let p = embassy_stm32::init(Default::default()); - unsafe { Dbgmcu::enable_all() }; - let button = Input::new(p.PA0, Pull::Up); let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); 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 2f6e5511..b34e5457 100644 --- a/examples/stm32wl55/src/bin/button_exti.rs +++ b/examples/stm32wl55/src/bin/button_exti.rs @@ -7,7 +7,6 @@ #[path = "../example_common.rs"] mod example_common; use embassy::executor::Spawner; -use embassy_stm32::dbgmcu::Dbgmcu; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{Input, Pull}; use embassy_stm32::Peripherals; @@ -18,8 +17,6 @@ use example_common::*; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello World!"); - unsafe { Dbgmcu::enable_all() }; - let button = Input::new(p.PA0, Pull::Up); let mut button = ExtiInput::new(button, p.EXTI0); diff --git a/stm32-data b/stm32-data index bfd4797d..12be5f3d 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit bfd4797d1278c3e0b4611bc79e12346dedbde7c9 +Subproject commit 12be5f3da4ba38850d94ab865d2b920bd936300b diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index b1980d84..8646accf 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs @@ -1,4 +1,5 @@ use chiptool::generate::CommonModule; +use chiptool::ir::IR; use regex::Regex; use serde::Deserialize; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -116,11 +117,7 @@ impl BlockInfo { } } -fn find_reg_for_field<'c>( - rcc: &'c ir::IR, - reg_regex: &str, - field_name: &str, -) -> Option<(&'c str, &'c str)> { +fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> { let reg_regex = Regex::new(reg_regex).unwrap(); for (name, fieldset) in &rcc.fieldsets { @@ -273,19 +270,18 @@ pub fn gen(options: Options) { }); // Load RCC register for chip - let rcc = core.peripherals.iter().find_map(|(name, p)| { - if name == "RCC" { - p.block.as_ref().map(|block| { - let bi = BlockInfo::parse(block); - let rcc_reg_path = data_dir - .join("registers") - .join(&format!("{}_{}.yaml", bi.module, bi.version)); - serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap() - }) - } else { - None - } - }); + let (_, rcc) = core + .peripherals + .iter() + .find(|(name, _)| name == &"RCC") + .expect("RCC peripheral missing"); + + let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block"); + let bi = BlockInfo::parse(&rcc_block); + let rcc_reg_path = data_dir + .join("registers") + .join(&format!("{}_{}.yaml", bi.module, bi.version)); + let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap(); let mut peripheral_versions: BTreeMap = BTreeMap::new(); let mut pin_table: Vec> = Vec::new(); @@ -424,73 +420,71 @@ pub fn gen(options: Options) { _ => {} } - if let Some(rcc) = &rcc { - // Workaround for clock registers being split on some chip families. Assume fields are - // named after peripheral and look for first field matching and use that register. - let mut en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); - let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); + // Workaround for clock registers being split on some chip families. Assume fields are + // named after peripheral and look for first field matching and use that register. + let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); + let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); - if en.is_none() && name.ends_with("1") { - en = find_reg_for_field( - &rcc, - "^.+ENR\\d*$", - &format!("{}EN", &name[..name.len() - 1]), - ); - rst = find_reg_for_field( - &rcc, - "^.+RSTR\\d*$", - &format!("{}RST", &name[..name.len() - 1]), - ); + if en.is_none() && name.ends_with("1") { + en = find_reg( + &rcc, + "^.+ENR\\d*$", + &format!("{}EN", &name[..name.len() - 1]), + ); + rst = find_reg( + &rcc, + "^.+RSTR\\d*$", + &format!("{}RST", &name[..name.len() - 1]), + ); + } + + match (en, rst) { + (Some((enable_reg, enable_field)), reset_reg_field) => { + let clock = match &p.clock { + Some(clock) => clock.as_str(), + None => { + // No clock was specified, derive the clock name from the enable register name. + Regex::new("([A-Z]+\\d*).*") + .unwrap() + .captures(enable_reg) + .unwrap() + .get(1) + .unwrap() + .as_str() + } + }; + + let clock = if name.starts_with("TIM") { + format!("{}_tim", clock.to_ascii_lowercase()) + } else { + clock.to_ascii_lowercase() + }; + + let mut row = Vec::with_capacity(6); + row.push(name.clone()); + row.push(clock); + row.push(enable_reg.to_ascii_lowercase()); + + if let Some((reset_reg, reset_field)) = reset_reg_field { + row.push(reset_reg.to_ascii_lowercase()); + row.push(format!("set_{}", enable_field.to_ascii_lowercase())); + row.push(format!("set_{}", reset_field.to_ascii_lowercase())); + } else { + row.push(format!("set_{}", enable_field.to_ascii_lowercase())); + } + + if !name.starts_with("GPIO") { + peripheral_rcc_table.push(row); + } else { + gpio_rcc_table.push(row); + gpio_regs.insert(enable_reg.to_ascii_lowercase()); + } } - - match (en, rst) { - (Some((enable_reg, enable_field)), reset_reg_field) => { - let clock = match &p.clock { - Some(clock) => clock.as_str(), - None => { - // No clock was specified, derive the clock name from the enable register name. - Regex::new("([A-Z]+\\d*).*") - .unwrap() - .captures(enable_reg) - .unwrap() - .get(1) - .unwrap() - .as_str() - } - }; - - let clock = if name.starts_with("TIM") { - format!("{}_tim", clock.to_ascii_lowercase()) - } else { - clock.to_ascii_lowercase() - }; - - let mut row = Vec::with_capacity(6); - row.push(name.clone()); - row.push(clock); - row.push(enable_reg.to_ascii_lowercase()); - - if let Some((reset_reg, reset_field)) = reset_reg_field { - row.push(reset_reg.to_ascii_lowercase()); - row.push(format!("set_{}", enable_field.to_ascii_lowercase())); - row.push(format!("set_{}", reset_field.to_ascii_lowercase())); - } else { - row.push(format!("set_{}", enable_field.to_ascii_lowercase())); - } - - if !name.starts_with("GPIO") { - peripheral_rcc_table.push(row); - } else { - gpio_rcc_table.push(row); - gpio_regs.insert(enable_reg.to_ascii_lowercase()); - } - } - (None, Some(_)) => { - println!("Unable to find enable register for {}", name) - } - (None, None) => { - println!("Unable to find enable and reset register for {}", name) - } + (None, Some(_)) => { + println!("Unable to find enable register for {}", name) + } + (None, None) => { + println!("Unable to find enable and reset register for {}", name) } } } @@ -502,6 +496,10 @@ pub fn gen(options: Options) { gpio_rcc_table.push(vec![reg]); } + // We should always find GPIO RCC regs. If not, it means something + // is broken and GPIO won't work because it's not enabled. + assert!(!gpio_rcc_table.is_empty()); + for (id, channel_info) in &core.dma_channels { let mut row = Vec::new(); 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 31f68404..0380affc 100644 --- a/stm32-metapac-gen/src/main.rs +++ b/stm32-metapac-gen/src/main.rs @@ -1,3 +1,4 @@ +use std::env::args; use std::path::PathBuf; use stm32_metapac_gen::*; @@ -5,13 +6,24 @@ fn main() { let out_dir = PathBuf::from("out"); let data_dir = PathBuf::from("../stm32-data/data"); - let chips = std::fs::read_dir(data_dir.join("chips")) - .unwrap() - .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) - .filter(|s| s.ends_with(".yaml")) - .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride - .map(|s| s.strip_suffix(".yaml").unwrap().to_string()) - .collect(); + let args: Vec = args().collect(); + + let chips = match &args[..] { + [_, chip] => { + vec![chip.clone()] + } + [_] => { + std::fs::read_dir(data_dir.join("chips")) + .unwrap() + .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) + .filter(|s| s.ends_with(".yaml")) + .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride + .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4 + .map(|s| s.strip_suffix(".yaml").unwrap().to_string()) + .collect() + } + _ => panic!("usage: stm32-metapac-gen [chip?]"), + }; gen(Options { out_dir,