Remove Peripheral trait, rename PeripheralRef->Peri.

This commit is contained in:
Dario Nieuwenhuis 2025-03-26 16:01:37 +01:00
parent 9edf5b7f04
commit d41eeeae79
225 changed files with 2645 additions and 3215 deletions

View File

@ -55,11 +55,11 @@ use defmt::info;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
use embassy_nrf::Peripherals; use embassy_nrf::{Peri, Peripherals};
// Declare async tasks // Declare async tasks
#[embassy_executor::task] #[embassy_executor::task]
async fn blink(pin: AnyPin) { async fn blink(pin: Peri<'static, AnyPin>) {
let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
loop { loop {
@ -77,7 +77,7 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default()); let p = embassy_nrf::init(Default::default());
// Spawned tasks run in the background, concurrently. // Spawned tasks run in the background, concurrently.
spawner.spawn(blink(p.P0_13.degrade())).unwrap(); spawner.spawn(blink(p.P0_13.into())).unwrap();
let mut button = Input::new(p.P0_11, Pull::Up); let mut button = Input::new(p.P0_11, Pull::Up);
loop { loop {

View File

@ -10,16 +10,16 @@ use embassy_rp::dma::Channel;
use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate};
use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::program::pio_asm;
use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine};
use embassy_rp::{Peripheral, PeripheralRef}; use embassy_rp::Peri;
use fixed::types::extra::U8; use fixed::types::extra::U8;
use fixed::FixedU32; use fixed::FixedU32;
/// SPI comms driven by PIO. /// SPI comms driven by PIO.
pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA> { pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA: Channel> {
cs: Output<'d>, cs: Output<'d>,
sm: StateMachine<'d, PIO, SM>, sm: StateMachine<'d, PIO, SM>,
irq: Irq<'d, PIO, 0>, irq: Irq<'d, PIO, 0>,
dma: PeripheralRef<'d, DMA>, dma: Peri<'d, DMA>,
wrap_target: u8, wrap_target: u8,
} }
@ -48,20 +48,16 @@ where
PIO: Instance, PIO: Instance,
{ {
/// Create a new instance of PioSpi. /// Create a new instance of PioSpi.
pub fn new<DIO, CLK>( pub fn new(
common: &mut Common<'d, PIO>, common: &mut Common<'d, PIO>,
mut sm: StateMachine<'d, PIO, SM>, mut sm: StateMachine<'d, PIO, SM>,
clock_divider: FixedU32<U8>, clock_divider: FixedU32<U8>,
irq: Irq<'d, PIO, 0>, irq: Irq<'d, PIO, 0>,
cs: Output<'d>, cs: Output<'d>,
dio: DIO, dio: Peri<'d, impl PioPin>,
clk: CLK, clk: Peri<'d, impl PioPin>,
dma: impl Peripheral<P = DMA> + 'd, dma: Peri<'d, DMA>,
) -> Self ) -> Self {
where
DIO: PioPin,
CLK: PioPin,
{
let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER { let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER {
let overclock_program = pio_asm!( let overclock_program = pio_asm!(
".side_set 1" ".side_set 1"
@ -146,7 +142,7 @@ where
cs, cs,
sm, sm,
irq, irq,
dma: dma.into_ref(), dma: dma,
wrap_target: loaded_program.wrap.target, wrap_target: loaded_program.wrap.target,
} }
} }

View File

@ -9,7 +9,7 @@ pub use embassy_boot::{
}; };
use embassy_nrf::nvmc::PAGE_SIZE; use embassy_nrf::nvmc::PAGE_SIZE;
use embassy_nrf::peripherals::WDT; use embassy_nrf::peripherals::WDT;
use embassy_nrf::wdt; use embassy_nrf::{wdt, Peri};
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
/// A bootloader for nRF devices. /// A bootloader for nRF devices.
@ -113,7 +113,7 @@ pub struct WatchdogFlash<FLASH> {
impl<FLASH> WatchdogFlash<FLASH> { impl<FLASH> WatchdogFlash<FLASH> {
/// Start a new watchdog with a given flash and WDT peripheral and a timeout /// Start a new watchdog with a given flash and WDT peripheral and a timeout
pub fn start(flash: FLASH, wdt: WDT, config: wdt::Config) -> Self { pub fn start(flash: FLASH, wdt: Peri<'static, WDT>, config: wdt::Config) -> Self {
let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) { let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) {
Ok(x) => x, Ok(x) => x,
Err(_) => { Err(_) => {

View File

@ -10,6 +10,7 @@ pub use embassy_boot::{
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE}; use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
use embassy_rp::peripherals::{FLASH, WATCHDOG}; use embassy_rp::peripherals::{FLASH, WATCHDOG};
use embassy_rp::watchdog::Watchdog; use embassy_rp::watchdog::Watchdog;
use embassy_rp::Peri;
use embassy_time::Duration; use embassy_time::Duration;
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
@ -68,7 +69,7 @@ pub struct WatchdogFlash<'d, const SIZE: usize> {
impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
/// Start a new watchdog with a given flash and watchdog peripheral and a timeout /// Start a new watchdog with a given flash and watchdog peripheral and a timeout
pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self { pub fn start(flash: Peri<'static, FLASH>, watchdog: Peri<'static, WATCHDOG>, timeout: Duration) -> Self {
let flash = Flash::<_, Blocking, SIZE>::new_blocking(flash); let flash = Flash::<_, Blocking, SIZE>::new_blocking(flash);
let mut watchdog = Watchdog::new(watchdog); let mut watchdog = Watchdog::new(watchdog);
watchdog.start(timeout); watchdog.start(timeout);

View File

@ -11,7 +11,7 @@ pub mod drop;
mod macros; mod macros;
mod peripheral; mod peripheral;
pub mod ratio; pub mod ratio;
pub use peripheral::{Peripheral, PeripheralRef}; pub use peripheral::{Peri, PeripheralType};
#[cfg(feature = "cortex-m")] #[cfg(feature = "cortex-m")]
pub mod interrupt; pub mod interrupt;

View File

@ -18,8 +18,8 @@ macro_rules! peripherals_definition {
/// ///
/// You must ensure that you're only using one instance of this type at a time. /// You must ensure that you're only using one instance of this type at a time.
#[inline] #[inline]
pub unsafe fn steal() -> Self { pub unsafe fn steal() -> $crate::Peri<'static, Self> {
Self{ _private: ()} $crate::Peri::new_unchecked(Self{ _private: ()})
} }
} }
@ -42,7 +42,7 @@ macro_rules! peripherals_struct {
$( $(
#[doc = concat!(stringify!($name), " peripheral")] #[doc = concat!(stringify!($name), " peripheral")]
$(#[$cfg])? $(#[$cfg])?
pub $name: peripherals::$name, pub $name: $crate::Peri<'static, peripherals::$name>,
)* )*
} }
@ -108,28 +108,26 @@ macro_rules! peripherals {
}; };
} }
/// Convenience converting into reference.
#[macro_export]
macro_rules! into_ref {
($($name:ident),*) => {
$(
let mut $name = $name.into_ref();
)*
}
}
/// Implement the peripheral trait. /// Implement the peripheral trait.
#[macro_export] #[macro_export]
macro_rules! impl_peripheral { macro_rules! impl_peripheral {
($type:ident) => { ($type:ident<$($T:ident $(: $bound:tt $(+ $others:tt )*)?),*>) => {
impl $crate::Peripheral for $type { impl<$($T: $($bound $(+$others)*)?),*> Copy for $type <$($T),*> {}
type P = $type; impl<$($T: $($bound $(+$others)*)?),*> Clone for $type <$($T),*> {
fn clone(&self) -> Self {
#[inline] *self
unsafe fn clone_unchecked(&self) -> Self::P {
#[allow(clippy::needless_update)]
$type { ..*self }
} }
} }
impl<$($T: $($bound $(+$others)*)?),*> PeripheralType for $type <$($T),*> {}
};
($type:ident) => {
impl Copy for $type {}
impl Clone for $type {
fn clone(&self) -> Self {
*self
}
}
impl $crate::PeripheralType for $type {}
}; };
} }

View File

@ -1,5 +1,5 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::{Deref, DerefMut}; use core::ops::Deref;
/// An exclusive reference to a peripheral. /// An exclusive reference to a peripheral.
/// ///
@ -9,20 +9,26 @@ use core::ops::{Deref, DerefMut};
/// - Memory efficiency: Peripheral singletons are typically either zero-sized (for concrete /// - Memory efficiency: Peripheral singletons are typically either zero-sized (for concrete
/// peripherals like `PA9` or `SPI4`) or very small (for example `AnyPin`, which is 1 byte). /// peripherals like `PA9` or `SPI4`) or very small (for example `AnyPin`, which is 1 byte).
/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized. /// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized.
/// PeripheralRef stores a copy of `T` instead, so it's the same size. /// Peripheral stores a copy of `T` instead, so it's the same size.
/// - Code size efficiency. If the user uses the same driver with both `SPI4` and `&mut SPI4`, /// - Code size efficiency. If the user uses the same driver with both `SPI4` and `&mut SPI4`,
/// the driver code would be monomorphized two times. With PeripheralRef, the driver is generic /// the driver code would be monomorphized two times. With Peri, the driver is generic
/// over a lifetime only. `SPI4` becomes `PeripheralRef<'static, SPI4>`, and `&mut SPI4` becomes /// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes
/// `PeripheralRef<'a, SPI4>`. Lifetimes don't cause monomorphization. /// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization.
pub struct PeripheralRef<'a, T> { pub struct Peri<'a, T: PeripheralType> {
inner: T, inner: T,
_lifetime: PhantomData<&'a mut T>, _lifetime: PhantomData<&'a mut T>,
} }
impl<'a, T> PeripheralRef<'a, T> { impl<'a, T: PeripheralType> Peri<'a, T> {
/// Create a new reference to a peripheral. /// Create a new owned a peripheral.
///
/// For use by HALs only.
///
/// If you're an end user you shouldn't use this, you should use `steal()`
/// on the actual peripheral types instead.
#[inline] #[inline]
pub fn new(inner: T) -> Self { #[doc(hidden)]
pub unsafe fn new_unchecked(inner: T) -> Self {
Self { Self {
inner, inner,
_lifetime: PhantomData, _lifetime: PhantomData,
@ -38,46 +44,38 @@ impl<'a, T> PeripheralRef<'a, T> {
/// create two SPI drivers on `SPI1`, because they will "fight" each other. /// create two SPI drivers on `SPI1`, because they will "fight" each other.
/// ///
/// You should strongly prefer using `reborrow()` instead. It returns a /// You should strongly prefer using `reborrow()` instead. It returns a
/// `PeripheralRef` that borrows `self`, which allows the borrow checker /// `Peri` that borrows `self`, which allows the borrow checker
/// to enforce this at compile time. /// to enforce this at compile time.
pub unsafe fn clone_unchecked(&self) -> PeripheralRef<'a, T> pub unsafe fn clone_unchecked(&self) -> Peri<'a, T> {
where Peri::new_unchecked(self.inner)
T: Peripheral<P = T>,
{
PeripheralRef::new(self.inner.clone_unchecked())
} }
/// Reborrow into a "child" PeripheralRef. /// Reborrow into a "child" Peri.
/// ///
/// `self` will stay borrowed until the child PeripheralRef is dropped. /// `self` will stay borrowed until the child Peripheral is dropped.
pub fn reborrow(&mut self) -> PeripheralRef<'_, T> pub fn reborrow(&mut self) -> Peri<'_, T> {
where // safety: we're returning the clone inside a new Peripheral that borrows
T: Peripheral<P = T>,
{
// safety: we're returning the clone inside a new PeripheralRef that borrows
// self, so user code can't use both at the same time. // self, so user code can't use both at the same time.
PeripheralRef::new(unsafe { self.inner.clone_unchecked() }) unsafe { self.clone_unchecked() }
} }
/// Map the inner peripheral using `Into`. /// Map the inner peripheral using `Into`.
/// ///
/// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an /// This converts from `Peri<'a, T>` to `Peri<'a, U>`, using an
/// `Into` impl to convert from `T` to `U`. /// `Into` impl to convert from `T` to `U`.
/// ///
/// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`. /// For example, this can be useful to.into() GPIO pins: converting from Peri<'a, PB11>` to `Peri<'a, AnyPin>`.
#[inline] #[inline]
pub fn map_into<U>(self) -> PeripheralRef<'a, U> pub fn into<U>(self) -> Peri<'a, U>
where where
T: Into<U>, T: Into<U>,
U: PeripheralType,
{ {
PeripheralRef { unsafe { Peri::new_unchecked(self.inner.into()) }
inner: self.inner.into(),
_lifetime: PhantomData,
}
} }
} }
impl<'a, T> Deref for PeripheralRef<'a, T> { impl<'a, T: PeripheralType> Deref for Peri<'a, T> {
type Target = T; type Target = T;
#[inline] #[inline]
@ -86,92 +84,5 @@ impl<'a, T> Deref for PeripheralRef<'a, T> {
} }
} }
/// Trait for any type that can be used as a peripheral of type `P`. /// Marker trait for peripheral types.
/// pub trait PeripheralType: Copy + Sized {}
/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`),
/// or borrowed peripherals (e.g. `&mut TWISPI0`).
///
/// For example, if you have a driver with a constructor like this:
///
/// ```ignore
/// impl<'d, T: Instance> Twim<'d, T> {
/// pub fn new(
/// twim: impl Peripheral<P = T> + 'd,
/// irq: impl Peripheral<P = T::Interrupt> + 'd,
/// sda: impl Peripheral<P = impl GpioPin> + 'd,
/// scl: impl Peripheral<P = impl GpioPin> + 'd,
/// config: Config,
/// ) -> Self { .. }
/// }
/// ```
///
/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`):
///
/// ```ignore
/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
/// ```
///
/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long
/// as the borrows last:
///
/// ```ignore
/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
/// ```
///
/// # Implementation details, for HAL authors
///
/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral<P = ..>` in
/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`,
/// and storing that in the driver struct.
///
/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
pub trait Peripheral: Sized {
/// Peripheral singleton type
type P;
/// Unsafely clone (duplicate) a peripheral singleton.
///
/// # Safety
///
/// This returns an owned clone of the peripheral. You must manually ensure
/// only one copy of the peripheral is in use at a time. For example, don't
/// create two SPI drivers on `SPI1`, because they will "fight" each other.
///
/// You should strongly prefer using `into_ref()` instead. It returns a
/// `PeripheralRef`, which allows the borrow checker to enforce this at compile time.
unsafe fn clone_unchecked(&self) -> Self::P;
/// Convert a value into a `PeripheralRef`.
///
/// When called on an owned `T`, yields a `PeripheralRef<'static, T>`.
/// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`.
#[inline]
fn into_ref<'a>(self) -> PeripheralRef<'a, Self::P>
where
Self: 'a,
{
PeripheralRef::new(unsafe { self.clone_unchecked() })
}
}
impl<'b, T: DerefMut> Peripheral for T
where
T::Target: Peripheral,
{
type P = <T::Target as Peripheral>::P;
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P {
T::Target::clone_unchecked(self)
}
}
impl<'b, T: Peripheral> Peripheral for PeripheralRef<'_, T> {
type P = T::P;
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P {
T::clone_unchecked(self)
}
}

View File

@ -5,7 +5,7 @@ use core::future::Future;
use core::pin::Pin as FuturePin; use core::pin::Pin as FuturePin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::pac::gpio::vals::*; use crate::pac::gpio::vals::*;
@ -74,7 +74,7 @@ pub enum Port {
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
/// mode. /// mode.
pub struct Flex<'d> { pub struct Flex<'d> {
pin: PeripheralRef<'d, AnyPin>, pin: Peri<'d, AnyPin>,
} }
impl<'d> Flex<'d> { impl<'d> Flex<'d> {
@ -83,11 +83,9 @@ impl<'d> Flex<'d> {
/// The pin remains disconnected. The initial output level is unspecified, but can be changed /// The pin remains disconnected. The initial output level is unspecified, but can be changed
/// before the pin is put into output mode. /// before the pin is put into output mode.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { pub fn new(pin: Peri<'d, impl Pin>) -> Self {
into_ref!(pin);
// Pin will be in disconnected state. // Pin will be in disconnected state.
Self { pin: pin.map_into() } Self { pin: pin.into() }
} }
/// Set the pin's pull. /// Set the pin's pull.
@ -345,7 +343,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> { impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_input(); pin.set_as_input();
pin.set_pull(pull); pin.set_pull(pull);
@ -421,7 +419,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> { impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level] configuration. /// Create GPIO output driver for a [Pin] with the provided [Level] configuration.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_output(); pin.set_as_output();
pin.set_level(initial_output); pin.set_level(initial_output);
@ -491,7 +489,7 @@ pub struct OutputOpenDrain<'d> {
impl<'d> OutputOpenDrain<'d> { impl<'d> OutputOpenDrain<'d> {
/// Create a new GPIO open drain output driver for a [Pin] with the provided [Level]. /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level].
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_level(initial_output); pin.set_level(initial_output);
pin.set_as_input_output(); pin.set_as_input_output();
@ -599,7 +597,7 @@ impl<'d> OutputOpenDrain<'d> {
/// Type-erased GPIO pin /// Type-erased GPIO pin
pub struct AnyPin { pub struct AnyPin {
pin_port: u8, pub(crate) pin_port: u8,
} }
impl AnyPin { impl AnyPin {
@ -608,8 +606,8 @@ impl AnyPin {
/// # Safety /// # Safety
/// - `pin_port` should not in use by another driver. /// - `pin_port` should not in use by another driver.
#[inline] #[inline]
pub unsafe fn steal(pin_port: u8) -> Self { pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
Self { pin_port } Peri::new_unchecked(Self { pin_port })
} }
} }
@ -625,13 +623,7 @@ impl SealedPin for AnyPin {
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
fn degrade(self) -> AnyPin {
AnyPin {
pin_port: self.pin_port(),
}
}
/// The index of this pin in PINCM (pin control management) registers. /// The index of this pin in PINCM (pin control management) registers.
#[inline] #[inline]
fn pin_cm(&self) -> u8 { fn pin_cm(&self) -> u8 {
@ -866,7 +858,9 @@ macro_rules! impl_pin {
impl From<crate::peripherals::$name> for crate::gpio::AnyPin { impl From<crate::peripherals::$name> for crate::gpio::AnyPin {
fn from(val: crate::peripherals::$name) -> Self { fn from(val: crate::peripherals::$name) -> Self {
crate::gpio::Pin::degrade(val) Self {
pin_port: crate::gpio::SealedPin::pin_port(&val),
}
} }
} }
}; };
@ -928,11 +922,11 @@ pub(crate) trait SealedPin {
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
struct InputFuture<'d> { struct InputFuture<'d> {
pin: PeripheralRef<'d, AnyPin>, pin: Peri<'d, AnyPin>,
} }
impl<'d> InputFuture<'d> { impl<'d> InputFuture<'d> {
fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { fn new(pin: Peri<'d, AnyPin>, polarity: Polarity) -> Self {
let block = pin.block(); let block = pin.block();
// Before clearing any previous edge events, we must disable events. // Before clearing any previous edge events, we must disable events.

View File

@ -50,7 +50,7 @@ pub(crate) mod _generated {
// Reexports // Reexports
pub(crate) use _generated::gpio_pincm; pub(crate) use _generated::gpio_pincm;
pub use _generated::{peripherals, Peripherals}; pub use _generated::{peripherals, Peripherals};
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_internal::Peri;
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use mspm0_metapac as pac; pub use mspm0_metapac as pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]

View File

@ -16,7 +16,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Orde
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::atomic_ring_buffer::RingBuffer; use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::Peri;
use pac::uarte::vals; use pac::uarte::vals;
// Re-export SVD variants to allow user to directly set values // Re-export SVD variants to allow user to directly set values
pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity};
@ -28,7 +28,7 @@ use crate::ppi::{
}; };
use crate::timer::{Instance as TimerInstance, Timer}; use crate::timer::{Instance as TimerInstance, Timer};
use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance};
use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; use crate::{interrupt, pac, EASY_DMA_SIZE};
pub(crate) struct State { pub(crate) struct State {
tx_buf: RingBuffer, tx_buf: RingBuffer,
@ -222,27 +222,26 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd. /// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
timer: impl Peripheral<P = T> + 'd, timer: Peri<'d, T>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, timer, rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner( Self::new_inner(
uarte, uarte,
timer, timer,
ppi_ch1.map_into(), ppi_ch1.into(),
ppi_ch2.map_into(), ppi_ch2.into(),
ppi_group.map_into(), ppi_group.into(),
rxd.map_into(), rxd.into(),
txd.map_into(), txd.into(),
None, None,
None, None,
config, config,
@ -258,31 +257,30 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd. /// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
timer: impl Peripheral<P = T> + 'd, timer: Peri<'d, T>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: Peri<'d, impl GpioPin>,
rts: impl Peripheral<P = impl GpioPin> + 'd, rts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, timer, rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner( Self::new_inner(
uarte, uarte,
timer, timer,
ppi_ch1.map_into(), ppi_ch1.into(),
ppi_ch2.map_into(), ppi_ch2.into(),
ppi_group.map_into(), ppi_group.into(),
rxd.map_into(), rxd.into(),
txd.map_into(), txd.into(),
Some(cts.map_into()), Some(cts.into()),
Some(rts.map_into()), Some(rts.into()),
config, config,
rx_buffer, rx_buffer,
tx_buffer, tx_buffer,
@ -291,15 +289,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn new_inner( fn new_inner(
peri: PeripheralRef<'d, U>, peri: Peri<'d, U>,
timer: PeripheralRef<'d, T>, timer: Peri<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>, ppi_group: Peri<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>, rxd: Peri<'d, AnyPin>,
txd: PeripheralRef<'d, AnyPin>, txd: Peri<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<Peri<'d, AnyPin>>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
@ -372,20 +370,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
/// Reader part of the buffered UARTE driver. /// Reader part of the buffered UARTE driver.
pub struct BufferedUarteTx<'d, U: UarteInstance> { pub struct BufferedUarteTx<'d, U: UarteInstance> {
_peri: PeripheralRef<'d, U>, _peri: Peri<'d, U>,
} }
impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
/// Create a new BufferedUarteTx without hardware flow control. /// Create a new BufferedUarteTx without hardware flow control.
pub fn new( pub fn new(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, txd); Self::new_inner(uarte, txd.into(), None, config, tx_buffer)
Self::new_inner(uarte, txd.map_into(), None, config, tx_buffer)
} }
/// Create a new BufferedUarte with hardware flow control (RTS/CTS) /// Create a new BufferedUarte with hardware flow control (RTS/CTS)
@ -394,21 +391,20 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
/// ///
/// Panics if `rx_buffer.len()` is odd. /// Panics if `rx_buffer.len()` is odd.
pub fn new_with_cts( pub fn new_with_cts(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, txd, cts); Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer)
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config, tx_buffer)
} }
fn new_inner( fn new_inner(
peri: PeripheralRef<'d, U>, peri: Peri<'d, U>,
txd: PeripheralRef<'d, AnyPin>, txd: Peri<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
@ -426,9 +422,9 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
} }
fn new_innerer( fn new_innerer(
peri: PeripheralRef<'d, U>, peri: Peri<'d, U>,
txd: PeripheralRef<'d, AnyPin>, txd: Peri<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<Peri<'d, AnyPin>>,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
let r = U::regs(); let r = U::regs();
@ -542,7 +538,7 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> {
/// Reader part of the buffered UARTE driver. /// Reader part of the buffered UARTE driver.
pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> {
_peri: PeripheralRef<'d, U>, _peri: Peri<'d, U>,
timer: Timer<'d, T>, timer: Timer<'d, T>,
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
_ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
@ -557,24 +553,23 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd. /// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
timer: impl Peripheral<P = T> + 'd, timer: Peri<'d, T>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, timer, rxd, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner( Self::new_inner(
uarte, uarte,
timer, timer,
ppi_ch1.map_into(), ppi_ch1.into(),
ppi_ch2.map_into(), ppi_ch2.into(),
ppi_group.map_into(), ppi_group.into(),
rxd.map_into(), rxd.into(),
None, None,
config, config,
rx_buffer, rx_buffer,
@ -588,26 +583,25 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd. /// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new_with_rts( pub fn new_with_rts(
uarte: impl Peripheral<P = U> + 'd, uarte: Peri<'d, U>,
timer: impl Peripheral<P = T> + 'd, timer: Peri<'d, T>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
rts: impl Peripheral<P = impl GpioPin> + 'd, rts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(uarte, timer, rxd, rts, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner( Self::new_inner(
uarte, uarte,
timer, timer,
ppi_ch1.map_into(), ppi_ch1.into(),
ppi_ch2.map_into(), ppi_ch2.into(),
ppi_group.map_into(), ppi_group.into(),
rxd.map_into(), rxd.into(),
Some(rts.map_into()), Some(rts.into()),
config, config,
rx_buffer, rx_buffer,
) )
@ -615,13 +609,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn new_inner( fn new_inner(
peri: PeripheralRef<'d, U>, peri: Peri<'d, U>,
timer: PeripheralRef<'d, T>, timer: Peri<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>, ppi_group: Peri<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>, rxd: Peri<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
@ -640,13 +634,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn new_innerer( fn new_innerer(
peri: PeripheralRef<'d, U>, peri: Peri<'d, U>,
timer: PeripheralRef<'d, T>, timer: Peri<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>, ppi_group: Peri<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>, rxd: Peri<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<Peri<'d, AnyPin>>,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
assert!(rx_buffer.len() % 2 == 0); assert!(rx_buffer.len() % 2 == 0);

View File

@ -7,20 +7,19 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_internal::into_ref; use embassy_hal_internal::PeripheralType;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::{interrupt, pac, Peripheral, PeripheralRef}; use crate::{interrupt, pac, Peri};
/// An instance of the EGU. /// An instance of the EGU.
pub struct Egu<'d, T: Instance> { pub struct Egu<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Egu<'d, T> { impl<'d, T: Instance> Egu<'d, T> {
/// Create a new EGU instance. /// Create a new EGU instance.
pub fn new(_p: impl Peripheral<P = T> + 'd) -> Self { pub fn new(_p: Peri<'d, T>) -> Self {
into_ref!(_p);
Self { _p } Self { _p }
} }
@ -39,7 +38,7 @@ pub(crate) trait SealedInstance {
/// Basic Egu instance. /// Basic Egu instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -5,14 +5,14 @@ use core::convert::Infallible;
use core::hint::unreachable_unchecked; use core::hint::unreachable_unchecked;
use cfg_if::cfg_if; use cfg_if::cfg_if;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use crate::pac;
use crate::pac::common::{Reg, RW}; use crate::pac::common::{Reg, RW};
use crate::pac::gpio; use crate::pac::gpio;
use crate::pac::gpio::vals; use crate::pac::gpio::vals;
#[cfg(not(feature = "_nrf51"))] #[cfg(not(feature = "_nrf51"))]
use crate::pac::shared::{regs::Psel, vals::Connect}; use crate::pac::shared::{regs::Psel, vals::Connect};
use crate::{pac, Peripheral};
/// A GPIO port with up to 32 pins. /// A GPIO port with up to 32 pins.
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
@ -49,7 +49,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> { impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_input(pull); pin.set_as_input(pull);
@ -210,7 +210,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> { impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration. /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, drive: OutputDrive) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, drive: OutputDrive) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
match initial_output { match initial_output {
Level::High => pin.set_high(), Level::High => pin.set_high(),
@ -310,7 +310,7 @@ fn convert_pull(pull: Pull) -> vals::Pull {
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
/// mode. /// mode.
pub struct Flex<'d> { pub struct Flex<'d> {
pub(crate) pin: PeripheralRef<'d, AnyPin>, pub(crate) pin: Peri<'d, AnyPin>,
} }
impl<'d> Flex<'d> { impl<'d> Flex<'d> {
@ -319,10 +319,9 @@ impl<'d> Flex<'d> {
/// The pin remains disconnected. The initial output level is unspecified, but can be changed /// The pin remains disconnected. The initial output level is unspecified, but can be changed
/// before the pin is put into output mode. /// before the pin is put into output mode.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { pub fn new(pin: Peri<'d, impl Pin>) -> Self {
into_ref!(pin);
// Pin will be in disconnected state. // Pin will be in disconnected state.
Self { pin: pin.map_into() } Self { pin: pin.into() }
} }
/// Put the pin into input mode. /// Put the pin into input mode.
@ -503,7 +502,7 @@ pub(crate) trait SealedPin {
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// Number of the pin within the port (0..31) /// Number of the pin within the port (0..31)
#[inline] #[inline]
fn pin(&self) -> u8 { fn pin(&self) -> u8 {
@ -529,19 +528,11 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static
fn psel_bits(&self) -> pac::shared::regs::Psel { fn psel_bits(&self) -> pac::shared::regs::Psel {
pac::shared::regs::Psel(self.pin_port() as u32) pac::shared::regs::Psel(self.pin_port() as u32)
} }
/// Convert from concrete pin type PX_XX to type erased `AnyPin`.
#[inline]
fn degrade(self) -> AnyPin {
AnyPin {
pin_port: self.pin_port(),
}
}
} }
/// Type-erased GPIO pin /// Type-erased GPIO pin
pub struct AnyPin { pub struct AnyPin {
pin_port: u8, pub(crate) pin_port: u8,
} }
impl AnyPin { impl AnyPin {
@ -550,8 +541,8 @@ impl AnyPin {
/// # Safety /// # Safety
/// - `pin_port` should not in use by another driver. /// - `pin_port` should not in use by another driver.
#[inline] #[inline]
pub unsafe fn steal(pin_port: u8) -> Self { pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
Self { pin_port } Peri::new_unchecked(Self { pin_port })
} }
} }
@ -573,7 +564,7 @@ pub(crate) trait PselBits {
} }
#[cfg(not(feature = "_nrf51"))] #[cfg(not(feature = "_nrf51"))]
impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { impl<'a, P: Pin> PselBits for Option<Peri<'a, P>> {
#[inline] #[inline]
fn psel_bits(&self) -> pac::shared::regs::Psel { fn psel_bits(&self) -> pac::shared::regs::Psel {
match self { match self {
@ -611,8 +602,10 @@ macro_rules! impl_pin {
} }
impl From<peripherals::$type> for crate::gpio::AnyPin { impl From<peripherals::$type> for crate::gpio::AnyPin {
fn from(val: peripherals::$type) -> Self { fn from(_val: peripherals::$type) -> Self {
crate::gpio::Pin::degrade(val) Self {
pin_port: $port_num * 32 + $pin_num,
}
} }
} }
}; };

View File

@ -4,7 +4,7 @@ use core::convert::Infallible;
use core::future::{poll_fn, Future}; use core::future::{poll_fn, Future};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _};
@ -189,7 +189,7 @@ impl Iterator for BitIter {
/// GPIOTE channel driver in input mode /// GPIOTE channel driver in input mode
pub struct InputChannel<'d> { pub struct InputChannel<'d> {
ch: PeripheralRef<'d, AnyChannel>, ch: Peri<'d, AnyChannel>,
pin: Input<'d>, pin: Input<'d>,
} }
@ -204,9 +204,7 @@ impl<'d> Drop for InputChannel<'d> {
impl<'d> InputChannel<'d> { impl<'d> InputChannel<'d> {
/// Create a new GPIOTE input channel driver. /// Create a new GPIOTE input channel driver.
pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self {
into_ref!(ch);
let g = regs(); let g = regs();
let num = ch.number(); let num = ch.number();
@ -228,7 +226,7 @@ impl<'d> InputChannel<'d> {
g.events_in(num).write_value(0); g.events_in(num).write_value(0);
InputChannel { ch: ch.map_into(), pin } InputChannel { ch: ch.into(), pin }
} }
/// Asynchronously wait for an event in this channel. /// Asynchronously wait for an event in this channel.
@ -261,7 +259,7 @@ impl<'d> InputChannel<'d> {
/// GPIOTE channel driver in output mode /// GPIOTE channel driver in output mode
pub struct OutputChannel<'d> { pub struct OutputChannel<'d> {
ch: PeripheralRef<'d, AnyChannel>, ch: Peri<'d, AnyChannel>,
_pin: Output<'d>, _pin: Output<'d>,
} }
@ -276,8 +274,7 @@ impl<'d> Drop for OutputChannel<'d> {
impl<'d> OutputChannel<'d> { impl<'d> OutputChannel<'d> {
/// Create a new GPIOTE output channel driver. /// Create a new GPIOTE output channel driver.
pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self {
into_ref!(ch);
let g = regs(); let g = regs();
let num = ch.number(); let num = ch.number();
@ -301,7 +298,7 @@ impl<'d> OutputChannel<'d> {
}); });
OutputChannel { OutputChannel {
ch: ch.map_into(), ch: ch.into(),
_pin: pin, _pin: pin,
} }
} }
@ -351,14 +348,12 @@ impl<'d> OutputChannel<'d> {
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub(crate) struct PortInputFuture<'a> { pub(crate) struct PortInputFuture<'a> {
pin: PeripheralRef<'a, AnyPin>, pin: Peri<'a, AnyPin>,
} }
impl<'a> PortInputFuture<'a> { impl<'a> PortInputFuture<'a> {
fn new(pin: impl Peripheral<P = impl GpioPin> + 'a) -> Self { fn new(pin: Peri<'a, impl GpioPin>) -> Self {
Self { Self { pin: pin.into() }
pin: pin.into_ref().map_into(),
}
} }
} }
@ -415,13 +410,13 @@ impl<'d> Flex<'d> {
/// Wait until the pin is high. If it is already high, return immediately. /// Wait until the pin is high. If it is already high, return immediately.
pub async fn wait_for_high(&mut self) { pub async fn wait_for_high(&mut self) {
self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); self.pin.conf().modify(|w| w.set_sense(Sense::HIGH));
PortInputFuture::new(&mut self.pin).await PortInputFuture::new(self.pin.reborrow()).await
} }
/// Wait until the pin is low. If it is already low, return immediately. /// Wait until the pin is low. If it is already low, return immediately.
pub async fn wait_for_low(&mut self) { pub async fn wait_for_low(&mut self) {
self.pin.conf().modify(|w| w.set_sense(Sense::LOW)); self.pin.conf().modify(|w| w.set_sense(Sense::LOW));
PortInputFuture::new(&mut self.pin).await PortInputFuture::new(self.pin.reborrow()).await
} }
/// Wait for the pin to undergo a transition from low to high. /// Wait for the pin to undergo a transition from low to high.
@ -443,7 +438,7 @@ impl<'d> Flex<'d> {
} else { } else {
self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); self.pin.conf().modify(|w| w.set_sense(Sense::HIGH));
} }
PortInputFuture::new(&mut self.pin).await PortInputFuture::new(self.pin.reborrow()).await
} }
} }
@ -455,24 +450,14 @@ trait SealedChannel {}
/// ///
/// Implemented by all GPIOTE channels. /// Implemented by all GPIOTE channels.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Channel: SealedChannel + Into<AnyChannel> + Sized + 'static { pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
/// Get the channel number. /// Get the channel number.
fn number(&self) -> usize; fn number(&self) -> usize;
/// Convert this channel to a type-erased `AnyChannel`.
///
/// This allows using several channels in situations that might require
/// them to be the same type, like putting them in an array.
fn degrade(self) -> AnyChannel {
AnyChannel {
number: self.number() as u8,
}
}
} }
/// Type-erased channel. /// Type-erased channel.
/// ///
/// Obtained by calling `Channel::degrade`. /// Obtained by calling `Channel::into()`.
/// ///
/// This allows using several channels in situations that might require /// This allows using several channels in situations that might require
/// them to be the same type, like putting them in an array. /// them to be the same type, like putting them in an array.
@ -498,7 +483,9 @@ macro_rules! impl_channel {
impl From<peripherals::$type> for AnyChannel { impl From<peripherals::$type> for AnyChannel {
fn from(val: peripherals::$type) -> Self { fn from(val: peripherals::$type) -> Self {
Channel::degrade(val) Self {
number: val.number() as u8,
}
} }
} }
}; };

View File

@ -10,14 +10,14 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::i2s::vals; use crate::pac::i2s::vals;
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; use crate::{interrupt, pac, EASY_DMA_SIZE};
/// Type alias for `MultiBuffering` with 2 buffers. /// Type alias for `MultiBuffering` with 2 buffers.
pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>;
@ -406,12 +406,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// I2S driver. /// I2S driver.
pub struct I2S<'d, T: Instance> { pub struct I2S<'d, T: Instance> {
i2s: PeripheralRef<'d, T>, i2s: Peri<'d, T>,
mck: Option<PeripheralRef<'d, AnyPin>>, mck: Option<Peri<'d, AnyPin>>,
sck: PeripheralRef<'d, AnyPin>, sck: Peri<'d, AnyPin>,
lrck: PeripheralRef<'d, AnyPin>, lrck: Peri<'d, AnyPin>,
sdin: Option<PeripheralRef<'d, AnyPin>>, sdin: Option<Peri<'d, AnyPin>>,
sdout: Option<PeripheralRef<'d, AnyPin>>, sdout: Option<Peri<'d, AnyPin>>,
master_clock: Option<MasterClock>, master_clock: Option<MasterClock>,
config: Config, config: Config,
} }
@ -419,20 +419,19 @@ pub struct I2S<'d, T: Instance> {
impl<'d, T: Instance> I2S<'d, T> { impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in master mode /// Create a new I2S in master mode
pub fn new_master( pub fn new_master(
i2s: impl Peripheral<P = T> + 'd, i2s: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
mck: impl Peripheral<P = impl GpioPin> + 'd, mck: Peri<'d, impl GpioPin>,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
lrck: impl Peripheral<P = impl GpioPin> + 'd, lrck: Peri<'d, impl GpioPin>,
master_clock: MasterClock, master_clock: MasterClock,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(i2s, mck, sck, lrck);
Self { Self {
i2s, i2s,
mck: Some(mck.map_into()), mck: Some(mck.into()),
sck: sck.map_into(), sck: sck.into(),
lrck: lrck.map_into(), lrck: lrck.into(),
sdin: None, sdin: None,
sdout: None, sdout: None,
master_clock: Some(master_clock), master_clock: Some(master_clock),
@ -442,18 +441,17 @@ impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in slave mode /// Create a new I2S in slave mode
pub fn new_slave( pub fn new_slave(
i2s: impl Peripheral<P = T> + 'd, i2s: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
lrck: impl Peripheral<P = impl GpioPin> + 'd, lrck: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(i2s, sck, lrck);
Self { Self {
i2s, i2s,
mck: None, mck: None,
sck: sck.map_into(), sck: sck.into(),
lrck: lrck.map_into(), lrck: lrck.into(),
sdin: None, sdin: None,
sdout: None, sdout: None,
master_clock: None, master_clock: None,
@ -464,10 +462,10 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S output only /// I2S output only
pub fn output<S: Sample, const NB: usize, const NS: usize>( pub fn output<S: Sample, const NB: usize, const NS: usize>(
mut self, mut self,
sdout: impl Peripheral<P = impl GpioPin> + 'd, sdout: Peri<'d, impl GpioPin>,
buffers: MultiBuffering<S, NB, NS>, buffers: MultiBuffering<S, NB, NS>,
) -> OutputStream<'d, T, S, NB, NS> { ) -> OutputStream<'d, T, S, NB, NS> {
self.sdout = Some(sdout.into_ref().map_into()); self.sdout = Some(sdout.into());
OutputStream { OutputStream {
_p: self.build(), _p: self.build(),
buffers, buffers,
@ -477,10 +475,10 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S input only /// I2S input only
pub fn input<S: Sample, const NB: usize, const NS: usize>( pub fn input<S: Sample, const NB: usize, const NS: usize>(
mut self, mut self,
sdin: impl Peripheral<P = impl GpioPin> + 'd, sdin: Peri<'d, impl GpioPin>,
buffers: MultiBuffering<S, NB, NS>, buffers: MultiBuffering<S, NB, NS>,
) -> InputStream<'d, T, S, NB, NS> { ) -> InputStream<'d, T, S, NB, NS> {
self.sdin = Some(sdin.into_ref().map_into()); self.sdin = Some(sdin.into());
InputStream { InputStream {
_p: self.build(), _p: self.build(),
buffers, buffers,
@ -490,13 +488,13 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S full duplex (input and output) /// I2S full duplex (input and output)
pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>( pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>(
mut self, mut self,
sdin: impl Peripheral<P = impl GpioPin> + 'd, sdin: Peri<'d, impl GpioPin>,
sdout: impl Peripheral<P = impl GpioPin> + 'd, sdout: Peri<'d, impl GpioPin>,
buffers_out: MultiBuffering<S, NB, NS>, buffers_out: MultiBuffering<S, NB, NS>,
buffers_in: MultiBuffering<S, NB, NS>, buffers_in: MultiBuffering<S, NB, NS>,
) -> FullDuplexStream<'d, T, S, NB, NS> { ) -> FullDuplexStream<'d, T, S, NB, NS> {
self.sdout = Some(sdout.into_ref().map_into()); self.sdout = Some(sdout.into());
self.sdin = Some(sdin.into_ref().map_into()); self.sdin = Some(sdin.into());
FullDuplexStream { FullDuplexStream {
_p: self.build(), _p: self.build(),
@ -505,7 +503,7 @@ impl<'d, T: Instance> I2S<'d, T> {
} }
} }
fn build(self) -> PeripheralRef<'d, T> { fn build(self) -> Peri<'d, T> {
self.apply_config(); self.apply_config();
self.select_pins(); self.select_pins();
self.setup_interrupt(); self.setup_interrupt();
@ -702,7 +700,7 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S output /// I2S output
pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
buffers: MultiBuffering<S, NB, NS>, buffers: MultiBuffering<S, NB, NS>,
} }
@ -756,7 +754,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream<
/// I2S input /// I2S input
pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
buffers: MultiBuffering<S, NB, NS>, buffers: MultiBuffering<S, NB, NS>,
} }
@ -811,7 +809,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<'
/// I2S full duplex stream (input & output) /// I2S full duplex stream (input & output)
pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
buffers_out: MultiBuffering<S, NB, NS>, buffers_out: MultiBuffering<S, NB, NS>,
buffers_in: MultiBuffering<S, NB, NS>, buffers_in: MultiBuffering<S, NB, NS>,
} }
@ -1148,7 +1146,7 @@ pub(crate) trait SealedInstance {
/// I2S peripheral instance. /// I2S peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -263,7 +263,7 @@ pub use chip::pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]
pub(crate) use chip::pac; pub(crate) use chip::pac;
pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_internal::{Peri, PeripheralType};
pub use crate::chip::interrupt; pub use crate::chip::interrupt;
#[cfg(feature = "rt")] #[cfg(feature = "rt")]

View File

@ -13,7 +13,6 @@ use core::future::poll_fn;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode}; pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode};
@ -22,7 +21,7 @@ use crate::pac::nfct::vals;
use crate::pac::NFCT; use crate::pac::NFCT;
use crate::peripherals::NFCT; use crate::peripherals::NFCT;
use crate::util::slice_in_ram; use crate::util::slice_in_ram;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac, Peri};
/// NFCID1 (aka UID) of different sizes. /// NFCID1 (aka UID) of different sizes.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
@ -96,7 +95,7 @@ pub enum Error {
/// NFC tag emulator driver. /// NFC tag emulator driver.
pub struct NfcT<'d> { pub struct NfcT<'d> {
_p: PeripheralRef<'d, NFCT>, _p: Peri<'d, NFCT>,
rx_buf: [u8; 256], rx_buf: [u8; 256],
tx_buf: [u8; 256], tx_buf: [u8; 256],
} }
@ -104,12 +103,10 @@ pub struct NfcT<'d> {
impl<'d> NfcT<'d> { impl<'d> NfcT<'d> {
/// Create an Nfc Tag driver /// Create an Nfc Tag driver
pub fn new( pub fn new(
_p: impl Peripheral<P = NFCT> + 'd, _p: Peri<'d, NFCT>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::NFCT, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::NFCT, InterruptHandler> + 'd,
config: &Config, config: &Config,
) -> Self { ) -> Self {
into_ref!(_p);
let r = pac::NFCT; let r = pac::NFCT;
unsafe { unsafe {

View File

@ -2,14 +2,13 @@
use core::{ptr, slice}; use core::{ptr, slice};
use embassy_hal_internal::{into_ref, PeripheralRef};
use embedded_storage::nor_flash::{ use embedded_storage::nor_flash::{
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
}; };
use crate::pac::nvmc::vals; use crate::pac::nvmc::vals;
use crate::peripherals::NVMC; use crate::peripherals::NVMC;
use crate::{pac, Peripheral}; use crate::{pac, Peri};
#[cfg(not(feature = "_nrf5340-net"))] #[cfg(not(feature = "_nrf5340-net"))]
/// Erase size of NVMC flash in bytes. /// Erase size of NVMC flash in bytes.
@ -42,13 +41,12 @@ impl NorFlashError for Error {
/// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits. /// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits.
pub struct Nvmc<'d> { pub struct Nvmc<'d> {
_p: PeripheralRef<'d, NVMC>, _p: Peri<'d, NVMC>,
} }
impl<'d> Nvmc<'d> { impl<'d> Nvmc<'d> {
/// Create Nvmc driver. /// Create Nvmc driver.
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self { pub fn new(_p: Peri<'d, NVMC>) -> Self {
into_ref!(_p);
Self { _p } Self { _p }
} }

View File

@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::I7F1; use fixed::types::I7F1;
@ -25,7 +25,7 @@ pub use crate::pac::pdm::vals::Freq as Frequency;
feature = "_nrf91", feature = "_nrf91",
))] ))]
pub use crate::pac::pdm::vals::Ratio; pub use crate::pac::pdm::vals::Ratio;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// Interrupt handler /// Interrupt handler
pub struct InterruptHandler<T: Instance> { pub struct InterruptHandler<T: Instance> {
@ -54,7 +54,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// PDM microphone interface /// PDM microphone interface
pub struct Pdm<'d, T: Instance> { pub struct Pdm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
} }
/// PDM error /// PDM error
@ -89,24 +89,16 @@ pub enum SamplerState {
impl<'d, T: Instance> Pdm<'d, T> { impl<'d, T: Instance> Pdm<'d, T> {
/// Create PDM driver /// Create PDM driver
pub fn new( pub fn new(
pdm: impl Peripheral<P = T> + 'd, pdm: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
clk: impl Peripheral<P = impl GpioPin> + 'd, clk: Peri<'d, impl GpioPin>,
din: impl Peripheral<P = impl GpioPin> + 'd, din: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(pdm, clk, din); Self::new_inner(pdm, clk.into(), din.into(), config)
Self::new_inner(pdm, clk.map_into(), din.map_into(), config)
} }
fn new_inner( fn new_inner(pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self {
pdm: PeripheralRef<'d, T>,
clk: PeripheralRef<'d, AnyPin>,
din: PeripheralRef<'d, AnyPin>,
config: Config,
) -> Self {
into_ref!(pdm);
let r = T::regs(); let r = T::regs();
// setup gpio pins // setup gpio pins
@ -452,7 +444,7 @@ pub(crate) trait SealedInstance {
/// PDM peripheral instance /// PDM peripheral instance
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral /// Interrupt for this peripheral
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -1,7 +1,5 @@
use embassy_hal_internal::into_ref;
use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
use crate::{pac, Peripheral}; use crate::{pac, Peri};
const DPPI_ENABLE_BIT: u32 = 0x8000_0000; const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
@ -12,14 +10,14 @@ pub(crate) fn regs() -> pac::dppic::Dppic {
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
/// Configure PPI channel to trigger `task` on `event`. /// Configure PPI channel to trigger `task` on `event`.
pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task: Task<'d>) -> Self { pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self {
Ppi::new_many_to_many(ch, [event], [task]) Ppi::new_many_to_many(ch, [event], [task])
} }
} }
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
/// Configure PPI channel to trigger both `task1` and `task2` on `event`. /// Configure PPI channel to trigger both `task1` and `task2` on `event`.
pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self {
Ppi::new_many_to_many(ch, [event], [task1, task2]) Ppi::new_many_to_many(ch, [event], [task1, task2])
} }
} }
@ -28,13 +26,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
Ppi<'d, C, EVENT_COUNT, TASK_COUNT> Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
{ {
/// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires. /// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires.
pub fn new_many_to_many( pub fn new_many_to_many(ch: Peri<'d, C>, events: [Event<'d>; EVENT_COUNT], tasks: [Task<'d>; TASK_COUNT]) -> Self {
ch: impl Peripheral<P = C> + 'd,
events: [Event<'d>; EVENT_COUNT],
tasks: [Task<'d>; TASK_COUNT],
) -> Self {
into_ref!(ch);
let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK); let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
for task in tasks { for task in tasks {
if unsafe { task.subscribe_reg().read_volatile() } != 0 { if unsafe { task.subscribe_reg().read_volatile() } != 0 {

View File

@ -18,10 +18,10 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ptr::NonNull; use core::ptr::NonNull;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use crate::pac::common::{Reg, RW, W}; use crate::pac::common::{Reg, RW, W};
use crate::{peripherals, Peripheral}; use crate::peripherals;
#[cfg_attr(feature = "_dppi", path = "dppi.rs")] #[cfg_attr(feature = "_dppi", path = "dppi.rs")]
#[cfg_attr(feature = "_ppi", path = "ppi.rs")] #[cfg_attr(feature = "_ppi", path = "ppi.rs")]
@ -30,7 +30,7 @@ pub(crate) use _version::*;
/// PPI channel driver. /// PPI channel driver.
pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
ch: PeripheralRef<'d, C>, ch: Peri<'d, C>,
#[cfg(feature = "_dppi")] #[cfg(feature = "_dppi")]
events: [Event<'d>; EVENT_COUNT], events: [Event<'d>; EVENT_COUNT],
#[cfg(feature = "_dppi")] #[cfg(feature = "_dppi")]
@ -39,16 +39,14 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize
/// PPI channel group driver. /// PPI channel group driver.
pub struct PpiGroup<'d, G: Group> { pub struct PpiGroup<'d, G: Group> {
g: PeripheralRef<'d, G>, g: Peri<'d, G>,
} }
impl<'d, G: Group> PpiGroup<'d, G> { impl<'d, G: Group> PpiGroup<'d, G> {
/// Create a new PPI group driver. /// Create a new PPI group driver.
/// ///
/// The group is initialized as containing no channels. /// The group is initialized as containing no channels.
pub fn new(g: impl Peripheral<P = G> + 'd) -> Self { pub fn new(g: Peri<'d, G>) -> Self {
into_ref!(g);
let r = regs(); let r = regs();
let n = g.number(); let n = g.number();
r.chg(n).write(|_| ()); r.chg(n).write(|_| ());
@ -210,34 +208,22 @@ pub(crate) trait SealedGroup {}
/// Interface for PPI channels. /// Interface for PPI channels.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Channel: SealedChannel + Peripheral<P = Self> + Sized + 'static { pub trait Channel: SealedChannel + PeripheralType + Sized + 'static {
/// Returns the number of the channel /// Returns the number of the channel
fn number(&self) -> usize; fn number(&self) -> usize;
} }
/// Interface for PPI channels that can be configured. /// Interface for PPI channels that can be configured.
pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> { pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {}
/// Convert into a type erased configurable channel.
fn degrade(self) -> AnyConfigurableChannel;
}
/// Interface for PPI channels that cannot be configured. /// Interface for PPI channels that cannot be configured.
pub trait StaticChannel: Channel + Into<AnyStaticChannel> { pub trait StaticChannel: Channel + Into<AnyStaticChannel> {}
/// Convert into a type erased static channel.
fn degrade(self) -> AnyStaticChannel;
}
/// Interface for a group of PPI channels. /// Interface for a group of PPI channels.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Group: SealedGroup + Peripheral<P = Self> + Into<AnyGroup> + Sized + 'static { pub trait Group: SealedGroup + PeripheralType + Into<AnyGroup> + Sized + 'static {
/// Returns the number of the group. /// Returns the number of the group.
fn number(&self) -> usize; fn number(&self) -> usize;
/// Convert into a type erased group.
fn degrade(self) -> AnyGroup {
AnyGroup {
number: self.number() as u8,
}
}
} }
// ====================== // ======================
@ -255,11 +241,7 @@ impl Channel for AnyStaticChannel {
self.number as usize self.number as usize
} }
} }
impl StaticChannel for AnyStaticChannel { impl StaticChannel for AnyStaticChannel {}
fn degrade(self) -> AnyStaticChannel {
self
}
}
/// The any configurable channel can represent any configurable channel at runtime. /// The any configurable channel can represent any configurable channel at runtime.
/// This can be used to have fewer generic parameters in some places. /// This can be used to have fewer generic parameters in some places.
@ -273,11 +255,7 @@ impl Channel for AnyConfigurableChannel {
self.number as usize self.number as usize
} }
} }
impl ConfigurableChannel for AnyConfigurableChannel { impl ConfigurableChannel for AnyConfigurableChannel {}
fn degrade(self) -> AnyConfigurableChannel {
self
}
}
#[cfg(not(feature = "_nrf51"))] #[cfg(not(feature = "_nrf51"))]
macro_rules! impl_ppi_channel { macro_rules! impl_ppi_channel {
@ -291,35 +269,23 @@ macro_rules! impl_ppi_channel {
}; };
($type:ident, $number:expr => static) => { ($type:ident, $number:expr => static) => {
impl_ppi_channel!($type, $number); impl_ppi_channel!($type, $number);
impl crate::ppi::StaticChannel for peripherals::$type { impl crate::ppi::StaticChannel for peripherals::$type {}
fn degrade(self) -> crate::ppi::AnyStaticChannel {
use crate::ppi::Channel;
crate::ppi::AnyStaticChannel {
number: self.number() as u8,
}
}
}
impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { impl From<peripherals::$type> for crate::ppi::AnyStaticChannel {
fn from(val: peripherals::$type) -> Self { fn from(val: peripherals::$type) -> Self {
crate::ppi::StaticChannel::degrade(val) Self {
number: crate::ppi::Channel::number(&val) as u8,
}
} }
} }
}; };
($type:ident, $number:expr => configurable) => { ($type:ident, $number:expr => configurable) => {
impl_ppi_channel!($type, $number); impl_ppi_channel!($type, $number);
impl crate::ppi::ConfigurableChannel for peripherals::$type { impl crate::ppi::ConfigurableChannel for peripherals::$type {}
fn degrade(self) -> crate::ppi::AnyConfigurableChannel {
use crate::ppi::Channel;
crate::ppi::AnyConfigurableChannel {
number: self.number() as u8,
}
}
}
impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel {
fn from(val: peripherals::$type) -> Self { fn from(val: peripherals::$type) -> Self {
crate::ppi::ConfigurableChannel::degrade(val) Self {
number: crate::ppi::Channel::number(&val) as u8,
}
} }
} }
}; };
@ -351,7 +317,9 @@ macro_rules! impl_group {
impl From<peripherals::$type> for crate::ppi::AnyGroup { impl From<peripherals::$type> for crate::ppi::AnyGroup {
fn from(val: peripherals::$type) -> Self { fn from(val: peripherals::$type) -> Self {
crate::ppi::Group::degrade(val) Self {
number: crate::ppi::Group::number(&val) as u8,
}
} }
} }
}; };

View File

@ -1,7 +1,5 @@
use embassy_hal_internal::into_ref;
use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
use crate::{pac, Peripheral}; use crate::{pac, Peri};
impl<'d> Task<'d> { impl<'d> Task<'d> {
fn reg_val(&self) -> u32 { fn reg_val(&self) -> u32 {
@ -21,9 +19,7 @@ pub(crate) fn regs() -> pac::ppi::Ppi {
#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task
impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> {
/// Configure PPI channel to trigger `task`. /// Configure PPI channel to trigger `task`.
pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self { pub fn new_zero_to_one(ch: Peri<'d, C>, task: Task) -> Self {
into_ref!(ch);
let r = regs(); let r = regs();
let n = ch.number(); let n = ch.number();
r.fork(n).tep().write_value(task.reg_val()); r.fork(n).tep().write_value(task.reg_val());
@ -34,9 +30,7 @@ impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> {
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
/// Configure PPI channel to trigger `task` on `event`. /// Configure PPI channel to trigger `task` on `event`.
pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task: Task<'d>) -> Self { pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self {
into_ref!(ch);
let r = regs(); let r = regs();
let n = ch.number(); let n = ch.number();
r.ch(n).eep().write_value(event.reg_val()); r.ch(n).eep().write_value(event.reg_val());
@ -49,9 +43,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
/// Configure PPI channel to trigger both `task1` and `task2` on `event`. /// Configure PPI channel to trigger both `task1` and `task2` on `event`.
pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self {
into_ref!(ch);
let r = regs(); let r = regs();
let n = ch.number(); let n = ch.number();
r.ch(n).eep().write_value(event.reg_val()); r.ch(n).eep().write_value(event.reg_val());

View File

@ -4,34 +4,34 @@
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED};
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::pwm::vals; use crate::pac::pwm::vals;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// SimplePwm is the traditional pwm interface you're probably used to, allowing /// SimplePwm is the traditional pwm interface you're probably used to, allowing
/// to simply set a duty cycle across up to four channels. /// to simply set a duty cycle across up to four channels.
pub struct SimplePwm<'d, T: Instance> { pub struct SimplePwm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
duty: [u16; 4], duty: [u16; 4],
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<Peri<'d, AnyPin>>,
} }
/// SequencePwm allows you to offload the updating of a sequence of duty cycles /// SequencePwm allows you to offload the updating of a sequence of duty cycles
/// to up to four channels, as well as repeat that sequence n times. /// to up to four channels, as well as repeat that sequence n times.
pub struct SequencePwm<'d, T: Instance> { pub struct SequencePwm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<Peri<'d, AnyPin>>,
} }
/// PWM error /// PWM error
@ -54,78 +54,61 @@ pub const PWM_CLK_HZ: u32 = 16_000_000;
impl<'d, T: Instance> SequencePwm<'d, T> { impl<'d, T: Instance> SequencePwm<'d, T> {
/// Create a new 1-channel PWM /// Create a new 1-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_1ch( pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> {
pwm: impl Peripheral<P = T> + 'd, Self::new_inner(pwm, Some(ch0.into()), None, None, None, config)
ch0: impl Peripheral<P = impl GpioPin> + 'd,
config: Config,
) -> Result<Self, Error> {
into_ref!(ch0);
Self::new_inner(pwm, Some(ch0.map_into()), None, None, None, config)
} }
/// Create a new 2-channel PWM /// Create a new 2-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_2ch( pub fn new_2ch(
pwm: impl Peripheral<P = T> + 'd, pwm: Peri<'d, T>,
ch0: impl Peripheral<P = impl GpioPin> + 'd, ch0: Peri<'d, impl GpioPin>,
ch1: impl Peripheral<P = impl GpioPin> + 'd, ch1: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
into_ref!(ch0, ch1); Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None, config)
Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config)
} }
/// Create a new 3-channel PWM /// Create a new 3-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_3ch( pub fn new_3ch(
pwm: impl Peripheral<P = T> + 'd, pwm: Peri<'d, T>,
ch0: impl Peripheral<P = impl GpioPin> + 'd, ch0: Peri<'d, impl GpioPin>,
ch1: impl Peripheral<P = impl GpioPin> + 'd, ch1: Peri<'d, impl GpioPin>,
ch2: impl Peripheral<P = impl GpioPin> + 'd, ch2: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
into_ref!(ch0, ch1, ch2); Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None, config)
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
None,
config,
)
} }
/// Create a new 4-channel PWM /// Create a new 4-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_4ch( pub fn new_4ch(
pwm: impl Peripheral<P = T> + 'd, pwm: Peri<'d, T>,
ch0: impl Peripheral<P = impl GpioPin> + 'd, ch0: Peri<'d, impl GpioPin>,
ch1: impl Peripheral<P = impl GpioPin> + 'd, ch1: Peri<'d, impl GpioPin>,
ch2: impl Peripheral<P = impl GpioPin> + 'd, ch2: Peri<'d, impl GpioPin>,
ch3: impl Peripheral<P = impl GpioPin> + 'd, ch3: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
into_ref!(ch0, ch1, ch2, ch3);
Self::new_inner( Self::new_inner(
pwm, pwm,
Some(ch0.map_into()), Some(ch0.into()),
Some(ch1.map_into()), Some(ch1.into()),
Some(ch2.map_into()), Some(ch2.into()),
Some(ch3.map_into()), Some(ch3.into()),
config, config,
) )
} }
fn new_inner( fn new_inner(
_pwm: impl Peripheral<P = T> + 'd, _pwm: Peri<'d, T>,
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
into_ref!(_pwm);
let r = T::regs(); let r = T::regs();
if let Some(pin) = &ch0 { if let Some(pin) = &ch0 {
@ -610,74 +593,54 @@ pub enum CounterMode {
impl<'d, T: Instance> SimplePwm<'d, T> { impl<'d, T: Instance> SimplePwm<'d, T> {
/// Create a new 1-channel PWM /// Create a new 1-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_1ch(pwm: impl Peripheral<P = T> + 'd, ch0: impl Peripheral<P = impl GpioPin> + 'd) -> Self { pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self {
unsafe { unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) }
into_ref!(ch0);
Self::new_inner(pwm, Some(ch0.map_into()), None, None, None)
}
} }
/// Create a new 2-channel PWM /// Create a new 2-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_2ch( pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self {
pwm: impl Peripheral<P = T> + 'd, Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None)
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
) -> Self {
into_ref!(ch0, ch1);
Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None)
} }
/// Create a new 3-channel PWM /// Create a new 3-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_3ch( pub fn new_3ch(
pwm: impl Peripheral<P = T> + 'd, pwm: Peri<'d, T>,
ch0: impl Peripheral<P = impl GpioPin> + 'd, ch0: Peri<'d, impl GpioPin>,
ch1: impl Peripheral<P = impl GpioPin> + 'd, ch1: Peri<'d, impl GpioPin>,
ch2: impl Peripheral<P = impl GpioPin> + 'd, ch2: Peri<'d, impl GpioPin>,
) -> Self { ) -> Self {
unsafe { unsafe { Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None) }
into_ref!(ch0, ch1, ch2);
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
None,
)
}
} }
/// Create a new 4-channel PWM /// Create a new 4-channel PWM
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
pub fn new_4ch( pub fn new_4ch(
pwm: impl Peripheral<P = T> + 'd, pwm: Peri<'d, T>,
ch0: impl Peripheral<P = impl GpioPin> + 'd, ch0: Peri<'d, impl GpioPin>,
ch1: impl Peripheral<P = impl GpioPin> + 'd, ch1: Peri<'d, impl GpioPin>,
ch2: impl Peripheral<P = impl GpioPin> + 'd, ch2: Peri<'d, impl GpioPin>,
ch3: impl Peripheral<P = impl GpioPin> + 'd, ch3: Peri<'d, impl GpioPin>,
) -> Self { ) -> Self {
unsafe { unsafe {
into_ref!(ch0, ch1, ch2, ch3);
Self::new_inner( Self::new_inner(
pwm, pwm,
Some(ch0.map_into()), Some(ch0.into()),
Some(ch1.map_into()), Some(ch1.into()),
Some(ch2.map_into()), Some(ch2.into()),
Some(ch3.map_into()), Some(ch3.into()),
) )
} }
} }
fn new_inner( fn new_inner(
_pwm: impl Peripheral<P = T> + 'd, _pwm: Peri<'d, T>,
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<Peri<'d, AnyPin>>,
) -> Self { ) -> Self {
into_ref!(_pwm);
let r = T::regs(); let r = T::regs();
for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() { for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() {
@ -896,7 +859,7 @@ pub(crate) trait SealedInstance {
/// PWM peripheral instance. /// PWM peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -6,18 +6,18 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::qdec::vals; use crate::pac::qdec::vals;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// Quadrature decoder driver. /// Quadrature decoder driver.
pub struct Qdec<'d, T: Instance> { pub struct Qdec<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
/// QDEC config /// QDEC config
@ -62,34 +62,32 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
impl<'d, T: Instance> Qdec<'d, T> { impl<'d, T: Instance> Qdec<'d, T> {
/// Create a new QDEC. /// Create a new QDEC.
pub fn new( pub fn new(
qdec: impl Peripheral<P = T> + 'd, qdec: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
a: impl Peripheral<P = impl GpioPin> + 'd, a: Peri<'d, impl GpioPin>,
b: impl Peripheral<P = impl GpioPin> + 'd, b: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(qdec, a, b); Self::new_inner(qdec, a.into(), b.into(), None, config)
Self::new_inner(qdec, a.map_into(), b.map_into(), None, config)
} }
/// Create a new QDEC, with a pin for LED output. /// Create a new QDEC, with a pin for LED output.
pub fn new_with_led( pub fn new_with_led(
qdec: impl Peripheral<P = T> + 'd, qdec: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
a: impl Peripheral<P = impl GpioPin> + 'd, a: Peri<'d, impl GpioPin>,
b: impl Peripheral<P = impl GpioPin> + 'd, b: Peri<'d, impl GpioPin>,
led: impl Peripheral<P = impl GpioPin> + 'd, led: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(qdec, a, b, led); Self::new_inner(qdec, a.into(), b.into(), Some(led.into()), config)
Self::new_inner(qdec, a.map_into(), b.map_into(), Some(led.map_into()), config)
} }
fn new_inner( fn new_inner(
p: PeripheralRef<'d, T>, p: Peri<'d, T>,
a: PeripheralRef<'d, AnyPin>, a: Peri<'d, AnyPin>,
b: PeripheralRef<'d, AnyPin>, b: Peri<'d, AnyPin>,
led: Option<PeripheralRef<'d, AnyPin>>, led: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
let r = T::regs(); let r = T::regs();
@ -272,7 +270,7 @@ pub(crate) trait SealedInstance {
/// qdec peripheral instance. /// qdec peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -8,7 +8,7 @@ use core::ptr;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
@ -19,7 +19,7 @@ use crate::pac::qspi::vals;
pub use crate::pac::qspi::vals::{ pub use crate::pac::qspi::vals::{
Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode, Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode,
}; };
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// Deep power-down config. /// Deep power-down config.
pub struct DeepPowerDownConfig { pub struct DeepPowerDownConfig {
@ -139,7 +139,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// QSPI flash driver. /// QSPI flash driver.
pub struct Qspi<'d, T: Instance> { pub struct Qspi<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
dpm_enabled: bool, dpm_enabled: bool,
capacity: u32, capacity: u32,
} }
@ -147,18 +147,16 @@ pub struct Qspi<'d, T: Instance> {
impl<'d, T: Instance> Qspi<'d, T> { impl<'d, T: Instance> Qspi<'d, T> {
/// Create a new QSPI driver. /// Create a new QSPI driver.
pub fn new( pub fn new(
qspi: impl Peripheral<P = T> + 'd, qspi: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
csn: impl Peripheral<P = impl GpioPin> + 'd, csn: Peri<'d, impl GpioPin>,
io0: impl Peripheral<P = impl GpioPin> + 'd, io0: Peri<'d, impl GpioPin>,
io1: impl Peripheral<P = impl GpioPin> + 'd, io1: Peri<'d, impl GpioPin>,
io2: impl Peripheral<P = impl GpioPin> + 'd, io2: Peri<'d, impl GpioPin>,
io3: impl Peripheral<P = impl GpioPin> + 'd, io3: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(qspi, sck, csn, io0, io1, io2, io3);
let r = T::regs(); let r = T::regs();
macro_rules! config_pin { macro_rules! config_pin {
@ -664,7 +662,7 @@ pub(crate) trait SealedInstance {
/// QSPI peripheral instance. /// QSPI peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -5,7 +5,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
pub use pac::radio::vals::Mode; pub use pac::radio::vals::Mode;
#[cfg(not(feature = "_nrf51"))] #[cfg(not(feature = "_nrf51"))]
use pac::radio::vals::Plen as PreambleLength; use pac::radio::vals::Plen as PreambleLength;
@ -15,20 +14,19 @@ use crate::pac::radio::vals;
use crate::radio::*; use crate::radio::*;
pub use crate::radio::{Error, TxPower}; pub use crate::radio::{Error, TxPower};
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::Peri;
/// Radio driver. /// Radio driver.
pub struct Radio<'d, T: Instance> { pub struct Radio<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Radio<'d, T> { impl<'d, T: Instance> Radio<'d, T> {
/// Create a new radio driver. /// Create a new radio driver.
pub fn new( pub fn new(
radio: impl Peripheral<P = T> + 'd, radio: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(radio);
let r = T::regs(); let r = T::regs();
r.pcnf1().write(|w| { r.pcnf1().write(|w| {

View File

@ -4,13 +4,12 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower}; use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::{self}; use crate::interrupt::{self};
use crate::pac::radio::vals; use crate::pac::radio::vals;
use crate::Peripheral; use crate::Peri;
/// Default (IEEE compliant) Start of Frame Delimiter /// Default (IEEE compliant) Start of Frame Delimiter
pub const DEFAULT_SFD: u8 = 0xA7; pub const DEFAULT_SFD: u8 = 0xA7;
@ -33,18 +32,16 @@ pub enum Cca {
/// IEEE 802.15.4 radio driver. /// IEEE 802.15.4 radio driver.
pub struct Radio<'d, T: Instance> { pub struct Radio<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
needs_enable: bool, needs_enable: bool,
} }
impl<'d, T: Instance> Radio<'d, T> { impl<'d, T: Instance> Radio<'d, T> {
/// Create a new IEEE 802.15.4 radio driver. /// Create a new IEEE 802.15.4 radio driver.
pub fn new( pub fn new(
radio: impl Peripheral<P = T> + 'd, radio: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(radio);
let r = T::regs(); let r = T::regs();
// Disable and enable to reset peripheral // Disable and enable to reset peripheral

View File

@ -19,11 +19,12 @@ pub mod ieee802154;
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_internal::PeripheralType;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::radio::vals::State as RadioState; use pac::radio::vals::State as RadioState;
pub use pac::radio::vals::Txpower as TxPower; pub use pac::radio::vals::Txpower as TxPower;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// RADIO error. /// RADIO error.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -94,7 +95,7 @@ macro_rules! impl_radio {
/// Radio peripheral instance. /// Radio peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -10,11 +10,11 @@ use core::task::Poll;
use critical_section::{CriticalSection, Mutex}; use critical_section::{CriticalSection, Mutex};
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::WakerRegistration; use embassy_sync::waitqueue::WakerRegistration;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler<T: Instance> { pub struct InterruptHandler<T: Instance> {
@ -56,7 +56,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// ///
/// It has a non-blocking API, and a blocking api through `rand`. /// It has a non-blocking API, and a blocking api through `rand`.
pub struct Rng<'d, T: Instance> { pub struct Rng<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
} }
impl<'d, T: Instance> Rng<'d, T> { impl<'d, T: Instance> Rng<'d, T> {
@ -67,11 +67,9 @@ impl<'d, T: Instance> Rng<'d, T> {
/// ///
/// The synchronous API is safe. /// The synchronous API is safe.
pub fn new( pub fn new(
rng: impl Peripheral<P = T> + 'd, rng: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(rng);
let this = Self { _peri: rng }; let this = Self { _peri: rng };
this.stop(); this.stop();
@ -250,7 +248,7 @@ pub(crate) trait SealedInstance {
/// RNG peripheral instance. /// RNG peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -3,11 +3,12 @@
#![macro_use] #![macro_use]
use core::future::poll_fn; use core::future::poll_fn;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
pub(crate) use vals::Psel as InputChannel; pub(crate) use vals::Psel as InputChannel;
@ -15,7 +16,7 @@ use crate::interrupt::InterruptExt;
use crate::pac::saadc::vals; use crate::pac::saadc::vals;
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals};
/// SAADC error /// SAADC error
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -87,37 +88,32 @@ pub struct ChannelConfig<'d> {
/// Acquisition time in microseconds. /// Acquisition time in microseconds.
pub time: Time, pub time: Time,
/// Positive channel to sample /// Positive channel to sample
p_channel: PeripheralRef<'d, AnyInput>, p_channel: AnyInput<'d>,
/// An optional negative channel to sample /// An optional negative channel to sample
n_channel: Option<PeripheralRef<'d, AnyInput>>, n_channel: Option<AnyInput<'d>>,
} }
impl<'d> ChannelConfig<'d> { impl<'d> ChannelConfig<'d> {
/// Default configuration for single ended channel sampling. /// Default configuration for single ended channel sampling.
pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self { pub fn single_ended(input: impl Input + 'd) -> Self {
into_ref!(input);
Self { Self {
reference: Reference::INTERNAL, reference: Reference::INTERNAL,
gain: Gain::GAIN1_6, gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS, resistor: Resistor::BYPASS,
time: Time::_10US, time: Time::_10US,
p_channel: input.map_into(), p_channel: input.degrade_saadc(),
n_channel: None, n_channel: None,
} }
} }
/// Default configuration for differential channel sampling. /// Default configuration for differential channel sampling.
pub fn differential( pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self {
p_input: impl Peripheral<P = impl Input> + 'd,
n_input: impl Peripheral<P = impl Input> + 'd,
) -> Self {
into_ref!(p_input, n_input);
Self { Self {
reference: Reference::INTERNAL, reference: Reference::INTERNAL,
gain: Gain::GAIN1_6, gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS, resistor: Resistor::BYPASS,
time: Time::_10US, time: Time::_10US,
p_channel: p_input.map_into(), p_channel: p_input.degrade_saadc(),
n_channel: Some(n_input.map_into()), n_channel: Some(n_input.degrade_saadc()),
} }
} }
} }
@ -133,19 +129,17 @@ pub enum CallbackResult {
/// One-shot and continuous SAADC. /// One-shot and continuous SAADC.
pub struct Saadc<'d, const N: usize> { pub struct Saadc<'d, const N: usize> {
_p: PeripheralRef<'d, peripherals::SAADC>, _p: Peri<'d, peripherals::SAADC>,
} }
impl<'d, const N: usize> Saadc<'d, N> { impl<'d, const N: usize> Saadc<'d, N> {
/// Create a new SAADC driver. /// Create a new SAADC driver.
pub fn new( pub fn new(
saadc: impl Peripheral<P = peripherals::SAADC> + 'd, saadc: Peri<'d, peripherals::SAADC>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SAADC, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SAADC, InterruptHandler> + 'd,
config: Config, config: Config,
channel_configs: [ChannelConfig; N], channel_configs: [ChannelConfig; N],
) -> Self { ) -> Self {
into_ref!(saadc);
let r = pac::SAADC; let r = pac::SAADC;
let Config { resolution, oversample } = config; let Config { resolution, oversample } = config;
@ -284,9 +278,9 @@ impl<'d, const N: usize> Saadc<'d, N> {
pub async fn run_task_sampler<F, T: TimerInstance, const N0: usize>( pub async fn run_task_sampler<F, T: TimerInstance, const N0: usize>(
&mut self, &mut self,
timer: &mut T, timer: Peri<'_, T>,
ppi_ch1: &mut impl ConfigurableChannel, ppi_ch1: Peri<'_, impl ConfigurableChannel>,
ppi_ch2: &mut impl ConfigurableChannel, ppi_ch2: Peri<'_, impl ConfigurableChannel>,
frequency: Frequency, frequency: Frequency,
sample_counter: u32, sample_counter: u32,
bufs: &mut [[[i16; N]; N0]; 2], bufs: &mut [[[i16; N]; N0]; 2],
@ -655,14 +649,18 @@ pub(crate) trait SealedInput {
/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Input: SealedInput + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static { pub trait Input: SealedInput + Sized {
/// Convert this SAADC input to a type-erased `AnyInput`. /// Convert this SAADC input to a type-erased `AnyInput`.
/// ///
/// This allows using several inputs in situations that might require /// This allows using several inputs in situations that might require
/// them to be the same type, like putting them in an array. /// them to be the same type, like putting them in an array.
fn degrade_saadc(self) -> AnyInput { fn degrade_saadc<'a>(self) -> AnyInput<'a>
where
Self: 'a,
{
AnyInput { AnyInput {
channel: self.channel(), channel: self.channel(),
_phantom: core::marker::PhantomData,
} }
} }
} }
@ -671,23 +669,36 @@ pub trait Input: SealedInput + Into<AnyInput> + Peripheral<P = Self> + Sized + '
/// ///
/// This allows using several inputs in situations that might require /// This allows using several inputs in situations that might require
/// them to be the same type, like putting them in an array. /// them to be the same type, like putting them in an array.
pub struct AnyInput { pub struct AnyInput<'a> {
channel: InputChannel, channel: InputChannel,
_phantom: PhantomData<&'a ()>,
} }
impl_peripheral!(AnyInput); impl<'a> AnyInput<'a> {
/// Reborrow into a "child" AnyInput.
///
/// `self` will stay borrowed until the child AnyInput is dropped.
pub fn reborrow(&mut self) -> AnyInput<'_> {
// safety: we're returning the clone inside a new Peripheral that borrows
// self, so user code can't use both at the same time.
Self {
channel: self.channel,
_phantom: PhantomData,
}
}
}
impl SealedInput for AnyInput { impl SealedInput for AnyInput<'_> {
fn channel(&self) -> InputChannel { fn channel(&self) -> InputChannel {
self.channel self.channel
} }
} }
impl Input for AnyInput {} impl Input for AnyInput<'_> {}
macro_rules! impl_saadc_input { macro_rules! impl_saadc_input {
($pin:ident, $ch:ident) => { ($pin:ident, $ch:ident) => {
impl_saadc_input!(@local, crate::peripherals::$pin, $ch); impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch);
}; };
(@local, $pin:ty, $ch:ident) => { (@local, $pin:ty, $ch:ident) => {
impl crate::saadc::SealedInput for $pin { impl crate::saadc::SealedInput for $pin {
@ -696,12 +707,6 @@ macro_rules! impl_saadc_input {
} }
} }
impl crate::saadc::Input for $pin {} impl crate::saadc::Input for $pin {}
impl From<$pin> for crate::saadc::AnyInput {
fn from(val: $pin) -> Self {
crate::saadc::Input::degrade_saadc(val)
}
}
}; };
} }

View File

@ -10,7 +10,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
pub use pac::spim::vals::{Frequency, Order as BitOrder}; pub use pac::spim::vals::{Frequency, Order as BitOrder};
@ -21,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::spim::vals; use crate::pac::spim::vals;
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// SPIM error /// SPIM error
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -100,73 +100,61 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// SPIM driver. /// SPIM driver.
pub struct Spim<'d, T: Instance> { pub struct Spim<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Spim<'d, T> { impl<'d, T: Instance> Spim<'d, T> {
/// Create a new SPIM driver. /// Create a new SPIM driver.
pub fn new( pub fn new(
spim: impl Peripheral<P = T> + 'd, spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: Peri<'d, impl GpioPin>,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(sck, miso, mosi); Self::new_inner(spim, Some(sck.into()), Some(miso.into()), Some(mosi.into()), config)
Self::new_inner(
spim,
Some(sck.map_into()),
Some(miso.map_into()),
Some(mosi.map_into()),
config,
)
} }
/// Create a new SPIM driver, capable of TX only (MOSI only). /// Create a new SPIM driver, capable of TX only (MOSI only).
pub fn new_txonly( pub fn new_txonly(
spim: impl Peripheral<P = T> + 'd, spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(sck, mosi); Self::new_inner(spim, Some(sck.into()), None, Some(mosi.into()), config)
Self::new_inner(spim, Some(sck.map_into()), None, Some(mosi.map_into()), config)
} }
/// Create a new SPIM driver, capable of RX only (MISO only). /// Create a new SPIM driver, capable of RX only (MISO only).
pub fn new_rxonly( pub fn new_rxonly(
spim: impl Peripheral<P = T> + 'd, spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(sck, miso); Self::new_inner(spim, Some(sck.into()), Some(miso.into()), None, config)
Self::new_inner(spim, Some(sck.map_into()), Some(miso.map_into()), None, config)
} }
/// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin. /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin.
pub fn new_txonly_nosck( pub fn new_txonly_nosck(
spim: impl Peripheral<P = T> + 'd, spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(mosi); Self::new_inner(spim, None, None, Some(mosi.into()), config)
Self::new_inner(spim, None, None, Some(mosi.map_into()), config)
} }
fn new_inner( fn new_inner(
spim: impl Peripheral<P = T> + 'd, spim: Peri<'d, T>,
sck: Option<PeripheralRef<'d, AnyPin>>, sck: Option<Peri<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>, miso: Option<Peri<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(spim);
let r = T::regs(); let r = T::regs();
// Configure pins // Configure pins
@ -511,7 +499,7 @@ pub(crate) trait SealedInstance {
/// SPIM peripheral instance /// SPIM peripheral instance
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -7,7 +7,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
pub use pac::spis::vals::Order as BitOrder; pub use pac::spis::vals::Order as BitOrder;
@ -18,7 +18,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::spis::vals; use crate::pac::spis::vals;
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// SPIS error /// SPIS error
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -98,95 +98,75 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// SPIS driver. /// SPIS driver.
pub struct Spis<'d, T: Instance> { pub struct Spis<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Spis<'d, T> { impl<'d, T: Instance> Spis<'d, T> {
/// Create a new SPIS driver. /// Create a new SPIS driver.
pub fn new( pub fn new(
spis: impl Peripheral<P = T> + 'd, spis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: Peri<'d, impl GpioPin>,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: Peri<'d, impl GpioPin>,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(cs, sck, miso, mosi);
Self::new_inner( Self::new_inner(
spis, spis,
cs.map_into(), cs.into(),
Some(sck.map_into()), Some(sck.into()),
Some(miso.map_into()), Some(miso.into()),
Some(mosi.map_into()), Some(mosi.into()),
config, config,
) )
} }
/// Create a new SPIS driver, capable of TX only (MISO only). /// Create a new SPIS driver, capable of TX only (MISO only).
pub fn new_txonly( pub fn new_txonly(
spis: impl Peripheral<P = T> + 'd, spis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: Peri<'d, impl GpioPin>,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(cs, sck, miso); Self::new_inner(spis, cs.into(), Some(sck.into()), Some(miso.into()), None, config)
Self::new_inner(
spis,
cs.map_into(),
Some(sck.map_into()),
Some(miso.map_into()),
None,
config,
)
} }
/// Create a new SPIS driver, capable of RX only (MOSI only). /// Create a new SPIS driver, capable of RX only (MOSI only).
pub fn new_rxonly( pub fn new_rxonly(
spis: impl Peripheral<P = T> + 'd, spis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: Peri<'d, impl GpioPin>,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: Peri<'d, impl GpioPin>,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(cs, sck, mosi); Self::new_inner(spis, cs.into(), Some(sck.into()), None, Some(mosi.into()), config)
Self::new_inner(
spis,
cs.map_into(),
Some(sck.map_into()),
None,
Some(mosi.map_into()),
config,
)
} }
/// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin.
pub fn new_txonly_nosck( pub fn new_txonly_nosck(
spis: impl Peripheral<P = T> + 'd, spis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: Peri<'d, impl GpioPin>,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(cs, miso); Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config)
Self::new_inner(spis, cs.map_into(), None, Some(miso.map_into()), None, config)
} }
fn new_inner( fn new_inner(
spis: impl Peripheral<P = T> + 'd, spis: Peri<'d, T>,
cs: PeripheralRef<'d, AnyPin>, cs: Peri<'d, AnyPin>,
sck: Option<PeripheralRef<'d, AnyPin>>, sck: Option<Peri<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>, miso: Option<Peri<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
into_ref!(spis, cs);
let r = T::regs(); let r = T::regs();
// Configure pins. // Configure pins.
@ -485,7 +465,7 @@ pub(crate) trait SealedInstance {
/// SPIS peripheral instance /// SPIS peripheral instance
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -4,13 +4,12 @@ use core::future::poll_fn;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::I30F2; use fixed::types::I30F2;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::peripherals::TEMP; use crate::peripherals::TEMP;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac, Peri};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler { pub struct InterruptHandler {
@ -27,7 +26,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHand
/// Builtin temperature sensor driver. /// Builtin temperature sensor driver.
pub struct Temp<'d> { pub struct Temp<'d> {
_peri: PeripheralRef<'d, TEMP>, _peri: Peri<'d, TEMP>,
} }
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
@ -35,11 +34,9 @@ static WAKER: AtomicWaker = AtomicWaker::new();
impl<'d> Temp<'d> { impl<'d> Temp<'d> {
/// Create a new temperature sensor driver. /// Create a new temperature sensor driver.
pub fn new( pub fn new(
_peri: impl Peripheral<P = TEMP> + 'd, _peri: Peri<'d, TEMP>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd,
) -> Self { ) -> Self {
into_ref!(_peri);
// Enable interrupt that signals temperature values // Enable interrupt that signals temperature values
interrupt::TEMP.unpend(); interrupt::TEMP.unpend();
unsafe { interrupt::TEMP.enable() }; unsafe { interrupt::TEMP.enable() };

View File

@ -6,11 +6,11 @@
#![macro_use] #![macro_use]
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use crate::pac;
use crate::pac::timer::vals; use crate::pac::timer::vals;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::{pac, Peripheral};
pub(crate) trait SealedInstance { pub(crate) trait SealedInstance {
/// The number of CC registers this instance has. /// The number of CC registers this instance has.
@ -20,7 +20,7 @@ pub(crate) trait SealedInstance {
/// Basic Timer instance. /// Basic Timer instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: crate::interrupt::typelevel::Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
@ -84,7 +84,7 @@ pub enum Frequency {
/// Timer driver. /// Timer driver.
pub struct Timer<'d, T: Instance> { pub struct Timer<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Timer<'d, T> { impl<'d, T: Instance> Timer<'d, T> {
@ -92,7 +92,7 @@ impl<'d, T: Instance> Timer<'d, T> {
/// ///
/// This can be useful for triggering tasks via PPI /// This can be useful for triggering tasks via PPI
/// `Uarte` uses this internally. /// `Uarte` uses this internally.
pub fn new(timer: impl Peripheral<P = T> + 'd) -> Self { pub fn new(timer: Peri<'d, T>) -> Self {
Self::new_inner(timer, false) Self::new_inner(timer, false)
} }
@ -100,13 +100,11 @@ impl<'d, T: Instance> Timer<'d, T> {
/// ///
/// This can be useful for triggering tasks via PPI /// This can be useful for triggering tasks via PPI
/// `Uarte` uses this internally. /// `Uarte` uses this internally.
pub fn new_counter(timer: impl Peripheral<P = T> + 'd) -> Self { pub fn new_counter(timer: Peri<'d, T>) -> Self {
Self::new_inner(timer, true) Self::new_inner(timer, true)
} }
fn new_inner(timer: impl Peripheral<P = T> + 'd, _is_counter: bool) -> Self { fn new_inner(timer: Peri<'d, T>, _is_counter: bool) -> Self {
into_ref!(timer);
let regs = T::regs(); let regs = T::regs();
let this = Self { _p: timer }; let this = Self { _p: timer };
@ -229,7 +227,7 @@ impl<'d, T: Instance> Timer<'d, T> {
/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register
pub struct Cc<'d, T: Instance> { pub struct Cc<'d, T: Instance> {
n: usize, n: usize,
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Cc<'d, T> { impl<'d, T: Instance> Cc<'d, T> {

View File

@ -10,7 +10,7 @@ use core::sync::atomic::Ordering::SeqCst;
use core::task::Poll; use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")] #[cfg(feature = "time")]
use embassy_time::{Duration, Instant}; use embassy_time::{Duration, Instant};
@ -23,7 +23,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::twim::vals; use crate::pac::twim::vals;
use crate::util::slice_in_ram; use crate::util::slice_in_ram;
use crate::{gpio, interrupt, pac, Peripheral}; use crate::{gpio, interrupt, pac};
/// TWIM config. /// TWIM config.
#[non_exhaustive] #[non_exhaustive]
@ -114,20 +114,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// TWI driver. /// TWI driver.
pub struct Twim<'d, T: Instance> { pub struct Twim<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Twim<'d, T> { impl<'d, T: Instance> Twim<'d, T> {
/// Create a new TWI driver. /// Create a new TWI driver.
pub fn new( pub fn new(
twim: impl Peripheral<P = T> + 'd, twim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd, sda: Peri<'d, impl GpioPin>,
scl: impl Peripheral<P = impl GpioPin> + 'd, scl: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(twim, sda, scl);
let r = T::regs(); let r = T::regs();
// Configure pins // Configure pins
@ -847,7 +845,7 @@ pub(crate) trait SealedInstance {
/// TWIM peripheral instance. /// TWIM peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -8,7 +8,7 @@ use core::sync::atomic::compiler_fence;
use core::sync::atomic::Ordering::SeqCst; use core::sync::atomic::Ordering::SeqCst;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")] #[cfg(feature = "time")]
use embassy_time::{Duration, Instant}; use embassy_time::{Duration, Instant};
@ -19,7 +19,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals; use crate::pac::gpio::vals as gpiovals;
use crate::pac::twis::vals; use crate::pac::twis::vals;
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{gpio, interrupt, pac, Peripheral}; use crate::{gpio, interrupt, pac};
/// TWIS config. /// TWIS config.
#[non_exhaustive] #[non_exhaustive]
@ -141,20 +141,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// TWIS driver. /// TWIS driver.
pub struct Twis<'d, T: Instance> { pub struct Twis<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Twis<'d, T> { impl<'d, T: Instance> Twis<'d, T> {
/// Create a new TWIS driver. /// Create a new TWIS driver.
pub fn new( pub fn new(
twis: impl Peripheral<P = T> + 'd, twis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd, sda: Peri<'d, impl GpioPin>,
scl: impl Peripheral<P = impl GpioPin> + 'd, scl: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(twis, sda, scl);
let r = T::regs(); let r = T::regs();
// Configure pins // Configure pins
@ -791,7 +789,7 @@ pub(crate) trait SealedInstance {
/// TWIS peripheral instance. /// TWIS peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -19,7 +19,7 @@ use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
// Re-export SVD variants to allow user to directly set values. // Re-export SVD variants to allow user to directly set values.
pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity};
@ -32,7 +32,7 @@ use crate::pac::uarte::vals;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
/// UARTE config. /// UARTE config.
#[derive(Clone)] #[derive(Clone)]
@ -141,56 +141,54 @@ pub struct Uarte<'d, T: Instance> {
/// ///
/// This can be obtained via [`Uarte::split`], or created directly. /// This can be obtained via [`Uarte::split`], or created directly.
pub struct UarteTx<'d, T: Instance> { pub struct UarteTx<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
/// Receiver part of the UARTE driver. /// Receiver part of the UARTE driver.
/// ///
/// This can be obtained via [`Uarte::split`], or created directly. /// This can be obtained via [`Uarte::split`], or created directly.
pub struct UarteRx<'d, T: Instance> { pub struct UarteRx<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
} }
impl<'d, T: Instance> Uarte<'d, T> { impl<'d, T: Instance> Uarte<'d, T> {
/// Create a new UARTE without hardware flow control /// Create a new UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, rxd, txd); Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config)
Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
} }
/// Create a new UARTE with hardware flow control (RTS/CTS) /// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: Peri<'d, impl GpioPin>,
rts: impl Peripheral<P = impl GpioPin> + 'd, rts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, rxd, txd, cts, rts);
Self::new_inner( Self::new_inner(
uarte, uarte,
rxd.map_into(), rxd.into(),
txd.map_into(), txd.into(),
Some(cts.map_into()), Some(cts.into()),
Some(rts.map_into()), Some(rts.into()),
config, config,
) )
} }
fn new_inner( fn new_inner(
uarte: PeripheralRef<'d, T>, uarte: Peri<'d, T>,
rxd: PeripheralRef<'d, AnyPin>, rxd: Peri<'d, AnyPin>,
txd: PeripheralRef<'d, AnyPin>, txd: Peri<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<Peri<'d, AnyPin>>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<Peri<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
let r = T::regs(); let r = T::regs();
@ -239,9 +237,9 @@ impl<'d, T: Instance> Uarte<'d, T> {
/// This is useful to concurrently transmit and receive from independent tasks. /// This is useful to concurrently transmit and receive from independent tasks.
pub fn split_with_idle<U: TimerInstance>( pub fn split_with_idle<U: TimerInstance>(
self, self,
timer: impl Peripheral<P = U> + 'd, timer: Peri<'d, U>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) { ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) {
(self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2)) (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2))
} }
@ -283,11 +281,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
} }
} }
pub(crate) fn configure_tx_pins( pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts: Option<Peri<'_, AnyPin>>) {
r: pac::uarte::Uarte,
txd: PeripheralRef<'_, AnyPin>,
cts: Option<PeripheralRef<'_, AnyPin>>,
) {
txd.set_high(); txd.set_high();
txd.conf().write(|w| { txd.conf().write(|w| {
w.set_dir(gpiovals::Dir::OUTPUT); w.set_dir(gpiovals::Dir::OUTPUT);
@ -306,11 +300,7 @@ pub(crate) fn configure_tx_pins(
r.psel().cts().write_value(cts.psel_bits()); r.psel().cts().write_value(cts.psel_bits());
} }
pub(crate) fn configure_rx_pins( pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts: Option<Peri<'_, AnyPin>>) {
r: pac::uarte::Uarte,
rxd: PeripheralRef<'_, AnyPin>,
rts: Option<PeripheralRef<'_, AnyPin>>,
) {
rxd.conf().write(|w| { rxd.conf().write(|w| {
w.set_dir(gpiovals::Dir::INPUT); w.set_dir(gpiovals::Dir::INPUT);
w.set_input(gpiovals::Input::CONNECT); w.set_input(gpiovals::Input::CONNECT);
@ -356,33 +346,26 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont
impl<'d, T: Instance> UarteTx<'d, T> { impl<'d, T: Instance> UarteTx<'d, T> {
/// Create a new tx-only UARTE without hardware flow control /// Create a new tx-only UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, txd); Self::new_inner(uarte, txd.into(), None, config)
Self::new_inner(uarte, txd.map_into(), None, config)
} }
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS) /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: Peri<'d, impl GpioPin>,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, txd, cts); Self::new_inner(uarte, txd.into(), Some(cts.into()), config)
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
} }
fn new_inner( fn new_inner(uarte: Peri<'d, T>, txd: Peri<'d, AnyPin>, cts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
uarte: PeripheralRef<'d, T>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
config: Config,
) -> Self {
let r = T::regs(); let r = T::regs();
configure(r, config, cts.is_some()); configure(r, config, cts.is_some());
@ -539,25 +522,23 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> {
impl<'d, T: Instance> UarteRx<'d, T> { impl<'d, T: Instance> UarteRx<'d, T> {
/// Create a new rx-only UARTE without hardware flow control /// Create a new rx-only UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, rxd); Self::new_inner(uarte, rxd.into(), None, config)
Self::new_inner(uarte, rxd.map_into(), None, config)
} }
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS) /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: Peri<'d, impl GpioPin>,
rts: impl Peripheral<P = impl GpioPin> + 'd, rts: Peri<'d, impl GpioPin>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(uarte, rxd, rts); Self::new_inner(uarte, rxd.into(), Some(rts.into()), config)
Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
} }
/// Check for errors and clear the error register if an error occured. /// Check for errors and clear the error register if an error occured.
@ -568,12 +549,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
ErrorSource::from_bits_truncate(err_bits.0).check() ErrorSource::from_bits_truncate(err_bits.0).check()
} }
fn new_inner( fn new_inner(uarte: Peri<'d, T>, rxd: Peri<'d, AnyPin>, rts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
uarte: PeripheralRef<'d, T>,
rxd: PeripheralRef<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>,
config: Config,
) -> Self {
let r = T::regs(); let r = T::regs();
configure(r, config, rts.is_some()); configure(r, config, rts.is_some());
@ -592,14 +568,12 @@ impl<'d, T: Instance> UarteRx<'d, T> {
/// Upgrade to an instance that supports idle line detection. /// Upgrade to an instance that supports idle line detection.
pub fn with_idle<U: TimerInstance>( pub fn with_idle<U: TimerInstance>(
self, self,
timer: impl Peripheral<P = U> + 'd, timer: Peri<'d, U>,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
) -> UarteRxWithIdle<'d, T, U> { ) -> UarteRxWithIdle<'d, T, U> {
let timer = Timer::new(timer); let timer = Timer::new(timer);
into_ref!(ppi_ch1, ppi_ch2);
let r = T::regs(); let r = T::regs();
// BAUDRATE register values are `baudrate * 2^32 / 16000000` // BAUDRATE register values are `baudrate * 2^32 / 16000000`
@ -617,7 +591,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
timer.cc(0).short_compare_stop(); timer.cc(0).short_compare_stop();
let mut ppi_ch1 = Ppi::new_one_to_two( let mut ppi_ch1 = Ppi::new_one_to_two(
ppi_ch1.map_into(), ppi_ch1.into(),
Event::from_reg(r.events_rxdrdy()), Event::from_reg(r.events_rxdrdy()),
timer.task_clear(), timer.task_clear(),
timer.task_start(), timer.task_start(),
@ -625,7 +599,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
ppi_ch1.enable(); ppi_ch1.enable();
let mut ppi_ch2 = Ppi::new_one_to_one( let mut ppi_ch2 = Ppi::new_one_to_one(
ppi_ch2.map_into(), ppi_ch2.into(),
timer.cc(0).event_compare(), timer.cc(0).event_compare(),
Task::from_reg(r.tasks_stoprx()), Task::from_reg(r.tasks_stoprx()),
); );
@ -992,7 +966,7 @@ pub(crate) trait SealedInstance {
/// UARTE peripheral instance. /// UARTE peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
use core::task::Poll; use core::task::Poll;
use cortex_m::peripheral::NVIC; use cortex_m::peripheral::NVIC;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_usb_driver as driver; use embassy_usb_driver as driver;
use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported};
@ -20,7 +20,7 @@ use self::vbus_detect::VbusDetect;
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::usbd::vals; use crate::pac::usbd::vals;
use crate::util::slice_in_ram; use crate::util::slice_in_ram;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac};
static BUS_WAKER: AtomicWaker = AtomicWaker::new(); static BUS_WAKER: AtomicWaker = AtomicWaker::new();
static EP0_WAKER: AtomicWaker = AtomicWaker::new(); static EP0_WAKER: AtomicWaker = AtomicWaker::new();
@ -87,7 +87,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// USB driver. /// USB driver.
pub struct Driver<'d, T: Instance, V: VbusDetect> { pub struct Driver<'d, T: Instance, V: VbusDetect> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
alloc_in: Allocator, alloc_in: Allocator,
alloc_out: Allocator, alloc_out: Allocator,
vbus_detect: V, vbus_detect: V,
@ -96,12 +96,10 @@ pub struct Driver<'d, T: Instance, V: VbusDetect> {
impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> {
/// Create a new USB driver. /// Create a new USB driver.
pub fn new( pub fn new(
usb: impl Peripheral<P = T> + 'd, usb: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
vbus_detect: V, vbus_detect: V,
) -> Self { ) -> Self {
into_ref!(usb);
T::Interrupt::unpend(); T::Interrupt::unpend();
unsafe { T::Interrupt::enable() }; unsafe { T::Interrupt::enable() };
@ -169,7 +167,7 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V
/// USB bus. /// USB bus.
pub struct Bus<'d, T: Instance, V: VbusDetect> { pub struct Bus<'d, T: Instance, V: VbusDetect> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
power_available: bool, power_available: bool,
vbus_detect: V, vbus_detect: V,
} }
@ -592,7 +590,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
/// USB control pipe. /// USB control pipe.
pub struct ControlPipe<'d, T: Instance> { pub struct ControlPipe<'d, T: Instance> {
_p: PeripheralRef<'d, T>, _p: Peri<'d, T>,
max_packet_size: u16, max_packet_size: u16,
} }
@ -779,7 +777,7 @@ pub(crate) trait SealedInstance {
/// USB peripheral instance. /// USB peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -3,9 +3,11 @@
//! This HAL implements a basic watchdog timer with 1..=8 handles. //! This HAL implements a basic watchdog timer with 1..=8 handles.
//! Once the watchdog has been started, it cannot be stopped. //! Once the watchdog has been started, it cannot be stopped.
use core::marker::PhantomData;
use crate::pac::wdt::vals; use crate::pac::wdt::vals;
pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
use crate::peripherals; use crate::{peripherals, Peri};
const MIN_TICKS: u32 = 15; const MIN_TICKS: u32 = 15;
@ -61,7 +63,7 @@ impl Default for Config {
/// Watchdog driver. /// Watchdog driver.
pub struct Watchdog { pub struct Watchdog {
_private: (), _wdt: Peri<'static, peripherals::WDT>,
} }
impl Watchdog { impl Watchdog {
@ -74,9 +76,9 @@ impl Watchdog {
/// `N` must be between 1 and 8, inclusive. /// `N` must be between 1 and 8, inclusive.
#[inline] #[inline]
pub fn try_new<const N: usize>( pub fn try_new<const N: usize>(
wdt: peripherals::WDT, wdt: Peri<'static, peripherals::WDT>,
config: Config, config: Config,
) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> { ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> {
assert!(N >= 1 && N <= 8); assert!(N >= 1 && N <= 8);
let r = crate::pac::WDT; let r = crate::pac::WDT;
@ -110,11 +112,19 @@ impl Watchdog {
r.tasks_start().write_value(1); r.tasks_start().write_value(1);
} }
let this = Self { _private: () }; let this = Self { _wdt: wdt };
let mut handles = [const { WatchdogHandle { index: 0 } }; N]; let mut handles = [const {
WatchdogHandle {
_wdt: PhantomData,
index: 0,
}
}; N];
for i in 0..N { for i in 0..N {
handles[i] = WatchdogHandle { index: i as u8 }; handles[i] = WatchdogHandle {
_wdt: PhantomData,
index: i as u8,
};
handles[i].pet(); handles[i].pet();
} }
@ -155,6 +165,7 @@ impl Watchdog {
/// Watchdog handle. /// Watchdog handle.
pub struct WatchdogHandle { pub struct WatchdogHandle {
_wdt: PhantomData<Peri<'static, peripherals::WDT>>,
index: u8, index: u8,
} }
@ -183,6 +194,9 @@ impl WatchdogHandle {
/// Watchdog must be initialized and `index` must be between `0` and `N-1` /// Watchdog must be initialized and `index` must be between `0` and `N-1`
/// where `N` is the handle count when initializing. /// where `N` is the handle count when initializing.
pub unsafe fn steal(index: u8) -> Self { pub unsafe fn steal(index: u8) -> Self {
Self { index } Self {
_wdt: PhantomData,
index,
}
} }
} }

View File

@ -1,7 +1,7 @@
use embassy_hal_internal::impl_peripheral; use embassy_hal_internal::{impl_peripheral, PeripheralType};
use crate::pac_utils::*; use crate::pac_utils::*;
use crate::{peripherals, Peripheral, PeripheralRef}; use crate::{peripherals, Peri};
pub(crate) fn init() { pub(crate) fn init() {
// Enable clocks for GPIO, PINT, and IOCON // Enable clocks for GPIO, PINT, and IOCON
@ -45,7 +45,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> { impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [initial output](Level). /// Create GPIO output driver for a [Pin] with the provided [initial output](Level).
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_output(); pin.set_as_output();
let mut result = Self { pin }; let mut result = Self { pin };
@ -90,7 +90,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> { impl<'d> Input<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Pull]. /// Create GPIO output driver for a [Pin] with the provided [Pull].
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_input(); pin.set_as_input();
let mut result = Self { pin }; let mut result = Self { pin };
@ -124,7 +124,7 @@ impl<'d> Input<'d> {
/// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a /// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a
/// reference to a type-erased pin called ["AnyPin"](AnyPin). /// reference to a type-erased pin called ["AnyPin"](AnyPin).
pub struct Flex<'d> { pub struct Flex<'d> {
pub(crate) pin: PeripheralRef<'d, AnyPin>, pub(crate) pin: Peri<'d, AnyPin>,
} }
impl<'d> Flex<'d> { impl<'d> Flex<'d> {
@ -132,10 +132,8 @@ impl<'d> Flex<'d> {
/// ///
/// Note: you cannot assume that the pin will be in Digital mode after this call. /// Note: you cannot assume that the pin will be in Digital mode after this call.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { pub fn new(pin: Peri<'d, impl Pin>) -> Self {
Self { Self { pin: pin.into() }
pin: pin.into_ref().map_into(),
}
} }
/// Get the bank of this pin. See also [Bank]. /// Get the bank of this pin. See also [Bank].
@ -218,15 +216,7 @@ pub(crate) trait SealedPin: Sized {
/// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the /// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the
/// `embassy-nxp` crate due to the [SealedPin] trait. /// `embassy-nxp` crate due to the [SealedPin] trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// Degrade to a generic pin struct
fn degrade(self) -> AnyPin {
AnyPin {
pin_bank: self.pin_bank(),
pin_number: self.pin_number(),
}
}
/// Returns the pin number within a bank /// Returns the pin number within a bank
#[inline] #[inline]
fn pin(&self) -> u8 { fn pin(&self) -> u8 {
@ -252,8 +242,8 @@ impl AnyPin {
/// # Safety /// # Safety
/// ///
/// You must ensure that youre only using one instance of this type at a time. /// You must ensure that youre only using one instance of this type at a time.
pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Self { pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> {
Self { pin_bank, pin_number } Peri::new_unchecked(Self { pin_bank, pin_number })
} }
} }
@ -289,7 +279,10 @@ macro_rules! impl_pin {
impl From<peripherals::$name> for crate::gpio::AnyPin { impl From<peripherals::$name> for crate::gpio::AnyPin {
fn from(val: peripherals::$name) -> Self { fn from(val: peripherals::$name) -> Self {
crate::gpio::Pin::degrade(val) Self {
pin_bank: val.pin_bank(),
pin_number: val.pin_number(),
}
} }
} }
}; };

View File

@ -4,7 +4,7 @@ pub mod gpio;
mod pac_utils; mod pac_utils;
pub mod pint; pub mod pint;
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_internal::Peri;
pub use lpc55_pac as pac; pub use lpc55_pac as pac;
/// Initialize the `embassy-nxp` HAL with the provided configuration. /// Initialize the `embassy-nxp` HAL with the provided configuration.

View File

@ -5,12 +5,12 @@ use core::pin::Pin as FuturePin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use critical_section::Mutex; use critical_section::Mutex;
use embassy_hal_internal::{Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{self, AnyPin, Level, SealedPin}; use crate::gpio::{self, AnyPin, Level, SealedPin};
use crate::pac::interrupt; use crate::pac::interrupt;
use crate::pac_utils::*; use crate::pac_utils::*;
use crate::Peri;
struct PinInterrupt { struct PinInterrupt {
assigned: bool, assigned: bool,
@ -107,14 +107,14 @@ pub(crate) fn init() {
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
struct InputFuture<'d> { struct InputFuture<'d> {
#[allow(dead_code)] #[allow(dead_code)]
pin: PeripheralRef<'d, AnyPin>, pin: Peri<'d, AnyPin>,
interrupt_number: usize, interrupt_number: usize,
} }
impl<'d> InputFuture<'d> { impl<'d> InputFuture<'d> {
/// Create a new input future. Returns None if all interrupts are in use. /// Create a new input future. Returns None if all interrupts are in use.
fn new(pin: impl Peripheral<P = impl gpio::Pin> + 'd, interrupt_on: InterruptOn) -> Option<Self> { fn new(pin: Peri<'d, impl gpio::Pin>, interrupt_on: InterruptOn) -> Option<Self> {
let pin = pin.into_ref().map_into(); let pin = pin.into();
let interrupt_number = next_available_interrupt()?; let interrupt_number = next_available_interrupt()?;
// Clear interrupt, just in case // Clear interrupt, just in case
@ -344,35 +344,35 @@ impl gpio::Flex<'_> {
/// Wait for a falling or rising edge on the pin. You can have at most 8 pins waiting. If you /// Wait for a falling or rising edge on the pin. You can have at most 8 pins waiting. If you
/// try to wait for more than 8 pins, this function will return `None`. /// try to wait for more than 8 pins, this function will return `None`.
pub async fn wait_for_any_edge(&mut self) -> Option<()> { pub async fn wait_for_any_edge(&mut self) -> Option<()> {
InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Both))?.await; InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Both))?.await;
Some(()) Some(())
} }
/// Wait for a falling edge on the pin. You can have at most 8 pins waiting. If you try to wait /// Wait for a falling edge on the pin. You can have at most 8 pins waiting. If you try to wait
/// for more than 8 pins, this function will return `None`. /// for more than 8 pins, this function will return `None`.
pub async fn wait_for_falling_edge(&mut self) -> Option<()> { pub async fn wait_for_falling_edge(&mut self) -> Option<()> {
InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Falling))?.await; InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Falling))?.await;
Some(()) Some(())
} }
/// Wait for a rising edge on the pin. You can have at most 8 pins waiting. If you try to wait /// Wait for a rising edge on the pin. You can have at most 8 pins waiting. If you try to wait
/// for more than 8 pins, this function will return `None`. /// for more than 8 pins, this function will return `None`.
pub async fn wait_for_rising_edge(&mut self) -> Option<()> { pub async fn wait_for_rising_edge(&mut self) -> Option<()> {
InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Rising))?.await; InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Rising))?.await;
Some(()) Some(())
} }
/// Wait for a low level on the pin. You can have at most 8 pins waiting. If you try to wait for /// Wait for a low level on the pin. You can have at most 8 pins waiting. If you try to wait for
/// more than 8 pins, this function will return `None`. /// more than 8 pins, this function will return `None`.
pub async fn wait_for_low(&mut self) -> Option<()> { pub async fn wait_for_low(&mut self) -> Option<()> {
InputFuture::new(&mut self.pin, InterruptOn::Level(Level::Low))?.await; InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::Low))?.await;
Some(()) Some(())
} }
/// Wait for a high level on the pin. You can have at most 8 pins waiting. If you try to wait for /// Wait for a high level on the pin. You can have at most 8 pins waiting. If you try to wait for
/// more than 8 pins, this function will return `None`. /// more than 8 pins, this function will return `None`.
pub async fn wait_for_high(&mut self) -> Option<()> { pub async fn wait_for_high(&mut self) -> Option<()> {
InputFuture::new(&mut self.pin, InterruptOn::Level(Level::High))?.await; InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::High))?.await;
Some(()) Some(())
} }
} }

View File

@ -5,7 +5,6 @@ use core::mem;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin}; use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin};
@ -13,7 +12,7 @@ use crate::interrupt::typelevel::Binding;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::pac::dma::vals::TreqSel; use crate::pac::dma::vals::TreqSel;
use crate::peripherals::{ADC, ADC_TEMP_SENSOR}; use crate::peripherals::{ADC, ADC_TEMP_SENSOR};
use crate::{dma, interrupt, pac, peripherals, Peripheral, RegExt}; use crate::{dma, interrupt, pac, peripherals, Peri, RegExt};
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
@ -23,8 +22,8 @@ static WAKER: AtomicWaker = AtomicWaker::new();
pub struct Config {} pub struct Config {}
enum Source<'p> { enum Source<'p> {
Pin(PeripheralRef<'p, AnyPin>), Pin(Peri<'p, AnyPin>),
TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>), TempSensor(Peri<'p, ADC_TEMP_SENSOR>),
} }
/// ADC channel. /// ADC channel.
@ -32,8 +31,7 @@ pub struct Channel<'p>(Source<'p>);
impl<'p> Channel<'p> { impl<'p> Channel<'p> {
/// Create a new ADC channel from pin with the provided [Pull] configuration. /// Create a new ADC channel from pin with the provided [Pull] configuration.
pub fn new_pin(pin: impl Peripheral<P = impl AdcPin + 'p> + 'p, pull: Pull) -> Self { pub fn new_pin(pin: Peri<'p, impl AdcPin + 'p>, pull: Pull) -> Self {
into_ref!(pin);
pin.pad_ctrl().modify(|w| { pin.pad_ctrl().modify(|w| {
#[cfg(feature = "_rp235x")] #[cfg(feature = "_rp235x")]
w.set_iso(false); w.set_iso(false);
@ -47,14 +45,14 @@ impl<'p> Channel<'p> {
w.set_pue(pull == Pull::Up); w.set_pue(pull == Pull::Up);
w.set_pde(pull == Pull::Down); w.set_pde(pull == Pull::Down);
}); });
Self(Source::Pin(pin.map_into())) Self(Source::Pin(pin.into()))
} }
/// Create a new ADC channel for the internal temperature sensor. /// Create a new ADC channel for the internal temperature sensor.
pub fn new_temp_sensor(s: impl Peripheral<P = ADC_TEMP_SENSOR> + 'p) -> Self { pub fn new_temp_sensor(s: Peri<'p, ADC_TEMP_SENSOR>) -> Self {
let r = pac::ADC; let r = pac::ADC;
r.cs().write_set(|w| w.set_ts_en(true)); r.cs().write_set(|w| w.set_ts_en(true));
Self(Source::TempSensor(s.into_ref())) Self(Source::TempSensor(s))
} }
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
@ -190,7 +188,7 @@ impl<'d, M: Mode> Adc<'d, M> {
impl<'d> Adc<'d, Async> { impl<'d> Adc<'d, Async> {
/// Create ADC driver in async mode. /// Create ADC driver in async mode.
pub fn new( pub fn new(
_inner: impl Peripheral<P = ADC> + 'd, _inner: Peri<'d, ADC>,
_irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>, _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
_config: Config, _config: Config,
) -> Self { ) -> Self {
@ -240,7 +238,7 @@ impl<'d> Adc<'d, Async> {
buf: &mut [W], buf: &mut [W],
fcs_err: bool, fcs_err: bool,
div: u16, div: u16,
dma: impl Peripheral<P = impl dma::Channel>, dma: Peri<'_, impl dma::Channel>,
) -> Result<(), Error> { ) -> Result<(), Error> {
#[cfg(feature = "rp2040")] #[cfg(feature = "rp2040")]
let mut rrobin = 0_u8; let mut rrobin = 0_u8;
@ -321,7 +319,7 @@ impl<'d> Adc<'d, Async> {
ch: &mut [Channel<'_>], ch: &mut [Channel<'_>],
buf: &mut [S], buf: &mut [S],
div: u16, div: u16,
dma: impl Peripheral<P = impl dma::Channel>, dma: Peri<'_, impl dma::Channel>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma) self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma)
.await .await
@ -337,7 +335,7 @@ impl<'d> Adc<'d, Async> {
ch: &mut [Channel<'_>], ch: &mut [Channel<'_>],
buf: &mut [Sample], buf: &mut [Sample],
div: u16, div: u16,
dma: impl Peripheral<P = impl dma::Channel>, dma: Peri<'_, impl dma::Channel>,
) { ) {
// errors are reported in individual samples // errors are reported in individual samples
let _ = self let _ = self
@ -360,7 +358,7 @@ impl<'d> Adc<'d, Async> {
ch: &mut Channel<'_>, ch: &mut Channel<'_>,
buf: &mut [S], buf: &mut [S],
div: u16, div: u16,
dma: impl Peripheral<P = impl dma::Channel>, dma: Peri<'_, impl dma::Channel>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma) self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma)
.await .await
@ -375,7 +373,7 @@ impl<'d> Adc<'d, Async> {
ch: &mut Channel<'_>, ch: &mut Channel<'_>,
buf: &mut [Sample], buf: &mut [Sample],
div: u16, div: u16,
dma: impl Peripheral<P = impl dma::Channel>, dma: Peri<'_, impl dma::Channel>,
) { ) {
// errors are reported in individual samples // errors are reported in individual samples
let _ = self let _ = self
@ -392,7 +390,7 @@ impl<'d> Adc<'d, Async> {
impl<'d> Adc<'d, Blocking> { impl<'d> Adc<'d, Blocking> {
/// Create ADC driver in blocking mode. /// Create ADC driver in blocking mode.
pub fn new_blocking(_inner: impl Peripheral<P = ADC> + 'd, _config: Config) -> Self { pub fn new_blocking(_inner: Peri<'d, ADC>, _config: Config) -> Self {
Self::setup(); Self::setup();
Self { phantom: PhantomData } Self { phantom: PhantomData }

View File

@ -8,20 +8,19 @@
//! This module provides functionality to poll BOOTSEL from an embassy application. //! This module provides functionality to poll BOOTSEL from an embassy application.
use crate::flash::in_ram; use crate::flash::in_ram;
use crate::Peri;
impl crate::peripherals::BOOTSEL { /// Reads the BOOTSEL button. Returns true if the button is pressed.
/// Polls the BOOTSEL button. Returns true if the button is pressed. ///
/// /// Reading isn't cheap, as this function waits for core 1 to finish it's current
/// Polling isn't cheap, as this function waits for core 1 to finish it's current /// task and for any DMAs from flash to complete
/// task and for any DMAs from flash to complete pub fn is_bootsel_pressed(_p: Peri<'_, crate::peripherals::BOOTSEL>) -> bool {
pub fn is_pressed(&mut self) -> bool { let mut cs_status = Default::default();
let mut cs_status = Default::default();
unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0");
// bootsel is active low, so invert // bootsel is active low, so invert
!cs_status.infrompad() !cs_status.infrompad()
}
} }
mod ram_helpers { mod ram_helpers {

View File

@ -7,13 +7,12 @@ use core::marker::PhantomData;
use core::sync::atomic::AtomicU16; use core::sync::atomic::AtomicU16;
use core::sync::atomic::{AtomicU32, Ordering}; use core::sync::atomic::{AtomicU32, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef};
use pac::clocks::vals::*; use pac::clocks::vals::*;
use crate::gpio::{AnyPin, SealedPin}; use crate::gpio::{AnyPin, SealedPin};
#[cfg(feature = "rp2040")] #[cfg(feature = "rp2040")]
use crate::pac::common::{Reg, RW}; use crate::pac::common::{Reg, RW};
use crate::{pac, reset, Peripheral}; use crate::{pac, reset, Peri};
// NOTE: all gpin handling is commented out for future reference. // NOTE: all gpin handling is commented out for future reference.
// gpin is not usually safe to use during the boot init() call, so it won't // gpin is not usually safe to use during the boot init() call, so it won't
@ -200,8 +199,8 @@ impl ClockConfig {
// pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) { // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) {
// match P::NR { // match P::NR {
// 0 => self.gpin0 = Some((hz, gpin.map_into())), // 0 => self.gpin0 = Some((hz, gpin.into())),
// 1 => self.gpin1 = Some((hz, gpin.map_into())), // 1 => self.gpin1 = Some((hz, gpin.into())),
// _ => unreachable!(), // _ => unreachable!(),
// } // }
// // pin is now provisionally bound. if the config is applied it must be forgotten, // // pin is now provisionally bound. if the config is applied it must be forgotten,
@ -845,15 +844,13 @@ impl_gpinpin!(PIN_22, 22, 1);
/// General purpose clock input driver. /// General purpose clock input driver.
pub struct Gpin<'d, T: GpinPin> { pub struct Gpin<'d, T: GpinPin> {
gpin: PeripheralRef<'d, AnyPin>, gpin: Peri<'d, AnyPin>,
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<'d, T: GpinPin> Gpin<'d, T> { impl<'d, T: GpinPin> Gpin<'d, T> {
/// Create new gpin driver. /// Create new gpin driver.
pub fn new(gpin: impl Peripheral<P = T> + 'd) -> Self { pub fn new(gpin: Peri<'d, T>) -> Self {
into_ref!(gpin);
#[cfg(feature = "rp2040")] #[cfg(feature = "rp2040")]
gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08)); gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08));
@ -867,14 +864,10 @@ impl<'d, T: GpinPin> Gpin<'d, T> {
}); });
Gpin { Gpin {
gpin: gpin.map_into(), gpin: gpin.into(),
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
// fn map_into(self) -> Gpin<'d, AnyPin> {
// unsafe { core::mem::transmute(self) }
// }
} }
impl<'d, T: GpinPin> Drop for Gpin<'d, T> { impl<'d, T: GpinPin> Drop for Gpin<'d, T> {
@ -936,14 +929,12 @@ pub enum GpoutSrc {
/// General purpose clock output driver. /// General purpose clock output driver.
pub struct Gpout<'d, T: GpoutPin> { pub struct Gpout<'d, T: GpoutPin> {
gpout: PeripheralRef<'d, T>, gpout: Peri<'d, T>,
} }
impl<'d, T: GpoutPin> Gpout<'d, T> { impl<'d, T: GpoutPin> Gpout<'d, T> {
/// Create new general purpose clock output. /// Create new general purpose clock output.
pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { pub fn new(gpout: Peri<'d, T>) -> Self {
into_ref!(gpout);
#[cfg(feature = "rp2040")] #[cfg(feature = "rp2040")]
gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08)); gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08));

View File

@ -4,7 +4,7 @@ use core::pin::Pin;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::dma::vals::DataSize; use pac::dma::vals::DataSize;
@ -42,7 +42,7 @@ pub(crate) unsafe fn init() {
/// ///
/// SAFETY: Slice must point to a valid location reachable by DMA. /// SAFETY: Slice must point to a valid location reachable by DMA.
pub unsafe fn read<'a, C: Channel, W: Word>( pub unsafe fn read<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a, ch: Peri<'a, C>,
from: *const W, from: *const W,
to: *mut [W], to: *mut [W],
dreq: vals::TreqSel, dreq: vals::TreqSel,
@ -63,7 +63,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
/// ///
/// SAFETY: Slice must point to a valid location reachable by DMA. /// SAFETY: Slice must point to a valid location reachable by DMA.
pub unsafe fn write<'a, C: Channel, W: Word>( pub unsafe fn write<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a, ch: Peri<'a, C>,
from: *const [W], from: *const [W],
to: *mut W, to: *mut W,
dreq: vals::TreqSel, dreq: vals::TreqSel,
@ -87,7 +87,7 @@ static mut DUMMY: u32 = 0;
/// ///
/// SAFETY: Slice must point to a valid location reachable by DMA. /// SAFETY: Slice must point to a valid location reachable by DMA.
pub unsafe fn write_repeated<'a, C: Channel, W: Word>( pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a, ch: Peri<'a, C>,
to: *mut W, to: *mut W,
len: usize, len: usize,
dreq: vals::TreqSel, dreq: vals::TreqSel,
@ -107,11 +107,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
/// DMA copy between slices. /// DMA copy between slices.
/// ///
/// SAFETY: Slices must point to locations reachable by DMA. /// SAFETY: Slices must point to locations reachable by DMA.
pub unsafe fn copy<'a, C: Channel, W: Word>( pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
ch: impl Peripheral<P = C> + 'a,
from: &[W],
to: &mut [W],
) -> Transfer<'a, C> {
let from_len = from.len(); let from_len = from.len();
let to_len = to.len(); let to_len = to.len();
assert_eq!(from_len, to_len); assert_eq!(from_len, to_len);
@ -128,7 +124,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(
} }
fn copy_inner<'a, C: Channel>( fn copy_inner<'a, C: Channel>(
ch: impl Peripheral<P = C> + 'a, ch: Peri<'a, C>,
from: *const u32, from: *const u32,
to: *mut u32, to: *mut u32,
len: usize, len: usize,
@ -137,8 +133,6 @@ fn copy_inner<'a, C: Channel>(
incr_write: bool, incr_write: bool,
dreq: vals::TreqSel, dreq: vals::TreqSel,
) -> Transfer<'a, C> { ) -> Transfer<'a, C> {
into_ref!(ch);
let p = ch.regs(); let p = ch.regs();
p.read_addr().write_value(from as u32); p.read_addr().write_value(from as u32);
@ -171,13 +165,11 @@ fn copy_inner<'a, C: Channel>(
/// DMA transfer driver. /// DMA transfer driver.
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Transfer<'a, C: Channel> { pub struct Transfer<'a, C: Channel> {
channel: PeripheralRef<'a, C>, channel: Peri<'a, C>,
} }
impl<'a, C: Channel> Transfer<'a, C> { impl<'a, C: Channel> Transfer<'a, C> {
pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self { pub(crate) fn new(channel: Peri<'a, C>) -> Self {
into_ref!(channel);
Self { channel } Self { channel }
} }
} }
@ -219,7 +211,7 @@ trait SealedWord {}
/// DMA channel interface. /// DMA channel interface.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Sized + 'static { pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
/// Channel number. /// Channel number.
fn number(&self) -> u8; fn number(&self) -> u8;
@ -227,11 +219,6 @@ pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Siz
fn regs(&self) -> pac::dma::Channel { fn regs(&self) -> pac::dma::Channel {
pac::DMA.ch(self.number() as _) pac::DMA.ch(self.number() as _)
} }
/// Convert into type-erased [AnyChannel].
fn degrade(self) -> AnyChannel {
AnyChannel { number: self.number() }
}
} }
/// DMA word. /// DMA word.
@ -287,7 +274,7 @@ macro_rules! channel {
impl From<peripherals::$name> for crate::dma::AnyChannel { impl From<peripherals::$name> for crate::dma::AnyChannel {
fn from(val: peripherals::$name) -> Self { fn from(val: peripherals::$name) -> Self {
crate::dma::Channel::degrade(val) Self { number: val.number() }
} }
} }
}; };

View File

@ -4,7 +4,7 @@ use core::marker::PhantomData;
use core::pin::Pin; use core::pin::Pin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embedded_storage::nor_flash::{ use embedded_storage::nor_flash::{
check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
ReadNorFlash, ReadNorFlash,
@ -114,7 +114,7 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, '
/// Flash driver. /// Flash driver.
pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> { pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
dma: Option<PeripheralRef<'d, AnyChannel>>, dma: Option<Peri<'d, AnyChannel>>,
phantom: PhantomData<(&'d mut T, M)>, phantom: PhantomData<(&'d mut T, M)>,
} }
@ -253,7 +253,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> { impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
/// Create a new flash driver in blocking mode. /// Create a new flash driver in blocking mode.
pub fn new_blocking(_flash: impl Peripheral<P = T> + 'd) -> Self { pub fn new_blocking(_flash: Peri<'d, T>) -> Self {
Self { Self {
dma: None, dma: None,
phantom: PhantomData, phantom: PhantomData,
@ -263,10 +263,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
/// Create a new flash driver in async mode. /// Create a new flash driver in async mode.
pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self { pub fn new(_flash: Peri<'d, T>, dma: Peri<'d, impl Channel>) -> Self {
into_ref!(dma);
Self { Self {
dma: Some(dma.map_into()), dma: Some(dma.into()),
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -316,7 +315,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _; const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _;
let transfer = unsafe { let transfer = unsafe {
crate::dma::read( crate::dma::read(
self.dma.as_mut().unwrap(), self.dma.as_mut().unwrap().reborrow(),
XIP_AUX_BASE, XIP_AUX_BASE,
data, data,
pac::dma::vals::TreqSel::XIP_STREAM, pac::dma::vals::TreqSel::XIP_STREAM,
@ -965,7 +964,7 @@ trait SealedMode {}
/// Flash instance. /// Flash instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance {} pub trait Instance: SealedInstance + PeripheralType {}
/// Flash mode. /// Flash mode.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Mode: SealedMode {} pub trait Mode: SealedMode {}

View File

@ -5,13 +5,13 @@ use core::future::Future;
use core::pin::Pin as FuturePin; use core::pin::Pin as FuturePin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::pac::common::{Reg, RW}; use crate::pac::common::{Reg, RW};
use crate::pac::SIO; use crate::pac::SIO;
use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, RegExt};
#[cfg(any(feature = "rp2040", feature = "rp235xa"))] #[cfg(any(feature = "rp2040", feature = "rp235xa"))]
pub(crate) const BANK0_PIN_COUNT: usize = 30; pub(crate) const BANK0_PIN_COUNT: usize = 30;
@ -115,7 +115,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> { impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_as_input(); pin.set_as_input();
pin.set_pull(pull); pin.set_pull(pull);
@ -266,11 +266,11 @@ fn IO_IRQ_QSPI() {
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
struct InputFuture<'d> { struct InputFuture<'d> {
pin: PeripheralRef<'d, AnyPin>, pin: Peri<'d, AnyPin>,
} }
impl<'d> InputFuture<'d> { impl<'d> InputFuture<'d> {
fn new(pin: PeripheralRef<'d, AnyPin>, level: InterruptTrigger) -> Self { fn new(pin: Peri<'d, AnyPin>, level: InterruptTrigger) -> Self {
let pin_group = (pin.pin() % 8) as usize; let pin_group = (pin.pin() % 8) as usize;
// first, clear the INTR register bits. without this INTR will still // first, clear the INTR register bits. without this INTR will still
// contain reports of previous edges, causing the IRQ to fire early // contain reports of previous edges, causing the IRQ to fire early
@ -359,7 +359,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> { impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level]. /// Create GPIO output driver for a [Pin] with the provided [Level].
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
match initial_output { match initial_output {
Level::High => pin.set_high(), Level::High => pin.set_high(),
@ -440,7 +440,7 @@ pub struct OutputOpenDrain<'d> {
impl<'d> OutputOpenDrain<'d> { impl<'d> OutputOpenDrain<'d> {
/// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level]. /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level].
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
let mut pin = Flex::new(pin); let mut pin = Flex::new(pin);
pin.set_low(); pin.set_low();
match initial_output { match initial_output {
@ -581,7 +581,7 @@ impl<'d> OutputOpenDrain<'d> {
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
/// mode. /// mode.
pub struct Flex<'d> { pub struct Flex<'d> {
pin: PeripheralRef<'d, AnyPin>, pin: Peri<'d, AnyPin>,
} }
impl<'d> Flex<'d> { impl<'d> Flex<'d> {
@ -590,9 +590,7 @@ impl<'d> Flex<'d> {
/// The pin remains disconnected. The initial output level is unspecified, but can be changed /// The pin remains disconnected. The initial output level is unspecified, but can be changed
/// before the pin is put into output mode. /// before the pin is put into output mode.
#[inline] #[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { pub fn new(pin: Peri<'d, impl Pin>) -> Self {
into_ref!(pin);
pin.pad_ctrl().write(|w| { pin.pad_ctrl().write(|w| {
#[cfg(feature = "_rp235x")] #[cfg(feature = "_rp235x")]
w.set_iso(false); w.set_iso(false);
@ -606,7 +604,7 @@ impl<'d> Flex<'d> {
w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _); w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _);
}); });
Self { pin: pin.map_into() } Self { pin: pin.into() }
} }
#[inline] #[inline]
@ -829,7 +827,7 @@ impl<'d> Drop for Flex<'d> {
/// Dormant wake driver. /// Dormant wake driver.
pub struct DormantWake<'w> { pub struct DormantWake<'w> {
pin: PeripheralRef<'w, AnyPin>, pin: Peri<'w, AnyPin>,
cfg: DormantWakeConfig, cfg: DormantWakeConfig,
} }
@ -919,14 +917,7 @@ pub(crate) trait SealedPin: Sized {
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// Degrade to a generic pin struct
fn degrade(self) -> AnyPin {
AnyPin {
pin_bank: self.pin_bank(),
}
}
/// Returns the pin number within a bank /// Returns the pin number within a bank
#[inline] #[inline]
fn pin(&self) -> u8 { fn pin(&self) -> u8 {
@ -951,8 +942,8 @@ impl AnyPin {
/// # Safety /// # Safety
/// ///
/// You must ensure that youre only using one instance of this type at a time. /// You must ensure that youre only using one instance of this type at a time.
pub unsafe fn steal(pin_bank: u8) -> Self { pub unsafe fn steal(pin_bank: u8) -> Peri<'static, Self> {
Self { pin_bank } Peri::new_unchecked(Self { pin_bank })
} }
} }
@ -979,7 +970,9 @@ macro_rules! impl_pin {
impl From<peripherals::$name> for crate::gpio::AnyPin { impl From<peripherals::$name> for crate::gpio::AnyPin {
fn from(val: peripherals::$name) -> Self { fn from(val: peripherals::$name) -> Self {
crate::gpio::Pin::degrade(val) Self {
pin_bank: val.pin_bank(),
}
} }
} }
}; };

View File

@ -5,13 +5,13 @@ use core::future;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::i2c; use pac::i2c;
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals};
/// I2C error abort reason /// I2C error abort reason
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -83,28 +83,25 @@ pub struct I2c<'d, T: Instance, M: Mode> {
impl<'d, T: Instance> I2c<'d, T, Blocking> { impl<'d, T: Instance> I2c<'d, T, Blocking> {
/// Create a new driver instance in blocking mode. /// Create a new driver instance in blocking mode.
pub fn new_blocking( pub fn new_blocking(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
scl: impl Peripheral<P = impl SclPin<T>> + 'd, scl: Peri<'d, impl SclPin<T>>,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd, sda: Peri<'d, impl SdaPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(scl, sda); Self::new_inner(peri, scl.into(), sda.into(), config)
Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
} }
} }
impl<'d, T: Instance> I2c<'d, T, Async> { impl<'d, T: Instance> I2c<'d, T, Async> {
/// Create a new driver instance in async mode. /// Create a new driver instance in async mode.
pub fn new_async( pub fn new_async(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
scl: impl Peripheral<P = impl SclPin<T>> + 'd, scl: Peri<'d, impl SclPin<T>>,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd, sda: Peri<'d, impl SdaPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(scl, sda); let i2c = Self::new_inner(peri, scl.into(), sda.into(), config);
let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
let r = T::regs(); let r = T::regs();
@ -378,14 +375,7 @@ where
} }
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
fn new_inner( fn new_inner(_peri: Peri<'d, T>, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self {
_peri: impl Peripheral<P = T> + 'd,
scl: PeripheralRef<'d, AnyPin>,
sda: PeripheralRef<'d, AnyPin>,
config: Config,
) -> Self {
into_ref!(_peri);
let reset = T::reset(); let reset = T::reset();
crate::reset::reset(reset); crate::reset::reset(reset);
crate::reset::unreset_wait(reset); crate::reset::unreset_wait(reset);
@ -804,7 +794,7 @@ impl_mode!(Async);
/// I2C instance. /// I2C instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance { pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -3,12 +3,11 @@ use core::future;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::into_ref;
use pac::i2c; use pac::i2c;
use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE};
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{pac, Peripheral}; use crate::{pac, Peri};
/// I2C error /// I2C error
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -87,14 +86,12 @@ pub struct I2cSlave<'d, T: Instance> {
impl<'d, T: Instance> I2cSlave<'d, T> { impl<'d, T: Instance> I2cSlave<'d, T> {
/// Create a new instance. /// Create a new instance.
pub fn new( pub fn new(
_peri: impl Peripheral<P = T> + 'd, _peri: Peri<'d, T>,
scl: impl Peripheral<P = impl SclPin<T>> + 'd, scl: Peri<'d, impl SclPin<T>>,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd, sda: Peri<'d, impl SdaPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(_peri, scl, sda);
assert!(config.addr != 0); assert!(config.addr != 0);
// Configure SCL & SDA pins // Configure SCL & SDA pins

View File

@ -54,7 +54,7 @@ pub mod pio;
pub(crate) mod relocate; pub(crate) mod relocate;
// Reexports // Reexports
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_internal::{Peri, PeripheralType};
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use rp_pac as pac; pub use rp_pac as pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]

View File

@ -51,7 +51,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::peripherals::CORE1; use crate::peripherals::CORE1;
use crate::{gpio, install_stack_guard, interrupt, pac}; use crate::{gpio, install_stack_guard, interrupt, pac, Peri};
const PAUSE_TOKEN: u32 = 0xDEADBEEF; const PAUSE_TOKEN: u32 = 0xDEADBEEF;
const RESUME_TOKEN: u32 = !0xDEADBEEF; const RESUME_TOKEN: u32 = !0xDEADBEEF;
@ -139,7 +139,7 @@ unsafe fn SIO_IRQ_FIFO() {
} }
/// Spawn a function on this core /// Spawn a function on this core
pub fn spawn_core1<F, const SIZE: usize>(_core1: CORE1, stack: &'static mut Stack<SIZE>, entry: F) pub fn spawn_core1<F, const SIZE: usize>(_core1: Peri<'static, CORE1>, stack: &'static mut Stack<SIZE>, entry: F)
where where
F: FnOnce() -> bad::Never + Send + 'static, F: FnOnce() -> bad::Never + Send + 'static,
{ {

View File

@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use atomic_polyfill::{AtomicU64, AtomicU8}; use atomic_polyfill::{AtomicU64, AtomicU8};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::extra::U8; use fixed::types::extra::U8;
use fixed::FixedU32; use fixed::FixedU32;
@ -235,7 +235,7 @@ impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
/// Type representing a PIO pin. /// Type representing a PIO pin.
pub struct Pin<'l, PIO: Instance> { pub struct Pin<'l, PIO: Instance> {
pin: PeripheralRef<'l, AnyPin>, pin: Peri<'l, AnyPin>,
pio: PhantomData<PIO>, pio: PhantomData<PIO>,
} }
@ -360,7 +360,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
/// Prepare DMA transfer from RX FIFO. /// Prepare DMA transfer from RX FIFO.
pub fn dma_pull<'a, C: Channel, W: Word>( pub fn dma_pull<'a, C: Channel, W: Word>(
&'a mut self, &'a mut self,
ch: PeripheralRef<'a, C>, ch: Peri<'a, C>,
data: &'a mut [W], data: &'a mut [W],
bswap: bool, bswap: bool,
) -> Transfer<'a, C> { ) -> Transfer<'a, C> {
@ -451,7 +451,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
/// Prepare a DMA transfer to TX FIFO. /// Prepare a DMA transfer to TX FIFO.
pub fn dma_push<'a, C: Channel, W: Word>( pub fn dma_push<'a, C: Channel, W: Word>(
&'a mut self, &'a mut self,
ch: PeripheralRef<'a, C>, ch: Peri<'a, C>,
data: &'a [W], data: &'a [W],
bswap: bool, bswap: bool,
) -> Transfer<'a, C> { ) -> Transfer<'a, C> {
@ -1147,9 +1147,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
/// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and* /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and*
/// all [`StateMachine`]s for this block have been dropped. **Other members /// all [`StateMachine`]s for this block have been dropped. **Other members
/// of [`Pio`] do not keep pin registrations alive.** /// of [`Pio`] do not keep pin registrations alive.**
pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { pub fn make_pio_pin(&mut self, pin: Peri<'d, impl PioPin + 'd>) -> Pin<'d, PIO> {
into_ref!(pin);
// enable the outputs // enable the outputs
pin.pad_ctrl().write(|w| w.set_od(false)); pin.pad_ctrl().write(|w| w.set_od(false));
// especially important on the 235x, where IE defaults to 0 // especially important on the 235x, where IE defaults to 0
@ -1171,7 +1169,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
// we can be relaxed about this because we're &mut here and nothing is cached // we can be relaxed about this because we're &mut here and nothing is cached
PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
Pin { Pin {
pin: pin.into_ref().map_into(), pin: pin.into(),
pio: PhantomData::default(), pio: PhantomData::default(),
} }
} }
@ -1304,7 +1302,7 @@ pub struct Pio<'d, PIO: Instance> {
impl<'d, PIO: Instance> Pio<'d, PIO> { impl<'d, PIO: Instance> Pio<'d, PIO> {
/// Create a new instance of a PIO peripheral. /// Create a new instance of a PIO peripheral.
pub fn new(_pio: impl Peripheral<P = PIO> + 'd, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self { pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self {
PIO::state().users.store(5, Ordering::Release); PIO::state().users.store(5, Ordering::Release);
PIO::state().used_pins.store(0, Ordering::Release); PIO::state().used_pins.store(0, Ordering::Release);
PIO::Interrupt::unpend(); PIO::Interrupt::unpend();
@ -1389,7 +1387,7 @@ trait SealedInstance {
/// PIO instance. /// PIO instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + Sized + Unpin { pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: crate::interrupt::typelevel::Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }

View File

@ -5,7 +5,7 @@ use crate::pio::{
Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection,
StateMachine, StateMachine,
}; };
use crate::{into_ref, Peripheral, PeripheralRef}; use crate::Peri;
/// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>) /// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>)
pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> { pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> {
@ -99,7 +99,7 @@ impl<'a, PIO: Instance> PioHD44780CommandSequenceProgram<'a, PIO> {
/// Pio backed HD44780 driver /// Pio backed HD44780 driver
pub struct PioHD44780<'l, P: Instance, const S: usize> { pub struct PioHD44780<'l, P: Instance, const S: usize> {
dma: PeripheralRef<'l, AnyChannel>, dma: Peri<'l, AnyChannel>,
sm: StateMachine<'l, P, S>, sm: StateMachine<'l, P, S>,
buf: [u8; 40], buf: [u8; 40],
@ -111,19 +111,17 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
common: &mut Common<'l, P>, common: &mut Common<'l, P>,
mut sm: StateMachine<'l, P, S>, mut sm: StateMachine<'l, P, S>,
mut irq: Irq<'l, P, S>, mut irq: Irq<'l, P, S>,
dma: impl Peripheral<P = impl Channel> + 'l, mut dma: Peri<'l, impl Channel>,
rs: impl PioPin, rs: Peri<'l, impl PioPin>,
rw: impl PioPin, rw: Peri<'l, impl PioPin>,
e: impl PioPin, e: Peri<'l, impl PioPin>,
db4: impl PioPin, db4: Peri<'l, impl PioPin>,
db5: impl PioPin, db5: Peri<'l, impl PioPin>,
db6: impl PioPin, db6: Peri<'l, impl PioPin>,
db7: impl PioPin, db7: Peri<'l, impl PioPin>,
word_prg: &PioHD44780CommandWordProgram<'l, P>, word_prg: &PioHD44780CommandWordProgram<'l, P>,
seq_prg: &PioHD44780CommandSequenceProgram<'l, P>, seq_prg: &PioHD44780CommandSequenceProgram<'l, P>,
) -> PioHD44780<'l, P, S> { ) -> PioHD44780<'l, P, S> {
into_ref!(dma);
let rs = common.make_pio_pin(rs); let rs = common.make_pio_pin(rs);
let rw = common.make_pio_pin(rw); let rw = common.make_pio_pin(rw);
let e = common.make_pio_pin(e); let e = common.make_pio_pin(e);
@ -176,7 +174,7 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await; sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await;
Self { Self {
dma: dma.map_into(), dma: dma.into(),
sm, sm,
buf: [0x20; 40], buf: [0x20; 40],
} }

View File

@ -6,16 +6,16 @@ use crate::dma::{AnyChannel, Channel, Transfer};
use crate::pio::{ use crate::pio::{
Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
}; };
use crate::{into_ref, Peripheral, PeripheralRef}; use crate::Peri;
/// This struct represents an i2s output driver program /// This struct represents an i2s output driver program
pub struct PioI2sOutProgram<'a, PIO: Instance> { pub struct PioI2sOutProgram<'d, PIO: Instance> {
prg: LoadedProgram<'a, PIO>, prg: LoadedProgram<'d, PIO>,
} }
impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> { impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
/// Load the program into the given pio /// Load the program into the given pio
pub fn new(common: &mut Common<'a, PIO>) -> Self { pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!( let prg = pio::pio_asm!(
".side_set 2", ".side_set 2",
" set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock
@ -37,27 +37,25 @@ impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> {
} }
/// Pio backed I2s output driver /// Pio backed I2s output driver
pub struct PioI2sOut<'a, P: Instance, const S: usize> { pub struct PioI2sOut<'d, P: Instance, const S: usize> {
dma: PeripheralRef<'a, AnyChannel>, dma: Peri<'d, AnyChannel>,
sm: StateMachine<'a, P, S>, sm: StateMachine<'d, P, S>,
} }
impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> { impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
/// Configure a state machine to output I2s /// Configure a state machine to output I2s
pub fn new( pub fn new(
common: &mut Common<'a, P>, common: &mut Common<'d, P>,
mut sm: StateMachine<'a, P, S>, mut sm: StateMachine<'d, P, S>,
dma: impl Peripheral<P = impl Channel> + 'a, dma: Peri<'d, impl Channel>,
data_pin: impl PioPin, data_pin: Peri<'d, impl PioPin>,
bit_clock_pin: impl PioPin, bit_clock_pin: Peri<'d, impl PioPin>,
lr_clock_pin: impl PioPin, lr_clock_pin: Peri<'d, impl PioPin>,
sample_rate: u32, sample_rate: u32,
bit_depth: u32, bit_depth: u32,
channels: u32, channels: u32,
program: &PioI2sOutProgram<'a, P>, program: &PioI2sOutProgram<'d, P>,
) -> Self { ) -> Self {
into_ref!(dma);
let data_pin = common.make_pio_pin(data_pin); let data_pin = common.make_pio_pin(data_pin);
let bit_clock_pin = common.make_pio_pin(bit_clock_pin); let bit_clock_pin = common.make_pio_pin(bit_clock_pin);
let left_right_clock_pin = common.make_pio_pin(lr_clock_pin); let left_right_clock_pin = common.make_pio_pin(lr_clock_pin);
@ -82,10 +80,7 @@ impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> {
sm.set_enable(true); sm.set_enable(true);
Self { Self { dma: dma.into(), sm }
dma: dma.map_into(),
sm,
}
} }
/// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer.

View File

@ -1,6 +1,7 @@
//! OneWire pio driver //! OneWire pio driver
use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine}; use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine};
use crate::Peri;
/// This struct represents an onewire driver program /// This struct represents an onewire driver program
pub struct PioOneWireProgram<'a, PIO: Instance> { pub struct PioOneWireProgram<'a, PIO: Instance> {
@ -69,7 +70,7 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> {
pub fn new( pub fn new(
common: &mut Common<'d, PIO>, common: &mut Common<'d, PIO>,
mut sm: StateMachine<'d, PIO, SM>, mut sm: StateMachine<'d, PIO, SM>,
pin: impl PioPin, pin: Peri<'d, impl PioPin>,
program: &PioOneWireProgram<'d, PIO>, program: &PioOneWireProgram<'d, PIO>,
) -> Self { ) -> Self {
let pin = common.make_pio_pin(pin); let pin = common.make_pio_pin(pin);

View File

@ -4,9 +4,9 @@ use core::time::Duration;
use pio::InstructionOperands; use pio::InstructionOperands;
use crate::clocks;
use crate::gpio::Level; use crate::gpio::Level;
use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine}; use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine};
use crate::{clocks, Peri};
/// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time /// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time
fn to_pio_cycles(duration: Duration) -> u32 { fn to_pio_cycles(duration: Duration) -> u32 {
@ -52,7 +52,7 @@ impl<'d, T: Instance, const SM: usize> PioPwm<'d, T, SM> {
pub fn new( pub fn new(
pio: &mut Common<'d, T>, pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>, mut sm: StateMachine<'d, T, SM>,
pin: impl PioPin, pin: Peri<'d, impl PioPin>,
program: &PioPwmProgram<'d, T>, program: &PioPwmProgram<'d, T>,
) -> Self { ) -> Self {
let pin = pio.make_pio_pin(pin); let pin = pio.make_pio_pin(pin);

View File

@ -6,6 +6,7 @@ use crate::gpio::Pull;
use crate::pio::{ use crate::pio::{
Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
}; };
use crate::Peri;
/// This struct represents an Encoder program loaded into pio instruction memory. /// This struct represents an Encoder program loaded into pio instruction memory.
pub struct PioEncoderProgram<'a, PIO: Instance> { pub struct PioEncoderProgram<'a, PIO: Instance> {
@ -33,8 +34,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
pub fn new( pub fn new(
pio: &mut Common<'d, T>, pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>, mut sm: StateMachine<'d, T, SM>,
pin_a: impl PioPin, pin_a: Peri<'d, impl PioPin>,
pin_b: impl PioPin, pin_b: Peri<'d, impl PioPin>,
program: &PioEncoderProgram<'d, T>, program: &PioEncoderProgram<'d, T>,
) -> Self { ) -> Self {
let mut pin_a = pio.make_pio_pin(pin_a); let mut pin_a = pio.make_pio_pin(pin_a);

View File

@ -7,6 +7,7 @@ use fixed::types::extra::U8;
use fixed::FixedU32; use fixed::FixedU32;
use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine}; use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine};
use crate::Peri;
/// This struct represents a Stepper driver program loaded into pio instruction memory. /// This struct represents a Stepper driver program loaded into pio instruction memory.
pub struct PioStepperProgram<'a, PIO: Instance> { pub struct PioStepperProgram<'a, PIO: Instance> {
@ -50,10 +51,10 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> {
pio: &mut Common<'d, T>, pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>, mut sm: StateMachine<'d, T, SM>,
irq: Irq<'d, T, SM>, irq: Irq<'d, T, SM>,
pin0: impl PioPin, pin0: Peri<'d, impl PioPin>,
pin1: impl PioPin, pin1: Peri<'d, impl PioPin>,
pin2: impl PioPin, pin2: Peri<'d, impl PioPin>,
pin3: impl PioPin, pin3: Peri<'d, impl PioPin>,
program: &PioStepperProgram<'d, T>, program: &PioStepperProgram<'d, T>,
) -> Self { ) -> Self {
let pin0 = pio.make_pio_pin(pin0); let pin0 = pio.make_pio_pin(pin0);

View File

@ -10,15 +10,16 @@ use crate::gpio::Level;
use crate::pio::{ use crate::pio::{
Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
}; };
use crate::Peri;
/// This struct represents a uart tx program loaded into pio instruction memory. /// This struct represents a uart tx program loaded into pio instruction memory.
pub struct PioUartTxProgram<'a, PIO: Instance> { pub struct PioUartTxProgram<'d, PIO: Instance> {
prg: LoadedProgram<'a, PIO>, prg: LoadedProgram<'d, PIO>,
} }
impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> { impl<'d, PIO: Instance> PioUartTxProgram<'d, PIO> {
/// Load the uart tx program into the given pio /// Load the uart tx program into the given pio
pub fn new(common: &mut Common<'a, PIO>) -> Self { pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!( let prg = pio::pio_asm!(
r#" r#"
.side_set 1 opt .side_set 1 opt
@ -41,18 +42,18 @@ impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> {
} }
/// PIO backed Uart transmitter /// PIO backed Uart transmitter
pub struct PioUartTx<'a, PIO: Instance, const SM: usize> { pub struct PioUartTx<'d, PIO: Instance, const SM: usize> {
sm_tx: StateMachine<'a, PIO, SM>, sm_tx: StateMachine<'d, PIO, SM>,
} }
impl<'a, PIO: Instance, const SM: usize> PioUartTx<'a, PIO, SM> { impl<'d, PIO: Instance, const SM: usize> PioUartTx<'d, PIO, SM> {
/// Configure a pio state machine to use the loaded tx program. /// Configure a pio state machine to use the loaded tx program.
pub fn new( pub fn new(
baud: u32, baud: u32,
common: &mut Common<'a, PIO>, common: &mut Common<'d, PIO>,
mut sm_tx: StateMachine<'a, PIO, SM>, mut sm_tx: StateMachine<'d, PIO, SM>,
tx_pin: impl PioPin, tx_pin: Peri<'d, impl PioPin>,
program: &PioUartTxProgram<'a, PIO>, program: &PioUartTxProgram<'d, PIO>,
) -> Self { ) -> Self {
let tx_pin = common.make_pio_pin(tx_pin); let tx_pin = common.make_pio_pin(tx_pin);
sm_tx.set_pins(Level::High, &[&tx_pin]); sm_tx.set_pins(Level::High, &[&tx_pin]);
@ -92,13 +93,13 @@ impl<PIO: Instance, const SM: usize> Write for PioUartTx<'_, PIO, SM> {
} }
/// This struct represents a Uart Rx program loaded into pio instruction memory. /// This struct represents a Uart Rx program loaded into pio instruction memory.
pub struct PioUartRxProgram<'a, PIO: Instance> { pub struct PioUartRxProgram<'d, PIO: Instance> {
prg: LoadedProgram<'a, PIO>, prg: LoadedProgram<'d, PIO>,
} }
impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> { impl<'d, PIO: Instance> PioUartRxProgram<'d, PIO> {
/// Load the uart rx program into the given pio /// Load the uart rx program into the given pio
pub fn new(common: &mut Common<'a, PIO>) -> Self { pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!( let prg = pio::pio_asm!(
r#" r#"
; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
@ -130,18 +131,18 @@ impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> {
} }
/// PIO backed Uart reciever /// PIO backed Uart reciever
pub struct PioUartRx<'a, PIO: Instance, const SM: usize> { pub struct PioUartRx<'d, PIO: Instance, const SM: usize> {
sm_rx: StateMachine<'a, PIO, SM>, sm_rx: StateMachine<'d, PIO, SM>,
} }
impl<'a, PIO: Instance, const SM: usize> PioUartRx<'a, PIO, SM> { impl<'d, PIO: Instance, const SM: usize> PioUartRx<'d, PIO, SM> {
/// Configure a pio state machine to use the loaded rx program. /// Configure a pio state machine to use the loaded rx program.
pub fn new( pub fn new(
baud: u32, baud: u32,
common: &mut Common<'a, PIO>, common: &mut Common<'d, PIO>,
mut sm_rx: StateMachine<'a, PIO, SM>, mut sm_rx: StateMachine<'d, PIO, SM>,
rx_pin: impl PioPin, rx_pin: Peri<'d, impl PioPin>,
program: &PioUartRxProgram<'a, PIO>, program: &PioUartRxProgram<'d, PIO>,
) -> Self { ) -> Self {
let mut cfg = Config::default(); let mut cfg = Config::default();
cfg.use_program(&program.prg, &[]); cfg.use_program(&program.prg, &[]);

View File

@ -9,7 +9,7 @@ use crate::dma::{AnyChannel, Channel};
use crate::pio::{ use crate::pio::{
Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
}; };
use crate::{into_ref, Peripheral, PeripheralRef}; use crate::Peri;
const T1: u8 = 2; // start bit const T1: u8 = 2; // start bit
const T2: u8 = 5; // data bit const T2: u8 = 5; // data bit
@ -53,7 +53,7 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> {
/// Pio backed ws2812 driver /// Pio backed ws2812 driver
/// Const N is the number of ws2812 leds attached to this pin /// Const N is the number of ws2812 leds attached to this pin
pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> { pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> {
dma: PeripheralRef<'d, AnyChannel>, dma: Peri<'d, AnyChannel>,
sm: StateMachine<'d, P, S>, sm: StateMachine<'d, P, S>,
} }
@ -62,12 +62,10 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
pub fn new( pub fn new(
pio: &mut Common<'d, P>, pio: &mut Common<'d, P>,
mut sm: StateMachine<'d, P, S>, mut sm: StateMachine<'d, P, S>,
dma: impl Peripheral<P = impl Channel> + 'd, dma: Peri<'d, impl Channel>,
pin: impl PioPin, pin: Peri<'d, impl PioPin>,
program: &PioWs2812Program<'d, P>, program: &PioWs2812Program<'d, P>,
) -> Self { ) -> Self {
into_ref!(dma);
// Setup sm0 // Setup sm0
let mut cfg = Config::default(); let mut cfg = Config::default();
@ -95,10 +93,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
sm.set_config(&cfg); sm.set_config(&cfg);
sm.set_enable(true); sm.set_enable(true);
Self { Self { dma: dma.into(), sm }
dma: dma.map_into(),
sm,
}
} }
/// Write a buffer of [smart_leds::RGB8] to the ws2812 string /// Write a buffer of [smart_leds::RGB8] to the ws2812 string

View File

@ -1,6 +1,6 @@
//! Pulse Width Modulation (PWM) //! Pulse Width Modulation (PWM)
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
pub use embedded_hal_1::pwm::SetDutyCycle; pub use embedded_hal_1::pwm::SetDutyCycle;
use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType}; use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType};
use fixed::traits::ToFixed; use fixed::traits::ToFixed;
@ -99,8 +99,8 @@ impl Error for PwmError {
/// PWM driver. /// PWM driver.
pub struct Pwm<'d> { pub struct Pwm<'d> {
pin_a: Option<PeripheralRef<'d, AnyPin>>, pin_a: Option<Peri<'d, AnyPin>>,
pin_b: Option<PeripheralRef<'d, AnyPin>>, pin_b: Option<Peri<'d, AnyPin>>,
slice: usize, slice: usize,
} }
@ -131,8 +131,8 @@ impl<'d> SetDutyCycle for Pwm<'d> {
impl<'d> Pwm<'d> { impl<'d> Pwm<'d> {
fn new_inner( fn new_inner(
slice: usize, slice: usize,
a: Option<PeripheralRef<'d, AnyPin>>, a: Option<Peri<'d, AnyPin>>,
b: Option<PeripheralRef<'d, AnyPin>>, b: Option<Peri<'d, AnyPin>>,
b_pull: Pull, b_pull: Pull,
config: Config, config: Config,
divmode: Divmode, divmode: Divmode,
@ -171,60 +171,34 @@ impl<'d> Pwm<'d> {
/// Create PWM driver without any configured pins. /// Create PWM driver without any configured pins.
#[inline] #[inline]
pub fn new_free<T: Slice>(slice: impl Peripheral<P = T> + 'd, config: Config) -> Self { pub fn new_free<T: Slice>(slice: Peri<'d, T>, config: Config) -> Self {
into_ref!(slice);
Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV)
} }
/// Create PWM driver with a single 'a' pin as output. /// Create PWM driver with a single 'a' pin as output.
#[inline] #[inline]
pub fn new_output_a<T: Slice>( pub fn new_output_a<T: Slice>(slice: Peri<'d, T>, a: Peri<'d, impl ChannelAPin<T>>, config: Config) -> Self {
slice: impl Peripheral<P = T> + 'd, Self::new_inner(slice.number(), Some(a.into()), None, Pull::None, config, Divmode::DIV)
a: impl Peripheral<P = impl ChannelAPin<T>> + 'd,
config: Config,
) -> Self {
into_ref!(slice, a);
Self::new_inner(
slice.number(),
Some(a.map_into()),
None,
Pull::None,
config,
Divmode::DIV,
)
} }
/// Create PWM driver with a single 'b' pin as output. /// Create PWM driver with a single 'b' pin as output.
#[inline] #[inline]
pub fn new_output_b<T: Slice>( pub fn new_output_b<T: Slice>(slice: Peri<'d, T>, b: Peri<'d, impl ChannelBPin<T>>, config: Config) -> Self {
slice: impl Peripheral<P = T> + 'd, Self::new_inner(slice.number(), None, Some(b.into()), Pull::None, config, Divmode::DIV)
b: impl Peripheral<P = impl ChannelBPin<T>> + 'd,
config: Config,
) -> Self {
into_ref!(slice, b);
Self::new_inner(
slice.number(),
None,
Some(b.map_into()),
Pull::None,
config,
Divmode::DIV,
)
} }
/// Create PWM driver with a 'a' and 'b' pins as output. /// Create PWM driver with a 'a' and 'b' pins as output.
#[inline] #[inline]
pub fn new_output_ab<T: Slice>( pub fn new_output_ab<T: Slice>(
slice: impl Peripheral<P = T> + 'd, slice: Peri<'d, T>,
a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, a: Peri<'d, impl ChannelAPin<T>>,
b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, b: Peri<'d, impl ChannelBPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(slice, a, b);
Self::new_inner( Self::new_inner(
slice.number(), slice.number(),
Some(a.map_into()), Some(a.into()),
Some(b.map_into()), Some(b.into()),
Pull::None, Pull::None,
config, config,
Divmode::DIV, Divmode::DIV,
@ -234,31 +208,29 @@ impl<'d> Pwm<'d> {
/// Create PWM driver with a single 'b' as input pin. /// Create PWM driver with a single 'b' as input pin.
#[inline] #[inline]
pub fn new_input<T: Slice>( pub fn new_input<T: Slice>(
slice: impl Peripheral<P = T> + 'd, slice: Peri<'d, T>,
b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, b: Peri<'d, impl ChannelBPin<T>>,
b_pull: Pull, b_pull: Pull,
mode: InputMode, mode: InputMode,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(slice, b); Self::new_inner(slice.number(), None, Some(b.into()), b_pull, config, mode.into())
Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into())
} }
/// Create PWM driver with a 'a' and 'b' pins in the desired input mode. /// Create PWM driver with a 'a' and 'b' pins in the desired input mode.
#[inline] #[inline]
pub fn new_output_input<T: Slice>( pub fn new_output_input<T: Slice>(
slice: impl Peripheral<P = T> + 'd, slice: Peri<'d, T>,
a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, a: Peri<'d, impl ChannelAPin<T>>,
b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, b: Peri<'d, impl ChannelBPin<T>>,
b_pull: Pull, b_pull: Pull,
mode: InputMode, mode: InputMode,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(slice, a, b);
Self::new_inner( Self::new_inner(
slice.number(), slice.number(),
Some(a.map_into()), Some(a.into()),
Some(b.map_into()), Some(b.into()),
b_pull, b_pull,
config, config,
mode.into(), mode.into(),
@ -373,8 +345,8 @@ impl<'d> Pwm<'d> {
} }
enum PwmChannelPin<'d> { enum PwmChannelPin<'d> {
A(PeripheralRef<'d, AnyPin>), A(Peri<'d, AnyPin>),
B(PeripheralRef<'d, AnyPin>), B(Peri<'d, AnyPin>),
} }
/// Single channel of Pwm driver. /// Single channel of Pwm driver.
@ -498,7 +470,7 @@ trait SealedSlice {}
/// PWM Slice. /// PWM Slice.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { pub trait Slice: PeripheralType + SealedSlice + Sized + 'static {
/// Slice number. /// Slice number.
fn number(&self) -> usize; fn number(&self) -> usize;
} }

View File

@ -1,7 +1,7 @@
//! RTC driver. //! RTC driver.
mod filter; mod filter;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
pub use self::filter::DateTimeFilter; pub use self::filter::DateTimeFilter;
@ -14,7 +14,7 @@ use crate::clocks::clk_rtc_freq;
/// A reference to the real time clock of the system /// A reference to the real time clock of the system
pub struct Rtc<'d, T: Instance> { pub struct Rtc<'d, T: Instance> {
inner: PeripheralRef<'d, T>, inner: Peri<'d, T>,
} }
impl<'d, T: Instance> Rtc<'d, T> { impl<'d, T: Instance> Rtc<'d, T> {
@ -23,9 +23,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
/// # Errors /// # Errors
/// ///
/// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self { pub fn new(inner: Peri<'d, T>) -> Self {
into_ref!(inner);
// Set the RTC divider // Set the RTC divider
inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1)); inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
@ -194,7 +192,7 @@ trait SealedInstance {
/// RTC peripheral instance. /// RTC peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance {} pub trait Instance: SealedInstance + PeripheralType {}
impl SealedInstance for crate::peripherals::RTC { impl SealedInstance for crate::peripherals::RTC {
fn regs(&self) -> crate::pac::rtc::Rtc { fn regs(&self) -> crate::pac::rtc::Rtc {

View File

@ -3,12 +3,12 @@ use core::marker::PhantomData;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_futures::join::join; use embassy_futures::join::join;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
pub use embedded_hal_02::spi::{Phase, Polarity}; pub use embedded_hal_02::spi::{Phase, Polarity};
use crate::dma::{AnyChannel, Channel}; use crate::dma::{AnyChannel, Channel};
use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
use crate::{pac, peripherals, Peripheral}; use crate::{pac, peripherals};
/// SPI errors. /// SPI errors.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -42,9 +42,9 @@ impl Default for Config {
/// SPI driver. /// SPI driver.
pub struct Spi<'d, T: Instance, M: Mode> { pub struct Spi<'d, T: Instance, M: Mode> {
inner: PeripheralRef<'d, T>, inner: Peri<'d, T>,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>, tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>, rx_dma: Option<Peri<'d, AnyChannel>>,
phantom: PhantomData<(&'d mut T, M)>, phantom: PhantomData<(&'d mut T, M)>,
} }
@ -73,17 +73,15 @@ fn calc_prescs(freq: u32) -> (u8, u8) {
impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
fn new_inner( fn new_inner(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: Option<PeripheralRef<'d, AnyPin>>, clk: Option<Peri<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<Peri<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>, miso: Option<Peri<'d, AnyPin>>,
cs: Option<PeripheralRef<'d, AnyPin>>, cs: Option<Peri<'d, AnyPin>>,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>, tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>, rx_dma: Option<Peri<'d, AnyChannel>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(inner);
Self::apply_config(&inner, &config); Self::apply_config(&inner, &config);
let p = inner.regs(); let p = inner.regs();
@ -161,7 +159,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
/// ///
/// Driver should be disabled before making changes and reenabled after the modifications /// Driver should be disabled before making changes and reenabled after the modifications
/// are applied. /// are applied.
fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) { fn apply_config(inner: &Peri<'d, T>, config: &Config) {
let p = inner.regs(); let p = inner.regs();
let (presc, postdiv) = calc_prescs(config.frequency); let (presc, postdiv) = calc_prescs(config.frequency);
@ -273,18 +271,17 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
impl<'d, T: Instance> Spi<'d, T, Blocking> { impl<'d, T: Instance> Spi<'d, T, Blocking> {
/// Create an SPI driver in blocking mode. /// Create an SPI driver in blocking mode.
pub fn new_blocking( pub fn new_blocking(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, mosi: Peri<'d, impl MosiPin<T> + 'd>,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, miso: Peri<'d, impl MisoPin<T> + 'd>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(clk, mosi, miso);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
Some(mosi.map_into()), Some(mosi.into()),
Some(miso.map_into()), Some(miso.into()),
None, None,
None, None,
None, None,
@ -294,16 +291,15 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
/// Create an SPI driver in blocking mode supporting writes only. /// Create an SPI driver in blocking mode supporting writes only.
pub fn new_blocking_txonly( pub fn new_blocking_txonly(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, mosi: Peri<'d, impl MosiPin<T> + 'd>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(clk, mosi);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
Some(mosi.map_into()), Some(mosi.into()),
None, None,
None, None,
None, None,
@ -314,17 +310,16 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
/// Create an SPI driver in blocking mode supporting reads only. /// Create an SPI driver in blocking mode supporting reads only.
pub fn new_blocking_rxonly( pub fn new_blocking_rxonly(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, miso: Peri<'d, impl MisoPin<T> + 'd>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(clk, miso);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
None, None,
Some(miso.map_into()), Some(miso.into()),
None, None,
None, None,
None, None,
@ -336,43 +331,41 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
impl<'d, T: Instance> Spi<'d, T, Async> { impl<'d, T: Instance> Spi<'d, T, Async> {
/// Create an SPI driver in async mode supporting DMA operations. /// Create an SPI driver in async mode supporting DMA operations.
pub fn new( pub fn new(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, mosi: Peri<'d, impl MosiPin<T> + 'd>,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, miso: Peri<'d, impl MisoPin<T> + 'd>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
rx_dma: impl Peripheral<P = impl Channel> + 'd, rx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx_dma, rx_dma, clk, mosi, miso);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
Some(mosi.map_into()), Some(mosi.into()),
Some(miso.map_into()), Some(miso.into()),
None, None,
Some(tx_dma.map_into()), Some(tx_dma.into()),
Some(rx_dma.map_into()), Some(rx_dma.into()),
config, config,
) )
} }
/// Create an SPI driver in async mode supporting DMA write operations only. /// Create an SPI driver in async mode supporting DMA write operations only.
pub fn new_txonly( pub fn new_txonly(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, mosi: Peri<'d, impl MosiPin<T> + 'd>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx_dma, clk, mosi);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
Some(mosi.map_into()), Some(mosi.into()),
None, None,
None, None,
Some(tx_dma.map_into()), Some(tx_dma.into()),
None, None,
config, config,
) )
@ -380,29 +373,28 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
/// Create an SPI driver in async mode supporting DMA read operations only. /// Create an SPI driver in async mode supporting DMA read operations only.
pub fn new_rxonly( pub fn new_rxonly(
inner: impl Peripheral<P = T> + 'd, inner: Peri<'d, T>,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, clk: Peri<'d, impl ClkPin<T> + 'd>,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, miso: Peri<'d, impl MisoPin<T> + 'd>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
rx_dma: impl Peripheral<P = impl Channel> + 'd, rx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx_dma, rx_dma, clk, miso);
Self::new_inner( Self::new_inner(
inner, inner,
Some(clk.map_into()), Some(clk.into()),
None, None,
Some(miso.map_into()), Some(miso.into()),
None, None,
Some(tx_dma.map_into()), Some(tx_dma.into()),
Some(rx_dma.map_into()), Some(rx_dma.into()),
config, config,
) )
} }
/// Write data to SPI using DMA. /// Write data to SPI using DMA.
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
let tx_ch = self.tx_dma.as_mut().unwrap(); let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
let tx_transfer = unsafe { let tx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
@ -427,14 +419,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
// Start RX first. Transfer starts when TX starts, if RX // Start RX first. Transfer starts when TX starts, if RX
// is not started yet we might lose bytes. // is not started yet we might lose bytes.
let rx_ch = self.rx_dma.as_mut().unwrap(); let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
let rx_transfer = unsafe { let rx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ) crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ)
}; };
let tx_ch = self.tx_dma.as_mut().unwrap(); let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
let tx_transfer = unsafe { let tx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
@ -462,20 +454,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
// Start RX first. Transfer starts when TX starts, if RX // Start RX first. Transfer starts when TX starts, if RX
// is not started yet we might lose bytes. // is not started yet we might lose bytes.
let rx_ch = self.rx_dma.as_mut().unwrap(); let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
let rx_transfer = unsafe { let rx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ) crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ)
}; };
let mut tx_ch = self.tx_dma.as_mut().unwrap(); let mut tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
let tx_transfer = async { let tx_transfer = async {
let p = self.inner.regs(); let p = self.inner.regs();
unsafe { unsafe {
crate::dma::write(&mut tx_ch, tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await; crate::dma::write(tx_ch.reborrow(), tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
if rx.len() > tx.len() { if rx.len() > tx.len() {
let write_bytes_len = rx.len() - tx.len(); let write_bytes_len = rx.len() - tx.len();
@ -519,7 +511,7 @@ pub trait Mode: SealedMode {}
/// SPI instance trait. /// SPI instance trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance {} pub trait Instance: SealedInstance + PeripheralType {}
macro_rules! impl_instance { macro_rules! impl_instance {
($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => {

View File

@ -5,7 +5,7 @@ use core::marker::PhantomData;
use core::ops::Not; use core::ops::Not;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::Peripheral; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use rand_core::Error; use rand_core::Error;
@ -20,7 +20,7 @@ trait SealedInstance {
/// TRNG peripheral instance. /// TRNG peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance { pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: Interrupt;
} }
@ -158,11 +158,7 @@ const TRNG_BLOCK_SIZE_BYTES: usize = TRNG_BLOCK_SIZE_BITS / 8;
impl<'d, T: Instance> Trng<'d, T> { impl<'d, T: Instance> Trng<'d, T> {
/// Create a new TRNG driver. /// Create a new TRNG driver.
pub fn new( pub fn new(_trng: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd, config: Config) -> Self {
_trng: impl Peripheral<P = T> + 'd,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
config: Config,
) -> Self {
let regs = T::regs(); let regs = T::regs();
regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false)); regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false));

View File

@ -90,17 +90,15 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
impl<'d, T: Instance> BufferedUart<'d, T> { impl<'d, T: Instance> BufferedUart<'d, T> {
/// Create a buffered UART instance. /// Create a buffered UART instance.
pub fn new( pub fn new(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx); super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
Self { Self {
@ -111,23 +109,21 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
/// Create a buffered UART instance with flow control. /// Create a buffered UART instance with flow control.
pub fn new_with_rtscts( pub fn new_with_rtscts(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: Peri<'d, impl RtsPin<T>>,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd, cts: Peri<'d, impl CtsPin<T>>,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx, cts, rts);
super::Uart::<'d, T, Async>::init( super::Uart::<'d, T, Async>::init(
Some(tx.map_into()), Some(tx.into()),
Some(rx.map_into()), Some(rx.into()),
Some(rts.map_into()), Some(rts.into()),
Some(cts.map_into()), Some(cts.into()),
config, config,
); );
init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
@ -184,15 +180,13 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
impl<'d, T: Instance> BufferedUartRx<'d, T> { impl<'d, T: Instance> BufferedUartRx<'d, T> {
/// Create a new buffered UART RX. /// Create a new buffered UART RX.
pub fn new( pub fn new(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(rx); super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
init_buffers::<T>(irq, None, Some(rx_buffer)); init_buffers::<T>(irq, None, Some(rx_buffer));
Self { phantom: PhantomData } Self { phantom: PhantomData }
@ -200,16 +194,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
/// Create a new buffered UART RX with flow control. /// Create a new buffered UART RX with flow control.
pub fn new_with_rts( pub fn new_with_rts(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: Peri<'d, impl RtsPin<T>>,
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(rx, rts); super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
init_buffers::<T>(irq, None, Some(rx_buffer)); init_buffers::<T>(irq, None, Some(rx_buffer));
Self { phantom: PhantomData } Self { phantom: PhantomData }
@ -338,15 +330,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
impl<'d, T: Instance> BufferedUartTx<'d, T> { impl<'d, T: Instance> BufferedUartTx<'d, T> {
/// Create a new buffered UART TX. /// Create a new buffered UART TX.
pub fn new( pub fn new(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx); super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
init_buffers::<T>(irq, Some(tx_buffer), None); init_buffers::<T>(irq, Some(tx_buffer), None);
Self { phantom: PhantomData } Self { phantom: PhantomData }
@ -354,16 +344,14 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
/// Create a new buffered UART TX with flow control. /// Create a new buffered UART TX with flow control.
pub fn new_with_cts( pub fn new_with_cts(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd, cts: Peri<'d, impl CtsPin<T>>,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, cts); super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
init_buffers::<T>(irq, Some(tx_buffer), None); init_buffers::<T>(irq, Some(tx_buffer), None);
Self { phantom: PhantomData } Self { phantom: PhantomData }

View File

@ -5,7 +5,7 @@ use core::task::Poll;
use atomic_polyfill::{AtomicU16, Ordering}; use atomic_polyfill::{AtomicU16, Ordering};
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select, Either};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::{Delay, Timer}; use embassy_time::{Delay, Timer};
use pac::uart::regs::Uartris; use pac::uart::regs::Uartris;
@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel};
use crate::gpio::{AnyPin, SealedPin}; use crate::gpio::{AnyPin, SealedPin};
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::pac::io::vals::{Inover, Outover}; use crate::pac::io::vals::{Inover, Outover};
use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, RegExt};
mod buffered; mod buffered;
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> {
/// UART TX driver. /// UART TX driver.
pub struct UartTx<'d, T: Instance, M: Mode> { pub struct UartTx<'d, T: Instance, M: Mode> {
tx_dma: Option<PeripheralRef<'d, AnyChannel>>, tx_dma: Option<Peri<'d, AnyChannel>>,
phantom: PhantomData<(&'d mut T, M)>, phantom: PhantomData<(&'d mut T, M)>,
} }
/// UART RX driver. /// UART RX driver.
pub struct UartRx<'d, T: Instance, M: Mode> { pub struct UartRx<'d, T: Instance, M: Mode> {
rx_dma: Option<PeripheralRef<'d, AnyChannel>>, rx_dma: Option<Peri<'d, AnyChannel>>,
phantom: PhantomData<(&'d mut T, M)>, phantom: PhantomData<(&'d mut T, M)>,
} }
impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
/// Create a new DMA-enabled UART which can only send data /// Create a new DMA-enabled UART which can only send data
pub fn new( pub fn new(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, tx_dma); Uart::<T, M>::init(Some(tx.into()), None, None, None, config);
Uart::<T, M>::init(Some(tx.map_into()), None, None, None, config); Self::new_inner(Some(tx_dma.into()))
Self::new_inner(Some(tx_dma.map_into()))
} }
fn new_inner(tx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
Self { Self {
tx_dma, tx_dma,
phantom: PhantomData, phantom: PhantomData,
@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
impl<'d, T: Instance> UartTx<'d, T, Blocking> { impl<'d, T: Instance> UartTx<'d, T, Blocking> {
/// Create a new UART TX instance for blocking mode operations. /// Create a new UART TX instance for blocking mode operations.
pub fn new_blocking( pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
_uart: impl Peripheral<P = T> + 'd, Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config);
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
config: Config,
) -> Self {
into_ref!(tx);
Uart::<T, Blocking>::init(Some(tx.map_into()), None, None, None, config);
Self::new_inner(None) Self::new_inner(None)
} }
@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
impl<'d, T: Instance> UartTx<'d, T, Async> { impl<'d, T: Instance> UartTx<'d, T, Async> {
/// Write to UART TX from the provided buffer using DMA. /// Write to UART TX from the provided buffer using DMA.
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
let ch = self.tx_dma.as_mut().unwrap(); let ch = self.tx_dma.as_mut().unwrap().reborrow();
let transfer = unsafe { let transfer = unsafe {
T::regs().uartdmacr().write_set(|reg| { T::regs().uartdmacr().write_set(|reg| {
reg.set_txdmae(true); reg.set_txdmae(true);
@ -268,18 +262,17 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
/// Create a new DMA-enabled UART which can only receive data /// Create a new DMA-enabled UART which can only receive data
pub fn new( pub fn new(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
rx_dma: impl Peripheral<P = impl Channel> + 'd, rx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(rx, rx_dma); Uart::<T, M>::init(None, Some(rx.into()), None, None, config);
Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config); Self::new_inner(true, Some(rx_dma.into()))
Self::new_inner(true, Some(rx_dma.map_into()))
} }
fn new_inner(has_irq: bool, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { fn new_inner(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
debug_assert_eq!(has_irq, rx_dma.is_some()); debug_assert_eq!(has_irq, rx_dma.is_some());
if has_irq { if has_irq {
// disable all error interrupts initially // disable all error interrupts initially
@ -346,13 +339,8 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
impl<'d, T: Instance> UartRx<'d, T, Blocking> { impl<'d, T: Instance> UartRx<'d, T, Blocking> {
/// Create a new UART RX instance for blocking mode operations. /// Create a new UART RX instance for blocking mode operations.
pub fn new_blocking( pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
_uart: impl Peripheral<P = T> + 'd, Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config);
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
config: Config,
) -> Self {
into_ref!(rx);
Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
Self::new_inner(false, None) Self::new_inner(false, None)
} }
@ -419,7 +407,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
// start a dma transfer. if errors have happened in the interim some error // start a dma transfer. if errors have happened in the interim some error
// interrupt flags will have been raised, and those will be picked up immediately // interrupt flags will have been raised, and those will be picked up immediately
// by the interrupt handler. // by the interrupt handler.
let ch = self.rx_dma.as_mut().unwrap(); let ch = self.rx_dma.as_mut().unwrap().reborrow();
T::regs().uartimsc().write_set(|w| { T::regs().uartimsc().write_set(|w| {
w.set_oeim(true); w.set_oeim(true);
w.set_beim(true); w.set_beim(true);
@ -566,7 +554,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
// start a dma transfer. if errors have happened in the interim some error // start a dma transfer. if errors have happened in the interim some error
// interrupt flags will have been raised, and those will be picked up immediately // interrupt flags will have been raised, and those will be picked up immediately
// by the interrupt handler. // by the interrupt handler.
let mut ch = self.rx_dma.as_mut().unwrap(); let ch = self.rx_dma.as_mut().unwrap();
T::regs().uartimsc().write_set(|w| { T::regs().uartimsc().write_set(|w| {
w.set_oeim(true); w.set_oeim(true);
w.set_beim(true); w.set_beim(true);
@ -583,7 +571,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
crate::dma::read( crate::dma::read(
&mut ch, ch.reborrow(),
T::regs().uartdr().as_ptr() as *const _, T::regs().uartdr().as_ptr() as *const _,
sbuffer, sbuffer,
T::RX_DREQ.into(), T::RX_DREQ.into(),
@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
impl<'d, T: Instance> Uart<'d, T, Blocking> { impl<'d, T: Instance> Uart<'d, T, Blocking> {
/// Create a new UART without hardware flow control /// Create a new UART without hardware flow control
pub fn new_blocking( pub fn new_blocking(
uart: impl Peripheral<P = T> + 'd, uart: Peri<'d, T>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx); Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config)
Self::new_inner(
uart,
tx.map_into(),
rx.map_into(),
None,
None,
false,
None,
None,
config,
)
} }
/// Create a new UART with hardware flow control (RTS/CTS) /// Create a new UART with hardware flow control (RTS/CTS)
pub fn new_with_rtscts_blocking( pub fn new_with_rtscts_blocking(
uart: impl Peripheral<P = T> + 'd, uart: Peri<'d, T>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: Peri<'d, impl RtsPin<T>>,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd, cts: Peri<'d, impl CtsPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx, cts, rts);
Self::new_inner( Self::new_inner(
uart, uart,
tx.map_into(), tx.into(),
rx.map_into(), rx.into(),
Some(rts.map_into()), Some(rts.into()),
Some(cts.map_into()), Some(cts.into()),
false, false,
None, None,
None, None,
@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
impl<'d, T: Instance> Uart<'d, T, Async> { impl<'d, T: Instance> Uart<'d, T, Async> {
/// Create a new DMA enabled UART without hardware flow control /// Create a new DMA enabled UART without hardware flow control
pub fn new( pub fn new(
uart: impl Peripheral<P = T> + 'd, uart: Peri<'d, T>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
rx_dma: impl Peripheral<P = impl Channel> + 'd, rx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx, tx_dma, rx_dma);
Self::new_inner( Self::new_inner(
uart, uart,
tx.map_into(), tx.into(),
rx.map_into(), rx.into(),
None, None,
None, None,
true, true,
Some(tx_dma.map_into()), Some(tx_dma.into()),
Some(rx_dma.map_into()), Some(rx_dma.into()),
config, config,
) )
} }
/// Create a new DMA enabled UART with hardware flow control (RTS/CTS) /// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uart: impl Peripheral<P = T> + 'd, uart: Peri<'d, T>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: Peri<'d, impl RtsPin<T>>,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd, cts: Peri<'d, impl CtsPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
tx_dma: impl Peripheral<P = impl Channel> + 'd, tx_dma: Peri<'d, impl Channel>,
rx_dma: impl Peripheral<P = impl Channel> + 'd, rx_dma: Peri<'d, impl Channel>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
Self::new_inner( Self::new_inner(
uart, uart,
tx.map_into(), tx.into(),
rx.map_into(), rx.into(),
Some(rts.map_into()), Some(rts.into()),
Some(cts.map_into()), Some(cts.into()),
true, true,
Some(tx_dma.map_into()), Some(tx_dma.into()),
Some(rx_dma.map_into()), Some(rx_dma.into()),
config, config,
) )
} }
@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
fn new_inner( fn new_inner(
_uart: impl Peripheral<P = T> + 'd, _uart: Peri<'d, T>,
mut tx: PeripheralRef<'d, AnyPin>, mut tx: Peri<'d, AnyPin>,
mut rx: PeripheralRef<'d, AnyPin>, mut rx: Peri<'d, AnyPin>,
mut rts: Option<PeripheralRef<'d, AnyPin>>, mut rts: Option<Peri<'d, AnyPin>>,
mut cts: Option<PeripheralRef<'d, AnyPin>>, mut cts: Option<Peri<'d, AnyPin>>,
has_irq: bool, has_irq: bool,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>, tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>, rx_dma: Option<Peri<'d, AnyChannel>>,
config: Config, config: Config,
) -> Self { ) -> Self {
Self::init( Self::init(
@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
} }
fn init( fn init(
tx: Option<PeripheralRef<'_, AnyPin>>, tx: Option<Peri<'_, AnyPin>>,
rx: Option<PeripheralRef<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>,
rts: Option<PeripheralRef<'_, AnyPin>>, rts: Option<Peri<'_, AnyPin>>,
cts: Option<PeripheralRef<'_, AnyPin>>, cts: Option<Peri<'_, AnyPin>>,
config: Config, config: Config,
) { ) {
let r = T::regs(); let r = T::regs();
@ -1326,7 +1300,7 @@ impl_mode!(Async);
/// UART instance. /// UART instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance { pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this instance. /// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -5,6 +5,7 @@ use core::slice;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::PeripheralType;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_usb_driver as driver; use embassy_usb_driver as driver;
use embassy_usb_driver::{ use embassy_usb_driver::{
@ -12,7 +13,7 @@ use embassy_usb_driver::{
}; };
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, Peri, RegExt};
trait SealedInstance { trait SealedInstance {
fn regs() -> crate::pac::usb::Usb; fn regs() -> crate::pac::usb::Usb;
@ -21,7 +22,7 @@ trait SealedInstance {
/// USB peripheral instance. /// USB peripheral instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
@ -107,7 +108,7 @@ pub struct Driver<'d, T: Instance> {
impl<'d, T: Instance> Driver<'d, T> { impl<'d, T: Instance> Driver<'d, T> {
/// Create a new USB driver. /// Create a new USB driver.
pub fn new(_usb: impl Peripheral<P = T> + 'd, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self { pub fn new(_usb: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self {
T::Interrupt::unpend(); T::Interrupt::unpend();
unsafe { T::Interrupt::enable() }; unsafe { T::Interrupt::enable() };

View File

@ -10,8 +10,8 @@ use core::marker::PhantomData;
use embassy_time::Duration; use embassy_time::Duration;
use crate::pac;
use crate::peripherals::WATCHDOG; use crate::peripherals::WATCHDOG;
use crate::{pac, Peri};
/// The reason for a system reset from the watchdog. /// The reason for a system reset from the watchdog.
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -30,7 +30,7 @@ pub struct Watchdog {
impl Watchdog { impl Watchdog {
/// Create a new `Watchdog` /// Create a new `Watchdog`
pub fn new(_watchdog: WATCHDOG) -> Self { pub fn new(_watchdog: Peri<'static, WATCHDOG>) -> Self {
Self { Self {
phantom: PhantomData, phantom: PhantomData,
load_value: 0, load_value: 0,

View File

@ -23,7 +23,7 @@ mod fmt;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::Peri;
use embassy_stm32::interrupt; use embassy_stm32::interrupt;
use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::peripherals::IPCC; use embassy_stm32::peripherals::IPCC;
@ -52,7 +52,7 @@ type PacketHeader = LinkedListNode;
/// Transport Layer for the Mailbox interface /// Transport Layer for the Mailbox interface
pub struct TlMbox<'d> { pub struct TlMbox<'d> {
_ipcc: PeripheralRef<'d, IPCC>, _ipcc: Peri<'d, IPCC>,
pub sys_subsystem: Sys, pub sys_subsystem: Sys,
pub mm_subsystem: MemoryManager, pub mm_subsystem: MemoryManager,
@ -92,13 +92,11 @@ impl<'d> TlMbox<'d> {
/// Figure 66. /// Figure 66.
// TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem
pub fn init( pub fn init(
ipcc: impl Peripheral<P = IPCC> + 'd, ipcc: Peri<'d, IPCC>,
_irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler> _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
+ interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>, + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(ipcc);
// this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289. // this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289.
// HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this // HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this
// implementation // implementation

View File

@ -324,7 +324,7 @@ fn main() {
let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
flash_regions.extend(quote! { flash_regions.extend(quote! {
#[cfg(flash)] #[cfg(flash)]
pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>); pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
}); });
} }
@ -356,7 +356,7 @@ fn main() {
#[cfg(flash)] #[cfg(flash)]
impl<'d, MODE> FlashLayout<'d, MODE> { impl<'d, MODE> FlashLayout<'d, MODE> {
pub(crate) fn new(p: embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { pub(crate) fn new(p: embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>) -> Self {
Self { Self {
#(#inits),*, #(#inits),*,
_mode: core::marker::PhantomData, _mode: core::marker::PhantomData,

View File

@ -8,7 +8,7 @@ use super::{
}; };
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{pac, rcc, Peripheral}; use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts. /// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300; pub const VREF_DEFAULT_MV: u32 = 3300;
@ -154,8 +154,7 @@ pub enum Averaging {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver. /// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd, sample_time: SampleTime, resolution: Resolution) -> Self { pub fn new(adc: Peri<'d, T>, sample_time: SampleTime, resolution: Resolution) -> Self {
embassy_hal_internal::into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK)); T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK));
@ -319,7 +318,7 @@ impl<'d, T: Instance> Adc<'d, T> {
Self::apply_channel_conf() Self::apply_channel_conf()
} }
async fn dma_convert(&mut self, rx_dma: &mut impl RxDma<T>, readings: &mut [u16]) { async fn dma_convert(&mut self, rx_dma: Peri<'_, impl RxDma<T>>, readings: &mut [u16]) {
// Enable overrun control, so no new DMA requests will be generated until // Enable overrun control, so no new DMA requests will be generated until
// previous DR values is read. // previous DR values is read.
T::regs().isr().modify(|reg| { T::regs().isr().modify(|reg| {
@ -374,7 +373,7 @@ impl<'d, T: Instance> Adc<'d, T> {
/// TODO(chudsaviet): externalize generic code and merge with read(). /// TODO(chudsaviet): externalize generic code and merge with read().
pub async fn read_in_hw_order( pub async fn read_in_hw_order(
&mut self, &mut self,
rx_dma: &mut impl RxDma<T>, rx_dma: Peri<'_, impl RxDma<T>>,
hw_channel_selection: u32, hw_channel_selection: u32,
scandir: Scandir, scandir: Scandir,
readings: &mut [u16], readings: &mut [u16],
@ -415,7 +414,7 @@ impl<'d, T: Instance> Adc<'d, T> {
// For other channels, use `read_in_hw_order()` or blocking read. // For other channels, use `read_in_hw_order()` or blocking read.
pub async fn read( pub async fn read(
&mut self, &mut self,
rx_dma: &mut impl RxDma<T>, rx_dma: Peri<'_, impl RxDma<T>>,
channel_sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>, channel_sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
readings: &mut [u16], readings: &mut [u16],
) { ) {

View File

@ -2,12 +2,10 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::into_ref;
use super::blocking_delay_us; use super::blocking_delay_us;
use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, rcc, Peripheral}; use crate::{interrupt, rcc, Peri};
pub const VDDA_CALIB_MV: u32 = 3300; pub const VDDA_CALIB_MV: u32 = 3300;
pub const ADC_MAX: u32 = (1 << 12) - 1; pub const ADC_MAX: u32 = (1 << 12) - 1;
@ -48,8 +46,7 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
} }
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
T::regs().cr2().modify(|reg| reg.set_adon(true)); T::regs().cr2().modify(|reg| reg.set_adon(true));

View File

@ -2,13 +2,11 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::into_ref;
use super::blocking_delay_us; use super::blocking_delay_us;
use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, rcc, Peripheral}; use crate::{interrupt, rcc, Peri};
pub const VDDA_CALIB_MV: u32 = 3300; pub const VDDA_CALIB_MV: u32 = 3300;
pub const ADC_MAX: u32 = (1 << 12) - 1; pub const ADC_MAX: u32 = (1 << 12) - 1;
@ -56,13 +54,11 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new( pub fn new(
adc: impl Peripheral<P = T> + 'd, adc: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
use crate::pac::adc::vals; use crate::pac::adc::vals;
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
// Enable the adc regulator // Enable the adc regulator

View File

@ -3,14 +3,13 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_futures::yield_now; use embassy_futures::yield_now;
use embassy_hal_internal::into_ref;
use embassy_time::Instant; use embassy_time::Instant;
use super::Resolution; use super::Resolution;
use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, rcc, Peripheral}; use crate::{interrupt, rcc, Peri};
const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ; const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ;
@ -138,11 +137,9 @@ impl<T: Instance> Drop for Temperature<T> {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new( pub fn new(
adc: impl Peripheral<P = T> + 'd, adc: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
//let r = T::regs(); //let r = T::regs();

View File

@ -11,7 +11,7 @@ use super::{blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolut
use crate::adc::SealedAdcChannel; use crate::adc::SealedAdcChannel;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{pac, rcc, Peripheral}; use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts. /// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300; pub const VREF_DEFAULT_MV: u32 = 3300;
@ -135,8 +135,7 @@ impl Prescaler {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver. /// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
embassy_hal_internal::into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
let prescaler = Prescaler::from_ker_ck(T::frequency()); let prescaler = Prescaler::from_ker_ck(T::frequency());
@ -364,8 +363,8 @@ impl<'d, T: Instance> Adc<'d, T> {
/// use embassy_stm32::adc::{Adc, AdcChannel} /// use embassy_stm32::adc::{Adc, AdcChannel}
/// ///
/// let mut adc = Adc::new(p.ADC1); /// let mut adc = Adc::new(p.ADC1);
/// let mut adc_pin0 = p.PA0.degrade_adc(); /// let mut adc_pin0 = p.PA0.into();
/// let mut adc_pin1 = p.PA1.degrade_adc(); /// let mut adc_pin1 = p.PA1.into();
/// let mut measurements = [0u16; 2]; /// let mut measurements = [0u16; 2];
/// ///
/// adc.read_async( /// adc.read_async(
@ -382,7 +381,7 @@ impl<'d, T: Instance> Adc<'d, T> {
/// ``` /// ```
pub async fn read( pub async fn read(
&mut self, &mut self,
rx_dma: &mut impl RxDma<T>, rx_dma: Peri<'_, impl RxDma<T>>,
sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
readings: &mut [u16], readings: &mut [u16],
) { ) {

View File

@ -22,6 +22,7 @@ use core::marker::PhantomData;
#[allow(unused)] #[allow(unused)]
#[cfg(not(any(adc_f3_v2)))] #[cfg(not(any(adc_f3_v2)))]
pub use _version::*; pub use _version::*;
use embassy_hal_internal::{impl_peripheral, PeripheralType};
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -42,7 +43,7 @@ dma_trait!(RxDma4, adc4::Instance);
/// Analog to Digital driver. /// Analog to Digital driver.
pub struct Adc<'d, T: Instance> { pub struct Adc<'d, T: Instance> {
#[allow(unused)] #[allow(unused)]
adc: crate::PeripheralRef<'d, T>, adc: crate::Peri<'d, T>,
#[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))] #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))]
sample_time: SampleTime, sample_time: SampleTime,
} }
@ -111,7 +112,7 @@ pub(crate) fn blocking_delay_us(us: u32) {
adc_c0 adc_c0
)))] )))]
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> { pub trait Instance: SealedInstance + crate::PeripheralType {
type Interrupt: crate::interrupt::typelevel::Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
/// ADC instance. /// ADC instance.
@ -132,7 +133,7 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
adc_c0 adc_c0
))] ))]
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
type Interrupt: crate::interrupt::typelevel::Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
@ -159,7 +160,7 @@ pub struct AnyAdcChannel<T> {
channel: u8, channel: u8,
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl_peripheral!(AnyAdcChannel<T: Instance>);
impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {} impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
fn channel(&self) -> u8 { fn channel(&self) -> u8 {
@ -233,11 +234,11 @@ foreach_adc!(
macro_rules! impl_adc_pin { macro_rules! impl_adc_pin {
($inst:ident, $pin:ident, $ch:expr) => { ($inst:ident, $pin:ident, $ch:expr) => {
impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {} impl crate::adc::AdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {}
impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin { impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {
#[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))]
fn setup(&mut self) { fn setup(&mut self) {
<Self as crate::gpio::SealedPin>::set_as_analog(self); <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(self);
} }
fn channel(&self) -> u8 { fn channel(&self) -> u8 {

View File

@ -2,13 +2,12 @@ use core::marker::PhantomData;
use core::mem; use core::mem;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_internal::{into_ref, Peripheral};
use stm32_metapac::adc::vals::SampleTime; use stm32_metapac::adc::vals::SampleTime;
use crate::adc::{Adc, AdcChannel, Instance, RxDma}; use crate::adc::{Adc, AdcChannel, Instance, RxDma};
use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; use crate::dma::{Priority, ReadableRingBuffer, TransferOptions};
use crate::pac::adc::vals; use crate::pac::adc::vals;
use crate::rcc; use crate::{rcc, Peri};
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct OverrunError; pub struct OverrunError;
@ -103,13 +102,8 @@ impl<'d, T: Instance> Adc<'d, T> {
/// It is critical to call `read` frequently to prevent DMA buffer overrun. /// It is critical to call `read` frequently to prevent DMA buffer overrun.
/// ///
/// [`read`]: #method.read /// [`read`]: #method.read
pub fn into_ring_buffered( pub fn into_ring_buffered(self, dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> RingBufferedAdc<'d, T> {
self,
dma: impl Peripheral<P = impl RxDma<T>> + 'd,
dma_buf: &'d mut [u16],
) -> RingBufferedAdc<'d, T> {
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
into_ref!(dma);
let opts: crate::dma::TransferOptions = TransferOptions { let opts: crate::dma::TransferOptions = TransferOptions {
half_transfer_ir: true, half_transfer_ir: true,

View File

@ -6,7 +6,7 @@ use crate::dma::Transfer;
pub use crate::pac::adc::regs::Adc4Chselrmod0; pub use crate::pac::adc::regs::Adc4Chselrmod0;
pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime}; pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime};
use crate::time::Hertz; use crate::time::Hertz;
use crate::{pac, rcc, Peripheral}; use crate::{pac, rcc, Peri};
const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);
@ -169,13 +169,13 @@ pub trait SealedInstance {
fn regs() -> crate::pac::adc::Adc4; fn regs() -> crate::pac::adc::Adc4;
} }
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
type Interrupt: crate::interrupt::typelevel::Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
pub struct Adc4<'d, T: Instance> { pub struct Adc4<'d, T: Instance> {
#[allow(unused)] #[allow(unused)]
adc: crate::PeripheralRef<'d, T>, adc: crate::Peri<'d, T>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -186,8 +186,7 @@ pub enum Adc4Error {
impl<'d, T: Instance> Adc4<'d, T> { impl<'d, T: Instance> Adc4<'d, T> {
/// Create a new ADC driver. /// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
embassy_hal_internal::into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
let prescaler = Prescaler::from_ker_ck(T::frequency()); let prescaler = Prescaler::from_ker_ck(T::frequency());
@ -379,15 +378,15 @@ impl<'d, T: Instance> Adc4<'d, T> {
/// let mut adc4 = adc4::Adc4::new(p.ADC4); /// let mut adc4 = adc4::Adc4::new(p.ADC4);
/// let mut adc4_pin1 = p.PC1; /// let mut adc4_pin1 = p.PC1;
/// let mut adc4_pin2 = p.PC0; /// let mut adc4_pin2 = p.PC0;
/// let mut degraded41 = adc4_pin1.degrade_adc(); /// let mut.into()d41 = adc4_pin1.into();
/// let mut degraded42 = adc4_pin2.degrade_adc(); /// let mut.into()d42 = adc4_pin2.into();
/// let mut measurements = [0u16; 2]; /// let mut measurements = [0u16; 2];
/// // not that the channels must be in ascending order /// // not that the channels must be in ascending order
/// adc4.read( /// adc4.read(
/// &mut p.GPDMA1_CH1, /// &mut p.GPDMA1_CH1,
/// [ /// [
/// &mut degraded42, /// &mut.into()d42,
/// &mut degraded41, /// &mut.into()d41,
/// ] /// ]
/// .into_iter(), /// .into_iter(),
/// &mut measurements, /// &mut measurements,
@ -395,7 +394,7 @@ impl<'d, T: Instance> Adc4<'d, T> {
/// ``` /// ```
pub async fn read( pub async fn read(
&mut self, &mut self,
rx_dma: &mut impl RxDma4<T>, rx_dma: Peri<'_, impl RxDma4<T>>,
sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>, sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
readings: &mut [u16], readings: &mut [u16],
) -> Result<(), Adc4Error> { ) -> Result<(), Adc4Error> {

View File

@ -2,7 +2,6 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::into_ref;
#[cfg(adc_l0)] #[cfg(adc_l0)]
use stm32_metapac::adc::vals::Ckmode; use stm32_metapac::adc::vals::Ckmode;
@ -10,7 +9,7 @@ use super::blocking_delay_us;
use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::peripherals::ADC1; use crate::peripherals::ADC1;
use crate::{interrupt, rcc, Peripheral}; use crate::{interrupt, rcc, Peri};
pub const VDDA_CALIB_MV: u32 = 3300; pub const VDDA_CALIB_MV: u32 = 3300;
pub const VREF_INT: u32 = 1230; pub const VREF_INT: u32 = 1230;
@ -63,10 +62,9 @@ impl super::SealedAdcChannel<ADC1> for Temperature {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new( pub fn new(
adc: impl Peripheral<P = T> + 'd, adc: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
// Delay 1μs when using HSI14 as the ADC clock. // Delay 1μs when using HSI14 as the ADC clock.

View File

@ -1,10 +1,8 @@
use embassy_hal_internal::into_ref;
use super::blocking_delay_us; use super::blocking_delay_us;
use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
use crate::peripherals::ADC1; use crate::peripherals::ADC1;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{rcc, Peripheral}; use crate::{rcc, Peri};
mod ringbuffered_v2; mod ringbuffered_v2;
pub use ringbuffered_v2::{RingBufferedAdc, Sequence}; pub use ringbuffered_v2::{RingBufferedAdc, Sequence};
@ -97,8 +95,7 @@ impl<'d, T> Adc<'d, T>
where where
T: Instance, T: Instance,
{ {
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
let presc = Prescaler::from_pclk2(T::frequency()); let presc = Prescaler::from_pclk2(T::frequency());

View File

@ -1,12 +1,11 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use embassy_hal_internal::into_ref;
use pac::adc::vals::Dmacfg; use pac::adc::vals::Dmacfg;
use super::{ use super::{
blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel,
}; };
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::{pac, rcc, Peripheral}; use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts. /// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300; pub const VREF_DEFAULT_MV: u32 = 3300;
@ -95,8 +94,7 @@ cfg_if! {
} }
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
T::regs().cr().modify(|reg| { T::regs().cr().modify(|reg| {
#[cfg(not(any(adc_g0, adc_u0)))] #[cfg(not(any(adc_g0, adc_u0)))]
@ -288,7 +286,7 @@ impl<'d, T: Instance> Adc<'d, T> {
/// ``` /// ```
pub async fn read( pub async fn read(
&mut self, &mut self,
rx_dma: &mut impl RxDma<T>, rx_dma: Peri<'_, impl RxDma<T>>,
sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
readings: &mut [u16], readings: &mut [u16],
) { ) {

View File

@ -9,7 +9,7 @@ use super::{
}; };
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{pac, rcc, Peripheral}; use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts. /// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300; pub const VREF_DEFAULT_MV: u32 = 3300;
@ -158,8 +158,7 @@ pub enum Averaging {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver. /// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { pub fn new(adc: Peri<'d, T>) -> Self {
embassy_hal_internal::into_ref!(adc);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
let prescaler = Prescaler::from_ker_ck(T::frequency()); let prescaler = Prescaler::from_ker_ck(T::frequency());
@ -344,8 +343,8 @@ impl<'d, T: Instance> Adc<'d, T> {
/// use embassy_stm32::adc::{Adc, AdcChannel} /// use embassy_stm32::adc::{Adc, AdcChannel}
/// ///
/// let mut adc = Adc::new(p.ADC1); /// let mut adc = Adc::new(p.ADC1);
/// let mut adc_pin0 = p.PA0.degrade_adc(); /// let mut adc_pin0 = p.PA0.into();
/// let mut adc_pin2 = p.PA2.degrade_adc(); /// let mut adc_pin2 = p.PA2.into();
/// let mut measurements = [0u16; 2]; /// let mut measurements = [0u16; 2];
/// ///
/// adc.read_async( /// adc.read_async(
@ -362,7 +361,7 @@ impl<'d, T: Instance> Adc<'d, T> {
/// ``` /// ```
pub async fn read( pub async fn read(
&mut self, &mut self,
rx_dma: &mut impl RxDma<T>, rx_dma: Peri<'_, impl RxDma<T>>,
sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
readings: &mut [u16], readings: &mut [u16],
) { ) {

View File

@ -6,7 +6,7 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::interrupt::InterruptExt; use embassy_hal_internal::interrupt::InterruptExt;
use embassy_hal_internal::into_ref; use embassy_hal_internal::PeripheralType;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -21,7 +21,7 @@ use crate::can::enums::{BusError, InternalOperation, TryReadError};
use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::gpio::{AfType, OutputType, Pull, Speed};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::rcc::{self, RccPeripheral}; use crate::rcc::{self, RccPeripheral};
use crate::{interrupt, peripherals, Peripheral}; use crate::{interrupt, peripherals, Peri};
/// Interrupt handler. /// Interrupt handler.
pub struct TxInterruptHandler<T: Instance> { pub struct TxInterruptHandler<T: Instance> {
@ -173,16 +173,15 @@ impl<'d> Can<'d> {
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode. /// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
/// You must call [Can::enable_non_blocking] to use the peripheral. /// You must call [Can::enable_non_blocking] to use the peripheral.
pub fn new<T: Instance>( pub fn new<T: Instance>(
_peri: impl Peripheral<P = T> + 'd, _peri: Peri<'d, T>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
_irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>> _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
+ interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>> + interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
+ interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>> + interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>
+ interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>> + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>>
+ 'd, + 'd,
) -> Self { ) -> Self {
into_ref!(_peri, rx, tx);
let info = T::info(); let info = T::info();
let regs = &T::info().regs; let regs = &T::info().regs;
@ -1083,7 +1082,7 @@ trait SealedInstance {
/// CAN instance trait. /// CAN instance trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + 'static { pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
/// TX interrupt for this instance. /// TX interrupt for this instance.
type TXInterrupt: crate::interrupt::typelevel::Interrupt; type TXInterrupt: crate::interrupt::typelevel::Interrupt;
/// RX0 interrupt for this instance. /// RX0 interrupt for this instance.

View File

@ -4,7 +4,7 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::interrupt::InterruptExt; use embassy_hal_internal::interrupt::InterruptExt;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::PeripheralType;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -13,7 +13,7 @@ use crate::can::fd::peripheral::Registers;
use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::gpio::{AfType, OutputType, Pull, Speed};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::rcc::{self, RccPeripheral}; use crate::rcc::{self, RccPeripheral};
use crate::{interrupt, peripherals, Peripheral}; use crate::{interrupt, peripherals, Peri};
pub(crate) mod fd; pub(crate) mod fd;
@ -175,15 +175,13 @@ impl<'d> CanConfigurator<'d> {
/// Creates a new Fdcan instance, keeping the peripheral in sleep mode. /// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
/// You must call [Fdcan::enable_non_blocking] to use the peripheral. /// You must call [Fdcan::enable_non_blocking] to use the peripheral.
pub fn new<T: Instance>( pub fn new<T: Instance>(
_peri: impl Peripheral<P = T> + 'd, _peri: Peri<'d, T>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: Peri<'d, impl RxPin<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: Peri<'d, impl TxPin<T>>,
_irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>> _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
+ interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>> + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
+ 'd, + 'd,
) -> CanConfigurator<'d> { ) -> CanConfigurator<'d> {
into_ref!(_peri, rx, tx);
rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
@ -957,7 +955,7 @@ trait SealedInstance {
/// Instance trait /// Instance trait
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static { pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
/// Interrupt 0 /// Interrupt 0
type IT0Interrupt: crate::interrupt::typelevel::Interrupt; type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
/// Interrupt 1 /// Interrupt 1
@ -965,7 +963,7 @@ pub trait Instance: SealedInstance + RccPeripheral + 'static {
} }
/// Fdcan Instance struct /// Fdcan Instance struct
pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); pub struct FdcanInstance<'a, T: Instance>(Peri<'a, T>);
macro_rules! impl_fdcan { macro_rules! impl_fdcan {
($inst:ident, ($inst:ident,

View File

@ -1,7 +1,7 @@
//! coordinate rotation digital computer (CORDIC) //! coordinate rotation digital computer (CORDIC)
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use crate::pac::cordic::vals; use crate::pac::cordic::vals;
use crate::{dma, peripherals, rcc}; use crate::{dma, peripherals, rcc};
@ -16,7 +16,7 @@ pub mod utils;
/// CORDIC driver /// CORDIC driver
pub struct Cordic<'d, T: Instance> { pub struct Cordic<'d, T: Instance> {
peri: PeripheralRef<'d, T>, peri: Peri<'d, T>,
config: Config, config: Config,
} }
@ -137,7 +137,7 @@ trait SealedInstance {
/// CORDIC instance trait /// CORDIC instance trait
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral {} pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral {}
/// CORDIC configuration /// CORDIC configuration
#[derive(Debug)] #[derive(Debug)]
@ -198,11 +198,9 @@ impl<'d, T: Instance> Cordic<'d, T> {
/// Note: /// Note:
/// If you need a peripheral -> CORDIC -> peripheral mode, /// If you need a peripheral -> CORDIC -> peripheral mode,
/// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config] /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config]
pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self { pub fn new(peri: Peri<'d, T>, config: Config) -> Self {
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
into_ref!(peri);
let mut instance = Self { peri, config }; let mut instance = Self { peri, config };
instance.reconfigure(); instance.reconfigure();
@ -378,8 +376,8 @@ impl<'d, T: Instance> Cordic<'d, T> {
/// If you want to make sure ARG2 is set to +1, consider run [.reconfigure()](Self::reconfigure). /// If you want to make sure ARG2 is set to +1, consider run [.reconfigure()](Self::reconfigure).
pub async fn async_calc_32bit( pub async fn async_calc_32bit(
&mut self, &mut self,
write_dma: impl Peripheral<P = impl WriteDma<T>>, mut write_dma: Peri<'_, impl WriteDma<T>>,
read_dma: impl Peripheral<P = impl ReadDma<T>>, mut read_dma: Peri<'_, impl ReadDma<T>>,
arg: &[u32], arg: &[u32],
res: &mut [u32], res: &mut [u32],
arg1_only: bool, arg1_only: bool,
@ -393,8 +391,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
let active_res_buf = &mut res[..res_cnt]; let active_res_buf = &mut res[..res_cnt];
into_ref!(write_dma, read_dma);
self.peri self.peri
.set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two }); .set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two });
@ -416,7 +412,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
unsafe { unsafe {
let write_transfer = dma::Transfer::new_write( let write_transfer = dma::Transfer::new_write(
&mut write_dma, write_dma.reborrow(),
write_req, write_req,
arg, arg,
T::regs().wdata().as_ptr() as *mut _, T::regs().wdata().as_ptr() as *mut _,
@ -424,7 +420,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
); );
let read_transfer = dma::Transfer::new_read( let read_transfer = dma::Transfer::new_read(
&mut read_dma, read_dma.reborrow(),
read_req, read_req,
T::regs().rdata().as_ptr() as *mut _, T::regs().rdata().as_ptr() as *mut _,
active_res_buf, active_res_buf,
@ -519,8 +515,8 @@ impl<'d, T: Instance> Cordic<'d, T> {
/// User will take respond to merge two u16 arguments into one u32 data, and/or split one u32 data into two u16 results. /// User will take respond to merge two u16 arguments into one u32 data, and/or split one u32 data into two u16 results.
pub async fn async_calc_16bit( pub async fn async_calc_16bit(
&mut self, &mut self,
write_dma: impl Peripheral<P = impl WriteDma<T>>, mut write_dma: Peri<'_, impl WriteDma<T>>,
read_dma: impl Peripheral<P = impl ReadDma<T>>, mut read_dma: Peri<'_, impl ReadDma<T>>,
arg: &[u32], arg: &[u32],
res: &mut [u32], res: &mut [u32],
) -> Result<usize, CordicError> { ) -> Result<usize, CordicError> {
@ -536,8 +532,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
let active_res_buf = &mut res[..res_cnt]; let active_res_buf = &mut res[..res_cnt];
into_ref!(write_dma, read_dma);
// In q1.15 mode, 1 write/read to access 2 arguments/results // In q1.15 mode, 1 write/read to access 2 arguments/results
self.peri.set_argument_count(AccessCount::One); self.peri.set_argument_count(AccessCount::One);
self.peri.set_result_count(AccessCount::One); self.peri.set_result_count(AccessCount::One);
@ -557,7 +551,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
unsafe { unsafe {
let write_transfer = dma::Transfer::new_write( let write_transfer = dma::Transfer::new_write(
&mut write_dma, write_dma.reborrow(),
write_req, write_req,
arg, arg,
T::regs().wdata().as_ptr() as *mut _, T::regs().wdata().as_ptr() as *mut _,
@ -565,7 +559,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
); );
let read_transfer = dma::Transfer::new_read( let read_transfer = dma::Transfer::new_read(
&mut read_dma, read_dma.reborrow(),
read_req, read_req,
T::regs().rdata().as_ptr() as *mut _, T::regs().rdata().as_ptr() as *mut _,
active_res_buf, active_res_buf,

View File

@ -1,23 +1,18 @@
use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC; use crate::peripherals::CRC;
use crate::{rcc, Peripheral}; use crate::{rcc, Peri};
/// CRC driver. /// CRC driver.
pub struct Crc<'d> { pub struct Crc<'d> {
_peri: PeripheralRef<'d, CRC>, _peri: Peri<'d, CRC>,
} }
impl<'d> Crc<'d> { impl<'d> Crc<'d> {
/// Instantiates the CRC32 peripheral and initializes it to default values. /// Instantiates the CRC32 peripheral and initializes it to default values.
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd) -> Self { pub fn new(peripheral: Peri<'d, CRC>) -> Self {
into_ref!(peripheral);
// Note: enable and reset come from RccPeripheral. // Note: enable and reset come from RccPeripheral.
// enable CRC clock in RCC. // enable CRC clock in RCC.
rcc::enable_and_reset::<CRC>(); rcc::enable_and_reset::<CRC>();
// Peripheral the peripheral
let mut instance = Self { _peri: peripheral }; let mut instance = Self { _peri: peripheral };
instance.reset(); instance.reset();
instance instance

View File

@ -1,13 +1,11 @@
use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::pac::crc::vals; use crate::pac::crc::vals;
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC; use crate::peripherals::CRC;
use crate::{rcc, Peripheral}; use crate::{rcc, Peri};
/// CRC driver. /// CRC driver.
pub struct Crc<'d> { pub struct Crc<'d> {
_peripheral: PeripheralRef<'d, CRC>, _peripheral: Peri<'d, CRC>,
_config: Config, _config: Config,
} }
@ -80,11 +78,10 @@ pub enum PolySize {
impl<'d> Crc<'d> { impl<'d> Crc<'d> {
/// Instantiates the CRC32 peripheral and initializes it to default values. /// Instantiates the CRC32 peripheral and initializes it to default values.
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self { pub fn new(peripheral: Peri<'d, CRC>, config: Config) -> Self {
// Note: enable and reset come from RccPeripheral. // Note: enable and reset come from RccPeripheral.
// reset to default values and enable CRC clock in RCC. // reset to default values and enable CRC clock in RCC.
rcc::enable_and_reset::<CRC>(); rcc::enable_and_reset::<CRC>();
into_ref!(peripheral);
let mut instance = Self { let mut instance = Self {
_peripheral: peripheral, _peripheral: peripheral,
_config: config, _config: config,

View File

@ -4,13 +4,13 @@ use core::cmp::min;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ptr; use core::ptr;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::dma::{ChannelAndRequest, TransferOptions}; use crate::dma::{ChannelAndRequest, TransferOptions};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::mode::{Async, Blocking, Mode}; use crate::mode::{Async, Blocking, Mode};
use crate::{interrupt, pac, peripherals, rcc, Peripheral}; use crate::{interrupt, pac, peripherals, rcc};
const DES_BLOCK_SIZE: usize = 8; // 64 bits const DES_BLOCK_SIZE: usize = 8; // 64 bits
const AES_BLOCK_SIZE: usize = 16; // 128 bits const AES_BLOCK_SIZE: usize = 16; // 128 bits
@ -988,7 +988,7 @@ pub enum Direction {
/// Crypto Accelerator Driver /// Crypto Accelerator Driver
pub struct Cryp<'d, T: Instance, M: Mode> { pub struct Cryp<'d, T: Instance, M: Mode> {
_peripheral: PeripheralRef<'d, T>, _peripheral: Peri<'d, T>,
_phantom: PhantomData<M>, _phantom: PhantomData<M>,
indma: Option<ChannelAndRequest<'d>>, indma: Option<ChannelAndRequest<'d>>,
outdma: Option<ChannelAndRequest<'d>>, outdma: Option<ChannelAndRequest<'d>>,
@ -997,11 +997,10 @@ pub struct Cryp<'d, T: Instance, M: Mode> {
impl<'d, T: Instance> Cryp<'d, T, Blocking> { impl<'d, T: Instance> Cryp<'d, T, Blocking> {
/// Create a new CRYP driver in blocking mode. /// Create a new CRYP driver in blocking mode.
pub fn new_blocking( pub fn new_blocking(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
into_ref!(peri);
let instance = Self { let instance = Self {
_peripheral: peri, _peripheral: peri,
_phantom: PhantomData, _phantom: PhantomData,
@ -1461,13 +1460,12 @@ impl<'d, T: Instance, M: Mode> Cryp<'d, T, M> {
impl<'d, T: Instance> Cryp<'d, T, Async> { impl<'d, T: Instance> Cryp<'d, T, Async> {
/// Create a new CRYP driver. /// Create a new CRYP driver.
pub fn new( pub fn new(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
indma: impl Peripheral<P = impl DmaIn<T>> + 'd, indma: Peri<'d, impl DmaIn<T>>,
outdma: impl Peripheral<P = impl DmaOut<T>> + 'd, outdma: Peri<'d, impl DmaOut<T>>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
into_ref!(peri, indma, outdma);
let instance = Self { let instance = Self {
_peripheral: peri, _peripheral: peri,
_phantom: PhantomData, _phantom: PhantomData,
@ -1879,7 +1877,7 @@ trait SealedInstance {
/// CRYP instance trait. /// CRYP instance trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
/// Interrupt for this CRYP instance. /// Interrupt for this CRYP instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -3,16 +3,15 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_internal::into_ref;
use crate::dma::ChannelAndRequest; use crate::dma::ChannelAndRequest;
use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::mode::{Async, Blocking, Mode as PeriMode};
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
use crate::pac::dac; use crate::pac::dac;
use crate::rcc::{self, RccPeripheral}; use crate::rcc::{self, RccPeripheral};
use crate::{peripherals, Peripheral}; use crate::{peripherals, Peri};
mod tsel; mod tsel;
use embassy_hal_internal::PeripheralType;
pub use tsel::TriggerSel; pub use tsel::TriggerSel;
/// Operating mode for DAC channel /// Operating mode for DAC channel
@ -121,12 +120,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> {
/// ///
/// By default, triggering is disabled, but it can be enabled using /// By default, triggering is disabled, but it can be enabled using
/// [`DacChannel::set_trigger()`]. /// [`DacChannel::set_trigger()`].
pub fn new( pub fn new(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = impl Dma<T, C>> + 'd,
pin: impl Peripheral<P = impl DacPin<T, C>> + 'd,
) -> Self {
into_ref!(dma, pin);
pin.set_as_analog(); pin.set_as_analog();
Self::new_inner( Self::new_inner(
peri, peri,
@ -147,8 +141,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> {
/// By default, triggering is disabled, but it can be enabled using /// By default, triggering is disabled, but it can be enabled using
/// [`DacChannel::set_trigger()`]. /// [`DacChannel::set_trigger()`].
#[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
pub fn new_internal(peri: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Dma<T, C>> + 'd) -> Self { pub fn new_internal(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>) -> Self {
into_ref!(dma);
Self::new_inner(peri, new_dma!(dma), Mode::NormalInternalUnbuffered) Self::new_inner(peri, new_dma!(dma), Mode::NormalInternalUnbuffered)
} }
@ -204,8 +197,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> {
/// ///
/// By default, triggering is disabled, but it can be enabled using /// By default, triggering is disabled, but it can be enabled using
/// [`DacChannel::set_trigger()`]. /// [`DacChannel::set_trigger()`].
pub fn new_blocking(peri: impl Peripheral<P = T> + 'd, pin: impl Peripheral<P = impl DacPin<T, C>> + 'd) -> Self { pub fn new_blocking(peri: Peri<'d, T>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
into_ref!(pin);
pin.set_as_analog(); pin.set_as_analog();
Self::new_inner( Self::new_inner(
peri, peri,
@ -226,14 +218,14 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> {
/// By default, triggering is disabled, but it can be enabled using /// By default, triggering is disabled, but it can be enabled using
/// [`DacChannel::set_trigger()`]. /// [`DacChannel::set_trigger()`].
#[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
pub fn new_internal_blocking(peri: impl Peripheral<P = T> + 'd) -> Self { pub fn new_internal_blocking(peri: Peri<'d, T>) -> Self {
Self::new_inner(peri, None, Mode::NormalInternalUnbuffered) Self::new_inner(peri, None, Mode::NormalInternalUnbuffered)
} }
} }
impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> { impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> {
fn new_inner( fn new_inner(
_peri: impl Peripheral<P = T> + 'd, _peri: Peri<'d, T>,
dma: Option<ChannelAndRequest<'d>>, dma: Option<ChannelAndRequest<'d>>,
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
) -> Self { ) -> Self {
@ -395,13 +387,12 @@ impl<'d, T: Instance> Dac<'d, T, Async> {
/// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
/// method on the underlying channels. /// method on the underlying channels.
pub fn new( pub fn new(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma_ch1: impl Peripheral<P = impl Dma<T, Ch1>> + 'd, dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
dma_ch2: impl Peripheral<P = impl Dma<T, Ch2>> + 'd, dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
pin_ch1: impl Peripheral<P = impl DacPin<T, Ch1> + crate::gpio::Pin> + 'd, pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
pin_ch2: impl Peripheral<P = impl DacPin<T, Ch2> + crate::gpio::Pin> + 'd, pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
) -> Self { ) -> Self {
into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
pin_ch1.set_as_analog(); pin_ch1.set_as_analog();
pin_ch2.set_as_analog(); pin_ch2.set_as_analog();
Self::new_inner( Self::new_inner(
@ -429,11 +420,10 @@ impl<'d, T: Instance> Dac<'d, T, Async> {
/// method on the underlying channels. /// method on the underlying channels.
#[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
pub fn new_internal( pub fn new_internal(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma_ch1: impl Peripheral<P = impl Dma<T, Ch1>> + 'd, dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
dma_ch2: impl Peripheral<P = impl Dma<T, Ch2>> + 'd, dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
) -> Self { ) -> Self {
into_ref!(dma_ch1, dma_ch2);
Self::new_inner( Self::new_inner(
peri, peri,
new_dma!(dma_ch1), new_dma!(dma_ch1),
@ -457,11 +447,10 @@ impl<'d, T: Instance> Dac<'d, T, Blocking> {
/// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
/// method on the underlying channels. /// method on the underlying channels.
pub fn new_blocking( pub fn new_blocking(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
pin_ch1: impl Peripheral<P = impl DacPin<T, Ch1> + crate::gpio::Pin> + 'd, pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
pin_ch2: impl Peripheral<P = impl DacPin<T, Ch2> + crate::gpio::Pin> + 'd, pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
) -> Self { ) -> Self {
into_ref!(pin_ch1, pin_ch2);
pin_ch1.set_as_analog(); pin_ch1.set_as_analog();
pin_ch2.set_as_analog(); pin_ch2.set_as_analog();
Self::new_inner( Self::new_inner(
@ -488,14 +477,14 @@ impl<'d, T: Instance> Dac<'d, T, Blocking> {
/// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
/// method on the underlying channels. /// method on the underlying channels.
#[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
pub fn new_internal(peri: impl Peripheral<P = T> + 'd) -> Self { pub fn new_internal(peri: Peri<'d, T>) -> Self {
Self::new_inner(peri, None, None, Mode::NormalInternalUnbuffered) Self::new_inner(peri, None, None, Mode::NormalInternalUnbuffered)
} }
} }
impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> { impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> {
fn new_inner( fn new_inner(
_peri: impl Peripheral<P = T> + 'd, _peri: Peri<'d, T>,
dma_ch1: Option<ChannelAndRequest<'d>>, dma_ch1: Option<ChannelAndRequest<'d>>,
dma_ch2: Option<ChannelAndRequest<'d>>, dma_ch2: Option<ChannelAndRequest<'d>>,
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
@ -572,7 +561,7 @@ trait SealedInstance {
/// DAC instance. /// DAC instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {} pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
/// Channel 1 marker type. /// Channel 1 marker type.
pub enum Ch1 {} pub enum Ch1 {}

View File

@ -3,13 +3,13 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::PeripheralType;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::gpio::{AfType, Pull}; use crate::gpio::{AfType, Pull};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, rcc, Peripheral}; use crate::{interrupt, rcc, Peri};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler<T: Instance> { pub struct InterruptHandler<T: Instance> {
@ -106,8 +106,7 @@ impl Default for Config {
macro_rules! config_pins { macro_rules! config_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
into_ref!($($pin),*); critical_section::with(|_| {
critical_section::with(|_| {
$( $(
$pin.set_as_af($pin.af_num(), AfType::input(Pull::None)); $pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
)* )*
@ -117,8 +116,8 @@ macro_rules! config_pins {
/// DCMI driver. /// DCMI driver.
pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> { pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
inner: PeripheralRef<'d, T>, inner: Peri<'d, T>,
dma: PeripheralRef<'d, Dma>, dma: Peri<'d, Dma>,
} }
impl<'d, T, Dma> Dcmi<'d, T, Dma> impl<'d, T, Dma> Dcmi<'d, T, Dma>
@ -128,23 +127,22 @@ where
{ {
/// Create a new DCMI driver with 8 data bits. /// Create a new DCMI driver with 8 data bits.
pub fn new_8bit( pub fn new_8bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, v_sync: Peri<'d, impl VSyncPin<T>>,
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, h_sync: Peri<'d, impl HSyncPin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
config_pins!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
@ -153,25 +151,24 @@ where
/// Create a new DCMI driver with 10 data bits. /// Create a new DCMI driver with 10 data bits.
pub fn new_10bit( pub fn new_10bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, v_sync: Peri<'d, impl VSyncPin<T>>,
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, h_sync: Peri<'d, impl HSyncPin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
config_pins!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
@ -180,27 +177,26 @@ where
/// Create a new DCMI driver with 12 data bits. /// Create a new DCMI driver with 12 data bits.
pub fn new_12bit( pub fn new_12bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
d10: impl Peripheral<P = impl D10Pin<T>> + 'd, d10: Peri<'d, impl D10Pin<T>>,
d11: impl Peripheral<P = impl D11Pin<T>> + 'd, d11: Peri<'d, impl D11Pin<T>>,
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, v_sync: Peri<'d, impl VSyncPin<T>>,
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, h_sync: Peri<'d, impl HSyncPin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(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);
config_pins!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
@ -209,29 +205,28 @@ where
/// Create a new DCMI driver with 14 data bits. /// Create a new DCMI driver with 14 data bits.
pub fn new_14bit( pub fn new_14bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
d10: impl Peripheral<P = impl D10Pin<T>> + 'd, d10: Peri<'d, impl D10Pin<T>>,
d11: impl Peripheral<P = impl D11Pin<T>> + 'd, d11: Peri<'d, impl D11Pin<T>>,
d12: impl Peripheral<P = impl D12Pin<T>> + 'd, d12: Peri<'d, impl D12Pin<T>>,
d13: impl Peripheral<P = impl D13Pin<T>> + 'd, d13: Peri<'d, impl D13Pin<T>>,
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, v_sync: Peri<'d, impl VSyncPin<T>>,
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, h_sync: Peri<'d, impl HSyncPin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(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);
config_pins!(v_sync, h_sync, pixclk); config_pins!(v_sync, h_sync, pixclk);
@ -240,21 +235,20 @@ where
/// Create a new DCMI driver with 8 data bits, with embedded synchronization. /// Create a new DCMI driver with 8 data bits, with embedded synchronization.
pub fn new_es_8bit( pub fn new_es_8bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
config_pins!(pixclk); config_pins!(pixclk);
@ -263,23 +257,22 @@ where
/// Create a new DCMI driver with 10 data bits, with embedded synchronization. /// Create a new DCMI driver with 10 data bits, with embedded synchronization.
pub fn new_es_10bit( pub fn new_es_10bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
config_pins!(pixclk); config_pins!(pixclk);
@ -288,25 +281,24 @@ where
/// Create a new DCMI driver with 12 data bits, with embedded synchronization. /// Create a new DCMI driver with 12 data bits, with embedded synchronization.
pub fn new_es_12bit( pub fn new_es_12bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
d10: impl Peripheral<P = impl D10Pin<T>> + 'd, d10: Peri<'d, impl D10Pin<T>>,
d11: impl Peripheral<P = impl D11Pin<T>> + 'd, d11: Peri<'d, impl D11Pin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(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);
config_pins!(pixclk); config_pins!(pixclk);
@ -315,27 +307,26 @@ where
/// Create a new DCMI driver with 14 data bits, with embedded synchronization. /// Create a new DCMI driver with 14 data bits, with embedded synchronization.
pub fn new_es_14bit( pub fn new_es_14bit(
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
dma: impl Peripheral<P = Dma> + 'd, dma: Peri<'d, Dma>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: Peri<'d, impl D0Pin<T>>,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: Peri<'d, impl D1Pin<T>>,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: Peri<'d, impl D2Pin<T>>,
d3: impl Peripheral<P = impl D3Pin<T>> + 'd, d3: Peri<'d, impl D3Pin<T>>,
d4: impl Peripheral<P = impl D4Pin<T>> + 'd, d4: Peri<'d, impl D4Pin<T>>,
d5: impl Peripheral<P = impl D5Pin<T>> + 'd, d5: Peri<'d, impl D5Pin<T>>,
d6: impl Peripheral<P = impl D6Pin<T>> + 'd, d6: Peri<'d, impl D6Pin<T>>,
d7: impl Peripheral<P = impl D7Pin<T>> + 'd, d7: Peri<'d, impl D7Pin<T>>,
d8: impl Peripheral<P = impl D8Pin<T>> + 'd, d8: Peri<'d, impl D8Pin<T>>,
d9: impl Peripheral<P = impl D9Pin<T>> + 'd, d9: Peri<'d, impl D9Pin<T>>,
d10: impl Peripheral<P = impl D10Pin<T>> + 'd, d10: Peri<'d, impl D10Pin<T>>,
d11: impl Peripheral<P = impl D11Pin<T>> + 'd, d11: Peri<'d, impl D11Pin<T>>,
d12: impl Peripheral<P = impl D12Pin<T>> + 'd, d12: Peri<'d, impl D12Pin<T>>,
d13: impl Peripheral<P = impl D13Pin<T>> + 'd, d13: Peri<'d, impl D13Pin<T>>,
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, pixclk: Peri<'d, impl PixClkPin<T>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(peri, dma);
config_pins!(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);
config_pins!(pixclk); config_pins!(pixclk);
@ -343,8 +334,8 @@ where
} }
fn new_inner( fn new_inner(
peri: PeripheralRef<'d, T>, peri: Peri<'d, T>,
dma: PeripheralRef<'d, Dma>, dma: Peri<'d, Dma>,
config: Config, config: Config,
use_embedded_synchronization: bool, use_embedded_synchronization: bool,
edm: u8, edm: u8,
@ -396,7 +387,7 @@ where
let r = self.inner.regs(); let r = self.inner.regs();
let src = r.dr().as_ptr() as *mut u32; let src = r.dr().as_ptr() as *mut u32;
let request = self.dma.request(); let request = self.dma.request();
let dma_read = unsafe { Transfer::new_read(&mut self.dma, request, src, buffer, Default::default()) }; let dma_read = unsafe { Transfer::new_read(self.dma.reborrow(), request, src, buffer, Default::default()) };
Self::clear_interrupt_flags(); Self::clear_interrupt_flags();
Self::enable_irqs(); Self::enable_irqs();
@ -435,7 +426,7 @@ trait SealedInstance: crate::rcc::RccPeripheral {
/// DCMI instance. /// DCMI instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + 'static { pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this instance. /// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }

View File

@ -3,7 +3,7 @@ use core::pin::Pin;
use core::sync::atomic::{fence, AtomicUsize, Ordering}; use core::sync::atomic::{fence, AtomicUsize, Ordering};
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::Peri;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer};
@ -571,13 +571,13 @@ impl AnyChannel {
/// DMA transfer. /// DMA transfer.
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Transfer<'a> { pub struct Transfer<'a> {
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
} }
impl<'a> Transfer<'a> { impl<'a> Transfer<'a> {
/// Create a new read DMA transfer (peripheral to memory). /// Create a new read DMA transfer (peripheral to memory).
pub unsafe fn new_read<W: Word>( pub unsafe fn new_read<W: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buf: &'a mut [W], buf: &'a mut [W],
@ -588,16 +588,14 @@ impl<'a> Transfer<'a> {
/// Create a new read DMA transfer (peripheral to memory), using raw pointers. /// Create a new read DMA transfer (peripheral to memory), using raw pointers.
pub unsafe fn new_read_raw<W: Word>( pub unsafe fn new_read_raw<W: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buf: *mut [W], buf: *mut [W],
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::PeripheralToMemory, Dir::PeripheralToMemory,
peri_addr as *const u32, peri_addr as *const u32,
@ -612,7 +610,7 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral). /// Create a new write DMA transfer (memory to peripheral).
pub unsafe fn new_write<MW: Word, PW: Word>( pub unsafe fn new_write<MW: Word, PW: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
buf: &'a [MW], buf: &'a [MW],
peri_addr: *mut PW, peri_addr: *mut PW,
@ -623,16 +621,14 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral), using raw pointers. /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
pub unsafe fn new_write_raw<MW: Word, PW: Word>( pub unsafe fn new_write_raw<MW: Word, PW: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
buf: *const [MW], buf: *const [MW],
peri_addr: *mut PW, peri_addr: *mut PW,
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::MemoryToPeripheral, Dir::MemoryToPeripheral,
peri_addr as *const u32, peri_addr as *const u32,
@ -647,17 +643,15 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
pub unsafe fn new_write_repeated<W: Word>( pub unsafe fn new_write_repeated<W: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
repeated: &'a W, repeated: &'a W,
count: usize, count: usize,
peri_addr: *mut W, peri_addr: *mut W,
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::MemoryToPeripheral, Dir::MemoryToPeripheral,
peri_addr as *const u32, peri_addr as *const u32,
@ -671,7 +665,7 @@ impl<'a> Transfer<'a> {
} }
unsafe fn new_inner( unsafe fn new_inner(
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
_request: Request, _request: Request,
dir: Dir, dir: Dir,
peri_addr: *const u32, peri_addr: *const u32,
@ -769,7 +763,7 @@ impl<'a> Future for Transfer<'a> {
// ============================== // ==============================
struct DmaCtrlImpl<'a>(PeripheralRef<'a, AnyChannel>); struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>);
impl<'a> DmaCtrl for DmaCtrlImpl<'a> { impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
fn get_remaining_transfers(&self) -> usize { fn get_remaining_transfers(&self) -> usize {
@ -795,21 +789,20 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
/// Ringbuffer for receiving data using DMA circular mode. /// Ringbuffer for receiving data using DMA circular mode.
pub struct ReadableRingBuffer<'a, W: Word> { pub struct ReadableRingBuffer<'a, W: Word> {
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
ringbuf: ReadableDmaRingBuffer<'a, W>, ringbuf: ReadableDmaRingBuffer<'a, W>,
} }
impl<'a, W: Word> ReadableRingBuffer<'a, W> { impl<'a, W: Word> ReadableRingBuffer<'a, W> {
/// Create a new ring buffer. /// Create a new ring buffer.
pub unsafe fn new( pub unsafe fn new(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
_request: Request, _request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buffer: &'a mut [W], buffer: &'a mut [W],
mut options: TransferOptions, mut options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel); let channel: Peri<'a, AnyChannel> = channel.into();
let channel: PeripheralRef<'a, AnyChannel> = channel.map_into();
let buffer_ptr = buffer.as_mut_ptr(); let buffer_ptr = buffer.as_mut_ptr();
let len = buffer.len(); let len = buffer.len();
@ -948,21 +941,20 @@ impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
/// Ringbuffer for writing data using DMA circular mode. /// Ringbuffer for writing data using DMA circular mode.
pub struct WritableRingBuffer<'a, W: Word> { pub struct WritableRingBuffer<'a, W: Word> {
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
ringbuf: WritableDmaRingBuffer<'a, W>, ringbuf: WritableDmaRingBuffer<'a, W>,
} }
impl<'a, W: Word> WritableRingBuffer<'a, W> { impl<'a, W: Word> WritableRingBuffer<'a, W> {
/// Create a new ring buffer. /// Create a new ring buffer.
pub unsafe fn new( pub unsafe fn new(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
_request: Request, _request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buffer: &'a mut [W], buffer: &'a mut [W],
mut options: TransferOptions, mut options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel); let channel: Peri<'a, AnyChannel> = channel.into();
let channel: PeripheralRef<'a, AnyChannel> = channel.map_into();
let len = buffer.len(); let len = buffer.len();
let dir = Dir::MemoryToPeripheral; let dir = Dir::MemoryToPeripheral;

View File

@ -5,7 +5,7 @@ use core::pin::Pin;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::Peri;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use super::word::{Word, WordSize}; use super::word::{Word, WordSize};
@ -109,13 +109,13 @@ impl AnyChannel {
/// DMA transfer. /// DMA transfer.
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Transfer<'a> { pub struct Transfer<'a> {
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
} }
impl<'a> Transfer<'a> { impl<'a> Transfer<'a> {
/// Create a new read DMA transfer (peripheral to memory). /// Create a new read DMA transfer (peripheral to memory).
pub unsafe fn new_read<W: Word>( pub unsafe fn new_read<W: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buf: &'a mut [W], buf: &'a mut [W],
@ -126,16 +126,14 @@ impl<'a> Transfer<'a> {
/// Create a new read DMA transfer (peripheral to memory), using raw pointers. /// Create a new read DMA transfer (peripheral to memory), using raw pointers.
pub unsafe fn new_read_raw<W: Word>( pub unsafe fn new_read_raw<W: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
peri_addr: *mut W, peri_addr: *mut W,
buf: *mut [W], buf: *mut [W],
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::PeripheralToMemory, Dir::PeripheralToMemory,
peri_addr as *const u32, peri_addr as *const u32,
@ -150,7 +148,7 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral). /// Create a new write DMA transfer (memory to peripheral).
pub unsafe fn new_write<MW: Word, PW: Word>( pub unsafe fn new_write<MW: Word, PW: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
buf: &'a [MW], buf: &'a [MW],
peri_addr: *mut PW, peri_addr: *mut PW,
@ -161,16 +159,14 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral), using raw pointers. /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
pub unsafe fn new_write_raw<MW: Word, PW: Word>( pub unsafe fn new_write_raw<MW: Word, PW: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
buf: *const [MW], buf: *const [MW],
peri_addr: *mut PW, peri_addr: *mut PW,
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::MemoryToPeripheral, Dir::MemoryToPeripheral,
peri_addr as *const u32, peri_addr as *const u32,
@ -185,17 +181,15 @@ impl<'a> Transfer<'a> {
/// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
pub unsafe fn new_write_repeated<MW: Word, PW: Word>( pub unsafe fn new_write_repeated<MW: Word, PW: Word>(
channel: impl Peripheral<P = impl Channel> + 'a, channel: Peri<'a, impl Channel>,
request: Request, request: Request,
repeated: &'a MW, repeated: &'a MW,
count: usize, count: usize,
peri_addr: *mut PW, peri_addr: *mut PW,
options: TransferOptions, options: TransferOptions,
) -> Self { ) -> Self {
into_ref!(channel);
Self::new_inner( Self::new_inner(
channel.map_into(), channel.into(),
request, request,
Dir::MemoryToPeripheral, Dir::MemoryToPeripheral,
peri_addr as *const u32, peri_addr as *const u32,
@ -209,7 +203,7 @@ impl<'a> Transfer<'a> {
} }
unsafe fn new_inner( unsafe fn new_inner(
channel: PeripheralRef<'a, AnyChannel>, channel: Peri<'a, AnyChannel>,
request: Request, request: Request,
dir: Dir, dir: Dir,
peri_addr: *const u32, peri_addr: *const u32,

View File

@ -22,7 +22,7 @@ pub(crate) use util::*;
pub(crate) mod ringbuffer; pub(crate) mod ringbuffer;
pub mod word; pub mod word;
use embassy_hal_internal::{impl_peripheral, Peripheral}; use embassy_hal_internal::{impl_peripheral, PeripheralType};
use crate::interrupt; use crate::interrupt;
@ -51,17 +51,7 @@ pub(crate) trait ChannelInterrupt {
/// DMA channel. /// DMA channel.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static { pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {}
/// Type-erase (degrade) this pin into an `AnyChannel`.
///
/// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
/// are all different types, into the same type. It is useful for
/// creating arrays of channels, or avoiding generics.
#[inline]
fn degrade(self) -> AnyChannel {
AnyChannel { id: self.id() }
}
}
macro_rules! dma_channel_impl { macro_rules! dma_channel_impl {
($channel_peri:ident, $index:expr) => { ($channel_peri:ident, $index:expr) => {
@ -79,8 +69,10 @@ macro_rules! dma_channel_impl {
impl crate::dma::Channel for crate::peripherals::$channel_peri {} impl crate::dma::Channel for crate::peripherals::$channel_peri {}
impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel { impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel {
fn from(x: crate::peripherals::$channel_peri) -> Self { fn from(val: crate::peripherals::$channel_peri) -> Self {
crate::dma::Channel::degrade(x) Self {
id: crate::dma::SealedChannel::id(&val),
}
} }
} }
}; };

View File

@ -1,13 +1,12 @@
use embassy_hal_internal::PeripheralRef;
use super::word::Word; use super::word::Word;
use super::{AnyChannel, Request, Transfer, TransferOptions}; use super::{AnyChannel, Request, Transfer, TransferOptions};
use crate::Peri;
/// Convenience wrapper, contains a channel and a request number. /// Convenience wrapper, contains a channel and a request number.
/// ///
/// Commonly used in peripheral drivers that own DMA channels. /// Commonly used in peripheral drivers that own DMA channels.
pub(crate) struct ChannelAndRequest<'d> { pub(crate) struct ChannelAndRequest<'d> {
pub channel: PeripheralRef<'d, AnyChannel>, pub channel: Peri<'d, AnyChannel>,
pub request: Request, pub request: Request,
} }
@ -18,7 +17,7 @@ impl<'d> ChannelAndRequest<'d> {
buf: &'a mut [W], buf: &'a mut [W],
options: TransferOptions, options: TransferOptions,
) -> Transfer<'a> { ) -> Transfer<'a> {
Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options) Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options)
} }
pub unsafe fn read_raw<'a, W: Word>( pub unsafe fn read_raw<'a, W: Word>(
@ -27,7 +26,7 @@ impl<'d> ChannelAndRequest<'d> {
buf: *mut [W], buf: *mut [W],
options: TransferOptions, options: TransferOptions,
) -> Transfer<'a> { ) -> Transfer<'a> {
Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options) Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options)
} }
pub unsafe fn write<'a, W: Word>( pub unsafe fn write<'a, W: Word>(
@ -36,7 +35,7 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut W, peri_addr: *mut W,
options: TransferOptions, options: TransferOptions,
) -> Transfer<'a> { ) -> Transfer<'a> {
Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options) Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options)
} }
pub unsafe fn write_raw<'a, MW: Word, PW: Word>( pub unsafe fn write_raw<'a, MW: Word, PW: Word>(
@ -45,7 +44,7 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut PW, peri_addr: *mut PW,
options: TransferOptions, options: TransferOptions,
) -> Transfer<'a> { ) -> Transfer<'a> {
Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options) Transfer::new_write_raw(self.channel.reborrow(), self.request, buf, peri_addr, options)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -56,6 +55,13 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut W, peri_addr: *mut W,
options: TransferOptions, options: TransferOptions,
) -> Transfer<'a> { ) -> Transfer<'a> {
Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options) Transfer::new_write_repeated(
self.channel.reborrow(),
self.request,
repeated,
count,
peri_addr,
options,
)
} }
} }

View File

@ -2,12 +2,12 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::PeripheralType;
//use crate::gpio::{AnyPin, SealedPin}; //use crate::gpio::{AnyPin, SealedPin};
use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::gpio::{AfType, AnyPin, OutputType, Speed};
use crate::rcc::{self, RccPeripheral}; use crate::rcc::{self, RccPeripheral};
use crate::{peripherals, Peripheral}; use crate::{peripherals, Peri};
/// Performs a busy-wait delay for a specified number of microseconds. /// Performs a busy-wait delay for a specified number of microseconds.
pub fn blocking_delay_ms(ms: u32) { pub fn blocking_delay_ms(ms: u32) {
@ -69,14 +69,12 @@ impl From<PacketType> for u8 {
/// DSIHOST driver. /// DSIHOST driver.
pub struct DsiHost<'d, T: Instance> { pub struct DsiHost<'d, T: Instance> {
_peri: PhantomData<&'d mut T>, _peri: PhantomData<&'d mut T>,
_te: PeripheralRef<'d, AnyPin>, _te: Peri<'d, AnyPin>,
} }
impl<'d, T: Instance> DsiHost<'d, T> { impl<'d, T: Instance> DsiHost<'d, T> {
/// Note: Full-Duplex modes are not supported at this time /// Note: Full-Duplex modes are not supported at this time
pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self { pub fn new(_peri: Peri<'d, T>, te: Peri<'d, impl TePin<T>>) -> Self {
into_ref!(te);
rcc::enable_and_reset::<T>(); rcc::enable_and_reset::<T>();
// Set Tearing Enable pin according to CubeMx example // Set Tearing Enable pin according to CubeMx example
@ -88,7 +86,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
*/ */
Self { Self {
_peri: PhantomData, _peri: PhantomData,
_te: te.map_into(), _te: te.into(),
} }
} }
@ -412,7 +410,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral {
/// DSI instance trait. /// DSI instance trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {} pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
pin_trait!(TePin, Instance); pin_trait!(TePin, Instance);

View File

@ -4,13 +4,13 @@ use core::future::poll_fn;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::Peri;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::peripherals::DTS; use crate::peripherals::DTS;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, pac, rcc, Peripheral}; use crate::{interrupt, pac, rcc};
mod tsel; mod tsel;
pub use tsel::TriggerSel; pub use tsel::TriggerSel;
@ -72,7 +72,7 @@ const MAX_DTS_CLK_FREQ: Hertz = Hertz::mhz(1);
/// Digital temperature sensor driver. /// Digital temperature sensor driver.
pub struct Dts<'d> { pub struct Dts<'d> {
_peri: PeripheralRef<'d, DTS>, _peri: Peri<'d, DTS>,
} }
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
@ -80,11 +80,10 @@ static WAKER: AtomicWaker = AtomicWaker::new();
impl<'d> Dts<'d> { impl<'d> Dts<'d> {
/// Create a new temperature sensor driver. /// Create a new temperature sensor driver.
pub fn new( pub fn new(
_peri: impl Peripheral<P = DTS> + 'd, _peri: Peri<'d, DTS>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::DTS, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::DTS, InterruptHandler> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(_peri);
rcc::enable_and_reset::<DTS>(); rcc::enable_and_reset::<DTS>();
let prescaler = rcc::frequency::<DTS>() / MAX_DTS_CLK_FREQ; let prescaler = rcc::frequency::<DTS>() / MAX_DTS_CLK_FREQ;

View File

@ -9,6 +9,7 @@ mod generic_phy;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use core::task::Context; use core::task::Context;
use embassy_hal_internal::PeripheralType;
use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -199,7 +200,7 @@ trait SealedInstance {
/// Ethernet instance. /// Ethernet instance.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + Send + 'static {}
impl SealedInstance for crate::peripherals::ETH { impl SealedInstance for crate::peripherals::ETH {
fn regs() -> crate::pac::eth::Eth { fn regs() -> crate::pac::eth::Eth {

View File

@ -6,7 +6,7 @@ mod tx_desc;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::Peri;
use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf};
pub(crate) use self::rx_desc::{RDes, RDesRing}; pub(crate) use self::rx_desc::{RDes, RDesRing};
@ -15,6 +15,7 @@ use super::*;
#[cfg(eth_v1a)] #[cfg(eth_v1a)]
use crate::gpio::Pull; use crate::gpio::Pull;
use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
use crate::interrupt;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
#[cfg(eth_v1a)] #[cfg(eth_v1a)]
use crate::pac::AFIO; use crate::pac::AFIO;
@ -22,7 +23,6 @@ use crate::pac::AFIO;
use crate::pac::SYSCFG; use crate::pac::SYSCFG;
use crate::pac::{ETH, RCC}; use crate::pac::{ETH, RCC};
use crate::rcc::SealedRccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler {} pub struct InterruptHandler {}
@ -47,11 +47,11 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandl
/// Ethernet driver. /// Ethernet driver.
pub struct Ethernet<'d, T: Instance, P: Phy> { pub struct Ethernet<'d, T: Instance, P: Phy> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
pub(crate) tx: TDesRing<'d>, pub(crate) tx: TDesRing<'d>,
pub(crate) rx: RDesRing<'d>, pub(crate) rx: RDesRing<'d>,
pins: [PeripheralRef<'d, AnyPin>; 9], pins: [Peri<'d, AnyPin>; 9],
pub(crate) phy: P, pub(crate) phy: P,
pub(crate) station_management: EthernetStationManagement<T>, pub(crate) station_management: EthernetStationManagement<T>,
pub(crate) mac_addr: [u8; 6], pub(crate) mac_addr: [u8; 6],
@ -95,22 +95,20 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
/// safety: the returned instance is not leak-safe /// safety: the returned instance is not leak-safe
pub fn new<const TX: usize, const RX: usize>( pub fn new<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, ref_clk: Peri<'d, impl RefClkPin<T>>,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, mdio: Peri<'d, impl MDIOPin<T>>,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, mdc: Peri<'d, impl MDCPin<T>>,
crs: impl Peripheral<P = impl CRSPin<T>> + 'd, crs: Peri<'d, impl CRSPin<T>>,
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, rx_d1: Peri<'d, impl RXD1Pin<T>>,
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
) -> Self { ) -> Self {
into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
// Enable the necessary Clocks // Enable the necessary Clocks
#[cfg(eth_v1a)] #[cfg(eth_v1a)]
critical_section::with(|_| { critical_section::with(|_| {
@ -213,15 +211,15 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
}; };
let pins = [ let pins = [
ref_clk.map_into(), ref_clk.into(),
mdio.map_into(), mdio.into(),
mdc.map_into(), mdc.into(),
crs.map_into(), crs.into(),
rx_d0.map_into(), rx_d0.into(),
rx_d1.map_into(), rx_d1.into(),
tx_d0.map_into(), tx_d0.into(),
tx_d1.map_into(), tx_d1.into(),
tx_en.map_into(), tx_en.into(),
]; ];
let mut this = Self { let mut this = Self {

View File

@ -3,16 +3,16 @@ mod descriptors;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::Peri;
use stm32_metapac::syscfg::vals::EthSelPhy; use stm32_metapac::syscfg::vals::EthSelPhy;
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
use super::*; use super::*;
use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
use crate::interrupt;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::pac::ETH; use crate::pac::ETH;
use crate::rcc::SealedRccPeripheral; use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler {} pub struct InterruptHandler {}
@ -37,7 +37,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandl
/// Ethernet driver. /// Ethernet driver.
pub struct Ethernet<'d, T: Instance, P: Phy> { pub struct Ethernet<'d, T: Instance, P: Phy> {
_peri: PeripheralRef<'d, T>, _peri: Peri<'d, T>,
pub(crate) tx: TDesRing<'d>, pub(crate) tx: TDesRing<'d>,
pub(crate) rx: RDesRing<'d>, pub(crate) rx: RDesRing<'d>,
pins: Pins<'d>, pins: Pins<'d>,
@ -48,8 +48,8 @@ pub struct Ethernet<'d, T: Instance, P: Phy> {
/// Pins of ethernet driver. /// Pins of ethernet driver.
enum Pins<'d> { enum Pins<'d> {
Rmii([PeripheralRef<'d, AnyPin>; 9]), Rmii([Peri<'d, AnyPin>; 9]),
Mii([PeripheralRef<'d, AnyPin>; 14]), Mii([Peri<'d, AnyPin>; 14]),
} }
macro_rules! config_pins { macro_rules! config_pins {
@ -67,17 +67,17 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
/// Create a new RMII ethernet driver using 9 pins. /// Create a new RMII ethernet driver using 9 pins.
pub fn new<const TX: usize, const RX: usize>( pub fn new<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, ref_clk: Peri<'d, impl RefClkPin<T>>,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, mdio: Peri<'d, impl MDIOPin<T>>,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, mdc: Peri<'d, impl MDCPin<T>>,
crs: impl Peripheral<P = impl CRSPin<T>> + 'd, crs: Peri<'d, impl CRSPin<T>>,
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, rx_d1: Peri<'d, impl RXD1Pin<T>>,
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
) -> Self { ) -> Self {
@ -92,19 +92,18 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII)); crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII));
}); });
into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
let pins = Pins::Rmii([ let pins = Pins::Rmii([
ref_clk.map_into(), ref_clk.into(),
mdio.map_into(), mdio.into(),
mdc.map_into(), mdc.into(),
crs.map_into(), crs.into(),
rx_d0.map_into(), rx_d0.into(),
rx_d1.map_into(), rx_d1.into(),
tx_d0.map_into(), tx_d0.into(),
tx_d1.map_into(), tx_d1.into(),
tx_en.map_into(), tx_en.into(),
]); ]);
Self::new_inner(queue, peri, irq, pins, phy, mac_addr) Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
@ -113,22 +112,22 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
/// Create a new MII ethernet driver using 14 pins. /// Create a new MII ethernet driver using 14 pins.
pub fn new_mii<const TX: usize, const RX: usize>( pub fn new_mii<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
rx_clk: impl Peripheral<P = impl RXClkPin<T>> + 'd, rx_clk: Peri<'d, impl RXClkPin<T>>,
tx_clk: impl Peripheral<P = impl TXClkPin<T>> + 'd, tx_clk: Peri<'d, impl TXClkPin<T>>,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, mdio: Peri<'d, impl MDIOPin<T>>,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, mdc: Peri<'d, impl MDCPin<T>>,
rxdv: impl Peripheral<P = impl RXDVPin<T>> + 'd, rxdv: Peri<'d, impl RXDVPin<T>>,
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, rx_d1: Peri<'d, impl RXD1Pin<T>>,
rx_d2: impl Peripheral<P = impl RXD2Pin<T>> + 'd, rx_d2: Peri<'d, impl RXD2Pin<T>>,
rx_d3: impl Peripheral<P = impl RXD3Pin<T>> + 'd, rx_d3: Peri<'d, impl RXD3Pin<T>>,
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_d2: impl Peripheral<P = impl TXD2Pin<T>> + 'd, tx_d2: Peri<'d, impl TXD2Pin<T>>,
tx_d3: impl Peripheral<P = impl TXD3Pin<T>> + 'd, tx_d3: Peri<'d, impl TXD3Pin<T>>,
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
) -> Self { ) -> Self {
@ -145,24 +144,23 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
.modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII)); .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII));
}); });
into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
let pins = Pins::Mii([ let pins = Pins::Mii([
rx_clk.map_into(), rx_clk.into(),
tx_clk.map_into(), tx_clk.into(),
mdio.map_into(), mdio.into(),
mdc.map_into(), mdc.into(),
rxdv.map_into(), rxdv.into(),
rx_d0.map_into(), rx_d0.into(),
rx_d1.map_into(), rx_d1.into(),
rx_d2.map_into(), rx_d2.into(),
rx_d3.map_into(), rx_d3.into(),
tx_d0.map_into(), tx_d0.into(),
tx_d1.map_into(), tx_d1.into(),
tx_d2.map_into(), tx_d2.into(),
tx_d3.map_into(), tx_d3.into(),
tx_en.map_into(), tx_en.into(),
]); ]);
Self::new_inner(queue, peri, irq, pins, phy, mac_addr) Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
@ -170,7 +168,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
fn new_inner<const TX: usize, const RX: usize>( fn new_inner<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
pins: Pins<'d>, pins: Pins<'d>,
phy: P, phy: P,
@ -254,7 +252,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
}; };
let mut this = Self { let mut this = Self {
_peri: peri.into_ref(), _peri: peri,
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
pins, pins,

View File

@ -5,13 +5,13 @@ use core::marker::PhantomData;
use core::pin::Pin; use core::pin::Pin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref}; use embassy_hal_internal::{impl_peripheral, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull}; use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull};
use crate::pac::exti::regs::Lines; use crate::pac::exti::regs::Lines;
use crate::pac::EXTI; use crate::pac::EXTI;
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peri};
const EXTI_COUNT: usize = 16; const EXTI_COUNT: usize = 16;
static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT];
@ -105,13 +105,7 @@ impl<'d> Unpin for ExtiInput<'d> {}
impl<'d> ExtiInput<'d> { impl<'d> ExtiInput<'d> {
/// Create an EXTI input. /// Create an EXTI input.
pub fn new<T: GpioPin>( pub fn new<T: GpioPin>(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull) -> Self {
pin: impl Peripheral<P = T> + 'd,
ch: impl Peripheral<P = T::ExtiChannel> + 'd,
pull: Pull,
) -> Self {
into_ref!(pin, ch);
// Needed if using AnyPin+AnyChannel. // Needed if using AnyPin+AnyChannel.
assert_eq!(pin.pin(), ch.number()); assert_eq!(pin.pin(), ch.number());
@ -338,23 +332,12 @@ trait SealedChannel {}
/// EXTI channel trait. /// EXTI channel trait.
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait Channel: SealedChannel + Sized { pub trait Channel: PeripheralType + SealedChannel + Sized {
/// Get the EXTI channel number. /// Get the EXTI channel number.
fn number(&self) -> u8; fn number(&self) -> u8;
/// Type-erase (degrade) this channel into an `AnyChannel`.
///
/// This converts EXTI channel singletons (`EXTI0`, `EXTI1`, ...), which
/// are all different types, into the same type. It is useful for
/// creating arrays of channels, or avoiding generics.
fn degrade(self) -> AnyChannel {
AnyChannel {
number: self.number() as u8,
}
}
} }
/// Type-erased (degraded) EXTI channel. /// Type-erased EXTI channel.
/// ///
/// This represents ownership over any EXTI channel, known at runtime. /// This represents ownership over any EXTI channel, known at runtime.
pub struct AnyChannel { pub struct AnyChannel {
@ -377,6 +360,14 @@ macro_rules! impl_exti {
$number $number
} }
} }
impl From<peripherals::$type> for AnyChannel {
fn from(val: peripherals::$type) -> Self {
Self {
number: val.number() as u8,
}
}
}
}; };
} }

Some files were not shown because too many files have changed in this diff Show More