607: stm32: Add standard crate-wide macros for pin/dma traits r=Dirbaio a=Dirbaio

All drivers will declare the traits using these macros.

This has a few implications:
- ALL drivers will have an Instance trait, even for drivers that usually have only one instance (for example crc, eth)
- It's no longer possible to have a fn configure() in pin traits, drivers will have to do that some other way

In the future, build.rs will generate all the impls instead of macrotables.

Pin/Dma traits are no longer explicitly sealed, since gpio::Pin and dma::Channel are already sealed, which has the same effect. This means the `af_num()` and `request()` funcs are now public, but IMO that's okay, they're unlikely to change.

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2022-02-11 23:11:12 +00:00 committed by GitHub
commit 5ae4e20f86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 913 additions and 1781 deletions

View File

@ -4,10 +4,7 @@ use core::ops::{Deref, DerefMut};
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use crate::gpio::{ use crate::gpio::sealed::AFType;
sealed::AFType::{OutputOpenDrain, OutputPushPull},
Pin,
};
use crate::{peripherals, rcc::RccPeripheral}; use crate::{peripherals, rcc::RccPeripheral};
pub use bxcan::*; pub use bxcan::*;
@ -26,8 +23,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
unborrow!(peri, rx, tx); unborrow!(peri, rx, tx);
unsafe { unsafe {
rx.set_as_af(rx.af_num(), OutputOpenDrain); rx.set_as_af(rx.af_num(), AFType::OutputOpenDrain);
tx.set_as_af(tx.af_num(), OutputPushPull); tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
} }
T::enable(); T::enable();
@ -66,24 +63,12 @@ impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
} }
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*;
pub trait Instance { pub trait Instance {
fn regs() -> &'static crate::pac::can::Can; fn regs() -> &'static crate::pac::can::Can;
} }
pub trait RxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait TxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
} }
pub trait Instance: sealed::Instance + RccPeripheral {} pub trait Instance: sealed::Instance + RccPeripheral {}
pub trait RxPin<T: Instance>: sealed::RxPin<T> {}
pub trait TxPin<T: Instance>: sealed::TxPin<T> {}
crate::pac::peripherals!( crate::pac::peripherals!(
(can, $inst:ident) => { (can, $inst:ident) => {
@ -125,29 +110,20 @@ crate::pac::peripherals!(
}; };
); );
macro_rules! impl_pin { pin_trait!(RxPin, Instance);
($inst:ident, $pin:ident, $signal:ident, $af:expr) => { pin_trait!(TxPin, Instance);
impl $signal<peripherals::$inst> for peripherals::$pin {}
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
};
}
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, can, CAN, $pin:ident, TX, $af:expr) => { ($inst:ident, can, CAN, $pin:ident, TX, $af:expr) => {
impl_pin!($inst, $pin, TxPin, $af); pin_trait_impl!(TxPin, $inst, $pin, $af);
}; };
($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => { ($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => {
impl_pin!($inst, $pin, RxPin, $af); pin_trait_impl!(RxPin, $inst, $pin, $af);
}; };
($inst:ident, can, CAN, $pin:ident, TX) => { ($inst:ident, can, CAN, $pin:ident, TX) => {
impl_pin!($inst, $pin, TxPin, 0); pin_trait_impl!(TxPin, $inst, $pin, 0);
}; };
($inst:ident, can, CAN, $pin:ident, RX) => { ($inst:ident, can, CAN, $pin:ident, RX) => {
impl_pin!($inst, $pin, RxPin, 0); pin_trait_impl!(RxPin, $inst, $pin, 0);
}; };
); );

View File

@ -1,22 +1,13 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use crate::gpio::sealed::Pin as __GpioPin;
use crate::gpio::Pin as GpioPin;
use embassy::interrupt::{Interrupt, InterruptExt}; use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use futures::future::poll_fn; use futures::future::poll_fn;
#[macro_export] use crate::gpio::{sealed::AFType, Speed};
macro_rules! configure {
($($name:ident),*) => {
$(
unsafe { $name.unborrow() }.configure();
)*
}
}
/// The level on the VSync pin when the data is not valid on the parallel interface. /// The level on the VSync pin when the data is not valid on the parallel interface.
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
@ -76,7 +67,20 @@ impl Default for Config {
} }
} }
pub struct Dcmi<'d, T: Instance, Dma: FrameDma> { macro_rules! config_pins {
($($pin:ident),*) => {
unborrow!($($pin),*);
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$(
$pin.set_as_af($pin.af_num(), AFType::Input);
$pin.set_speed(Speed::VeryHigh);
)*
})
};
}
pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
inner: T, inner: T,
dma: Dma, dma: Dma,
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
@ -85,53 +89,54 @@ pub struct Dcmi<'d, T: Instance, Dma: FrameDma> {
impl<'d, T, Dma> Dcmi<'d, T, Dma> impl<'d, T, Dma> Dcmi<'d, T, Dma>
where where
T: Instance, T: Instance,
Dma: FrameDma, Dma: FrameDma<T>,
{ {
pub fn new_8bit( pub fn new_8bit(
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
configure!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
Self::new_inner(peri, dma, irq, config, false, 0b00) Self::new_inner(peri, dma, irq, config, false, 0b00)
} }
pub fn new_10bit( pub fn new_10bit(
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
configure!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
Self::new_inner(peri, dma, irq, config, false, 0b01) Self::new_inner(peri, dma, irq, config, false, 0b01)
} }
@ -140,55 +145,56 @@ where
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
d10: impl Unborrow<Target = impl D10Pin> + 'd, d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
d11: impl Unborrow<Target = impl D11Pin> + 'd, d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
configure!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
Self::new_inner(peri, dma, irq, config, false, 0b10) Self::new_inner(peri, dma, irq, config, false, 0b10)
} }
pub fn new_14bit( pub fn new_14bit(
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
d10: impl Unborrow<Target = impl D10Pin> + 'd, d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
d11: impl Unborrow<Target = impl D11Pin> + 'd, d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
d12: impl Unborrow<Target = impl D12Pin> + 'd, d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
d13: impl Unborrow<Target = impl D13Pin> + 'd, d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
configure!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
Self::new_inner(peri, dma, irq, config, false, 0b11) Self::new_inner(peri, dma, irq, config, false, 0b11)
} }
@ -197,20 +203,20 @@ where
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
configure!(pixclk); config_pins!(pixclk);
Self::new_inner(peri, dma, irq, config, true, 0b00) Self::new_inner(peri, dma, irq, config, true, 0b00)
} }
@ -219,22 +225,22 @@ where
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
configure!(pixclk); config_pins!(pixclk);
Self::new_inner(peri, dma, irq, config, true, 0b01) Self::new_inner(peri, dma, irq, config, true, 0b01)
} }
@ -243,51 +249,52 @@ where
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
d10: impl Unborrow<Target = impl D10Pin> + 'd, d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
d11: impl Unborrow<Target = impl D11Pin> + 'd, d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
configure!(pixclk); config_pins!(pixclk);
Self::new_inner(peri, dma, irq, config, true, 0b10) Self::new_inner(peri, dma, irq, config, true, 0b10)
} }
pub fn new_es_14bit( pub fn new_es_14bit(
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd, d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd, d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd, d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd, d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd, d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd, d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd, d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd, d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd, d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd, d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
d10: impl Unborrow<Target = impl D10Pin> + 'd, d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
d11: impl Unborrow<Target = impl D11Pin> + 'd, d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
d12: impl Unborrow<Target = impl D12Pin> + 'd, d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
d13: impl Unborrow<Target = impl D13Pin> + 'd, d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(peri, dma, irq); unborrow!(peri, dma, irq);
configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
configure!(pixclk); config_pins!(pixclk);
Self::new_inner(peri, dma, irq, config, true, 0b11) Self::new_inner(peri, dma, irq, config, true, 0b11)
} }
@ -424,75 +431,32 @@ where
} }
mod sealed { mod sealed {
use super::*; pub trait Instance: crate::rcc::RccPeripheral {
use crate::rcc::RccPeripheral;
pub trait Instance: RccPeripheral {
fn regs(&self) -> crate::pac::dcmi::Dcmi; fn regs(&self) -> crate::pac::dcmi::Dcmi;
} }
pub trait FrameDma {
fn request(&self) -> crate::dma::Request;
}
macro_rules! pin {
($name:ident) => {
pub trait $name: GpioPin {
fn configure(&mut self);
}
};
}
pin!(D0Pin);
pin!(D1Pin);
pin!(D2Pin);
pin!(D3Pin);
pin!(D4Pin);
pin!(D5Pin);
pin!(D6Pin);
pin!(D7Pin);
pin!(D8Pin);
pin!(D9Pin);
pin!(D10Pin);
pin!(D11Pin);
pin!(D12Pin);
pin!(D13Pin);
pin!(HSyncPin);
pin!(VSyncPin);
pin!(PixClkPin);
} }
pub trait Instance: sealed::Instance + 'static { pub trait Instance: sealed::Instance + 'static {
type Interrupt: Interrupt; type Interrupt: Interrupt;
} }
pub trait FrameDma: sealed::FrameDma + crate::dma::Channel {} pin_trait!(D0Pin, Instance);
pin_trait!(D1Pin, Instance);
macro_rules! pin { pin_trait!(D2Pin, Instance);
($name:ident) => { pin_trait!(D3Pin, Instance);
pub trait $name: sealed::$name + 'static {} pin_trait!(D4Pin, Instance);
}; pin_trait!(D5Pin, Instance);
} pin_trait!(D6Pin, Instance);
pin_trait!(D7Pin, Instance);
pin!(D0Pin); pin_trait!(D8Pin, Instance);
pin!(D1Pin); pin_trait!(D9Pin, Instance);
pin!(D2Pin); pin_trait!(D10Pin, Instance);
pin!(D3Pin); pin_trait!(D11Pin, Instance);
pin!(D4Pin); pin_trait!(D12Pin, Instance);
pin!(D5Pin); pin_trait!(D13Pin, Instance);
pin!(D6Pin); pin_trait!(HSyncPin, Instance);
pin!(D7Pin); pin_trait!(VSyncPin, Instance);
pin!(D8Pin); pin_trait!(PixClkPin, Instance);
pin!(D9Pin);
pin!(D10Pin);
pin!(D11Pin);
pin!(D12Pin);
pin!(D13Pin);
pin!(HSyncPin);
pin!(VSyncPin);
pin!(PixClkPin);
// allow unused as U5 sources do not contain interrupt nor dma data // allow unused as U5 sources do not contain interrupt nor dma data
#[allow(unused)] #[allow(unused)]
@ -516,112 +480,67 @@ crate::pac::interrupts! {
}; };
} }
// allow unused as U5 sources do not contain interrupt nor dma data dma_trait!(FrameDma, Instance);
#[allow(unused)]
macro_rules! impl_dma {
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
impl<T> sealed::$signal for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
fn request(&self) -> crate::dma::Request {
$request
}
}
impl<T> $signal for T where T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux> {}
};
($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
impl sealed::$signal for crate::peripherals::$channel {
fn request(&self) -> crate::dma::Request {
$request
}
}
impl $signal for crate::peripherals::$channel {}
};
}
crate::pac::peripheral_dma_channels! { crate::pac::peripheral_dma_channels! {
($peri:ident, dcmi, $kind:ident, PSSI, $channel:tt, $request:expr) => { ($peri:ident, dcmi, $kind:ident, PSSI, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, FrameDma, $request); dma_trait_impl!(FrameDma, $peri, $channel, $request);
}; };
($peri:ident, dcmi, $kind:ident, DCMI, $channel:tt, $request:expr) => { ($peri:ident, dcmi, $kind:ident, DCMI, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, FrameDma, $request); dma_trait_impl!(FrameDma, $peri, $channel, $request);
};
}
macro_rules! impl_pin {
($pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal for crate::peripherals::$pin {
fn configure(&mut self) {
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
self.set_as_af($af, crate::gpio::sealed::AFType::Input);
self.block().ospeedr().modify(|w| {
w.set_ospeedr(
self.pin() as usize,
crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED,
)
});
})
}
}
impl $signal for crate::peripherals::$pin {}
}; };
} }
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, dcmi, DCMI, $pin:ident, D0, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D0, $af:expr) => {
impl_pin!($pin, D0Pin, $af); pin_trait_impl!(D0Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D1, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D1, $af:expr) => {
impl_pin!($pin, D1Pin, $af); pin_trait_impl!(D1Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D2, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D2, $af:expr) => {
impl_pin!($pin, D2Pin, $af); pin_trait_impl!(D2Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D3, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D3, $af:expr) => {
impl_pin!($pin, D3Pin, $af); pin_trait_impl!(D3Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D4, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D4, $af:expr) => {
impl_pin!($pin, D4Pin, $af); pin_trait_impl!(D4Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D5, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D5, $af:expr) => {
impl_pin!($pin, D5Pin, $af); pin_trait_impl!(D5Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D6, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D6, $af:expr) => {
impl_pin!($pin, D6Pin, $af); pin_trait_impl!(D6Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D7, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D7, $af:expr) => {
impl_pin!($pin, D7Pin, $af); pin_trait_impl!(D7Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D8, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D8, $af:expr) => {
impl_pin!($pin, D8Pin, $af); pin_trait_impl!(D8Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D9, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D9, $af:expr) => {
impl_pin!($pin, D9Pin, $af); pin_trait_impl!(D9Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D10, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D10, $af:expr) => {
impl_pin!($pin, D10Pin, $af); pin_trait_impl!(D10Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D11, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D11, $af:expr) => {
impl_pin!($pin, D11Pin, $af); pin_trait_impl!(D11Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D12, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D12, $af:expr) => {
impl_pin!($pin, D12Pin, $af); pin_trait_impl!(D12Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, D13, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, D13, $af:expr) => {
impl_pin!($pin, D13Pin, $af); pin_trait_impl!(D13Pin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, HSYNC, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, HSYNC, $af:expr) => {
impl_pin!($pin, HSyncPin, $af); pin_trait_impl!(HSyncPin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, VSYNC, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, VSYNC, $af:expr) => {
impl_pin!($pin, VSyncPin, $af); pin_trait_impl!(VSyncPin, $inst, $pin, $af);
}; };
($inst:ident, dcmi, DCMI, $pin:ident, PIXCLK, $af:expr) => { ($inst:ident, dcmi, DCMI, $pin:ident, PIXCLK, $af:expr) => {
impl_pin!($pin, PixClkPin, $af); pin_trait_impl!(PixClkPin, $inst, $pin, $af);
}; };
); );

View File

@ -18,9 +18,10 @@ use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use transfers::*; pub mod low_level {
pub use super::transfers::*;
}
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use transfers::*; pub(crate) use transfers::*;
#[cfg(any(bdma_v2, dma_v2, dmamux))] #[cfg(any(bdma_v2, dma_v2, dmamux))]

View File

@ -33,3 +33,58 @@ pub unsafe trait PHY {
/// Poll link to see if it is up and FD with 100Mbps /// Poll link to see if it is up and FD with 100Mbps
fn poll_link<S: StationManagement>(sm: &mut S) -> bool; fn poll_link<S: StationManagement>(sm: &mut S) -> bool;
} }
pub(crate) mod sealed {
pub trait Instance {
fn regs() -> crate::pac::eth::Eth;
}
}
pub trait Instance: sealed::Instance + Send + 'static {}
impl sealed::Instance for crate::peripherals::ETH {
fn regs() -> crate::pac::eth::Eth {
crate::pac::ETH
}
}
impl Instance for crate::peripherals::ETH {}
pin_trait!(RefClkPin, Instance);
pin_trait!(MDIOPin, Instance);
pin_trait!(MDCPin, Instance);
pin_trait!(CRSPin, Instance);
pin_trait!(RXD0Pin, Instance);
pin_trait!(RXD1Pin, Instance);
pin_trait!(TXD0Pin, Instance);
pin_trait!(TXD1Pin, Instance);
pin_trait!(TXEnPin, Instance);
crate::pac::peripheral_pins!(
($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
pin_trait_impl!(RefClkPin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
pin_trait_impl!(MDIOPin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
pin_trait_impl!(MDCPin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
pin_trait_impl!(CRSPin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
pin_trait_impl!(RXD0Pin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
pin_trait_impl!(RXD1Pin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
pin_trait_impl!(TXD0Pin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
pin_trait_impl!(TXD1Pin, $inst, $pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
pin_trait_impl!(TXEnPin, $inst, $pin, $af);
};
);

View File

@ -12,29 +12,31 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
use crate::gpio::sealed::Pin as __GpioPin; use crate::gpio::sealed::Pin as __GpioPin;
use crate::gpio::Pin as GpioPin; use crate::gpio::Pin as GpioPin;
use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin}; use crate::gpio::{sealed::AFType, AnyPin, Speed};
use crate::pac::gpio::vals::Ospeedr; use crate::pac::gpio::vals::Ospeedr;
use crate::pac::{ETH, RCC, SYSCFG}; use crate::pac::{ETH, RCC, SYSCFG};
use crate::peripherals;
mod descriptors; mod descriptors;
mod rx_desc; mod rx_desc;
mod tx_desc; mod tx_desc;
use super::{StationManagement, PHY}; use super::*;
use descriptors::DescriptorRing; use descriptors::DescriptorRing;
use stm32_metapac::eth::vals::{ use stm32_metapac::eth::vals::{
Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf, Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf,
}; };
pub struct State<'d, const TX: usize, const RX: usize>(StateStorage<Inner<'d, TX, RX>>); pub struct State<'d, T: Instance, const TX: usize, const RX: usize>(
impl<'d, const TX: usize, const RX: usize> State<'d, TX, RX> { StateStorage<Inner<'d, T, TX, RX>>,
pub const fn new() -> Self { );
impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
pub fn new() -> Self {
Self(StateStorage::new()) Self(StateStorage::new())
} }
} }
pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> {
state: PeripheralMutex<'d, Inner<'d, TX, RX>>, pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
pins: [AnyPin; 9], pins: [AnyPin; 9],
_phy: P, _phy: P,
clock_range: Cr, clock_range: Cr,
@ -42,21 +44,33 @@ pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> {
mac_addr: [u8; 6], mac_addr: [u8; 6],
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { macro_rules! config_pins {
($($pin:ident),*) => {
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$(
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
$pin.set_speed(Speed::VeryHigh);
)*
})
};
}
impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T, P, TX, RX> {
/// safety: the returned instance is not leak-safe /// safety: the returned instance is not leak-safe
pub unsafe fn new( pub unsafe fn new(
state: &'d mut State<'d, TX, RX>, state: &'d mut State<'d, T, TX, RX>,
peri: impl Unborrow<Target = peripherals::ETH> + 'd, peri: impl Unborrow<Target = T> + 'd,
interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
ref_clk: impl Unborrow<Target = impl RefClkPin> + 'd, ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
mdio: impl Unborrow<Target = impl MDIOPin> + 'd, mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
mdc: impl Unborrow<Target = impl MDCPin> + 'd, mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
crs: impl Unborrow<Target = impl CRSPin> + 'd, crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
rx_d0: impl Unborrow<Target = impl RXD0Pin> + 'd, rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
rx_d1: impl Unborrow<Target = impl RXD1Pin> + 'd, rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
tx_d0: impl Unborrow<Target = impl TXD0Pin> + 'd, tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
tx_d1: impl Unborrow<Target = impl TXD1Pin> + 'd, tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
tx_en: impl Unborrow<Target = impl TXEnPin> + 'd, tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
phy_addr: u8, phy_addr: u8,
@ -77,15 +91,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true)); SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true));
}); });
ref_clk.configure(); config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
mdio.configure();
mdc.configure();
crs.configure();
rx_d0.configure();
rx_d1.configure();
tx_d0.configure();
tx_d1.configure();
tx_en.configure();
// NOTE(unsafe) We are ourselves not leak-safe. // NOTE(unsafe) We are ourselves not leak-safe.
let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri)); let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri));
@ -204,8 +210,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
} }
} }
unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement unsafe impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> StationManagement
for Ethernet<'d, P, TX, RX> for Ethernet<'d, T, P, TX, RX>
{ {
fn smi_read(&mut self, reg: u8) -> u16 { fn smi_read(&mut self, reg: u8) -> u16 {
// NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self` // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self`
@ -242,7 +248,9 @@ unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement
} }
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX, RX> { impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Device
for Ethernet<'d, T, P, TX, RX>
{
fn is_transmit_ready(&mut self) -> bool { fn is_transmit_ready(&mut self) -> bool {
self.state.with(|s| s.desc_ring.tx.available()) self.state.with(|s| s.desc_ring.tx.available())
} }
@ -279,7 +287,9 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX
} }
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX, RX> { impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
for Ethernet<'d, T, P, TX, RX>
{
fn drop(&mut self) { fn drop(&mut self) {
// NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers
unsafe { unsafe {
@ -312,13 +322,13 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
//---------------------------------------------------------------------- //----------------------------------------------------------------------
struct Inner<'d, const TX: usize, const RX: usize> { struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
_peri: PhantomData<&'d mut peripherals::ETH>, _peri: PhantomData<&'d mut T>,
desc_ring: DescriptorRing<TX, RX>, desc_ring: DescriptorRing<TX, RX>,
} }
impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> { impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
pub fn new(_peri: impl Unborrow<Target = peripherals::ETH> + 'd) -> Self { pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
Self { Self {
_peri: PhantomData, _peri: PhantomData,
desc_ring: DescriptorRing::new(), desc_ring: DescriptorRing::new(),
@ -326,7 +336,7 @@ impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> {
} }
} }
impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX> { impl<'d, T: Instance, const TX: usize, const RX: usize> PeripheralState for Inner<'d, T, TX, RX> {
type Interrupt = crate::interrupt::ETH; type Interrupt = crate::interrupt::ETH;
fn on_interrupt(&mut self) { fn on_interrupt(&mut self) {
@ -351,123 +361,4 @@ impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX>
} }
} }
mod sealed {
use super::*;
pub trait RefClkPin: GpioPin {
fn configure(&mut self);
}
pub trait MDIOPin: GpioPin {
fn configure(&mut self);
}
pub trait MDCPin: GpioPin {
fn configure(&mut self);
}
pub trait CRSPin: GpioPin {
fn configure(&mut self);
}
pub trait RXD0Pin: GpioPin {
fn configure(&mut self);
}
pub trait RXD1Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXD0Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXD1Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXEnPin: GpioPin {
fn configure(&mut self);
}
}
pub trait RefClkPin: sealed::RefClkPin + 'static {}
pub trait MDIOPin: sealed::MDIOPin + 'static {}
pub trait MDCPin: sealed::MDCPin + 'static {}
pub trait CRSPin: sealed::CRSPin + 'static {}
pub trait RXD0Pin: sealed::RXD0Pin + 'static {}
pub trait RXD1Pin: sealed::RXD1Pin + 'static {}
pub trait TXD0Pin: sealed::TXD0Pin + 'static {}
pub trait TXD1Pin: sealed::TXD1Pin + 'static {}
pub trait TXEnPin: sealed::TXEnPin + 'static {}
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
macro_rules! impl_pin {
($pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal for peripherals::$pin {
fn configure(&mut self) {
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.block()
.ospeedr()
.modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
})
}
}
impl $signal for peripherals::$pin {}
};
}
// impl sealed::RefClkPin for peripherals::PA1 {
// fn configure(&mut self) {
// // NOTE(unsafe) Exclusive access to the registers
// critical_section::with(|_| unsafe {
// self.set_as_af(11, OutputPushPull);
// self.block()
// .ospeedr()
// .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
// })
// }
// }
// impl RefClkPin for peripherals::PA1 {}
crate::pac::peripheral_pins!(
($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
impl_pin!($pin, RefClkPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
impl_pin!($pin, MDIOPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
impl_pin!($pin, MDCPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
impl_pin!($pin, CRSPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
impl_pin!($pin, RXD0Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
impl_pin!($pin, RXD1Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
impl_pin!($pin, TXD0Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
impl_pin!($pin, TXD1Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
impl_pin!($pin, TXEnPin, $af);
};
);

View File

@ -8,25 +8,24 @@ use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStor
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
use crate::gpio::sealed::Pin as __GpioPin; use crate::gpio::sealed::Pin as _;
use crate::gpio::Pin as GpioPin; use crate::gpio::{sealed::AFType, AnyPin, Speed};
use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin};
use crate::pac::gpio::vals::Ospeedr;
use crate::pac::{ETH, RCC, SYSCFG}; use crate::pac::{ETH, RCC, SYSCFG};
use crate::peripherals;
mod descriptors; mod descriptors;
use super::{StationManagement, PHY}; use super::*;
use descriptors::DescriptorRing; use descriptors::DescriptorRing;
pub struct State<'d, const TX: usize, const RX: usize>(StateStorage<Inner<'d, TX, RX>>); pub struct State<'d, T: Instance, const TX: usize, const RX: usize>(
impl<'d, const TX: usize, const RX: usize> State<'d, TX, RX> { StateStorage<Inner<'d, T, TX, RX>>,
pub const fn new() -> Self { );
impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
pub fn new() -> Self {
Self(StateStorage::new()) Self(StateStorage::new())
} }
} }
pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> { pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
state: PeripheralMutex<'d, Inner<'d, TX, RX>>, state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
pins: [AnyPin; 9], pins: [AnyPin; 9],
_phy: P, _phy: P,
clock_range: u8, clock_range: u8,
@ -34,21 +33,33 @@ pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> {
mac_addr: [u8; 6], mac_addr: [u8; 6],
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { macro_rules! config_pins {
($($pin:ident),*) => {
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$(
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
$pin.set_speed(Speed::VeryHigh);
)*
})
};
}
impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T, P, TX, RX> {
/// safety: the returned instance is not leak-safe /// safety: the returned instance is not leak-safe
pub unsafe fn new( pub unsafe fn new(
state: &'d mut State<'d, TX, RX>, state: &'d mut State<'d, T, TX, RX>,
peri: impl Unborrow<Target = peripherals::ETH> + 'd, peri: impl Unborrow<Target = T> + 'd,
interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
ref_clk: impl Unborrow<Target = impl RefClkPin> + 'd, ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
mdio: impl Unborrow<Target = impl MDIOPin> + 'd, mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
mdc: impl Unborrow<Target = impl MDCPin> + 'd, mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
crs: impl Unborrow<Target = impl CRSPin> + 'd, crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
rx_d0: impl Unborrow<Target = impl RXD0Pin> + 'd, rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
rx_d1: impl Unborrow<Target = impl RXD1Pin> + 'd, rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
tx_d0: impl Unborrow<Target = impl TXD0Pin> + 'd, tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
tx_d1: impl Unborrow<Target = impl TXD1Pin> + 'd, tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
tx_en: impl Unborrow<Target = impl TXEnPin> + 'd, tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
phy_addr: u8, phy_addr: u8,
@ -69,15 +80,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
SYSCFG.pmcr().modify(|w| w.set_epis(0b100)); SYSCFG.pmcr().modify(|w| w.set_epis(0b100));
}); });
ref_clk.configure(); config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
mdio.configure();
mdc.configure();
crs.configure();
rx_d0.configure();
rx_d1.configure();
tx_d0.configure();
tx_d1.configure();
tx_en.configure();
// NOTE(unsafe) We are ourselves not leak-safe. // NOTE(unsafe) We are ourselves not leak-safe.
let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri)); let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri));
@ -193,8 +196,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
} }
} }
unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement unsafe impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> StationManagement
for Ethernet<'d, P, TX, RX> for Ethernet<'d, T, P, TX, RX>
{ {
fn smi_read(&mut self, reg: u8) -> u16 { fn smi_read(&mut self, reg: u8) -> u16 {
// NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self` // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self`
@ -231,7 +234,9 @@ unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement
} }
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX, RX> { impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Device
for Ethernet<'d, T, P, TX, RX>
{
fn is_transmit_ready(&mut self) -> bool { fn is_transmit_ready(&mut self) -> bool {
self.state.with(|s| s.desc_ring.tx.available()) self.state.with(|s| s.desc_ring.tx.available())
} }
@ -268,7 +273,9 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX
} }
} }
impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX, RX> { impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
for Ethernet<'d, T, P, TX, RX>
{
fn drop(&mut self) { fn drop(&mut self) {
// NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers
unsafe { unsafe {
@ -301,9 +308,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
// NOTE(unsafe) Exclusive access to the regs // NOTE(unsafe) Exclusive access to the regs
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
pin.set_as_analog(); pin.set_as_analog();
pin.block() pin.set_speed(Speed::Low);
.ospeedr()
.modify(|w| w.set_ospeedr(pin.pin() as usize, Ospeedr::LOWSPEED));
}) })
} }
} }
@ -311,13 +316,13 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
//---------------------------------------------------------------------- //----------------------------------------------------------------------
struct Inner<'d, const TX: usize, const RX: usize> { struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
_peri: PhantomData<&'d mut peripherals::ETH>, _peri: PhantomData<&'d mut T>,
desc_ring: DescriptorRing<TX, RX>, desc_ring: DescriptorRing<TX, RX>,
} }
impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> { impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
pub fn new(_peri: impl Unborrow<Target = peripherals::ETH> + 'd) -> Self { pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
Self { Self {
_peri: PhantomData, _peri: PhantomData,
desc_ring: DescriptorRing::new(), desc_ring: DescriptorRing::new(),
@ -325,7 +330,7 @@ impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> {
} }
} }
impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX> { impl<'d, T: Instance, const TX: usize, const RX: usize> PeripheralState for Inner<'d, T, TX, RX> {
type Interrupt = crate::interrupt::ETH; type Interrupt = crate::interrupt::ETH;
fn on_interrupt(&mut self) { fn on_interrupt(&mut self) {
@ -350,110 +355,4 @@ impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX>
} }
} }
mod sealed {
use super::*;
pub trait RefClkPin: GpioPin {
fn configure(&mut self);
}
pub trait MDIOPin: GpioPin {
fn configure(&mut self);
}
pub trait MDCPin: GpioPin {
fn configure(&mut self);
}
pub trait CRSPin: GpioPin {
fn configure(&mut self);
}
pub trait RXD0Pin: GpioPin {
fn configure(&mut self);
}
pub trait RXD1Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXD0Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXD1Pin: GpioPin {
fn configure(&mut self);
}
pub trait TXEnPin: GpioPin {
fn configure(&mut self);
}
}
pub trait RefClkPin: sealed::RefClkPin + 'static {}
pub trait MDIOPin: sealed::MDIOPin + 'static {}
pub trait MDCPin: sealed::MDCPin + 'static {}
pub trait CRSPin: sealed::CRSPin + 'static {}
pub trait RXD0Pin: sealed::RXD0Pin + 'static {}
pub trait RXD1Pin: sealed::RXD1Pin + 'static {}
pub trait TXD0Pin: sealed::TXD0Pin + 'static {}
pub trait TXD1Pin: sealed::TXD1Pin + 'static {}
pub trait TXEnPin: sealed::TXEnPin + 'static {}
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
macro_rules! impl_pin {
($pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal for peripherals::$pin {
fn configure(&mut self) {
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.block()
.ospeedr()
.modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
})
}
}
impl $signal for peripherals::$pin {}
};
}
crate::pac::peripheral_pins!(
($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
impl_pin!($pin, RefClkPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
impl_pin!($pin, MDIOPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
impl_pin!($pin, MDCPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
impl_pin!($pin, CRSPin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
impl_pin!($pin, RXD0Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
impl_pin!($pin, RXD1Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
impl_pin!($pin, TXD0Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
impl_pin!($pin, TXD1Pin, $af);
};
($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
impl_pin!($pin, TXEnPin, $af);
};
);

View File

@ -1,11 +1,13 @@
mod pins;
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use pins::*; use crate::gpio::sealed::AFType::OutputPushPull;
use crate::gpio::Speed;
use crate::pac::gpio::vals::Pupdr;
mod pins;
pub use pins::*;
pub struct Fmc<'d, T: Instance> { pub struct Fmc<'d, T: Instance> {
peri: PhantomData<&'d mut T>, peri: PhantomData<&'d mut T>,
@ -34,16 +36,21 @@ where
<T as crate::rcc::sealed::RccPeripheral>::frequency().0 <T as crate::rcc::sealed::RccPeripheral>::frequency().0
} }
} }
macro_rules! config_pins { macro_rules! config_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
unborrow!($($pin),*);
$( $(
$pin.configure(); $pin.set_as_af($pin.af_num(), OutputPushPull);
$pin.set_speed(Speed::VeryHigh);
$pin.block().pupdr().modify(|w| w.set_pupdr($pin.pin() as usize, Pupdr::PULLUP));
)* )*
}; };
} }
macro_rules! fmc_sdram_constructor { macro_rules! fmc_sdram_constructor {
($name:ident: ( ($name:ident: (
bank: $bank:expr,
addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*], addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*],
ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*], ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*],
d: [$(($d_pin_name:ident: $d_signal:ident)),*], d: [$(($d_pin_name:ident: $d_signal:ident)),*],
@ -52,21 +59,15 @@ macro_rules! fmc_sdram_constructor {
)) => { )) => {
pub fn $name<CHIP: stm32_fmc::SdramChip>( pub fn $name<CHIP: stm32_fmc::SdramChip>(
_instance: impl Unborrow<Target = T> + 'd, _instance: impl Unborrow<Target = T> + 'd,
$($addr_pin_name: impl Unborrow<Target = impl $addr_signal> + 'd),*, $($addr_pin_name: impl Unborrow<Target = impl $addr_signal<T>> + 'd),*,
$($ba_pin_name: impl Unborrow<Target = impl $ba_signal> + 'd),*, $($ba_pin_name: impl Unborrow<Target = impl $ba_signal<T>> + 'd),*,
$($d_pin_name: impl Unborrow<Target = impl $d_signal> + 'd),*, $($d_pin_name: impl Unborrow<Target = impl $d_signal<T>> + 'd),*,
$($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal> + 'd),*, $($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal<T>> + 'd),*,
$($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal> + 'd),*, $($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal<T>> + 'd),*,
chip: CHIP chip: CHIP
) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> { ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
unborrow!(
$($addr_pin_name),*,
$($ba_pin_name),*,
$($d_pin_name),*,
$($nbl_pin_name),*,
$($ctrl_pin_name),*
);
critical_section::with(|_| unsafe {
config_pins!( config_pins!(
$($addr_pin_name),*, $($addr_pin_name),*,
$($ba_pin_name),*, $($ba_pin_name),*,
@ -74,17 +75,12 @@ macro_rules! fmc_sdram_constructor {
$($nbl_pin_name),*, $($nbl_pin_name),*,
$($ctrl_pin_name),* $($ctrl_pin_name),*
); );
});
let fmc = Self { peri: PhantomData }; let fmc = Self { peri: PhantomData };
stm32_fmc::Sdram::new( stm32_fmc::Sdram::new_unchecked(
fmc, fmc,
( $bank,
$($addr_pin_name),*,
$($ba_pin_name),*,
$($d_pin_name),*,
$($nbl_pin_name),*,
$($ctrl_pin_name),*,
),
chip, chip,
) )
} }
@ -93,6 +89,7 @@ macro_rules! fmc_sdram_constructor {
impl<'d, T: Instance> Fmc<'d, T> { impl<'d, T: Instance> Fmc<'d, T> {
fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: ( fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: (
bank: stm32_fmc::SdramTargetBank::Bank1,
addr: [ addr: [
(a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
], ],
@ -112,6 +109,7 @@ impl<'d, T: Instance> Fmc<'d, T> {
)); ));
fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: ( fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: (
bank: stm32_fmc::SdramTargetBank::Bank2,
addr: [ addr: [
(a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
], ],
@ -131,8 +129,6 @@ impl<'d, T: Instance> Fmc<'d, T> {
)); ));
} }
pub trait Instance: sealed::Instance + 'static {}
crate::pac::peripherals!( crate::pac::peripherals!(
(fmc, $inst:ident) => { (fmc, $inst:ident) => {
impl crate::fmc::sealed::Instance for crate::peripherals::$inst { impl crate::fmc::sealed::Instance for crate::peripherals::$inst {

View File

@ -2,671 +2,417 @@ pub(crate) mod sealed {
pub trait Instance: crate::rcc::sealed::RccPeripheral { pub trait Instance: crate::rcc::sealed::RccPeripheral {
fn regs() -> crate::pac::fmc::Fmc; fn regs() -> crate::pac::fmc::Fmc;
} }
macro_rules! declare_pin {
($name:ident) => {
pub trait $name {
fn configure(&mut self);
}
};
}
declare_pin!(SDNWEPin);
declare_pin!(SDNCASPin);
declare_pin!(SDNRASPin);
declare_pin!(SDNE0Pin);
declare_pin!(SDNE1Pin);
declare_pin!(SDCKE0Pin);
declare_pin!(SDCKE1Pin);
declare_pin!(SDCLKPin);
declare_pin!(NBL0Pin);
declare_pin!(NBL1Pin);
declare_pin!(NBL2Pin);
declare_pin!(NBL3Pin);
declare_pin!(INTPin);
declare_pin!(NLPin);
declare_pin!(NWaitPin);
declare_pin!(NE1Pin);
declare_pin!(NE2Pin);
declare_pin!(NE3Pin);
declare_pin!(NE4Pin);
declare_pin!(NCEPin);
declare_pin!(NOEPin);
declare_pin!(NWEPin);
declare_pin!(ClkPin);
declare_pin!(BA0Pin);
declare_pin!(BA1Pin);
declare_pin!(D0Pin);
declare_pin!(D1Pin);
declare_pin!(D2Pin);
declare_pin!(D3Pin);
declare_pin!(D4Pin);
declare_pin!(D5Pin);
declare_pin!(D6Pin);
declare_pin!(D7Pin);
declare_pin!(D8Pin);
declare_pin!(D9Pin);
declare_pin!(D10Pin);
declare_pin!(D11Pin);
declare_pin!(D12Pin);
declare_pin!(D13Pin);
declare_pin!(D14Pin);
declare_pin!(D15Pin);
declare_pin!(D16Pin);
declare_pin!(D17Pin);
declare_pin!(D18Pin);
declare_pin!(D19Pin);
declare_pin!(D20Pin);
declare_pin!(D21Pin);
declare_pin!(D22Pin);
declare_pin!(D23Pin);
declare_pin!(D24Pin);
declare_pin!(D25Pin);
declare_pin!(D26Pin);
declare_pin!(D27Pin);
declare_pin!(D28Pin);
declare_pin!(D29Pin);
declare_pin!(D30Pin);
declare_pin!(D31Pin);
declare_pin!(DA0Pin);
declare_pin!(DA1Pin);
declare_pin!(DA2Pin);
declare_pin!(DA3Pin);
declare_pin!(DA4Pin);
declare_pin!(DA5Pin);
declare_pin!(DA6Pin);
declare_pin!(DA7Pin);
declare_pin!(DA8Pin);
declare_pin!(DA9Pin);
declare_pin!(DA10Pin);
declare_pin!(DA11Pin);
declare_pin!(DA12Pin);
declare_pin!(DA13Pin);
declare_pin!(DA14Pin);
declare_pin!(DA15Pin);
declare_pin!(A0Pin);
declare_pin!(A1Pin);
declare_pin!(A2Pin);
declare_pin!(A3Pin);
declare_pin!(A4Pin);
declare_pin!(A5Pin);
declare_pin!(A6Pin);
declare_pin!(A7Pin);
declare_pin!(A8Pin);
declare_pin!(A9Pin);
declare_pin!(A10Pin);
declare_pin!(A11Pin);
declare_pin!(A12Pin);
declare_pin!(A13Pin);
declare_pin!(A14Pin);
declare_pin!(A15Pin);
declare_pin!(A16Pin);
declare_pin!(A17Pin);
declare_pin!(A18Pin);
declare_pin!(A19Pin);
declare_pin!(A20Pin);
declare_pin!(A21Pin);
declare_pin!(A22Pin);
declare_pin!(A23Pin);
declare_pin!(A24Pin);
declare_pin!(A25Pin);
} }
macro_rules! declare_pin { pub trait Instance: sealed::Instance + 'static {}
($name:ident, $fmc_pin:ident) => {
pub trait $name: sealed::$name + stm32_fmc::$fmc_pin + 'static {}
};
}
declare_pin!(SDNWEPin, SDNWE); pin_trait!(SDNWEPin, Instance);
declare_pin!(SDNCASPin, SDNCAS); pin_trait!(SDNCASPin, Instance);
declare_pin!(SDNRASPin, SDNRAS); pin_trait!(SDNRASPin, Instance);
declare_pin!(SDNE0Pin, SDNE0); pin_trait!(SDNE0Pin, Instance);
declare_pin!(SDNE1Pin, SDNE1); pin_trait!(SDNE1Pin, Instance);
declare_pin!(SDCKE0Pin, SDCKE0); pin_trait!(SDCKE0Pin, Instance);
declare_pin!(SDCKE1Pin, SDCKE1); pin_trait!(SDCKE1Pin, Instance);
declare_pin!(SDCLKPin, SDCLK); pin_trait!(SDCLKPin, Instance);
declare_pin!(NBL0Pin, NBL0); pin_trait!(NBL0Pin, Instance);
declare_pin!(NBL1Pin, NBL1); pin_trait!(NBL1Pin, Instance);
declare_pin!(NBL2Pin, NBL2); pin_trait!(NBL2Pin, Instance);
declare_pin!(NBL3Pin, NBL3); pin_trait!(NBL3Pin, Instance);
declare_pin!(INTPin, INT); pin_trait!(INTPin, Instance);
declare_pin!(NLPin, NL); pin_trait!(NLPin, Instance);
declare_pin!(NWaitPin, NWAIT); pin_trait!(NWaitPin, Instance);
declare_pin!(NE1Pin, NE1); pin_trait!(NE1Pin, Instance);
declare_pin!(NE2Pin, NE2); pin_trait!(NE2Pin, Instance);
declare_pin!(NE3Pin, NE3); pin_trait!(NE3Pin, Instance);
declare_pin!(NE4Pin, NE4); pin_trait!(NE4Pin, Instance);
declare_pin!(NCEPin, NCE); pin_trait!(NCEPin, Instance);
declare_pin!(NOEPin, NOE); pin_trait!(NOEPin, Instance);
declare_pin!(NWEPin, NWE); pin_trait!(NWEPin, Instance);
declare_pin!(ClkPin, CLK); pin_trait!(ClkPin, Instance);
declare_pin!(BA0Pin, BA0); pin_trait!(BA0Pin, Instance);
declare_pin!(BA1Pin, BA1); pin_trait!(BA1Pin, Instance);
declare_pin!(D0Pin, D0); pin_trait!(D0Pin, Instance);
declare_pin!(D1Pin, D1); pin_trait!(D1Pin, Instance);
declare_pin!(D2Pin, D2); pin_trait!(D2Pin, Instance);
declare_pin!(D3Pin, D3); pin_trait!(D3Pin, Instance);
declare_pin!(D4Pin, D4); pin_trait!(D4Pin, Instance);
declare_pin!(D5Pin, D5); pin_trait!(D5Pin, Instance);
declare_pin!(D6Pin, D6); pin_trait!(D6Pin, Instance);
declare_pin!(D7Pin, D7); pin_trait!(D7Pin, Instance);
declare_pin!(D8Pin, D8); pin_trait!(D8Pin, Instance);
declare_pin!(D9Pin, D9); pin_trait!(D9Pin, Instance);
declare_pin!(D10Pin, D10); pin_trait!(D10Pin, Instance);
declare_pin!(D11Pin, D11); pin_trait!(D11Pin, Instance);
declare_pin!(D12Pin, D12); pin_trait!(D12Pin, Instance);
declare_pin!(D13Pin, D13); pin_trait!(D13Pin, Instance);
declare_pin!(D14Pin, D14); pin_trait!(D14Pin, Instance);
declare_pin!(D15Pin, D15); pin_trait!(D15Pin, Instance);
declare_pin!(D16Pin, D16); pin_trait!(D16Pin, Instance);
declare_pin!(D17Pin, D17); pin_trait!(D17Pin, Instance);
declare_pin!(D18Pin, D18); pin_trait!(D18Pin, Instance);
declare_pin!(D19Pin, D19); pin_trait!(D19Pin, Instance);
declare_pin!(D20Pin, D20); pin_trait!(D20Pin, Instance);
declare_pin!(D21Pin, D21); pin_trait!(D21Pin, Instance);
declare_pin!(D22Pin, D22); pin_trait!(D22Pin, Instance);
declare_pin!(D23Pin, D23); pin_trait!(D23Pin, Instance);
declare_pin!(D24Pin, D24); pin_trait!(D24Pin, Instance);
declare_pin!(D25Pin, D25); pin_trait!(D25Pin, Instance);
declare_pin!(D26Pin, D26); pin_trait!(D26Pin, Instance);
declare_pin!(D27Pin, D27); pin_trait!(D27Pin, Instance);
declare_pin!(D28Pin, D28); pin_trait!(D28Pin, Instance);
declare_pin!(D29Pin, D29); pin_trait!(D29Pin, Instance);
declare_pin!(D30Pin, D30); pin_trait!(D30Pin, Instance);
declare_pin!(D31Pin, D31); pin_trait!(D31Pin, Instance);
declare_pin!(DA0Pin, DA0); pin_trait!(DA0Pin, Instance);
declare_pin!(DA1Pin, DA1); pin_trait!(DA1Pin, Instance);
declare_pin!(DA2Pin, DA2); pin_trait!(DA2Pin, Instance);
declare_pin!(DA3Pin, DA3); pin_trait!(DA3Pin, Instance);
declare_pin!(DA4Pin, DA4); pin_trait!(DA4Pin, Instance);
declare_pin!(DA5Pin, DA5); pin_trait!(DA5Pin, Instance);
declare_pin!(DA6Pin, DA6); pin_trait!(DA6Pin, Instance);
declare_pin!(DA7Pin, DA7); pin_trait!(DA7Pin, Instance);
declare_pin!(DA8Pin, DA8); pin_trait!(DA8Pin, Instance);
declare_pin!(DA9Pin, DA9); pin_trait!(DA9Pin, Instance);
declare_pin!(DA10Pin, DA10); pin_trait!(DA10Pin, Instance);
declare_pin!(DA11Pin, DA11); pin_trait!(DA11Pin, Instance);
declare_pin!(DA12Pin, DA12); pin_trait!(DA12Pin, Instance);
declare_pin!(DA13Pin, DA13); pin_trait!(DA13Pin, Instance);
declare_pin!(DA14Pin, DA14); pin_trait!(DA14Pin, Instance);
declare_pin!(DA15Pin, DA15); pin_trait!(DA15Pin, Instance);
declare_pin!(A0Pin, A0); pin_trait!(A0Pin, Instance);
declare_pin!(A1Pin, A1); pin_trait!(A1Pin, Instance);
declare_pin!(A2Pin, A2); pin_trait!(A2Pin, Instance);
declare_pin!(A3Pin, A3); pin_trait!(A3Pin, Instance);
declare_pin!(A4Pin, A4); pin_trait!(A4Pin, Instance);
declare_pin!(A5Pin, A5); pin_trait!(A5Pin, Instance);
declare_pin!(A6Pin, A6); pin_trait!(A6Pin, Instance);
declare_pin!(A7Pin, A7); pin_trait!(A7Pin, Instance);
declare_pin!(A8Pin, A8); pin_trait!(A8Pin, Instance);
declare_pin!(A9Pin, A9); pin_trait!(A9Pin, Instance);
declare_pin!(A10Pin, A10); pin_trait!(A10Pin, Instance);
declare_pin!(A11Pin, A11); pin_trait!(A11Pin, Instance);
declare_pin!(A12Pin, A12); pin_trait!(A12Pin, Instance);
declare_pin!(A13Pin, A13); pin_trait!(A13Pin, Instance);
declare_pin!(A14Pin, A14); pin_trait!(A14Pin, Instance);
declare_pin!(A15Pin, A15); pin_trait!(A15Pin, Instance);
declare_pin!(A16Pin, A16); pin_trait!(A16Pin, Instance);
declare_pin!(A17Pin, A17); pin_trait!(A17Pin, Instance);
declare_pin!(A18Pin, A18); pin_trait!(A18Pin, Instance);
declare_pin!(A19Pin, A19); pin_trait!(A19Pin, Instance);
declare_pin!(A20Pin, A20); pin_trait!(A20Pin, Instance);
declare_pin!(A21Pin, A21); pin_trait!(A21Pin, Instance);
declare_pin!(A22Pin, A22); pin_trait!(A22Pin, Instance);
declare_pin!(A23Pin, A23); pin_trait!(A23Pin, Instance);
declare_pin!(A24Pin, A24); pin_trait!(A24Pin, Instance);
declare_pin!(A25Pin, A25); pin_trait!(A25Pin, Instance);
macro_rules! impl_pin {
($pin:ident, $signal:ident, $fmc_name:ident, $af:expr) => {
impl sealed::$signal for crate::peripherals::$pin {
fn configure(&mut self) {
use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
use crate::gpio::Pin;
use crate::gpio::Speed;
use crate::pac::gpio::vals::Pupdr;
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.set_speed(Speed::VeryHigh);
self.block()
.pupdr()
.modify(|w| w.set_pupdr(self.pin() as usize, Pupdr::PULLUP));
})
}
}
impl stm32_fmc::$fmc_name for crate::peripherals::$pin {}
impl $signal for crate::peripherals::$pin {}
};
}
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => {
impl_pin!($pin, A0Pin, A0, $af); pin_trait_impl!(A0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => {
impl_pin!($pin, A1Pin, A1, $af); pin_trait_impl!(A1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => {
impl_pin!($pin, A2Pin, A2, $af); pin_trait_impl!(A2Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => {
impl_pin!($pin, A3Pin, A3, $af); pin_trait_impl!(A3Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => {
impl_pin!($pin, A4Pin, A4, $af); pin_trait_impl!(A4Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => {
impl_pin!($pin, A5Pin, A5, $af); pin_trait_impl!(A5Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => {
impl_pin!($pin, A6Pin, A6, $af); pin_trait_impl!(A6Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => {
impl_pin!($pin, A7Pin, A7, $af); pin_trait_impl!(A7Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => {
impl_pin!($pin, A8Pin, A8, $af); pin_trait_impl!(A8Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => {
impl_pin!($pin, A9Pin, A9, $af); pin_trait_impl!(A9Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => {
impl_pin!($pin, A10Pin, A10, $af); pin_trait_impl!(A10Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => {
impl_pin!($pin, A11Pin, A11, $af); pin_trait_impl!(A11Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => {
impl_pin!($pin, A12Pin, A12, $af); pin_trait_impl!(A12Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => {
impl_pin!($pin, A13Pin, A13, $af); pin_trait_impl!(A13Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => {
impl_pin!($pin, A14Pin, A14, $af); pin_trait_impl!(A14Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => {
impl_pin!($pin, A15Pin, A15, $af); pin_trait_impl!(A15Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => {
impl_pin!($pin, A16Pin, A16, $af); pin_trait_impl!(A16Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => {
impl_pin!($pin, A17Pin, A17, $af); pin_trait_impl!(A17Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => {
impl_pin!($pin, A18Pin, A18, $af); pin_trait_impl!(A18Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => {
impl_pin!($pin, A19Pin, A19, $af); pin_trait_impl!(A19Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => {
impl_pin!($pin, A20Pin, A20, $af); pin_trait_impl!(A20Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => {
impl_pin!($pin, A21Pin, A21, $af); pin_trait_impl!(A21Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => {
impl_pin!($pin, A22Pin, A22, $af); pin_trait_impl!(A22Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => {
impl_pin!($pin, A23Pin, A23, $af); pin_trait_impl!(A23Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => {
impl_pin!($pin, A24Pin, A24, $af); pin_trait_impl!(A24Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => {
impl_pin!($pin, A25Pin, A25, $af); pin_trait_impl!(A25Pin, $inst, $pin, $af);
}; };
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => {
impl_pin!($pin, D0Pin, D0, $af); pin_trait_impl!(D0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => {
impl_pin!($pin, D1Pin, D1, $af); pin_trait_impl!(D1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => {
impl_pin!($pin, D2Pin, D2, $af); pin_trait_impl!(D2Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => {
impl_pin!($pin, D3Pin, D3, $af); pin_trait_impl!(D3Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => {
impl_pin!($pin, D4Pin, D4, $af); pin_trait_impl!(D4Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => {
impl_pin!($pin, D5Pin, D5, $af); pin_trait_impl!(D5Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => {
impl_pin!($pin, D6Pin, D6, $af); pin_trait_impl!(D6Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => {
impl_pin!($pin, D7Pin, D7, $af); pin_trait_impl!(D7Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => {
impl_pin!($pin, D8Pin, D8, $af); pin_trait_impl!(D8Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => {
impl_pin!($pin, D9Pin, D9, $af); pin_trait_impl!(D9Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => {
impl_pin!($pin, D10Pin, D10, $af); pin_trait_impl!(D10Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => {
impl_pin!($pin, D11Pin, D11, $af); pin_trait_impl!(D11Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => {
impl_pin!($pin, D12Pin, D12, $af); pin_trait_impl!(D12Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => {
impl_pin!($pin, D13Pin, D13, $af); pin_trait_impl!(D13Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => {
impl_pin!($pin, D14Pin, D14, $af); pin_trait_impl!(D14Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => {
impl_pin!($pin, D15Pin, D15, $af); pin_trait_impl!(D15Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => {
impl_pin!($pin, D16Pin, D16, $af); pin_trait_impl!(D16Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => {
impl_pin!($pin, D17Pin, D17, $af); pin_trait_impl!(D17Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => {
impl_pin!($pin, D18Pin, D18, $af); pin_trait_impl!(D18Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => {
impl_pin!($pin, D19Pin, D19, $af); pin_trait_impl!(D19Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => {
impl_pin!($pin, D20Pin, D20, $af); pin_trait_impl!(D20Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => {
impl_pin!($pin, D21Pin, D21, $af); pin_trait_impl!(D21Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => {
impl_pin!($pin, D22Pin, D22, $af); pin_trait_impl!(D22Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => {
impl_pin!($pin, D23Pin, D23, $af); pin_trait_impl!(D23Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => {
impl_pin!($pin, D24Pin, D24, $af); pin_trait_impl!(D24Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => {
impl_pin!($pin, D25Pin, D25, $af); pin_trait_impl!(D25Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => {
impl_pin!($pin, D26Pin, D26, $af); pin_trait_impl!(D26Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => {
impl_pin!($pin, D27Pin, D27, $af); pin_trait_impl!(D27Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => {
impl_pin!($pin, D28Pin, D28, $af); pin_trait_impl!(D28Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => {
impl_pin!($pin, D29Pin, D29, $af); pin_trait_impl!(D29Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => {
impl_pin!($pin, D30Pin, D30, $af); pin_trait_impl!(D30Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => {
impl_pin!($pin, D31Pin, D31, $af); pin_trait_impl!(D31Pin, $inst, $pin, $af);
}; };
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => {
impl_pin!($pin, DA0Pin, DA0, $af); pin_trait_impl!(DA0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => {
impl_pin!($pin, DA1Pin, DA1, $af); pin_trait_impl!(DA1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => {
impl_pin!($pin, DA2Pin, DA2, $af); pin_trait_impl!(DA2Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => {
impl_pin!($pin, DA3Pin, DA3, $af); pin_trait_impl!(DA3Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => {
impl_pin!($pin, DA4Pin, DA4, $af); pin_trait_impl!(DA4Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => {
impl_pin!($pin, DA5Pin, DA5, $af); pin_trait_impl!(DA5Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => {
impl_pin!($pin, DA6Pin, DA6, $af); pin_trait_impl!(DA6Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => {
impl_pin!($pin, DA7Pin, DA7, $af); pin_trait_impl!(DA7Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => {
impl_pin!($pin, DA8Pin, DA8, $af); pin_trait_impl!(DA8Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => {
impl_pin!($pin, DA9Pin, DA9, $af); pin_trait_impl!(DA9Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => {
impl_pin!($pin, DA10Pin, DA10, $af); pin_trait_impl!(DA10Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => {
impl_pin!($pin, DA11Pin, DA11, $af); pin_trait_impl!(DA11Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => {
impl_pin!($pin, DA12Pin, DA12, $af); pin_trait_impl!(DA12Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => {
impl_pin!($pin, DA13Pin, DA13, $af); pin_trait_impl!(DA13Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => {
impl_pin!($pin, DA14Pin, DA14, $af); pin_trait_impl!(DA14Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => {
impl_pin!($pin, DA15Pin, DA15, $af); pin_trait_impl!(DA15Pin, $inst, $pin, $af);
}; };
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => {
impl_pin!($pin, SDNWEPin, SDNWE, $af); pin_trait_impl!(SDNWEPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => {
impl_pin!($pin, SDNCASPin, SDNCAS, $af); pin_trait_impl!(SDNCASPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => {
impl_pin!($pin, SDNRASPin, SDNRAS, $af); pin_trait_impl!(SDNRASPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => {
impl_pin!($pin, SDNE0Pin, SDNE0, $af); pin_trait_impl!(SDNE0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => {
impl_pin!($pin, SDNE1Pin, SDNE1, $af); pin_trait_impl!(SDNE1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => {
impl_pin!($pin, SDCKE0Pin, SDCKE0, $af); pin_trait_impl!(SDCKE0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => {
impl_pin!($pin, SDCKE1Pin, SDCKE1, $af); pin_trait_impl!(SDCKE1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => {
impl_pin!($pin, SDCLKPin, SDCLK, $af); pin_trait_impl!(SDCLKPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => {
impl_pin!($pin, NBL0Pin, NBL0, $af); pin_trait_impl!(NBL0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => {
impl_pin!($pin, NBL1Pin, NBL1, $af); pin_trait_impl!(NBL1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => {
impl_pin!($pin, NBL2Pin, NBL2, $af); pin_trait_impl!(NBL2Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => {
impl_pin!($pin, NBL3Pin, NBL3, $af); pin_trait_impl!(NBL3Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => {
impl_pin!($pin, INTPin, INT, $af); pin_trait_impl!(INTPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => {
impl_pin!($pin, NLPin, NL, $af); pin_trait_impl!(NLPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => {
impl_pin!($pin, NWaitPin, NWAIT, $af); pin_trait_impl!(NWaitPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => {
impl_pin!($pin, NE1Pin, NE1, $af); pin_trait_impl!(NE1Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => {
impl_pin!($pin, NE2Pin, NE2, $af); pin_trait_impl!(NE2Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => {
impl_pin!($pin, NE3Pin, NE3, $af); pin_trait_impl!(NE3Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => {
impl_pin!($pin, NE4Pin, NE4, $af); pin_trait_impl!(NE4Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => {
impl_pin!($pin, NCEPin, NCE, $af); pin_trait_impl!(NCEPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => {
impl_pin!($pin, NOEPin, NOE, $af); pin_trait_impl!(NOEPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => {
impl_pin!($pin, NWEPin, NWE, $af); pin_trait_impl!(NWEPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => {
impl_pin!($pin, ClkPin, CLK, $af); pin_trait_impl!(ClkPin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => {
impl_pin!($pin, BA0Pin, BA0, $af); pin_trait_impl!(BA0Pin, $inst, $pin, $af);
}; };
($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => { ($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => {
impl_pin!($pin, BA1Pin, BA1, $af); pin_trait_impl!(BA1Pin, $inst, $pin, $af);
}; };
); );

View File

@ -483,7 +483,7 @@ pub(crate) mod sealed {
pub trait OptionalPin {} pub trait OptionalPin {}
} }
pub trait Pin: sealed::Pin + Sized { pub trait Pin: sealed::Pin + Sized + 'static {
#[cfg(feature = "exti")] #[cfg(feature = "exti")]
type ExtiChannel: crate::exti::Channel; type ExtiChannel: crate::exti::Channel;
@ -638,3 +638,8 @@ mod eh02 {
} }
} }
} }
#[cfg(feature = "unstable-pac")]
pub mod low_level {
pub use super::sealed::*;
}

View File

@ -5,7 +5,7 @@ use embassy::interrupt::Interrupt;
#[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(i2c_v1, path = "v1.rs")]
#[cfg_attr(i2c_v2, path = "v2.rs")] #[cfg_attr(i2c_v2, path = "v2.rs")]
mod _version; mod _version;
use crate::{dma, peripherals}; use crate::peripherals;
pub use _version::*; pub use _version::*;
#[derive(Debug)] #[derive(Debug)]
@ -21,44 +21,20 @@ pub enum Error {
} }
pub(crate) mod sealed { pub(crate) mod sealed {
use super::dma; pub trait Instance: crate::rcc::RccPeripheral {
use crate::gpio::Pin;
use crate::rcc::RccPeripheral;
pub trait Instance: RccPeripheral {
fn regs() -> crate::pac::i2c::I2c; fn regs() -> crate::pac::i2c::I2c;
fn state_number() -> usize; fn state_number() -> usize;
} }
pub trait SclPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait SdaPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait RxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
pub trait TxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
} }
pub trait Instance: sealed::Instance + 'static { pub trait Instance: sealed::Instance + 'static {
type Interrupt: Interrupt; type Interrupt: Interrupt;
} }
pub trait SclPin<T: Instance>: sealed::SclPin<T> + 'static {} pin_trait!(SclPin, Instance);
pin_trait!(SdaPin, Instance);
pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + 'static {} dma_trait!(RxDma, Instance);
dma_trait!(TxDma, Instance);
pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {}
pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {}
macro_rules! i2c_state { macro_rules! i2c_state {
(I2C1) => { (I2C1) => {
@ -93,77 +69,34 @@ crate::pac::interrupts!(
impl Instance for peripherals::$inst { impl Instance for peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::$irq;
} }
}; };
); );
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl $signal<peripherals::$inst> for peripherals::$pin {}
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
};
}
#[cfg(not(rcc_f1))] #[cfg(not(rcc_f1))]
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => { ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
impl_pin!($inst, $pin, SdaPin, $af); pin_trait_impl!(SdaPin, $inst, $pin, $af);
}; };
($inst:ident, i2c, I2C, $pin:ident, SCL, $af:expr) => { ($inst:ident, i2c, I2C, $pin:ident, SCL, $af:expr) => {
impl_pin!($inst, $pin, SclPin, $af); pin_trait_impl!(SclPin, $inst, $pin, $af);
}; };
); );
#[cfg(rcc_f1)] #[cfg(rcc_f1)]
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, i2c, I2C, $pin:ident, SDA) => { ($inst:ident, i2c, I2C, $pin:ident, SDA) => {
impl_pin!($inst, $pin, SdaPin, 0); pin_trait_impl!(SdaPin, $inst, $pin, 0);
}; };
($inst:ident, i2c, I2C, $pin:ident, SCL) => { ($inst:ident, i2c, I2C, $pin:ident, SCL) => {
impl_pin!($inst, $pin, SclPin, 0); pin_trait_impl!(SdaPin, $inst, $pin, 0);
}; };
); );
#[allow(unused)]
macro_rules! impl_dma {
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
impl<T> sealed::$signal<peripherals::$inst> for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
fn request(&self) -> dma::Request {
$request
}
}
impl<T> $signal<peripherals::$inst> for T where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
{
}
};
($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
fn request(&self) -> dma::Request {
$request
}
}
impl $signal<peripherals::$inst> for peripherals::$channel {}
};
}
crate::pac::peripheral_dma_channels! { crate::pac::peripheral_dma_channels! {
($peri:ident, i2c, $kind:ident, RX, $channel:tt, $request:expr) => { ($peri:ident, i2c, $kind:ident, RX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, RxDma, $request); dma_trait_impl!(RxDma, $peri, $channel, $request);
}; };
($peri:ident, i2c, $kind:ident, TX, $channel:tt, $request:expr) => { ($peri:ident, i2c, $kind:ident, TX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, TxDma, $request); dma_trait_impl!(TxDma, $peri, $channel, $request);
}; };
} }

View File

@ -13,6 +13,7 @@ pub mod fmt;
// Utilities // Utilities
pub mod interrupt; pub mod interrupt;
pub mod time; pub mod time;
mod traits;
// Always-present hardware // Always-present hardware
pub mod dma; pub mod dma;

View File

@ -1,11 +1,3 @@
#[cfg(feature = "unstable-pac")]
#[macro_use]
pub mod pins;
#[cfg(not(feature = "unstable-pac"))]
#[macro_use]
pub(crate) mod pins;
pub mod simple_pwm; pub mod simple_pwm;
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
@ -62,7 +54,7 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*; use super::*;
pub trait CaptureCompareCapable16bitInstance: crate::timer::sealed::Basic16bitInstance { pub trait CaptureCompare16bitInstance: crate::timer::sealed::Basic16bitInstance {
unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
unsafe fn enable_channel(&mut self, channel: Channel, enable: bool); unsafe fn enable_channel(&mut self, channel: Channel, enable: bool);
@ -72,7 +64,7 @@ pub(crate) mod sealed {
unsafe fn get_max_compare_value(&self) -> u16; unsafe fn get_max_compare_value(&self) -> u16;
} }
pub trait CaptureCompareCapable32bitInstance: pub trait CaptureCompare32bitInstance:
crate::timer::sealed::GeneralPurpose32bitInstance crate::timer::sealed::GeneralPurpose32bitInstance
{ {
unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
@ -85,19 +77,22 @@ pub(crate) mod sealed {
} }
} }
pub trait CaptureCompareCapable16bitInstance: pub trait CaptureCompare16bitInstance:
sealed::CaptureCompareCapable16bitInstance + crate::timer::Basic16bitInstance + 'static sealed::CaptureCompare16bitInstance + crate::timer::Basic16bitInstance + 'static
{ {
} }
pub trait CaptureCompareCapable32bitInstance: pub trait CaptureCompare32bitInstance:
sealed::CaptureCompareCapable32bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static sealed::CaptureCompare32bitInstance
+ CaptureCompare16bitInstance
+ crate::timer::GeneralPurpose32bitInstance
+ 'static
{ {
} }
#[allow(unused)] #[allow(unused)]
macro_rules! impl_compare_capable_16bit { macro_rules! impl_compare_capable_16bit {
($inst:ident) => { ($inst:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode( unsafe fn set_output_compare_mode(
&mut self, &mut self,
channel: crate::pwm::Channel, channel: crate::pwm::Channel,
@ -134,7 +129,7 @@ macro_rules! impl_compare_capable_16bit {
crate::pac::interrupts! { crate::pac::interrupts! {
($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode( unsafe fn set_output_compare_mode(
&mut self, &mut self,
channel: crate::pwm::Channel, channel: crate::pwm::Channel,
@ -167,14 +162,14 @@ crate::pac::interrupts! {
} }
} }
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl CaptureCompare16bitInstance for crate::peripherals::$inst {
} }
}; };
($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
impl_compare_capable_16bit!($inst); impl_compare_capable_16bit!($inst);
impl crate::pwm::sealed::CaptureCompareCapable32bitInstance for crate::peripherals::$inst { impl crate::pwm::sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode( unsafe fn set_output_compare_mode(
&mut self, &mut self,
channel: crate::pwm::Channel, channel: crate::pwm::Channel,
@ -200,16 +195,16 @@ crate::pac::interrupts! {
self.regs_gp32().arr().read().arr() as u32 self.regs_gp32().arr().read().arr() as u32
} }
} }
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl CaptureCompare16bitInstance for crate::peripherals::$inst {
} }
impl CaptureCompareCapable32bitInstance for crate::peripherals::$inst { impl CaptureCompare32bitInstance for crate::peripherals::$inst {
} }
}; };
($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode( unsafe fn set_output_compare_mode(
&mut self, &mut self,
channel: crate::pwm::Channel, channel: crate::pwm::Channel,
@ -242,56 +237,72 @@ crate::pac::interrupts! {
} }
} }
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { impl CaptureCompare16bitInstance for crate::peripherals::$inst {
} }
}; };
} }
pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, timer, $block:ident, $pin:ident, CH1, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH1, $af:expr) => {
impl_pin!($inst, Channel1Pin, $pin, $af); pin_trait_impl!(Channel1Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH1N, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH1N, $af:expr) => {
impl_pin!($inst, Channel1ComplementaryPin, $pin, $af); pin_trait_impl!(Channel1ComplementaryPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH2, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH2, $af:expr) => {
impl_pin!($inst, Channel2Pin, $pin, $af); pin_trait_impl!(Channel2Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH2N, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH2N, $af:expr) => {
impl_pin!($inst, Channel2ComplementaryPin, $pin, $af); pin_trait_impl!(Channel2ComplementaryPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH3, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH3, $af:expr) => {
impl_pin!($inst, Channel3Pin, $pin, $af); pin_trait_impl!(Channel3Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH3N, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH3N, $af:expr) => {
impl_pin!($inst, Channel3ComplementaryPin, $pin, $af); pin_trait_impl!(Channel3ComplementaryPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH4, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH4, $af:expr) => {
impl_pin!($inst, Channel4Pin, $pin, $af); pin_trait_impl!(Channel4Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, CH4N, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, CH4N, $af:expr) => {
impl_pin!($inst, Channel4ComplementaryPin, $pin, $af); pin_trait_impl!(Channel4ComplementaryPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, ETR, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, ETR, $af:expr) => {
impl_pin!($inst, ExternalTriggerPin, $pin, $af); pin_trait_impl!(ExternalTriggerPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN, $af:expr) => {
impl_pin!($inst, BreakInputPin, $pin, $af); pin_trait_impl!(BreakInputPin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP1, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP1, $af:expr) => {
impl_pin!($inst, BreakInputComparator1Pin, $pin, $af); pin_trait_impl!(BreakInputComparator1Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP2, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP2, $af:expr) => {
impl_pin!($inst, BreakInputComparator2Pin, $pin, $af); pin_trait_impl!(BreakInputComparator2Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN2, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN2, $af:expr) => {
impl_pin!($inst, BreakInput2Pin, $pin, $af); pin_trait_impl!(BreakInput2Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP1, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP1, $af:expr) => {
impl_pin!($inst, BreakInput2Comparator1Pin, $pin, $af); pin_trait_impl!(BreakInput2Comparator1Pin, $inst, $pin, $af);
}; };
($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP2, $af:expr) => { ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP2, $af:expr) => {
impl_pin!($inst, BreakInput2Comparator2Pin, $pin, $af); pin_trait_impl!(BreakInput2Comparator2Pin, $inst, $pin, $af);
}; };
); );

View File

@ -1,126 +0,0 @@
use crate::gpio::Pin;
#[cfg(feature = "unstable-pac")]
pub mod low_level {
pub use super::sealed::*;
}
pub(crate) mod sealed {
use crate::gpio::sealed::Pin;
pub trait Channel1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel1ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel2ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel3Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel3ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel4Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel4ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait ExternalTriggerPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputComparator1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputComparator2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Comparator1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Comparator2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
}
pub trait Channel1Pin<Timer>: sealed::Channel1Pin<Timer> + Pin + 'static {}
pub trait Channel1ComplementaryPin<Timer>:
sealed::Channel1ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel2Pin<Timer>: sealed::Channel2Pin<Timer> + 'static {}
pub trait Channel2ComplementaryPin<Timer>:
sealed::Channel2ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel3Pin<Timer>: sealed::Channel3Pin<Timer> + 'static {}
pub trait Channel3ComplementaryPin<Timer>:
sealed::Channel3ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel4Pin<Timer>: sealed::Channel4Pin<Timer> + 'static {}
pub trait Channel4ComplementaryPin<Timer>:
sealed::Channel4ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait ExternalTriggerPin<Timer>: sealed::ExternalTriggerPin<Timer> + Pin + 'static {}
pub trait BreakInputPin<Timer>: sealed::BreakInputPin<Timer> + Pin + 'static {}
pub trait BreakInputComparator1Pin<Timer>:
sealed::BreakInputComparator1Pin<Timer> + Pin + 'static
{
}
pub trait BreakInputComparator2Pin<Timer>:
sealed::BreakInputComparator2Pin<Timer> + Pin + 'static
{
}
pub trait BreakInput2Pin<Timer>: sealed::BreakInput2Pin<Timer> + Pin + 'static {}
pub trait BreakInput2Comparator1Pin<Timer>:
sealed::BreakInput2Comparator1Pin<Timer> + Pin + 'static
{
}
pub trait BreakInput2Comparator2Pin<Timer>:
sealed::BreakInput2Comparator2Pin<Timer> + Pin + 'static
{
}
#[allow(unused)]
macro_rules! impl_pin {
($timer:ident, $signal:ident, $pin:ident, $af:expr) => {
impl crate::pwm::pins::sealed::$signal<crate::peripherals::$timer>
for crate::peripherals::$pin
{
unsafe fn configure(&mut self) {
use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::Speed;
self.set_low();
self.set_speed(Speed::VeryHigh);
self.set_as_af($af, AFType::OutputPushPull);
}
}
impl crate::pwm::pins::$signal<crate::peripherals::$timer> for crate::peripherals::$pin {}
};
}

View File

@ -1,25 +1,40 @@
use crate::{
pwm::{pins::*, CaptureCompareCapable16bitInstance, Channel, OutputCompareMode},
time::Hertz,
};
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use super::*;
#[allow(unused_imports)]
use crate::gpio::sealed::{AFType, Pin};
use crate::time::Hertz;
pub struct SimplePwm<'d, T> { pub struct SimplePwm<'d, T> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
inner: T, inner: T,
} }
impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> { macro_rules! config_pins {
($($pin:ident),*) => {
unborrow!($($pin),*);
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$(
$pin.set_low();
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
#[cfg(gpio_v2)]
$pin.set_speed(crate::gpio::Speed::VeryHigh);
)*
})
};
}
impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
pub fn new_1ch<F: Into<Hertz>>( pub fn new_1ch<F: Into<Hertz>>(
tim: impl Unborrow<Target = T> + 'd, tim: impl Unborrow<Target = T> + 'd,
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
freq: F, freq: F,
) -> Self { ) -> Self {
unborrow!(ch1); Self::new_inner(tim, freq, move || {
Self::new_inner(tim, freq, move || unsafe { config_pins!(ch1);
ch1.configure();
}) })
} }
@ -29,10 +44,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
freq: F, freq: F,
) -> Self { ) -> Self {
unborrow!(ch1, ch2); Self::new_inner(tim, freq, move || {
Self::new_inner(tim, freq, move || unsafe { config_pins!(ch1, ch2);
ch1.configure();
ch2.configure();
}) })
} }
@ -43,11 +56,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
freq: F, freq: F,
) -> Self { ) -> Self {
unborrow!(ch1, ch2, ch3); Self::new_inner(tim, freq, move || {
Self::new_inner(tim, freq, move || unsafe { config_pins!(ch1, ch2, ch3);
ch1.configure();
ch2.configure();
ch3.configure();
}) })
} }
@ -59,12 +69,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd, ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd,
freq: F, freq: F,
) -> Self { ) -> Self {
unborrow!(ch1, ch2, ch3, ch4); Self::new_inner(tim, freq, move || {
Self::new_inner(tim, freq, move || unsafe { config_pins!(ch1, ch2, ch3, ch4);
ch1.configure();
ch2.configure();
ch3.configure();
ch4.configure();
}) })
} }

View File

@ -4,8 +4,8 @@ use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use stm32_metapac::rcc::vals::{Mco1, Mco2}; use stm32_metapac::rcc::vals::{Mco1, Mco2};
use crate::gpio::sealed::Pin as __GpioPin; use crate::gpio::sealed::AFType;
use crate::gpio::Pin; use crate::gpio::Speed;
use crate::pac::rcc::vals::Timpre; use crate::pac::rcc::vals::Timpre;
use crate::pac::rcc::vals::{Ckpersel, Dppre, Hpre, Hsebyp, Hsidiv, Pllsrc, Sw}; use crate::pac::rcc::vals::{Ckpersel, Dppre, Hpre, Hsebyp, Hsidiv, Pllsrc, Sw};
use crate::pac::{PWR, RCC, SYSCFG}; use crate::pac::{PWR, RCC, SYSCFG};
@ -318,21 +318,15 @@ impl McoSource for Mco2Source {
} }
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*;
pub trait McoInstance { pub trait McoInstance {
type Source; type Source;
unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8); unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8);
} }
pub trait McoPin<T: McoInstance>: Pin {
fn configure(&mut self);
}
} }
pub trait McoInstance: sealed::McoInstance + 'static {} pub trait McoInstance: sealed::McoInstance + 'static {}
pub trait McoPin<T: McoInstance>: sealed::McoPin<T> + 'static {} pin_trait!(McoPin, McoInstance);
macro_rules! impl_peri { macro_rules! impl_peri {
($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
@ -354,32 +348,12 @@ macro_rules! impl_peri {
impl_peri!(MCO1, Mco1, set_mco1, set_mco1pre); impl_peri!(MCO1, Mco1, set_mco1, set_mco1pre);
impl_peri!(MCO2, Mco2, set_mco2, set_mco2pre); impl_peri!(MCO2, Mco2, set_mco2, set_mco2pre);
macro_rules! impl_pin {
($peri:ident, $pin:ident, $af:expr) => {
impl McoPin<peripherals::$peri> for peripherals::$pin {}
impl sealed::McoPin<peripherals::$peri> for peripherals::$pin {
fn configure(&mut self) {
critical_section::with(|_| unsafe {
self.set_as_af($af, crate::gpio::sealed::AFType::OutputPushPull);
self.block().ospeedr().modify(|w| {
w.set_ospeedr(
self.pin() as usize,
crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED,
)
});
})
}
}
};
}
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, rcc, RCC, $pin:ident, MCO_1, $af:expr) => { ($inst:ident, rcc, RCC, $pin:ident, MCO_1, $af:expr) => {
impl_pin!(MCO1, $pin, $af); pin_trait_impl!(McoPin, MCO1, $pin, $af);
}; };
($inst:ident, rcc, RCC, $pin:ident, MCO_2, $af:expr) => { ($inst:ident, rcc, RCC, $pin:ident, MCO_2, $af:expr) => {
impl_pin!(MCO2, $pin, $af); pin_trait_impl!(McoPin, MCO2, $pin, $af);
}; };
); );
@ -396,11 +370,11 @@ impl<'d, T: McoInstance> Mco<'d, T> {
) -> Self { ) -> Self {
unborrow!(pin); unborrow!(pin);
unsafe { critical_section::with(|_| unsafe {
T::apply_clock_settings(source.into_raw(), prescaler.into_raw()); T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
} pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
pin.set_speed(Speed::VeryHigh);
pin.configure(); });
Self { Self {
phantom: PhantomData, phantom: PhantomData,

View File

@ -1140,7 +1140,6 @@ impl Cmd {
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*; use super::*;
use crate::gpio::Pin as GpioPin;
pub trait Instance { pub trait Instance {
type Interrupt: Interrupt; type Interrupt: Interrupt;
@ -1148,51 +1147,21 @@ pub(crate) mod sealed {
fn inner() -> SdmmcInner; fn inner() -> SdmmcInner;
fn state() -> &'static AtomicWaker; fn state() -> &'static AtomicWaker;
} }
pub trait CkPin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait CmdPin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D0Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D1Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D2Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D3Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D4Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D5Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D6Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait D7Pin<T: Instance>: GpioPin {
const AF_NUM: u8;
}
pub trait Pins<T: Instance> {} pub trait Pins<T: Instance> {}
} }
pub trait Instance: sealed::Instance + 'static {} pub trait Instance: sealed::Instance + 'static {}
pub trait CkPin<T: Instance>: sealed::CkPin<T> + 'static {} pin_trait!(CkPin, Instance);
pub trait CmdPin<T: Instance>: sealed::CmdPin<T> + 'static {} pin_trait!(CmdPin, Instance);
pub trait D0Pin<T: Instance>: sealed::D0Pin<T> + 'static {} pin_trait!(D0Pin, Instance);
pub trait D1Pin<T: Instance>: sealed::D1Pin<T> + 'static {} pin_trait!(D1Pin, Instance);
pub trait D2Pin<T: Instance>: sealed::D2Pin<T> + 'static {} pin_trait!(D2Pin, Instance);
pub trait D3Pin<T: Instance>: sealed::D3Pin<T> + 'static {} pin_trait!(D3Pin, Instance);
pub trait D4Pin<T: Instance>: sealed::D4Pin<T> + 'static {} pin_trait!(D4Pin, Instance);
pub trait D5Pin<T: Instance>: sealed::D5Pin<T> + 'static {} pin_trait!(D5Pin, Instance);
pub trait D6Pin<T: Instance>: sealed::D6Pin<T> + 'static {} pin_trait!(D6Pin, Instance);
pub trait D7Pin<T: Instance>: sealed::D7Pin<T> + 'static {} pin_trait!(D7Pin, Instance);
pub trait Pins<T: Instance>: sealed::Pins<T> + 'static { pub trait Pins<T: Instance>: sealed::Pins<T> + 'static {
const BUSWIDTH: BusWidth; const BUSWIDTH: BusWidth;
@ -1258,37 +1227,37 @@ where
// clk // clk
let block = clk_pin.block(); let block = clk_pin.block();
let n = clk_pin.pin() as usize; let n = clk_pin.pin() as usize;
let afr_num = CLK::AF_NUM; let afr_num = clk_pin.af_num();
configure_pin(block, n, afr_num, false); configure_pin(block, n, afr_num, false);
// cmd // cmd
let block = cmd_pin.block(); let block = cmd_pin.block();
let n = cmd_pin.pin() as usize; let n = cmd_pin.pin() as usize;
let afr_num = CMD::AF_NUM; let afr_num = cmd_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
// d0 // d0
let block = d0_pin.block(); let block = d0_pin.block();
let n = d0_pin.pin() as usize; let n = d0_pin.pin() as usize;
let afr_num = D0::AF_NUM; let afr_num = d0_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
// d1 // d1
let block = d1_pin.block(); let block = d1_pin.block();
let n = d1_pin.pin() as usize; let n = d1_pin.pin() as usize;
let afr_num = D1::AF_NUM; let afr_num = d1_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
// d2 // d2
let block = d2_pin.block(); let block = d2_pin.block();
let n = d2_pin.pin() as usize; let n = d2_pin.pin() as usize;
let afr_num = D2::AF_NUM; let afr_num = d2_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
// d3 // d3
let block = d3_pin.block(); let block = d3_pin.block();
let n = d3_pin.pin() as usize; let n = d3_pin.pin() as usize;
let afr_num = D3::AF_NUM; let afr_num = d3_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
}); });
} }
@ -1404,19 +1373,19 @@ where
// clk // clk
let block = clk_pin.block(); let block = clk_pin.block();
let n = clk_pin.pin() as usize; let n = clk_pin.pin() as usize;
let afr_num = CLK::AF_NUM; let afr_num = clk_pin.af_num();
configure_pin(block, n, afr_num, false); configure_pin(block, n, afr_num, false);
// cmd // cmd
let block = cmd_pin.block(); let block = cmd_pin.block();
let n = cmd_pin.pin() as usize; let n = cmd_pin.pin() as usize;
let afr_num = CMD::AF_NUM; let afr_num = cmd_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
// d0 // d0
let block = d0_pin.block(); let block = d0_pin.block();
let n = d0_pin.pin() as usize; let n = d0_pin.pin() as usize;
let afr_num = D0::AF_NUM; let afr_num = d0_pin.af_num();
configure_pin(block, n, afr_num, true); configure_pin(block, n, afr_num, true);
}); });
} }
@ -1491,49 +1460,39 @@ crate::pac::peripherals!(
}; };
); );
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
const AF_NUM: u8 = $af;
}
impl $signal<peripherals::$inst> for peripherals::$pin {}
};
}
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, sdmmc, SDMMC, $pin:ident, CK, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, CK, $af:expr) => {
impl_pin!($inst, $pin, CkPin, $af); pin_trait_impl!(CkPin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, CMD, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, CMD, $af:expr) => {
impl_pin!($inst, $pin, CmdPin, $af); pin_trait_impl!(CmdPin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D0, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D0, $af:expr) => {
impl_pin!($inst, $pin, D0Pin, $af); pin_trait_impl!(D0Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D1, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D1, $af:expr) => {
impl_pin!($inst, $pin, D1Pin, $af); pin_trait_impl!(D1Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D2, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D2, $af:expr) => {
impl_pin!($inst, $pin, D2Pin, $af); pin_trait_impl!(D2Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D3, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D3, $af:expr) => {
impl_pin!($inst, $pin, D3Pin, $af); pin_trait_impl!(D3Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D4, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D4, $af:expr) => {
impl_pin!($inst, $pin, D4Pin, $af); pin_trait_impl!(D4Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D5, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D5, $af:expr) => {
impl_pin!($inst, $pin, D5Pin, $af); pin_trait_impl!(D5Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => {
impl_pin!($inst, $pin, D6Pin, $af); pin_trait_impl!(D6Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => {
impl_pin!($inst, $pin, D7Pin, $af); pin_trait_impl!(D7Pin, $inst, $pin, $af);
}; };
($inst:ident, sdmmc, SDMMC, $pin:ident, D8, $af:expr) => { ($inst:ident, sdmmc, SDMMC, $pin:ident, D8, $af:expr) => {
impl_pin!($inst, $pin, D8Pin, $af); pin_trait_impl!(D8Pin, $inst, $pin, $af);
}; };
); );

View File

@ -6,10 +6,9 @@ use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use self::sealed::WordSize; use self::sealed::WordSize;
use crate::dma;
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::sealed::{AFType, Pin as _};
use crate::gpio::{AnyPin, Pin}; use crate::gpio::AnyPin;
use crate::pac::spi::{regs, vals}; use crate::pac::spi::{regs, vals};
use crate::peripherals; use crate::peripherals;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
@ -416,23 +415,23 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub async fn write(&mut self, data: &[u8]) -> Result<(), Error> pub async fn write(&mut self, data: &[u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
{ {
self.write_dma_u8(data).await self.write_dma_u8(data).await
} }
pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
self.read_dma_u8(data).await self.read_dma_u8(data).await
} }
pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
self.transfer_dma_u8(read, write).await self.transfer_dma_u8(read, write).await
} }
@ -682,9 +681,7 @@ mod eh1 {
} }
} }
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8> impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::Write<u8> for Spi<'d, T, Tx, Rx> {
for Spi<'d, T, Tx, Rx>
{
type WriteFuture<'a> type WriteFuture<'a>
where where
Self: 'a, Self: 'a,
@ -712,8 +709,8 @@ mod eh1 {
} }
} }
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::Read<u8>
embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx> for Spi<'d, T, Tx, Rx>
{ {
type ReadFuture<'a> type ReadFuture<'a>
where where
@ -742,8 +739,8 @@ mod eh1 {
} }
} }
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::ReadWrite<u8>
embedded_hal_async::spi::ReadWrite<u8> for Spi<'d, T, Tx, Rx> for Spi<'d, T, Tx, Rx>
{ {
type TransferFuture<'a> type TransferFuture<'a>
where where
@ -800,26 +797,6 @@ pub(crate) mod sealed {
fn regs() -> &'static crate::pac::spi::Spi; fn regs() -> &'static crate::pac::spi::Spi;
} }
pub trait SckPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait MosiPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait MisoPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait TxDmaChannel<T: Instance> {
fn request(&self) -> dma::Request;
}
pub trait RxDmaChannel<T: Instance> {
fn request(&self) -> dma::Request;
}
pub trait Word: Copy + 'static { pub trait Word: Copy + 'static {
const WORDSIZE: WordSize; const WORDSIZE: WordSize;
} }
@ -886,11 +863,11 @@ impl Word for u8 {}
impl Word for u16 {} impl Word for u16 {}
pub trait Instance: sealed::Instance + RccPeripheral {} pub trait Instance: sealed::Instance + RccPeripheral {}
pub trait SckPin<T: Instance>: sealed::SckPin<T> {} pin_trait!(SckPin, Instance);
pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {} pin_trait!(MosiPin, Instance);
pub trait MisoPin<T: Instance>: sealed::MisoPin<T> {} pin_trait!(MisoPin, Instance);
pub trait TxDmaChannel<T: Instance>: sealed::TxDmaChannel<T> + dma::Channel {} dma_trait!(RxDma, Instance);
pub trait RxDmaChannel<T: Instance>: sealed::RxDmaChannel<T> + dma::Channel {} dma_trait!(TxDma, Instance);
crate::pac::peripherals!( crate::pac::peripherals!(
(spi, $inst:ident) => { (spi, $inst:ident) => {
@ -904,80 +881,37 @@ crate::pac::peripherals!(
}; };
); );
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl $signal<peripherals::$inst> for peripherals::$pin {}
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
};
}
#[cfg(not(rcc_f1))] #[cfg(not(rcc_f1))]
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => { ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
impl_pin!($inst, $pin, SckPin, $af); pin_trait_impl!(SckPin, $inst, $pin, $af);
}; };
($inst:ident, spi, SPI, $pin:ident, MOSI, $af:expr) => { ($inst:ident, spi, SPI, $pin:ident, MOSI, $af:expr) => {
impl_pin!($inst, $pin, MosiPin, $af); pin_trait_impl!(MosiPin, $inst, $pin, $af);
}; };
($inst:ident, spi, SPI, $pin:ident, MISO, $af:expr) => { ($inst:ident, spi, SPI, $pin:ident, MISO, $af:expr) => {
impl_pin!($inst, $pin, MisoPin, $af); pin_trait_impl!(MisoPin, $inst, $pin, $af);
}; };
); );
#[cfg(rcc_f1)] #[cfg(rcc_f1)]
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
($inst:ident, spi, SPI, $pin:ident, SCK) => { ($inst:ident, spi, SPI, $pin:ident, SCK) => {
impl_pin!($inst, $pin, SckPin, 0); pin_trait_impl!(SckPin, $inst, $pin, 0);
}; };
($inst:ident, spi, SPI, $pin:ident, MOSI) => { ($inst:ident, spi, SPI, $pin:ident, MOSI) => {
impl_pin!($inst, $pin, MosiPin, 0); pin_trait_impl!(MosiPin, $inst, $pin, 0);
}; };
($inst:ident, spi, SPI, $pin:ident, MISO) => { ($inst:ident, spi, SPI, $pin:ident, MISO) => {
impl_pin!($inst, $pin, MisoPin, 0); pin_trait_impl!(MisoPin, $inst, $pin, 0);
}; };
); );
macro_rules! impl_dma {
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
impl<T> sealed::$signal<peripherals::$inst> for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
fn request(&self) -> dma::Request {
$request
}
}
impl<T> $signal<peripherals::$inst> for T where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
{
}
};
($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
fn request(&self) -> dma::Request {
$request
}
}
impl $signal<peripherals::$inst> for peripherals::$channel {}
};
}
crate::pac::peripheral_dma_channels! { crate::pac::peripheral_dma_channels! {
($peri:ident, spi, $kind:ident, RX, $channel:tt, $request:expr) => { ($peri:ident, spi, $kind:ident, RX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, RxDmaChannel, $request); dma_trait_impl!(RxDma, $peri, $channel, $request);
}; };
($peri:ident, spi, $kind:ident, TX, $channel:tt, $request:expr) => { ($peri:ident, spi, $kind:ident, TX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, TxDmaChannel, $request); dma_trait_impl!(TxDma, $peri, $channel, $request);
}; };
} }

View File

@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
{ {
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -40,8 +40,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -93,8 +93,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
write: *const [u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
let (_, rx_len) = slice_ptr_parts(read); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write); let (_, tx_len) = slice_ptr_parts(write);

View File

@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
{ {
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -45,8 +45,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
unsafe { unsafe {
T::regs().cr1().modify(|w| { T::regs().cr1().modify(|w| {
@ -98,8 +98,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
write: *const [u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
let (_, rx_len) = slice_ptr_parts(read); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write); let (_, tx_len) = slice_ptr_parts(write);

View File

@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
{ {
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
unsafe { unsafe {
@ -48,8 +48,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
self.set_word_size(WordSize::EightBit); self.set_word_size(WordSize::EightBit);
unsafe { unsafe {
@ -104,8 +104,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
write: *const [u8], write: *const [u8],
) -> Result<(), Error> ) -> Result<(), Error>
where where
Tx: TxDmaChannel<T>, Tx: TxDma<T>,
Rx: RxDmaChannel<T>, Rx: RxDma<T>,
{ {
let (_, rx_len) = slice_ptr_parts(read); let (_, rx_len) = slice_ptr_parts(read);
let (_, tx_len) = slice_ptr_parts(write); let (_, tx_len) = slice_ptr_parts(write);

View File

@ -0,0 +1,53 @@
#![macro_use]
macro_rules! pin_trait {
($signal:ident, $instance:path) => {
pub trait $signal<T: $instance>: crate::gpio::Pin {
fn af_num(&self) -> u8;
}
};
}
macro_rules! pin_trait_impl {
($signal:ident, $instance:ident, $pin:ident, $af:expr) => {
impl $signal<crate::peripherals::$instance> for crate::peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
};
}
// ====================
macro_rules! dma_trait {
($signal:ident, $instance:path) => {
pub trait $signal<T: $instance>: crate::dma::Channel {
fn request(&self) -> crate::dma::Request;
}
};
}
#[allow(unused)]
macro_rules! dma_trait_impl {
// DMAMUX
($signal:ident, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
impl<T> $signal<crate::peripherals::$instance> for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
fn request(&self) -> crate::dma::Request {
$request
}
}
};
// No DMAMUX
($signal:ident, $instance:ident, {channel: $channel:ident}, $request:expr) => {
impl $signal<crate::peripherals::$instance> for crate::peripherals::$channel {
fn request(&self) -> crate::dma::Request {
$request
}
}
};
}

View File

@ -7,10 +7,9 @@ use embassy_hal_common::unborrow;
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
use crate::gpio::Pin;
use crate::pac::usart::{regs, vals}; use crate::pac::usart::{regs, vals};
use crate::peripherals;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{dma, peripherals};
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum DataBits { pub enum DataBits {
@ -601,46 +600,23 @@ unsafe fn clear_interrupt_flag(r: crate::pac::usart::Usart, flag: InterruptFlag)
} }
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*;
pub trait Instance { pub trait Instance {
fn regs(&self) -> crate::pac::usart::Usart; fn regs(&self) -> crate::pac::usart::Usart;
} }
pub trait RxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait TxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait CtsPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait RtsPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait CkPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
}
pub trait RxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
pub trait TxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
} }
pub trait Instance: sealed::Instance + RccPeripheral { pub trait Instance: sealed::Instance + RccPeripheral {
type Interrupt: Interrupt; type Interrupt: Interrupt;
} }
pub trait RxPin<T: Instance>: sealed::RxPin<T> {}
pub trait TxPin<T: Instance>: sealed::TxPin<T> {} pin_trait!(RxPin, Instance);
pub trait CtsPin<T: Instance>: sealed::CtsPin<T> {} pin_trait!(TxPin, Instance);
pub trait RtsPin<T: Instance>: sealed::RtsPin<T> {} pin_trait!(CtsPin, Instance);
pub trait CkPin<T: Instance>: sealed::CkPin<T> {} pin_trait!(RtsPin, Instance);
pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {} pin_trait!(CkPin, Instance);
pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {}
dma_trait!(TxDma, Instance);
dma_trait!(RxDma, Instance);
crate::pac::interrupts!( crate::pac::interrupts!(
($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
@ -653,57 +629,44 @@ crate::pac::interrupts!(
impl Instance for peripherals::$inst { impl Instance for peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::$irq;
} }
}; };
); );
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
impl $signal<peripherals::$inst> for peripherals::$pin {}
};
}
#[cfg(not(rcc_f1))] #[cfg(not(rcc_f1))]
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
// USART // USART
($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => { ($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => {
impl_pin!($inst, $pin, TxPin, $af); pin_trait_impl!(TxPin, $inst, $pin, $af);
}; };
($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => { ($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => {
impl_pin!($inst, $pin, RxPin, $af); pin_trait_impl!(RxPin, $inst, $pin, $af);
}; };
($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => { ($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => {
impl_pin!($inst, $pin, CtsPin, $af); pin_trait_impl!(CtsPin, $inst, $pin, $af);
}; };
($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => { ($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => {
impl_pin!($inst, $pin, RtsPin, $af); pin_trait_impl!(RtsPin, $inst, $pin, $af);
}; };
($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => { ($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => {
impl_pin!($inst, $pin, CkPin, $af); pin_trait_impl!(CkPin, $inst, $pin, $af);
}; };
// UART // UART
($inst:ident, uart, UART, $pin:ident, TX, $af:expr) => { ($inst:ident, usart, UART, $pin:ident, TX, $af:expr) => {
impl_pin!($inst, $pin, TxPin, $af); pin_trait_impl!(TxPin, $inst, $pin, $af);
}; };
($inst:ident, uart, UART, $pin:ident, RX, $af:expr) => { ($inst:ident, usart, UART, $pin:ident, RX, $af:expr) => {
impl_pin!($inst, $pin, RxPin, $af); pin_trait_impl!(RxPin, $inst, $pin, $af);
}; };
($inst:ident, uart, UART, $pin:ident, CTS, $af:expr) => { ($inst:ident, usart, UART, $pin:ident, CTS, $af:expr) => {
impl_pin!($inst, $pin, CtsPin, $af); pin_trait_impl!(CtsPin, $inst, $pin, $af);
}; };
($inst:ident, uart, UART, $pin:ident, RTS, $af:expr) => { ($inst:ident, usart, UART, $pin:ident, RTS, $af:expr) => {
impl_pin!($inst, $pin, RtsPin, $af); pin_trait_impl!(RtsPin, $inst, $pin, $af);
}; };
($inst:ident, uart, UART, $pin:ident, CK, $af:expr) => { ($inst:ident, usart, UART, $pin:ident, CK, $af:expr) => {
impl_pin!($inst, $pin, CkPin, $af); pin_trait_impl!(CkPin, $inst, $pin, $af);
}; };
); );
@ -712,78 +675,50 @@ crate::pac::peripheral_pins!(
// USART // USART
($inst:ident, usart, USART, $pin:ident, TX) => { ($inst:ident, usart, USART, $pin:ident, TX) => {
impl_pin!($inst, $pin, TxPin, 0); pin_trait_impl!(TxPin, $inst, $pin, 0);
}; };
($inst:ident, usart, USART, $pin:ident, RX) => { ($inst:ident, usart, USART, $pin:ident, RX) => {
impl_pin!($inst, $pin, RxPin, 0); pin_trait_impl!(RxPin, $inst, $pin, 0);
}; };
($inst:ident, usart, USART, $pin:ident, CTS) => { ($inst:ident, usart, USART, $pin:ident, CTS) => {
impl_pin!($inst, $pin, CtsPin, 0); pin_trait_impl!(CtsPin, $inst, $pin, 0);
}; };
($inst:ident, usart, USART, $pin:ident, RTS) => { ($inst:ident, usart, USART, $pin:ident, RTS) => {
impl_pin!($inst, $pin, RtsPin, 0); pin_trait_impl!(RtsPin, $inst, $pin, 0);
}; };
($inst:ident, usart, USART, $pin:ident, CK) => { ($inst:ident, usart, USART, $pin:ident, CK) => {
impl_pin!($inst, $pin, CkPin, 0); pin_trait_impl!(CkPin, $inst, $pin, 0);
}; };
// UART // UART
($inst:ident, uart, UART, $pin:ident, TX) => { ($inst:ident, usart, UART, $pin:ident, TX) => {
impl_pin!($inst, $pin, TxPin, 0); pin_trait_impl!(TxPin, $inst, $pin, 0);
}; };
($inst:ident, uart, UART, $pin:ident, RX) => { ($inst:ident, usart, UART, $pin:ident, RX) => {
impl_pin!($inst, $pin, RxPin, 0); pin_trait_impl!(RxPin, $inst, $pin, 0);
}; };
($inst:ident, uart, UART, $pin:ident, CTS) => { ($inst:ident, usart, UART, $pin:ident, CTS) => {
impl_pin!($inst, $pin, CtsPin, 0); pin_trait_impl!(CtsPin, $inst, $pin, 0);
}; };
($inst:ident, uart, UART, $pin:ident, RTS) => { ($inst:ident, usart, UART, $pin:ident, RTS) => {
impl_pin!($inst, $pin, RtsPin, 0); pin_trait_impl!(RtsPin, $inst, $pin, 0);
}; };
($inst:ident, uart, UART, $pin:ident, CK) => { ($inst:ident, usart, UART, $pin:ident, CK) => {
impl_pin!($inst, $pin, CkPin, 0); pin_trait_impl!(CkPin, $inst, $pin, 0);
}; };
); );
#[allow(unused)]
macro_rules! impl_dma {
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
impl<T> sealed::$signal<peripherals::$inst> for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
fn request(&self) -> dma::Request {
$request
}
}
impl<T> $signal<peripherals::$inst> for T where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
{
}
};
($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
fn request(&self) -> dma::Request {
$request
}
}
impl $signal<peripherals::$inst> for peripherals::$channel {}
};
}
crate::pac::peripheral_dma_channels! { crate::pac::peripheral_dma_channels! {
($peri:ident, usart, $kind:ident, RX, $channel:tt, $request:expr) => { ($peri:ident, usart, $kind:ident, RX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, RxDma, $request); dma_trait_impl!(RxDma, $peri, $channel, $request);
}; };
($peri:ident, usart, $kind:ident, TX, $channel:tt, $request:expr) => { ($peri:ident, usart, $kind:ident, TX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, TxDma, $request); dma_trait_impl!(TxDma, $peri, $channel, $request);
}; };
($peri:ident, uart, $kind:ident, RX, $channel:tt, $request:expr) => { ($peri:ident, uart, $kind:ident, RX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, RxDma, $request); dma_trait_impl!(RxDma, $peri, $channel, $request);
}; };
($peri:ident, uart, $kind:ident, TX, $channel:tt, $request:expr) => { ($peri:ident, uart, $kind:ident, TX, $channel:tt, $request:expr) => {
impl_dma!($peri, $channel, TxDma, $request); dma_trait_impl!(TxDma, $peri, $channel, $request);
}; };
} }

View File

@ -1,16 +1,25 @@
use crate::{peripherals, rcc::RccPeripheral};
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
pub use embassy_hal_common::usb::*;
pub use synopsys_usb_otg::UsbBus;
use synopsys_usb_otg::{PhyType, UsbPeripheral}; use synopsys_usb_otg::{PhyType, UsbPeripheral};
macro_rules! config_pins { use crate::gpio::sealed::AFType;
use crate::gpio::Speed;
use crate::{peripherals, rcc::RccPeripheral};
pub use embassy_hal_common::usb::*;
pub use synopsys_usb_otg::UsbBus;
macro_rules! config_ulpi_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
unborrow!($($pin),*);
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$( $(
$pin.configure(); $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
$pin.set_speed(Speed::VeryHigh);
)* )*
})
}; };
} }
@ -27,7 +36,11 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
dm: impl Unborrow<Target = impl DmPin<T>> + 'd, dm: impl Unborrow<Target = impl DmPin<T>> + 'd,
) -> Self { ) -> Self {
unborrow!(dp, dm); unborrow!(dp, dm);
config_pins!(dp, dm);
unsafe {
dp.set_as_af(dp.af_num(), AFType::OutputPushPull);
dm.set_as_af(dm.af_num(), AFType::OutputPushPull);
}
Self { Self {
phantom: PhantomData, phantom: PhantomData,
@ -51,10 +64,10 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd, ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd,
ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd, ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd,
) -> Self { ) -> Self {
unborrow!(ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp); config_ulpi_pins!(
unborrow!(ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, ulpi_d7); ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4,
config_pins!(ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp); ulpi_d5, ulpi_d6, ulpi_d7
config_pins!(ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, ulpi_d7); );
Self { Self {
phantom: PhantomData, phantom: PhantomData,
@ -100,48 +113,27 @@ pub(crate) mod sealed {
const FIFO_DEPTH_WORDS: usize; const FIFO_DEPTH_WORDS: usize;
const ENDPOINT_COUNT: usize; const ENDPOINT_COUNT: usize;
} }
macro_rules! declare_pins {
($name:ident) => {
pub trait $name<T: Instance> {
fn configure(&mut self);
}
};
($($name:ident),*) => {
$(
declare_pins!($name);
)*
};
}
// Internal PHY pins
declare_pins!(DpPin, DmPin);
// External PHY pins
declare_pins!(UlpiClkPin, UlpiDirPin, UlpiNxtPin, UlpiStpPin);
declare_pins!(UlpiD0Pin, UlpiD1Pin, UlpiD2Pin, UlpiD3Pin);
declare_pins!(UlpiD4Pin, UlpiD5Pin, UlpiD6Pin, UlpiD7Pin);
} }
pub trait Instance: sealed::Instance + RccPeripheral {} pub trait Instance: sealed::Instance + RccPeripheral {}
macro_rules! declare_pins { // Internal PHY pins
($name:ident) => { pin_trait!(DpPin, Instance);
pub trait $name<T: Instance>: sealed::$name<T> {} pin_trait!(DmPin, Instance);
};
($($name:ident),*) => { // External PHY pins
$( pin_trait!(UlpiClkPin, Instance);
declare_pins!($name); pin_trait!(UlpiDirPin, Instance);
)* pin_trait!(UlpiNxtPin, Instance);
}; pin_trait!(UlpiStpPin, Instance);
} pin_trait!(UlpiD0Pin, Instance);
pin_trait!(UlpiD1Pin, Instance);
declare_pins!(DpPin, DmPin); pin_trait!(UlpiD2Pin, Instance);
declare_pins!(UlpiClkPin, UlpiDirPin, UlpiNxtPin, UlpiStpPin); pin_trait!(UlpiD3Pin, Instance);
declare_pins!(UlpiD0Pin, UlpiD1Pin, UlpiD2Pin, UlpiD3Pin); pin_trait!(UlpiD4Pin, Instance);
declare_pins!(UlpiD4Pin, UlpiD5Pin, UlpiD6Pin, UlpiD7Pin); pin_trait!(UlpiD5Pin, Instance);
pin_trait!(UlpiD6Pin, Instance);
pin_trait!(UlpiD7Pin, Instance);
crate::pac::peripherals!( crate::pac::peripherals!(
(otgfs, $inst:ident) => { (otgfs, $inst:ident) => {
@ -240,93 +232,58 @@ crate::pac::interrupts!(
}; };
); );
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl $signal<peripherals::$inst> for peripherals::$pin {}
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn configure(&mut self) {
use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
});
}
}
};
}
// ULPI pins have to be set to VeryHigh speed
macro_rules! impl_ulpi_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl $signal<peripherals::$inst> for peripherals::$pin {}
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn configure(&mut self) {
use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
use crate::gpio::Speed;
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.set_speed(Speed::VeryHigh);
});
}
}
};
}
crate::pac::peripheral_pins!( crate::pac::peripheral_pins!(
// FS internal phy pins // FS internal phy pins
($inst:ident, otgfs, OTG_FS, $pin:ident, DP, $af:expr) => { ($inst:ident, otgfs, OTG_FS, $pin:ident, DP, $af:expr) => {
impl_pin!($inst, $pin, DpPin, $af); pin_trait_impl!(DpPin, $inst, $pin, $af);
}; };
($inst:ident, otgfs, OTG_FS, $pin:ident, DM, $af:expr) => { ($inst:ident, otgfs, OTG_FS, $pin:ident, DM, $af:expr) => {
impl_pin!($inst, $pin, DmPin, $af); pin_trait_impl!(DmPin, $inst, $pin, $af);
}; };
// HS internal phy pins // HS internal phy pins
($inst:ident, otghs, OTG_HS, $pin:ident, DP, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, DP, $af:expr) => {
impl_pin!($inst, $pin, DpPin, $af); pin_trait_impl!(DpPin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, DM, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, DM, $af:expr) => {
impl_pin!($inst, $pin, DmPin, $af); pin_trait_impl!(DmPin, $inst, $pin, $af);
}; };
// HS external phy pins // HS external phy pins
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_CK, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_CK, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiClkPin, $af); pin_trait_impl!(UlpiClkPin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_DIR, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_DIR, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiDirPin, $af); pin_trait_impl!(UlpiDirPin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_NXT, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_NXT, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiNxtPin, $af); pin_trait_impl!(UlpiNxtPin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_STP, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_STP, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiStpPin, $af); pin_trait_impl!(UlpiStpPin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D0, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D0, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD0Pin, $af); pin_trait_impl!(UlpiD0Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D1, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D1, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD1Pin, $af); pin_trait_impl!(UlpiD1Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D2, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D2, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD2Pin, $af); pin_trait_impl!(UlpiD2Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D3, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D3, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD3Pin, $af); pin_trait_impl!(UlpiD3Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D4, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D4, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD4Pin, $af); pin_trait_impl!(UlpiD4Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D5, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D5, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD5Pin, $af); pin_trait_impl!(UlpiD5Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D6, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D6, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD6Pin, $af); pin_trait_impl!(UlpiD6Pin, $inst, $pin, $af);
}; };
($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D7, $af:expr) => { ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D7, $af:expr) => {
impl_ulpi_pin!($inst, $pin, UlpiD7Pin, $af); pin_trait_impl!(UlpiD7Pin, $inst, $pin, $af);
}; };
); );

View File

@ -4,6 +4,7 @@
#[path = "../example_common.rs"] #[path = "../example_common.rs"]
mod example_common; mod example_common;
use embassy_stm32::peripherals::ETH;
use example_common::config; use example_common::config;
use cortex_m_rt::entry; use cortex_m_rt::entry;
@ -27,7 +28,7 @@ use peripherals::RNG;
#[embassy::task] #[embassy::task]
async fn main_task( async fn main_task(
device: &'static mut Ethernet<'static, LAN8742A, 4, 4>, device: &'static mut Ethernet<'static, ETH, LAN8742A, 4, 4>,
config: &'static mut StaticConfigurator, config: &'static mut StaticConfigurator,
spawner: Spawner, spawner: Spawner,
) { ) {
@ -82,8 +83,8 @@ fn _embassy_rand(buf: &mut [u8]) {
static mut RNG_INST: Option<Rng<RNG>> = None; static mut RNG_INST: Option<Rng<RNG>> = None;
static EXECUTOR: Forever<Executor> = Forever::new(); static EXECUTOR: Forever<Executor> = Forever::new();
static STATE: Forever<State<'static, 4, 4>> = Forever::new(); static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
static ETH: Forever<Ethernet<'static, LAN8742A, 4, 4>> = Forever::new(); static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new();
static CONFIG: Forever<StaticConfigurator> = Forever::new(); static CONFIG: Forever<StaticConfigurator> = Forever::new();
static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();

View File

@ -4,6 +4,7 @@
#[path = "../example_common.rs"] #[path = "../example_common.rs"]
mod example_common; mod example_common;
use embassy_stm32::peripherals::ETH;
use example_common::config; use example_common::config;
use cortex_m_rt::entry; use cortex_m_rt::entry;
@ -26,7 +27,7 @@ use peripherals::RNG;
#[embassy::task] #[embassy::task]
async fn main_task( async fn main_task(
device: &'static mut Ethernet<'static, LAN8742A, 4, 4>, device: &'static mut Ethernet<'static, ETH, LAN8742A, 4, 4>,
config: &'static mut StaticConfigurator, config: &'static mut StaticConfigurator,
spawner: Spawner, spawner: Spawner,
) { ) {
@ -81,8 +82,8 @@ fn _embassy_rand(buf: &mut [u8]) {
static mut RNG_INST: Option<Rng<RNG>> = None; static mut RNG_INST: Option<Rng<RNG>> = None;
static EXECUTOR: Forever<Executor> = Forever::new(); static EXECUTOR: Forever<Executor> = Forever::new();
static STATE: Forever<State<'static, 4, 4>> = Forever::new(); static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
static ETH: Forever<Ethernet<'static, LAN8742A, 4, 4>> = Forever::new(); static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new();
static CONFIG: Forever<StaticConfigurator> = Forever::new(); static CONFIG: Forever<StaticConfigurator> = Forever::new();
static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();

View File

@ -10,9 +10,10 @@ use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use embassy_stm32::pwm::{pins::*, Channel, OutputCompareMode}; use embassy_stm32::gpio::low_level::AFType;
use embassy_stm32::gpio::Speed;
use embassy_stm32::pwm::*;
use embassy_stm32::time::{Hertz, U32Ext}; use embassy_stm32::time::{Hertz, U32Ext};
use embassy_stm32::timer::GeneralPurpose32bitInstance;
use embassy_stm32::{Config, Peripherals}; use embassy_stm32::{Config, Peripherals};
use example_common::*; use example_common::*;
@ -50,12 +51,12 @@ async fn main(_spawner: Spawner, p: Peripherals) {
Timer::after(Duration::from_millis(300)).await; Timer::after(Duration::from_millis(300)).await;
} }
} }
pub struct SimplePwm32<'d, T: GeneralPurpose32bitInstance> { pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
inner: T, inner: T,
} }
impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> { impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
pub fn new<F: Into<Hertz>>( pub fn new<F: Into<Hertz>>(
tim: impl Unborrow<Target = T> + 'd, tim: impl Unborrow<Target = T> + 'd,
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
@ -70,10 +71,14 @@ impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> {
<T as embassy_stm32::rcc::low_level::RccPeripheral>::reset(); <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset();
unsafe { unsafe {
ch1.configure(); ch1.set_speed(Speed::VeryHigh);
ch2.configure(); ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch3.configure(); ch2.set_speed(Speed::VeryHigh);
ch4.configure(); ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch3.set_speed(Speed::VeryHigh);
ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch4.set_speed(Speed::VeryHigh);
ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
} }
let mut this = Self { let mut this = Self {