Merge pull request #367 from embassy-rs/metapac-cleanup
stm32-metapac cleanups
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -2,3 +2,4 @@ target
 | 
				
			|||||||
Cargo.lock
 | 
					Cargo.lock
 | 
				
			||||||
third_party
 | 
					third_party
 | 
				
			||||||
/Cargo.toml
 | 
					/Cargo.toml
 | 
				
			||||||
 | 
					stm32-metapac-gen/out/
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
 | 
					use std::fs;
 | 
				
			||||||
use std::path::PathBuf;
 | 
					use std::path::PathBuf;
 | 
				
			||||||
use std::process::Command;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    let chip_name = env::vars_os()
 | 
					    let chip_name = env::vars_os()
 | 
				
			||||||
@@ -11,17 +11,72 @@ fn main() {
 | 
				
			|||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
        .to_ascii_lowercase();
 | 
					        .to_ascii_lowercase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct Peripheral {
 | 
				
			||||||
 | 
					        kind: String,
 | 
				
			||||||
 | 
					        name: String,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut peripherals: Vec<Peripheral> = 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<String> = 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_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
 | 
				
			||||||
    let out_file = out_dir.join("generated.rs").to_string_lossy().to_string();
 | 
					    let out_file = out_dir.join("generated.rs").to_string_lossy().to_string();
 | 
				
			||||||
 | 
					    fs::write(
 | 
				
			||||||
    let exit_code = Command::new("python3")
 | 
					        out_file,
 | 
				
			||||||
        .args(&["gen.py", &chip_name, &out_file])
 | 
					        format!(
 | 
				
			||||||
        .status()
 | 
					            "embassy_hal_common::peripherals!({});",
 | 
				
			||||||
        .expect("failed to execute gen.py");
 | 
					            singletons.join(",")
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    if !exit_code.success() {
 | 
					    )
 | 
				
			||||||
        panic!("gen.py exited with {:?}", exit_code)
 | 
					    .unwrap();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stm32_metapac::peripheral_versions!(
 | 
					    stm32_metapac::peripheral_versions!(
 | 
				
			||||||
        ($peri:ident, $version:ident) => {
 | 
					        ($peri:ident, $version:ident) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)});")
 | 
					 | 
				
			||||||
							
								
								
									
										270
									
								
								embassy-stm32/src/exti.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								embassy-stm32/src/exti.rs
									
									
									
									
									
										Normal file
									
								
							@@ -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<Self::Item> {
 | 
				
			||||||
 | 
					        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<Target = T::ExtiChannel> + 'd) -> Self {
 | 
				
			||||||
 | 
					        Self { pin }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
 | 
				
			||||||
 | 
					    type Error = Infallible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn is_high(&self) -> Result<bool, Self::Error> {
 | 
				
			||||||
 | 
					        self.pin.is_high()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn is_low(&self) -> Result<bool, Self::Error> {
 | 
				
			||||||
 | 
					        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<Self::Output> {
 | 
				
			||||||
 | 
					        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)))]
 | 
				
			||||||
 | 
					    <crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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)))]
 | 
					 | 
				
			||||||
    <crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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<Self::Item> {
 | 
					 | 
				
			||||||
        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<Target = T::ExtiChannel> + 'd) -> Self {
 | 
					 | 
				
			||||||
        Self { pin }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
 | 
					 | 
				
			||||||
    type Error = Infallible;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn is_high(&self) -> Result<bool, Self::Error> {
 | 
					 | 
				
			||||||
        self.pin.is_high()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn is_low(&self) -> Result<bool, Self::Error> {
 | 
					 | 
				
			||||||
        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<Self::Output> {
 | 
					 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
@@ -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<Self::Item> {
 | 
					 | 
				
			||||||
        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<Target = T::ExtiChannel> + 'd) -> Self {
 | 
					 | 
				
			||||||
        Self { pin }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
 | 
					 | 
				
			||||||
    type Error = Infallible;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn is_high(&self) -> Result<bool, Self::Error> {
 | 
					 | 
				
			||||||
        self.pin.is_high()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn is_low(&self) -> Result<bool, Self::Error> {
 | 
					 | 
				
			||||||
        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<Self::Output> {
 | 
					 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
@@ -68,12 +68,14 @@ pub use generated::{peripherals, Peripherals};
 | 
				
			|||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
pub struct Config {
 | 
					pub struct Config {
 | 
				
			||||||
    pub rcc: rcc::Config,
 | 
					    pub rcc: rcc::Config,
 | 
				
			||||||
 | 
					    pub enable_debug_during_sleep: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for Config {
 | 
					impl Default for Config {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            rcc: Default::default(),
 | 
					            rcc: Default::default(),
 | 
				
			||||||
 | 
					            enable_debug_during_sleep: true,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -83,6 +85,10 @@ pub fn init(config: Config) -> Peripherals {
 | 
				
			|||||||
    let p = Peripherals::take();
 | 
					    let p = Peripherals::take();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					    unsafe {
 | 
				
			||||||
 | 
					        if config.enable_debug_during_sleep {
 | 
				
			||||||
 | 
					            dbgmcu::Dbgmcu::enable_all();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        gpio::init();
 | 
					        gpio::init();
 | 
				
			||||||
        dma::init();
 | 
					        dma::init();
 | 
				
			||||||
        #[cfg(exti)]
 | 
					        #[cfg(exti)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ use core::marker::PhantomData;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use embassy::util::Unborrow;
 | 
					use embassy::util::Unborrow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use crate::pac::{FLASH, RCC};
 | 
					use crate::pac::{FLASH, RCC};
 | 
				
			||||||
use crate::peripherals;
 | 
					use crate::peripherals;
 | 
				
			||||||
use crate::time::Hertz;
 | 
					use crate::time::Hertz;
 | 
				
			||||||
@@ -27,7 +26,6 @@ pub struct Config {
 | 
				
			|||||||
    pub sys_ck: Option<Hertz>,
 | 
					    pub sys_ck: Option<Hertz>,
 | 
				
			||||||
    pub hclk: Option<Hertz>,
 | 
					    pub hclk: Option<Hertz>,
 | 
				
			||||||
    pub pclk: Option<Hertz>,
 | 
					    pub pclk: Option<Hertz>,
 | 
				
			||||||
    pub enable_debug_wfe: bool,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Rcc<'d> {
 | 
					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 {
 | 
					        Clocks {
 | 
				
			||||||
@@ -210,18 +202,6 @@ impl<'d> Rcc<'d> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub unsafe fn init(config: Config) {
 | 
					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(<peripherals::RCC as embassy::util::Steal>::steal(), config);
 | 
					    let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config);
 | 
				
			||||||
    let clocks = rcc.freeze();
 | 
					    let clocks = rcc.freeze();
 | 
				
			||||||
    set_freqs(clocks);
 | 
					    set_freqs(clocks);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ pub struct Config {
 | 
				
			|||||||
    pub hclk: Option<Hertz>,
 | 
					    pub hclk: Option<Hertz>,
 | 
				
			||||||
    pub pclk1: Option<Hertz>,
 | 
					    pub pclk1: Option<Hertz>,
 | 
				
			||||||
    pub pclk2: Option<Hertz>,
 | 
					    pub pclk2: Option<Hertz>,
 | 
				
			||||||
    pub enable_debug_wfe: bool,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// RCC peripheral
 | 
					/// 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 {
 | 
					        Clocks {
 | 
				
			||||||
            sys: Hertz(sysclk),
 | 
					            sys: Hertz(sysclk),
 | 
				
			||||||
            apb1: Hertz(pclk1),
 | 
					            apb1: Hertz(pclk1),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
 | 
				
			|||||||
use embassy::util::Unborrow;
 | 
					use embassy::util::Unborrow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::pac::rcc::vals::Timpre;
 | 
					use crate::pac::rcc::vals::Timpre;
 | 
				
			||||||
use crate::pac::{DBGMCU, RCC, SYSCFG};
 | 
					use crate::pac::{RCC, SYSCFG};
 | 
				
			||||||
use crate::peripherals;
 | 
					use crate::peripherals;
 | 
				
			||||||
use crate::pwr::{Power, VoltageScale};
 | 
					use crate::pwr::{Power, VoltageScale};
 | 
				
			||||||
use crate::rcc::{set_freqs, Clocks};
 | 
					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
 | 
					    /// Setup traceclk
 | 
				
			||||||
    /// Returns a pll1_r_ck
 | 
					    /// Returns a pll1_r_ck
 | 
				
			||||||
    fn traceclk_setup(&mut self, sys_use_pll1_p: bool) {
 | 
					    fn traceclk_setup(&mut self, sys_use_pll1_p: bool) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
pub use super::types::*;
 | 
					pub use super::types::*;
 | 
				
			||||||
use crate::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use crate::pac;
 | 
					use crate::pac;
 | 
				
			||||||
use crate::peripherals::{self, CRS, RCC, SYSCFG};
 | 
					use crate::peripherals::{self, CRS, RCC, SYSCFG};
 | 
				
			||||||
use crate::rcc::{get_freqs, set_freqs, Clocks};
 | 
					use crate::rcc::{get_freqs, set_freqs, Clocks};
 | 
				
			||||||
@@ -168,15 +167,6 @@ impl<'d> Rcc<'d> {
 | 
				
			|||||||
        unsafe { get_freqs() }
 | 
					        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 {
 | 
					    pub fn enable_hsi48(&mut self, _syscfg: &mut SYSCFG, _crs: CRS) -> HSI48 {
 | 
				
			||||||
        let rcc = pac::RCC;
 | 
					        let rcc = pac::RCC;
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
@@ -387,16 +377,6 @@ impl RccExt for RCC {
 | 
				
			|||||||
pub struct HSI48(());
 | 
					pub struct HSI48(());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub unsafe fn init(config: Config) {
 | 
					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 = <peripherals::RCC as embassy::util::Steal>::steal();
 | 
					    let r = <peripherals::RCC as embassy::util::Steal>::steal();
 | 
				
			||||||
    let clocks = r.freeze(config);
 | 
					    let clocks = r.freeze(config);
 | 
				
			||||||
    set_freqs(clocks);
 | 
					    set_freqs(clocks);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,8 @@ pub struct Clocks {
 | 
				
			|||||||
    pub sys: Hertz,
 | 
					    pub sys: Hertz,
 | 
				
			||||||
    pub apb1: Hertz,
 | 
					    pub apb1: Hertz,
 | 
				
			||||||
    pub apb2: Hertz,
 | 
					    pub apb2: Hertz,
 | 
				
			||||||
 | 
					    #[cfg(rcc_wl5)]
 | 
				
			||||||
 | 
					    pub apb3: Hertz,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub apb1_tim: Hertz,
 | 
					    pub apb1_tim: Hertz,
 | 
				
			||||||
    pub apb2_tim: Hertz,
 | 
					    pub apb2_tim: Hertz,
 | 
				
			||||||
@@ -17,13 +19,13 @@ pub struct Clocks {
 | 
				
			|||||||
    #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))]
 | 
					    #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))]
 | 
				
			||||||
    pub ahb: Hertz,
 | 
					    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,
 | 
					    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,
 | 
					    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,
 | 
					    pub ahb3: Hertz,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(any(rcc_h7))]
 | 
					    #[cfg(any(rcc_h7))]
 | 
				
			||||||
@@ -66,10 +68,10 @@ cfg_if::cfg_if! {
 | 
				
			|||||||
    } else if #[cfg(rcc_f4)] {
 | 
					    } else if #[cfg(rcc_f4)] {
 | 
				
			||||||
        mod f4;
 | 
					        mod f4;
 | 
				
			||||||
        pub use f4::*;
 | 
					        pub use f4::*;
 | 
				
			||||||
    } else if #[cfg(rcc_wb55)] {
 | 
					    } else if #[cfg(rcc_wb)] {
 | 
				
			||||||
        mod wb55;
 | 
					        mod wb;
 | 
				
			||||||
        pub use wb55::*;
 | 
					        pub use wb::*;
 | 
				
			||||||
    } else if #[cfg(rcc_wl5x)] {
 | 
					    } else if #[cfg(rcc_wl5)] {
 | 
				
			||||||
        mod wl5x;
 | 
					        mod wl5x;
 | 
				
			||||||
        pub use wl5x::*;
 | 
					        pub use wl5x::*;
 | 
				
			||||||
    } else if #[cfg(any(rcc_f0, rcc_f0x0))] {
 | 
					    } else if #[cfg(any(rcc_f0, rcc_f0x0))] {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,6 +190,9 @@ impl RccExt for RCC {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: completely untested
 | 
				
			||||||
 | 
					        let apb3_freq = ahb_freq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Clocks {
 | 
					        Clocks {
 | 
				
			||||||
            sys: sys_clk.hz(),
 | 
					            sys: sys_clk.hz(),
 | 
				
			||||||
            ahb1: ahb_freq.hz(),
 | 
					            ahb1: ahb_freq.hz(),
 | 
				
			||||||
@@ -197,6 +200,7 @@ impl RccExt for RCC {
 | 
				
			|||||||
            ahb3: ahb_freq.hz(),
 | 
					            ahb3: ahb_freq.hz(),
 | 
				
			||||||
            apb1: apb1_freq.hz(),
 | 
					            apb1: apb1_freq.hz(),
 | 
				
			||||||
            apb2: apb2_freq.hz(),
 | 
					            apb2: apb2_freq.hz(),
 | 
				
			||||||
 | 
					            apb3: apb3_freq.hz(),
 | 
				
			||||||
            apb1_tim: apb1_tim_freq.hz(),
 | 
					            apb1_tim: apb1_tim_freq.hz(),
 | 
				
			||||||
            apb2_tim: apb2_tim_freq.hz(),
 | 
					            apb2_tim: apb2_tim_freq.hz(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ use embassy_stm32::Peripherals;
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main(config = "example_common::config()")]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner, _p: Peripherals) -> ! {
 | 
					async fn main(_spawner: Spawner, _p: Peripherals) -> ! {
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        Timer::after(Duration::from_secs(1)).await;
 | 
					        Timer::after(Duration::from_secs(1)).await;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,13 +6,6 @@ use panic_probe as _;
 | 
				
			|||||||
pub use defmt::*;
 | 
					pub use defmt::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::sync::atomic::{AtomicUsize, Ordering};
 | 
					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}", {
 | 
					defmt::timestamp! {"{=u64}", {
 | 
				
			||||||
        static COUNT: AtomicUsize = AtomicUsize::new(0);
 | 
					        static COUNT: AtomicUsize = AtomicUsize::new(0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PB7, Level::High, Speed::Low);
 | 
					    let mut led = Output::new(p.PB7, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
					use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
				
			||||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
					use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
@@ -16,10 +15,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let button = Input::new(p.PC13, Pull::Down);
 | 
					    let button = Input::new(p.PC13, Pull::Down);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::exti::ExtiInput;
 | 
					use embassy_stm32::exti::ExtiInput;
 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PC13, Pull::Down);
 | 
					    let button = Input::new(p.PC13, Pull::Down);
 | 
				
			||||||
    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
					    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ mod example_common;
 | 
				
			|||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::can::filter::Mask32;
 | 
					use embassy_stm32::can::filter::Mask32;
 | 
				
			||||||
use embassy_stm32::can::{Can, Frame, StandardId};
 | 
					use embassy_stm32::can::{Can, Frame, StandardId};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut p = embassy_stm32::init(Default::default());
 | 
					    let mut p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The next two lines are a workaround for testing without transceiver.
 | 
					    // The next two lines are a workaround for testing without transceiver.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ mod example_common;
 | 
				
			|||||||
fn config() -> Config {
 | 
					fn config() -> Config {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.sys_ck = Some(Hertz(84_000_000));
 | 
					    config.rcc.sys_ck = Some(Hertz(84_000_000));
 | 
				
			||||||
    config.rcc.enable_debug_wfe = true;
 | 
					 | 
				
			||||||
    config
 | 
					    config
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::spi::{Config, Spi};
 | 
					use embassy_stm32::spi::{Config, Spi};
 | 
				
			||||||
@@ -21,10 +20,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World, dude!");
 | 
					    info!("Hello World, dude!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut spi = Spi::new(
 | 
					    let mut spi = Spi::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ mod example_common;
 | 
				
			|||||||
use core::fmt::Write;
 | 
					use core::fmt::Write;
 | 
				
			||||||
use core::str::from_utf8;
 | 
					use core::str::from_utf8;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::spi::{Config, Spi};
 | 
					use embassy_stm32::spi::{Config, Spi};
 | 
				
			||||||
use embassy_stm32::time::Hertz;
 | 
					use embassy_stm32::time::Hertz;
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -21,10 +20,6 @@ use heapless::String;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut spi = Spi::new(
 | 
					    let mut spi = Spi::new(
 | 
				
			||||||
        p.SPI1,
 | 
					        p.SPI1,
 | 
				
			||||||
        p.PB3,
 | 
					        p.PB3,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embedded_hal::blocking::serial::Write;
 | 
					use embedded_hal::blocking::serial::Write;
 | 
				
			||||||
@@ -17,10 +16,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let config = Config::default();
 | 
					    let config = Config::default();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use core::fmt::Write;
 | 
					use core::fmt::Write;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -20,10 +19,6 @@ use heapless::String;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let config = Config::default();
 | 
					    let config = Config::default();
 | 
				
			||||||
    let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, p.DMA1_CH3, NoDma, config);
 | 
					    let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, p.DMA1_CH3, NoDma, config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
@@ -18,8 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { Dbgmcu::enable_all() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PB14, Level::High, Speed::Low);
 | 
					    let mut led = Output::new(p.PB14, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::exti::ExtiInput;
 | 
					use embassy_stm32::exti::ExtiInput;
 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PC13, Pull::Down);
 | 
					    let button = Input::new(p.PC13, Pull::Down);
 | 
				
			||||||
    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
					    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,10 +19,6 @@ fn main() -> ! {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let p = embassy_stm32::init(config());
 | 
					    let p = embassy_stm32::init(config());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut dac = Dac::new(p.DAC1, p.PA4, NoPin);
 | 
					    let mut dac = Dac::new(p.DAC1, p.PA4, NoPin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
@@ -33,7 +29,6 @@ fn main() -> ! {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use micromath::F32Ext;
 | 
					use micromath::F32Ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn to_sine_wave(v: u8) -> u8 {
 | 
					fn to_sine_wave(v: u8) -> u8 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@ use embassy_macros::interrupt_take;
 | 
				
			|||||||
use embassy_net::{
 | 
					use embassy_net::{
 | 
				
			||||||
    Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
 | 
					    Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::eth::lan8742a::LAN8742A;
 | 
					use embassy_stm32::eth::lan8742a::LAN8742A;
 | 
				
			||||||
use embassy_stm32::eth::{Ethernet, State};
 | 
					use embassy_stm32::eth::{Ethernet, State};
 | 
				
			||||||
use embassy_stm32::rng::Random;
 | 
					use embassy_stm32::rng::Random;
 | 
				
			||||||
@@ -96,10 +95,6 @@ fn main() -> ! {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    info!("Setup RCC...");
 | 
					    info!("Setup RCC...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(config());
 | 
					    let p = embassy_stm32::init(config());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let rng = Random::new(p.RNG);
 | 
					    let rng = Random::new(p.RNG);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ use example_common::*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use core::str::from_utf8;
 | 
					use core::str::from_utf8;
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::peripherals::SPI3;
 | 
					use embassy_stm32::peripherals::SPI3;
 | 
				
			||||||
use embassy_stm32::time::U32Ext;
 | 
					use embassy_stm32::time::U32Ext;
 | 
				
			||||||
use heapless::String;
 | 
					use heapless::String;
 | 
				
			||||||
@@ -43,10 +42,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(config());
 | 
					    let p = embassy_stm32::init(config());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let spi = spi::Spi::new(
 | 
					    let spi = spi::Spi::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@ use example_common::*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use core::str::from_utf8;
 | 
					use core::str::from_utf8;
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3};
 | 
					use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3};
 | 
				
			||||||
use embassy_stm32::spi;
 | 
					use embassy_stm32::spi;
 | 
				
			||||||
use heapless::String;
 | 
					use heapless::String;
 | 
				
			||||||
@@ -39,10 +38,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(config());
 | 
					    let p = embassy_stm32::init(config());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let spi = spi::Spi::new(
 | 
					    let spi = spi::Spi::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ use embassy_stm32::usart::{Config, Uart};
 | 
				
			|||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					use cortex_m_rt::entry;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::task]
 | 
					#[embassy::task]
 | 
				
			||||||
async fn main_task() {
 | 
					async fn main_task() {
 | 
				
			||||||
@@ -39,10 +38,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let executor = EXECUTOR.put(Executor::new());
 | 
					    let executor = EXECUTOR.put(Executor::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    executor.run(|spawner| {
 | 
					    executor.run(|spawner| {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ mod example_common;
 | 
				
			|||||||
use core::fmt::Write;
 | 
					use core::fmt::Write;
 | 
				
			||||||
use embassy::executor::Executor;
 | 
					use embassy::executor::Executor;
 | 
				
			||||||
use embassy::util::Forever;
 | 
					use embassy::util::Forever;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embassy_traits::uart::Write as _Write;
 | 
					use embassy_traits::uart::Write as _Write;
 | 
				
			||||||
@@ -41,10 +40,6 @@ static EXECUTOR: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let executor = EXECUTOR.put(Executor::new());
 | 
					    let executor = EXECUTOR.put(Executor::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    executor.run(|spawner| {
 | 
					    executor.run(|spawner| {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ defmt = "0.2.0"
 | 
				
			|||||||
defmt-rtt = "0.2.0"
 | 
					defmt-rtt = "0.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cortex-m = "0.7.1"
 | 
					cortex-m = "0.7.1"
 | 
				
			||||||
cortex-m-rt = "0.6.14"
 | 
					cortex-m-rt = "0.7.0"
 | 
				
			||||||
embedded-hal = { version = "0.2.4" }
 | 
					embedded-hal = { version = "0.2.4" }
 | 
				
			||||||
panic-probe = { version = "0.2.0", features= ["print-defmt"] }
 | 
					panic-probe = { version = "0.2.0", features= ["print-defmt"] }
 | 
				
			||||||
futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
 | 
					futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,17 +10,14 @@ mod example_common;
 | 
				
			|||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::rcc::Rcc;
 | 
					 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner, mut p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    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);
 | 
					    let mut led = Output::new(p.PB5, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,22 +6,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy_stm32::{
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
    gpio::{Input, Level, Output, Pull, Speed},
 | 
					use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
				
			||||||
    rcc::*,
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
					use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					#[embassy::main]
 | 
				
			||||||
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
#[entry]
 | 
					 | 
				
			||||||
fn main() -> ! {
 | 
					 | 
				
			||||||
    info!("Hello World!");
 | 
					    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 button = Input::new(p.PB2, Pull::Up);
 | 
				
			||||||
    let mut led1 = Output::new(p.PA5, Level::High, Speed::Low);
 | 
					    let mut led1 = Output::new(p.PA5, Level::High, Speed::Low);
 | 
				
			||||||
    let mut led2 = Output::new(p.PB5, Level::High, Speed::Low);
 | 
					    let mut led2 = Output::new(p.PB5, Level::High, Speed::Low);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ use example_common::*;
 | 
				
			|||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner, mut p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, mut p: Peripherals) {
 | 
				
			||||||
    let mut rcc = rcc::Rcc::new(p.RCC);
 | 
					    let mut rcc = rcc::Rcc::new(p.RCC);
 | 
				
			||||||
    rcc.enable_debug_wfe(&mut p.DBGMCU, true);
 | 
					 | 
				
			||||||
    // Enables SYSCFG
 | 
					    // Enables SYSCFG
 | 
				
			||||||
    let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS);
 | 
					    let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,25 +7,21 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use cortex_m_rt::entry;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::rcc;
 | 
					 | 
				
			||||||
use embassy_stm32::spi::{Config, Spi};
 | 
					use embassy_stm32::spi::{Config, Spi};
 | 
				
			||||||
use embassy_stm32::time::Hertz;
 | 
					use embassy_stm32::time::Hertz;
 | 
				
			||||||
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::blocking::spi::Transfer;
 | 
					use embedded_hal::blocking::spi::Transfer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[entry]
 | 
					#[embassy::main]
 | 
				
			||||||
fn main() -> ! {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World, folks!");
 | 
					    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(
 | 
					    let mut spi = Spi::new(
 | 
				
			||||||
        p.SPI1,
 | 
					        p.SPI1,
 | 
				
			||||||
        p.PB3,
 | 
					        p.PB3,
 | 
				
			||||||
@@ -40,7 +36,7 @@ fn main() -> ! {
 | 
				
			|||||||
    let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh);
 | 
					    let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        let mut buf = [0x0A; 4];
 | 
					        let mut buf = [0x0Au8; 4];
 | 
				
			||||||
        unwrap!(cs.set_low());
 | 
					        unwrap!(cs.set_low());
 | 
				
			||||||
        unwrap!(spi.transfer(&mut buf));
 | 
					        unwrap!(spi.transfer(&mut buf));
 | 
				
			||||||
        unwrap!(cs.set_high());
 | 
					        unwrap!(cs.set_high());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,14 +11,11 @@ use example_common::*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embassy_stm32::{rcc, Peripherals};
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embassy_traits::uart::{Read, Write};
 | 
					use embassy_traits::uart::{Read, Write};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner, mut p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let mut rcc = rcc::Rcc::new(p.RCC);
 | 
					 | 
				
			||||||
    rcc.enable_debug_wfe(&mut p.DBGMCU, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut usart = Uart::new(
 | 
					    let mut usart = Uart::new(
 | 
				
			||||||
        p.USART1,
 | 
					        p.USART1,
 | 
				
			||||||
        p.PB7,
 | 
					        p.PB7,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,13 +15,10 @@ use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
 | 
				
			|||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::interrupt;
 | 
					use embassy_stm32::interrupt;
 | 
				
			||||||
use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
 | 
					use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
 | 
				
			||||||
use embassy_stm32::{rcc, Peripherals};
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner, mut p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let mut rcc = rcc::Rcc::new(p.RCC);
 | 
					 | 
				
			||||||
    rcc.enable_debug_wfe(&mut p.DBGMCU, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static mut TX_BUFFER: [u8; 8] = [0; 8];
 | 
					    static mut TX_BUFFER: [u8; 8] = [0; 8];
 | 
				
			||||||
    static mut RX_BUFFER: [u8; 256] = [0; 256];
 | 
					    static mut RX_BUFFER: [u8; 256] = [0; 256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ defmt = "0.2.0"
 | 
				
			|||||||
defmt-rtt = "0.2.0"
 | 
					defmt-rtt = "0.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cortex-m = "0.7.1"
 | 
					cortex-m = "0.7.1"
 | 
				
			||||||
cortex-m-rt = "0.6.14"
 | 
					cortex-m-rt = "0.7.0"
 | 
				
			||||||
embedded-hal = { version = "0.2.4" }
 | 
					embedded-hal = { version = "0.2.4" }
 | 
				
			||||||
panic-probe = { version = "0.2.0", features= ["print-defmt"] }
 | 
					panic-probe = { version = "0.2.0", features= ["print-defmt"] }
 | 
				
			||||||
futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
 | 
					futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ mod example_common;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use embassy::time::Delay;
 | 
					use embassy::time::Delay;
 | 
				
			||||||
use embassy_stm32::adc::{Adc, Resolution};
 | 
					use embassy_stm32::adc::{Adc, Resolution};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::pac;
 | 
					use embassy_stm32::pac;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,8 +17,6 @@ fn main() -> ! {
 | 
				
			|||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					    unsafe {
 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pac::RCC.ccipr().modify(|w| {
 | 
					        pac::RCC.ccipr().modify(|w| {
 | 
				
			||||||
            w.set_adcsel(0b11);
 | 
					            w.set_adcsel(0b11);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PB14, Level::High, Speed::Low);
 | 
					    let mut led = Output::new(p.PB14, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use embedded_hal::digital::v2::InputPin;
 | 
					use embedded_hal::digital::v2::InputPin;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
@@ -15,10 +14,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let button = Input::new(p.PC13, Pull::Up);
 | 
					    let button = Input::new(p.PC13, Pull::Up);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::exti::ExtiInput;
 | 
					use embassy_stm32::exti::ExtiInput;
 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -18,10 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PC13, Pull::Up);
 | 
					    let button = Input::new(p.PC13, Pull::Up);
 | 
				
			||||||
    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
					    let mut button = ExtiInput::new(button, p.EXTI13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_stm32::dac::{Channel, Dac, Value};
 | 
					use embassy_stm32::dac::{Channel, Dac, Value};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::NoPin;
 | 
					use embassy_stm32::gpio::NoPin;
 | 
				
			||||||
use embassy_stm32::pac;
 | 
					use embassy_stm32::pac;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
@@ -18,8 +17,6 @@ fn main() -> ! {
 | 
				
			|||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					    unsafe {
 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pac::RCC.apb1enr1().modify(|w| {
 | 
					        pac::RCC.apb1enr1().modify(|w| {
 | 
				
			||||||
            w.set_dac1en(true);
 | 
					            w.set_dac1en(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::spi::{Config, Spi};
 | 
					use embassy_stm32::spi::{Config, Spi};
 | 
				
			||||||
@@ -20,10 +19,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut spi = Spi::new(
 | 
					    let mut spi = Spi::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
					use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
				
			||||||
use embassy_stm32::spi::{Config, Spi};
 | 
					use embassy_stm32::spi::{Config, Spi};
 | 
				
			||||||
use embassy_stm32::time::Hertz;
 | 
					use embassy_stm32::time::Hertz;
 | 
				
			||||||
@@ -21,10 +20,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut spi = Spi::new(
 | 
					    let mut spi = Spi::new(
 | 
				
			||||||
        p.SPI3,
 | 
					        p.SPI3,
 | 
				
			||||||
        p.PC10,
 | 
					        p.PC10,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embedded_hal::blocking::serial::Write;
 | 
					use embedded_hal::blocking::serial::Write;
 | 
				
			||||||
@@ -17,10 +16,6 @@ use example_common::*;
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let config = Config::default();
 | 
					    let config = Config::default();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use core::fmt::Write;
 | 
					use core::fmt::Write;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::dma::NoDma;
 | 
					use embassy_stm32::dma::NoDma;
 | 
				
			||||||
use embassy_stm32::usart::{Config, Uart};
 | 
					use embassy_stm32::usart::{Config, Uart};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -20,10 +19,6 @@ use heapless::String;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        Dbgmcu::enable_all();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let config = Config::default();
 | 
					    let config = Config::default();
 | 
				
			||||||
    let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_CH3, NoDma, config);
 | 
					    let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, p.DMA1_CH3, NoDma, config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
@@ -18,8 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { Dbgmcu::enable_all() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PB0, Level::High, Speed::Low);
 | 
					    let mut led = Output::new(p.PB0, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								examples/stm32wb55/src/bin/button_exti.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/stm32wb55/src/bin/button_exti.rs
									
									
									
									
									
										Normal file
									
								
							@@ -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!");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,7 +8,6 @@
 | 
				
			|||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Timer};
 | 
					use embassy::time::{Duration, Timer};
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::gpio::{Level, Output, Speed};
 | 
					use embassy_stm32::gpio::{Level, Output, Speed};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
@@ -18,8 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { Dbgmcu::enable_all() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PB15, Level::High, Speed::Low);
 | 
					    let mut led = Output::new(p.PB15, Level::High, Speed::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,10 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy_stm32::{
 | 
					use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 | 
				
			||||||
    dbgmcu::Dbgmcu,
 | 
					 | 
				
			||||||
    gpio::{Input, Level, Output, Pull, Speed},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
					use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,8 +18,6 @@ fn main() -> ! {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let p = embassy_stm32::init(Default::default());
 | 
					    let p = embassy_stm32::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { Dbgmcu::enable_all() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PA0, Pull::Up);
 | 
					    let button = Input::new(p.PA0, Pull::Up);
 | 
				
			||||||
    let mut led1 = Output::new(p.PB15, Level::High, Speed::Low);
 | 
					    let mut led1 = Output::new(p.PB15, Level::High, Speed::Low);
 | 
				
			||||||
    let mut led2 = Output::new(p.PB9, Level::High, Speed::Low);
 | 
					    let mut led2 = Output::new(p.PB9, Level::High, Speed::Low);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_stm32::dbgmcu::Dbgmcu;
 | 
					 | 
				
			||||||
use embassy_stm32::exti::ExtiInput;
 | 
					use embassy_stm32::exti::ExtiInput;
 | 
				
			||||||
use embassy_stm32::gpio::{Input, Pull};
 | 
					use embassy_stm32::gpio::{Input, Pull};
 | 
				
			||||||
use embassy_stm32::Peripherals;
 | 
					use embassy_stm32::Peripherals;
 | 
				
			||||||
@@ -18,8 +17,6 @@ use example_common::*;
 | 
				
			|||||||
async fn main(_spawner: Spawner, p: Peripherals) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { Dbgmcu::enable_all() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PA0, Pull::Up);
 | 
					    let button = Input::new(p.PA0, Pull::Up);
 | 
				
			||||||
    let mut button = ExtiInput::new(button, p.EXTI0);
 | 
					    let mut button = ExtiInput::new(button, p.EXTI0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
 Submodule stm32-data updated: bfd4797d12...12be5f3da4
									
								
							@@ -1,4 +1,5 @@
 | 
				
			|||||||
use chiptool::generate::CommonModule;
 | 
					use chiptool::generate::CommonModule;
 | 
				
			||||||
 | 
					use chiptool::ir::IR;
 | 
				
			||||||
use regex::Regex;
 | 
					use regex::Regex;
 | 
				
			||||||
use serde::Deserialize;
 | 
					use serde::Deserialize;
 | 
				
			||||||
use std::collections::{BTreeMap, HashMap, HashSet};
 | 
					use std::collections::{BTreeMap, HashMap, HashSet};
 | 
				
			||||||
@@ -116,11 +117,7 @@ impl BlockInfo {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn find_reg_for_field<'c>(
 | 
					fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> {
 | 
				
			||||||
    rcc: &'c ir::IR,
 | 
					 | 
				
			||||||
    reg_regex: &str,
 | 
					 | 
				
			||||||
    field_name: &str,
 | 
					 | 
				
			||||||
) -> Option<(&'c str, &'c str)> {
 | 
					 | 
				
			||||||
    let reg_regex = Regex::new(reg_regex).unwrap();
 | 
					    let reg_regex = Regex::new(reg_regex).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (name, fieldset) in &rcc.fieldsets {
 | 
					    for (name, fieldset) in &rcc.fieldsets {
 | 
				
			||||||
@@ -273,19 +270,18 @@ pub fn gen(options: Options) {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Load RCC register for chip
 | 
					        // Load RCC register for chip
 | 
				
			||||||
        let rcc = core.peripherals.iter().find_map(|(name, p)| {
 | 
					        let (_, rcc) = core
 | 
				
			||||||
            if name == "RCC" {
 | 
					            .peripherals
 | 
				
			||||||
                p.block.as_ref().map(|block| {
 | 
					            .iter()
 | 
				
			||||||
                    let bi = BlockInfo::parse(block);
 | 
					            .find(|(name, _)| name == &"RCC")
 | 
				
			||||||
                    let rcc_reg_path = data_dir
 | 
					            .expect("RCC peripheral missing");
 | 
				
			||||||
                        .join("registers")
 | 
					
 | 
				
			||||||
                        .join(&format!("{}_{}.yaml", bi.module, bi.version));
 | 
					        let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
 | 
				
			||||||
                    serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap()
 | 
					        let bi = BlockInfo::parse(&rcc_block);
 | 
				
			||||||
                })
 | 
					        let rcc_reg_path = data_dir
 | 
				
			||||||
            } else {
 | 
					            .join("registers")
 | 
				
			||||||
                None
 | 
					            .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<String, String> = BTreeMap::new();
 | 
					        let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
 | 
				
			||||||
        let mut pin_table: Vec<Vec<String>> = Vec::new();
 | 
					        let mut pin_table: Vec<Vec<String>> = 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
 | 
				
			||||||
                    // 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.
 | 
				
			||||||
                    // 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 en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
 | 
					                let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
 | 
				
			||||||
                    let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if en.is_none() && name.ends_with("1") {
 | 
					                if en.is_none() && name.ends_with("1") {
 | 
				
			||||||
                        en = find_reg_for_field(
 | 
					                    en = find_reg(
 | 
				
			||||||
                            &rcc,
 | 
					                        &rcc,
 | 
				
			||||||
                            "^.+ENR\\d*$",
 | 
					                        "^.+ENR\\d*$",
 | 
				
			||||||
                            &format!("{}EN", &name[..name.len() - 1]),
 | 
					                        &format!("{}EN", &name[..name.len() - 1]),
 | 
				
			||||||
                        );
 | 
					                    );
 | 
				
			||||||
                        rst = find_reg_for_field(
 | 
					                    rst = find_reg(
 | 
				
			||||||
                            &rcc,
 | 
					                        &rcc,
 | 
				
			||||||
                            "^.+RSTR\\d*$",
 | 
					                        "^.+RSTR\\d*$",
 | 
				
			||||||
                            &format!("{}RST", &name[..name.len() - 1]),
 | 
					                        &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());
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    (None, Some(_)) => {
 | 
				
			||||||
                    match (en, rst) {
 | 
					                        println!("Unable to find enable register for {}", name)
 | 
				
			||||||
                        (Some((enable_reg, enable_field)), reset_reg_field) => {
 | 
					                    }
 | 
				
			||||||
                            let clock = match &p.clock {
 | 
					                    (None, None) => {
 | 
				
			||||||
                                Some(clock) => clock.as_str(),
 | 
					                        println!("Unable to find enable and reset register for {}", name)
 | 
				
			||||||
                                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)
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -502,6 +496,10 @@ pub fn gen(options: Options) {
 | 
				
			|||||||
            gpio_rcc_table.push(vec![reg]);
 | 
					            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 {
 | 
					        for (id, channel_info) in &core.dma_channels {
 | 
				
			||||||
            let mut row = Vec::new();
 | 
					            let mut row = Vec::new();
 | 
				
			||||||
            let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
 | 
					            let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use std::env::args;
 | 
				
			||||||
use std::path::PathBuf;
 | 
					use std::path::PathBuf;
 | 
				
			||||||
use stm32_metapac_gen::*;
 | 
					use stm32_metapac_gen::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5,13 +6,24 @@ fn main() {
 | 
				
			|||||||
    let out_dir = PathBuf::from("out");
 | 
					    let out_dir = PathBuf::from("out");
 | 
				
			||||||
    let data_dir = PathBuf::from("../stm32-data/data");
 | 
					    let data_dir = PathBuf::from("../stm32-data/data");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let chips = std::fs::read_dir(data_dir.join("chips"))
 | 
					    let args: Vec<String> = args().collect();
 | 
				
			||||||
        .unwrap()
 | 
					
 | 
				
			||||||
        .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string()))
 | 
					    let chips = match &args[..] {
 | 
				
			||||||
        .filter(|s| s.ends_with(".yaml"))
 | 
					        [_, chip] => {
 | 
				
			||||||
        .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride
 | 
					            vec![chip.clone()]
 | 
				
			||||||
        .map(|s| s.strip_suffix(".yaml").unwrap().to_string())
 | 
					        }
 | 
				
			||||||
        .collect();
 | 
					        [_] => {
 | 
				
			||||||
 | 
					            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 {
 | 
					    gen(Options {
 | 
				
			||||||
        out_dir,
 | 
					        out_dir,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user