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