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_time::{Duration, Timer};
use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
use embassy_nrf::Peripherals;
use embassy_nrf::{Peri, Peripherals};
// Declare async tasks
#[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);
loop {
@ -77,7 +77,7 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
// 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);
loop {

View File

@ -10,16 +10,16 @@ use embassy_rp::dma::Channel;
use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate};
use embassy_rp::pio::program::pio_asm;
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::FixedU32;
/// 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>,
sm: StateMachine<'d, PIO, SM>,
irq: Irq<'d, PIO, 0>,
dma: PeripheralRef<'d, DMA>,
dma: Peri<'d, DMA>,
wrap_target: u8,
}
@ -48,20 +48,16 @@ where
PIO: Instance,
{
/// Create a new instance of PioSpi.
pub fn new<DIO, CLK>(
pub fn new(
common: &mut Common<'d, PIO>,
mut sm: StateMachine<'d, PIO, SM>,
clock_divider: FixedU32<U8>,
irq: Irq<'d, PIO, 0>,
cs: Output<'d>,
dio: DIO,
clk: CLK,
dma: impl Peripheral<P = DMA> + 'd,
) -> Self
where
DIO: PioPin,
CLK: PioPin,
{
dio: Peri<'d, impl PioPin>,
clk: Peri<'d, impl PioPin>,
dma: Peri<'d, DMA>,
) -> Self {
let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER {
let overclock_program = pio_asm!(
".side_set 1"
@ -146,7 +142,7 @@ where
cs,
sm,
irq,
dma: dma.into_ref(),
dma: dma,
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::peripherals::WDT;
use embassy_nrf::wdt;
use embassy_nrf::{wdt, Peri};
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
/// A bootloader for nRF devices.
@ -113,7 +113,7 @@ pub struct WatchdogFlash<FLASH> {
impl<FLASH> WatchdogFlash<FLASH> {
/// 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) {
Ok(x) => x,
Err(_) => {

View File

@ -10,6 +10,7 @@ pub use embassy_boot::{
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
use embassy_rp::peripherals::{FLASH, WATCHDOG};
use embassy_rp::watchdog::Watchdog;
use embassy_rp::Peri;
use embassy_time::Duration;
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> {
/// 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 mut watchdog = Watchdog::new(watchdog);
watchdog.start(timeout);

View File

@ -11,7 +11,7 @@ pub mod drop;
mod macros;
mod peripheral;
pub mod ratio;
pub use peripheral::{Peripheral, PeripheralRef};
pub use peripheral::{Peri, PeripheralType};
#[cfg(feature = "cortex-m")]
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.
#[inline]
pub unsafe fn steal() -> Self {
Self{ _private: ()}
pub unsafe fn steal() -> $crate::Peri<'static, Self> {
$crate::Peri::new_unchecked(Self{ _private: ()})
}
}
@ -42,7 +42,7 @@ macro_rules! peripherals_struct {
$(
#[doc = concat!(stringify!($name), " peripheral")]
$(#[$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.
#[macro_export]
macro_rules! impl_peripheral {
($type:ident) => {
impl $crate::Peripheral for $type {
type P = $type;
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P {
#[allow(clippy::needless_update)]
$type { ..*self }
($type:ident<$($T:ident $(: $bound:tt $(+ $others:tt )*)?),*>) => {
impl<$($T: $($bound $(+$others)*)?),*> Copy for $type <$($T),*> {}
impl<$($T: $($bound $(+$others)*)?),*> Clone for $type <$($T),*> {
fn clone(&self) -> Self {
*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::ops::{Deref, DerefMut};
use core::ops::Deref;
/// 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
/// 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.
/// 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`,
/// the driver code would be monomorphized two times. With PeripheralRef, the driver is generic
/// over a lifetime only. `SPI4` becomes `PeripheralRef<'static, SPI4>`, and `&mut SPI4` becomes
/// `PeripheralRef<'a, SPI4>`. Lifetimes don't cause monomorphization.
pub struct PeripheralRef<'a, T> {
/// the driver code would be monomorphized two times. With Peri, the driver is generic
/// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes
/// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization.
pub struct Peri<'a, T: PeripheralType> {
inner: T,
_lifetime: PhantomData<&'a mut T>,
}
impl<'a, T> PeripheralRef<'a, T> {
/// Create a new reference to a peripheral.
impl<'a, T: PeripheralType> Peri<'a, T> {
/// 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]
pub fn new(inner: T) -> Self {
#[doc(hidden)]
pub unsafe fn new_unchecked(inner: T) -> Self {
Self {
inner,
_lifetime: PhantomData,
@ -38,46 +44,38 @@ impl<'a, T> PeripheralRef<'a, T> {
/// create two SPI drivers on `SPI1`, because they will "fight" each other.
///
/// 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.
pub unsafe fn clone_unchecked(&self) -> PeripheralRef<'a, T>
where
T: Peripheral<P = T>,
{
PeripheralRef::new(self.inner.clone_unchecked())
pub unsafe fn clone_unchecked(&self) -> Peri<'a, T> {
Peri::new_unchecked(self.inner)
}
/// Reborrow into a "child" PeripheralRef.
/// Reborrow into a "child" Peri.
///
/// `self` will stay borrowed until the child PeripheralRef is dropped.
pub fn reborrow(&mut self) -> PeripheralRef<'_, T>
where
T: Peripheral<P = T>,
{
// safety: we're returning the clone inside a new PeripheralRef that borrows
/// `self` will stay borrowed until the child Peripheral is dropped.
pub fn reborrow(&mut self) -> Peri<'_, T> {
// safety: we're returning the clone inside a new Peripheral that borrows
// 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`.
///
/// 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`.
///
/// 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]
pub fn map_into<U>(self) -> PeripheralRef<'a, U>
pub fn into<U>(self) -> Peri<'a, U>
where
T: Into<U>,
U: PeripheralType,
{
PeripheralRef {
inner: self.inner.into(),
_lifetime: PhantomData,
}
unsafe { Peri::new_unchecked(self.inner.into()) }
}
}
impl<'a, T> Deref for PeripheralRef<'a, T> {
impl<'a, T: PeripheralType> Deref for Peri<'a, T> {
type Target = T;
#[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`.
///
/// 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)
}
}
/// Marker trait for peripheral types.
pub trait PeripheralType: Copy + Sized {}

View File

@ -5,7 +5,7 @@ use core::future::Future;
use core::pin::Pin as FuturePin;
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 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
/// mode.
pub struct Flex<'d> {
pin: PeripheralRef<'d, AnyPin>,
pin: Peri<'d, AnyPin>,
}
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
/// before the pin is put into output mode.
#[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
into_ref!(pin);
pub fn new(pin: Peri<'d, impl Pin>) -> Self {
// Pin will be in disconnected state.
Self { pin: pin.map_into() }
Self { pin: pin.into() }
}
/// Set the pin's pull.
@ -345,7 +343,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[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);
pin.set_as_input();
pin.set_pull(pull);
@ -421,7 +419,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level] configuration.
#[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);
pin.set_as_output();
pin.set_level(initial_output);
@ -491,7 +489,7 @@ pub struct OutputOpenDrain<'d> {
impl<'d> OutputOpenDrain<'d> {
/// Create a new GPIO open drain output driver for a [Pin] with the provided [Level].
#[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);
pin.set_level(initial_output);
pin.set_as_input_output();
@ -599,7 +597,7 @@ impl<'d> OutputOpenDrain<'d> {
/// Type-erased GPIO pin
pub struct AnyPin {
pin_port: u8,
pub(crate) pin_port: u8,
}
impl AnyPin {
@ -608,8 +606,8 @@ impl AnyPin {
/// # Safety
/// - `pin_port` should not in use by another driver.
#[inline]
pub unsafe fn steal(pin_port: u8) -> Self {
Self { pin_port }
pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
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].
#[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
fn degrade(self) -> AnyPin {
AnyPin {
pin_port: self.pin_port(),
}
}
pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// The index of this pin in PINCM (pin control management) registers.
#[inline]
fn pin_cm(&self) -> u8 {
@ -866,7 +858,9 @@ macro_rules! impl_pin {
impl From<crate::peripherals::$name> for crate::gpio::AnyPin {
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"]
struct InputFuture<'d> {
pin: PeripheralRef<'d, AnyPin>,
pin: Peri<'d, AnyPin>,
}
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();
// Before clearing any previous edge events, we must disable events.

View File

@ -50,7 +50,7 @@ pub(crate) mod _generated {
// Reexports
pub(crate) use _generated::gpio_pincm;
pub use _generated::{peripherals, Peripherals};
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
pub use embassy_hal_internal::Peri;
#[cfg(feature = "unstable-pac")]
pub use mspm0_metapac as 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 embassy_hal_internal::atomic_ring_buffer::RingBuffer;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::Peri;
use pac::uarte::vals;
// Re-export SVD variants to allow user to directly set values
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::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 {
tx_buf: RingBuffer,
@ -222,27 +222,26 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)]
pub fn new(
uarte: impl Peripheral<P = U> + 'd,
timer: impl Peripheral<P = T> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd,
uarte: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
txd: Peri<'d, impl GpioPin>,
config: Config,
rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, timer, rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner(
uarte,
timer,
ppi_ch1.map_into(),
ppi_ch2.map_into(),
ppi_group.map_into(),
rxd.map_into(),
txd.map_into(),
ppi_ch1.into(),
ppi_ch2.into(),
ppi_group.into(),
rxd.into(),
txd.into(),
None,
None,
config,
@ -258,31 +257,30 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)]
pub fn new_with_rtscts(
uarte: impl Peripheral<P = U> + 'd,
timer: impl Peripheral<P = T> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd,
uarte: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd,
rts: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
txd: Peri<'d, impl GpioPin>,
cts: Peri<'d, impl GpioPin>,
rts: Peri<'d, impl GpioPin>,
config: Config,
rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, timer, rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner(
uarte,
timer,
ppi_ch1.map_into(),
ppi_ch2.map_into(),
ppi_group.map_into(),
rxd.map_into(),
txd.map_into(),
Some(cts.map_into()),
Some(rts.map_into()),
ppi_ch1.into(),
ppi_ch2.into(),
ppi_group.into(),
rxd.into(),
txd.into(),
Some(cts.into()),
Some(rts.into()),
config,
rx_buffer,
tx_buffer,
@ -291,15 +289,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
#[allow(clippy::too_many_arguments)]
fn new_inner(
peri: PeripheralRef<'d, U>,
timer: PeripheralRef<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
rts: Option<PeripheralRef<'d, AnyPin>>,
peri: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: Peri<'d, AnyGroup>,
rxd: Peri<'d, AnyPin>,
txd: Peri<'d, AnyPin>,
cts: Option<Peri<'d, AnyPin>>,
rts: Option<Peri<'d, AnyPin>>,
config: Config,
rx_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.
pub struct BufferedUarteTx<'d, U: UarteInstance> {
_peri: PeripheralRef<'d, U>,
_peri: Peri<'d, U>,
}
impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
/// Create a new BufferedUarteTx without hardware flow control.
pub fn new(
uarte: impl Peripheral<P = U> + 'd,
uarte: Peri<'d, U>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
txd: Peri<'d, impl GpioPin>,
config: Config,
tx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, txd);
Self::new_inner(uarte, txd.map_into(), None, config, tx_buffer)
Self::new_inner(uarte, txd.into(), None, config, tx_buffer)
}
/// 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.
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,
txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd,
txd: Peri<'d, impl GpioPin>,
cts: Peri<'d, impl GpioPin>,
config: Config,
tx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, txd, cts);
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config, tx_buffer)
Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer)
}
fn new_inner(
peri: PeripheralRef<'d, U>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
peri: Peri<'d, U>,
txd: Peri<'d, AnyPin>,
cts: Option<Peri<'d, AnyPin>>,
config: Config,
tx_buffer: &'d mut [u8],
) -> Self {
@ -426,9 +422,9 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
}
fn new_innerer(
peri: PeripheralRef<'d, U>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
peri: Peri<'d, U>,
txd: Peri<'d, AnyPin>,
cts: Option<Peri<'d, AnyPin>>,
tx_buffer: &'d mut [u8],
) -> Self {
let r = U::regs();
@ -542,7 +538,7 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> {
/// Reader part of the buffered UARTE driver.
pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> {
_peri: PeripheralRef<'d, U>,
_peri: Peri<'d, U>,
timer: Timer<'d, T>,
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
_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.
#[allow(clippy::too_many_arguments)]
pub fn new(
uarte: impl Peripheral<P = U> + 'd,
timer: impl Peripheral<P = T> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd,
uarte: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
config: Config,
rx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, timer, rxd, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner(
uarte,
timer,
ppi_ch1.map_into(),
ppi_ch2.map_into(),
ppi_group.map_into(),
rxd.map_into(),
ppi_ch1.into(),
ppi_ch2.into(),
ppi_group.into(),
rxd.into(),
None,
config,
rx_buffer,
@ -588,26 +583,25 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
/// Panics if `rx_buffer.len()` is odd.
#[allow(clippy::too_many_arguments)]
pub fn new_with_rts(
uarte: impl Peripheral<P = U> + 'd,
timer: impl Peripheral<P = T> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd,
uarte: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, impl ConfigurableChannel>,
ppi_ch2: Peri<'d, impl ConfigurableChannel>,
ppi_group: Peri<'d, impl Group>,
_irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
rts: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
rts: Peri<'d, impl GpioPin>,
config: Config,
rx_buffer: &'d mut [u8],
) -> Self {
into_ref!(uarte, timer, rxd, rts, ppi_ch1, ppi_ch2, ppi_group);
Self::new_inner(
uarte,
timer,
ppi_ch1.map_into(),
ppi_ch2.map_into(),
ppi_group.map_into(),
rxd.map_into(),
Some(rts.map_into()),
ppi_ch1.into(),
ppi_ch2.into(),
ppi_group.into(),
rxd.into(),
Some(rts.into()),
config,
rx_buffer,
)
@ -615,13 +609,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
#[allow(clippy::too_many_arguments)]
fn new_inner(
peri: PeripheralRef<'d, U>,
timer: PeripheralRef<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>,
peri: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: Peri<'d, AnyGroup>,
rxd: Peri<'d, AnyPin>,
rts: Option<Peri<'d, AnyPin>>,
config: Config,
rx_buffer: &'d mut [u8],
) -> Self {
@ -640,13 +634,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
#[allow(clippy::too_many_arguments)]
fn new_innerer(
peri: PeripheralRef<'d, U>,
timer: PeripheralRef<'d, T>,
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
ppi_group: PeripheralRef<'d, AnyGroup>,
rxd: PeripheralRef<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>,
peri: Peri<'d, U>,
timer: Peri<'d, T>,
ppi_ch1: Peri<'d, AnyConfigurableChannel>,
ppi_ch2: Peri<'d, AnyConfigurableChannel>,
ppi_group: Peri<'d, AnyGroup>,
rxd: Peri<'d, AnyPin>,
rts: Option<Peri<'d, AnyPin>>,
rx_buffer: &'d mut [u8],
) -> Self {
assert!(rx_buffer.len() % 2 == 0);

View File

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

View File

@ -5,14 +5,14 @@ use core::convert::Infallible;
use core::hint::unreachable_unchecked;
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::gpio;
use crate::pac::gpio::vals;
#[cfg(not(feature = "_nrf51"))]
use crate::pac::shared::{regs::Psel, vals::Connect};
use crate::{pac, Peripheral};
/// A GPIO port with up to 32 pins.
#[derive(Debug, Eq, PartialEq)]
@ -49,7 +49,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[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);
pin.set_as_input(pull);
@ -210,7 +210,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
#[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);
match initial_output {
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
/// mode.
pub struct Flex<'d> {
pub(crate) pin: PeripheralRef<'d, AnyPin>,
pub(crate) pin: Peri<'d, AnyPin>,
}
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
/// before the pin is put into output mode.
#[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
into_ref!(pin);
pub fn new(pin: Peri<'d, impl Pin>) -> Self {
// Pin will be in disconnected state.
Self { pin: pin.map_into() }
Self { pin: pin.into() }
}
/// 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].
#[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)
#[inline]
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 {
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
pub struct AnyPin {
pin_port: u8,
pub(crate) pin_port: u8,
}
impl AnyPin {
@ -550,8 +541,8 @@ impl AnyPin {
/// # Safety
/// - `pin_port` should not in use by another driver.
#[inline]
pub unsafe fn steal(pin_port: u8) -> Self {
Self { pin_port }
pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
Peri::new_unchecked(Self { pin_port })
}
}
@ -573,7 +564,7 @@ pub(crate) trait PselBits {
}
#[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]
fn psel_bits(&self) -> pac::shared::regs::Psel {
match self {
@ -611,8 +602,10 @@ macro_rules! impl_pin {
}
impl From<peripherals::$type> for crate::gpio::AnyPin {
fn from(val: peripherals::$type) -> Self {
crate::gpio::Pin::degrade(val)
fn from(_val: peripherals::$type) -> Self {
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::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 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
pub struct InputChannel<'d> {
ch: PeripheralRef<'d, AnyChannel>,
ch: Peri<'d, AnyChannel>,
pin: Input<'d>,
}
@ -204,9 +204,7 @@ impl<'d> Drop for InputChannel<'d> {
impl<'d> InputChannel<'d> {
/// Create a new GPIOTE input channel driver.
pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Input<'d>, polarity: InputChannelPolarity) -> Self {
into_ref!(ch);
pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self {
let g = regs();
let num = ch.number();
@ -228,7 +226,7 @@ impl<'d> InputChannel<'d> {
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.
@ -261,7 +259,7 @@ impl<'d> InputChannel<'d> {
/// GPIOTE channel driver in output mode
pub struct OutputChannel<'d> {
ch: PeripheralRef<'d, AnyChannel>,
ch: Peri<'d, AnyChannel>,
_pin: Output<'d>,
}
@ -276,8 +274,7 @@ impl<'d> Drop for OutputChannel<'d> {
impl<'d> OutputChannel<'d> {
/// Create a new GPIOTE output channel driver.
pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self {
into_ref!(ch);
pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self {
let g = regs();
let num = ch.number();
@ -301,7 +298,7 @@ impl<'d> OutputChannel<'d> {
});
OutputChannel {
ch: ch.map_into(),
ch: ch.into(),
_pin: pin,
}
}
@ -351,14 +348,12 @@ impl<'d> OutputChannel<'d> {
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub(crate) struct PortInputFuture<'a> {
pin: PeripheralRef<'a, AnyPin>,
pin: Peri<'a, AnyPin>,
}
impl<'a> PortInputFuture<'a> {
fn new(pin: impl Peripheral<P = impl GpioPin> + 'a) -> Self {
Self {
pin: pin.into_ref().map_into(),
}
fn new(pin: Peri<'a, impl GpioPin>) -> Self {
Self { pin: pin.into() }
}
}
@ -415,13 +410,13 @@ impl<'d> Flex<'d> {
/// Wait until the pin is high. If it is already high, return immediately.
pub async fn wait_for_high(&mut self) {
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.
pub async fn wait_for_low(&mut self) {
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.
@ -443,7 +438,7 @@ impl<'d> Flex<'d> {
} else {
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.
#[allow(private_bounds)]
pub trait Channel: SealedChannel + Into<AnyChannel> + Sized + 'static {
pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
/// Get the channel number.
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.
///
/// Obtained by calling `Channel::degrade`.
/// Obtained by calling `Channel::into()`.
///
/// This allows using several channels in situations that might require
/// 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 {
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 embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::typelevel::Interrupt;
use crate::pac::i2s::vals;
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.
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.
pub struct I2S<'d, T: Instance> {
i2s: PeripheralRef<'d, T>,
mck: Option<PeripheralRef<'d, AnyPin>>,
sck: PeripheralRef<'d, AnyPin>,
lrck: PeripheralRef<'d, AnyPin>,
sdin: Option<PeripheralRef<'d, AnyPin>>,
sdout: Option<PeripheralRef<'d, AnyPin>>,
i2s: Peri<'d, T>,
mck: Option<Peri<'d, AnyPin>>,
sck: Peri<'d, AnyPin>,
lrck: Peri<'d, AnyPin>,
sdin: Option<Peri<'d, AnyPin>>,
sdout: Option<Peri<'d, AnyPin>>,
master_clock: Option<MasterClock>,
config: Config,
}
@ -419,20 +419,19 @@ pub struct I2S<'d, T: Instance> {
impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in master mode
pub fn new_master(
i2s: impl Peripheral<P = T> + 'd,
i2s: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
mck: impl Peripheral<P = impl GpioPin> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd,
lrck: impl Peripheral<P = impl GpioPin> + 'd,
mck: Peri<'d, impl GpioPin>,
sck: Peri<'d, impl GpioPin>,
lrck: Peri<'d, impl GpioPin>,
master_clock: MasterClock,
config: Config,
) -> Self {
into_ref!(i2s, mck, sck, lrck);
Self {
i2s,
mck: Some(mck.map_into()),
sck: sck.map_into(),
lrck: lrck.map_into(),
mck: Some(mck.into()),
sck: sck.into(),
lrck: lrck.into(),
sdin: None,
sdout: None,
master_clock: Some(master_clock),
@ -442,18 +441,17 @@ impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in slave mode
pub fn new_slave(
i2s: impl Peripheral<P = T> + 'd,
i2s: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd,
lrck: impl Peripheral<P = impl GpioPin> + 'd,
sck: Peri<'d, impl GpioPin>,
lrck: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(i2s, sck, lrck);
Self {
i2s,
mck: None,
sck: sck.map_into(),
lrck: lrck.map_into(),
sck: sck.into(),
lrck: lrck.into(),
sdin: None,
sdout: None,
master_clock: None,
@ -464,10 +462,10 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S output only
pub fn output<S: Sample, const NB: usize, const NS: usize>(
mut self,
sdout: impl Peripheral<P = impl GpioPin> + 'd,
sdout: Peri<'d, impl GpioPin>,
buffers: MultiBuffering<S, NB, NS>,
) -> OutputStream<'d, T, S, NB, NS> {
self.sdout = Some(sdout.into_ref().map_into());
self.sdout = Some(sdout.into());
OutputStream {
_p: self.build(),
buffers,
@ -477,10 +475,10 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S input only
pub fn input<S: Sample, const NB: usize, const NS: usize>(
mut self,
sdin: impl Peripheral<P = impl GpioPin> + 'd,
sdin: Peri<'d, impl GpioPin>,
buffers: MultiBuffering<S, NB, NS>,
) -> InputStream<'d, T, S, NB, NS> {
self.sdin = Some(sdin.into_ref().map_into());
self.sdin = Some(sdin.into());
InputStream {
_p: self.build(),
buffers,
@ -490,13 +488,13 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S full duplex (input and output)
pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>(
mut self,
sdin: impl Peripheral<P = impl GpioPin> + 'd,
sdout: impl Peripheral<P = impl GpioPin> + 'd,
sdin: Peri<'d, impl GpioPin>,
sdout: Peri<'d, impl GpioPin>,
buffers_out: MultiBuffering<S, NB, NS>,
buffers_in: MultiBuffering<S, NB, NS>,
) -> FullDuplexStream<'d, T, S, NB, NS> {
self.sdout = Some(sdout.into_ref().map_into());
self.sdin = Some(sdin.into_ref().map_into());
self.sdout = Some(sdout.into());
self.sdin = Some(sdin.into());
FullDuplexStream {
_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.select_pins();
self.setup_interrupt();
@ -702,7 +700,7 @@ impl<'d, T: Instance> I2S<'d, T> {
/// I2S output
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>,
}
@ -756,7 +754,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream<
/// I2S input
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>,
}
@ -811,7 +809,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<'
/// I2S full duplex stream (input & output)
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_in: MultiBuffering<S, NB, NS>,
}
@ -1148,7 +1146,7 @@ pub(crate) trait SealedInstance {
/// I2S peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

@ -263,7 +263,7 @@ pub use chip::pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use chip::pac;
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;
#[cfg(feature = "rt")]

View File

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

View File

@ -2,14 +2,13 @@
use core::{ptr, slice};
use embassy_hal_internal::{into_ref, PeripheralRef};
use embedded_storage::nor_flash::{
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
};
use crate::pac::nvmc::vals;
use crate::peripherals::NVMC;
use crate::{pac, Peripheral};
use crate::{pac, Peri};
#[cfg(not(feature = "_nrf5340-net"))]
/// 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.
pub struct Nvmc<'d> {
_p: PeripheralRef<'d, NVMC>,
_p: Peri<'d, NVMC>,
}
impl<'d> Nvmc<'d> {
/// Create Nvmc driver.
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
into_ref!(_p);
pub fn new(_p: Peri<'d, NVMC>) -> Self {
Self { _p }
}

View File

@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
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 fixed::types::I7F1;
@ -25,7 +25,7 @@ pub use crate::pac::pdm::vals::Freq as Frequency;
feature = "_nrf91",
))]
pub use crate::pac::pdm::vals::Ratio;
use crate::{interrupt, pac, Peripheral};
use crate::{interrupt, pac};
/// Interrupt handler
pub struct InterruptHandler<T: Instance> {
@ -54,7 +54,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// PDM microphone interface
pub struct Pdm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>,
_peri: Peri<'d, T>,
}
/// PDM error
@ -89,24 +89,16 @@ pub enum SamplerState {
impl<'d, T: Instance> Pdm<'d, T> {
/// Create PDM driver
pub fn new(
pdm: impl Peripheral<P = T> + 'd,
pdm: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
clk: impl Peripheral<P = impl GpioPin> + 'd,
din: impl Peripheral<P = impl GpioPin> + 'd,
clk: Peri<'d, impl GpioPin>,
din: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(pdm, clk, din);
Self::new_inner(pdm, clk.map_into(), din.map_into(), config)
Self::new_inner(pdm, clk.into(), din.into(), config)
}
fn new_inner(
pdm: PeripheralRef<'d, T>,
clk: PeripheralRef<'d, AnyPin>,
din: PeripheralRef<'d, AnyPin>,
config: Config,
) -> Self {
into_ref!(pdm);
fn new_inner(pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self {
let r = T::regs();
// setup gpio pins
@ -452,7 +444,7 @@ pub(crate) trait SealedInstance {
/// PDM peripheral instance
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral
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 crate::{pac, Peripheral};
use crate::{pac, Peri};
const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
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> {
/// 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])
}
}
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
/// 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])
}
}
@ -28,13 +26,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
{
/// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires.
pub fn new_many_to_many(
ch: impl Peripheral<P = C> + 'd,
events: [Event<'d>; EVENT_COUNT],
tasks: [Task<'d>; TASK_COUNT],
) -> Self {
into_ref!(ch);
pub fn new_many_to_many(ch: Peri<'d, C>, events: [Event<'d>; EVENT_COUNT], tasks: [Task<'d>; TASK_COUNT]) -> Self {
let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
for task in tasks {
if unsafe { task.subscribe_reg().read_volatile() } != 0 {

View File

@ -18,10 +18,10 @@
use core::marker::PhantomData;
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::{peripherals, Peripheral};
use crate::peripherals;
#[cfg_attr(feature = "_dppi", path = "dppi.rs")]
#[cfg_attr(feature = "_ppi", path = "ppi.rs")]
@ -30,7 +30,7 @@ pub(crate) use _version::*;
/// PPI channel driver.
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")]
events: [Event<'d>; EVENT_COUNT],
#[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.
pub struct PpiGroup<'d, G: Group> {
g: PeripheralRef<'d, G>,
g: Peri<'d, G>,
}
impl<'d, G: Group> PpiGroup<'d, G> {
/// Create a new PPI group driver.
///
/// The group is initialized as containing no channels.
pub fn new(g: impl Peripheral<P = G> + 'd) -> Self {
into_ref!(g);
pub fn new(g: Peri<'d, G>) -> Self {
let r = regs();
let n = g.number();
r.chg(n).write(|_| ());
@ -210,34 +208,22 @@ pub(crate) trait SealedGroup {}
/// Interface for PPI channels.
#[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
fn number(&self) -> usize;
}
/// Interface for PPI channels that can be configured.
pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {
/// Convert into a type erased configurable channel.
fn degrade(self) -> AnyConfigurableChannel;
}
pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {}
/// Interface for PPI channels that cannot be configured.
pub trait StaticChannel: Channel + Into<AnyStaticChannel> {
/// Convert into a type erased static channel.
fn degrade(self) -> AnyStaticChannel;
}
pub trait StaticChannel: Channel + Into<AnyStaticChannel> {}
/// Interface for a group of PPI channels.
#[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.
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
}
}
impl StaticChannel for AnyStaticChannel {
fn degrade(self) -> AnyStaticChannel {
self
}
}
impl StaticChannel for AnyStaticChannel {}
/// The any configurable channel can represent any configurable channel at runtime.
/// This can be used to have fewer generic parameters in some places.
@ -273,11 +255,7 @@ impl Channel for AnyConfigurableChannel {
self.number as usize
}
}
impl ConfigurableChannel for AnyConfigurableChannel {
fn degrade(self) -> AnyConfigurableChannel {
self
}
}
impl ConfigurableChannel for AnyConfigurableChannel {}
#[cfg(not(feature = "_nrf51"))]
macro_rules! impl_ppi_channel {
@ -291,35 +269,23 @@ macro_rules! impl_ppi_channel {
};
($type:ident, $number:expr => static) => {
impl_ppi_channel!($type, $number);
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 crate::ppi::StaticChannel for peripherals::$type {}
impl From<peripherals::$type> for crate::ppi::AnyStaticChannel {
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) => {
impl_ppi_channel!($type, $number);
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 crate::ppi::ConfigurableChannel for peripherals::$type {}
impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel {
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 {
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 crate::{pac, Peripheral};
use crate::{pac, Peri};
impl<'d> Task<'d> {
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
impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> {
/// Configure PPI channel to trigger `task`.
pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self {
into_ref!(ch);
pub fn new_zero_to_one(ch: Peri<'d, C>, task: Task) -> Self {
let r = regs();
let n = ch.number();
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> {
/// 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 {
into_ref!(ch);
pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self {
let r = regs();
let n = ch.number();
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
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
/// 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 {
into_ref!(ch);
pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self {
let r = regs();
let n = ch.number();
r.ch(n).eep().write_value(event.reg_val());

View File

@ -4,34 +4,34 @@
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::pac::gpio::vals as gpiovals;
use crate::pac::pwm::vals;
use crate::ppi::{Event, Task};
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
/// to simply set a duty cycle across up to four channels.
pub struct SimplePwm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>,
_peri: Peri<'d, T>,
duty: [u16; 4],
ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>,
ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<Peri<'d, AnyPin>>,
}
/// 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.
pub struct SequencePwm<'d, T: Instance> {
_peri: PeripheralRef<'d, T>,
ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>,
_peri: Peri<'d, T>,
ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<Peri<'d, AnyPin>>,
}
/// PWM error
@ -54,78 +54,61 @@ pub const PWM_CLK_HZ: u32 = 16_000_000;
impl<'d, T: Instance> SequencePwm<'d, T> {
/// Create a new 1-channel PWM
#[allow(unused_unsafe)]
pub fn new_1ch(
pwm: impl Peripheral<P = T> + 'd,
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)
pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> {
Self::new_inner(pwm, Some(ch0.into()), None, None, None, config)
}
/// Create a new 2-channel PWM
#[allow(unused_unsafe)]
pub fn new_2ch(
pwm: impl Peripheral<P = T> + 'd,
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
pwm: Peri<'d, T>,
ch0: Peri<'d, impl GpioPin>,
ch1: Peri<'d, impl GpioPin>,
config: Config,
) -> Result<Self, Error> {
into_ref!(ch0, ch1);
Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config)
Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None, config)
}
/// Create a new 3-channel PWM
#[allow(unused_unsafe)]
pub fn new_3ch(
pwm: impl Peripheral<P = T> + 'd,
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
ch2: impl Peripheral<P = impl GpioPin> + 'd,
pwm: Peri<'d, T>,
ch0: Peri<'d, impl GpioPin>,
ch1: Peri<'d, impl GpioPin>,
ch2: Peri<'d, impl GpioPin>,
config: Config,
) -> Result<Self, Error> {
into_ref!(ch0, ch1, ch2);
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
None,
config,
)
Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None, config)
}
/// Create a new 4-channel PWM
#[allow(unused_unsafe)]
pub fn new_4ch(
pwm: impl Peripheral<P = T> + 'd,
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
ch2: impl Peripheral<P = impl GpioPin> + 'd,
ch3: impl Peripheral<P = impl GpioPin> + 'd,
pwm: Peri<'d, T>,
ch0: Peri<'d, impl GpioPin>,
ch1: Peri<'d, impl GpioPin>,
ch2: Peri<'d, impl GpioPin>,
ch3: Peri<'d, impl GpioPin>,
config: Config,
) -> Result<Self, Error> {
into_ref!(ch0, ch1, ch2, ch3);
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
Some(ch3.map_into()),
Some(ch0.into()),
Some(ch1.into()),
Some(ch2.into()),
Some(ch3.into()),
config,
)
}
fn new_inner(
_pwm: impl Peripheral<P = T> + 'd,
ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>,
_pwm: Peri<'d, T>,
ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<Peri<'d, AnyPin>>,
config: Config,
) -> Result<Self, Error> {
into_ref!(_pwm);
let r = T::regs();
if let Some(pin) = &ch0 {
@ -610,74 +593,54 @@ pub enum CounterMode {
impl<'d, T: Instance> SimplePwm<'d, T> {
/// Create a new 1-channel PWM
#[allow(unused_unsafe)]
pub fn new_1ch(pwm: impl Peripheral<P = T> + 'd, ch0: impl Peripheral<P = impl GpioPin> + 'd) -> Self {
unsafe {
into_ref!(ch0);
Self::new_inner(pwm, Some(ch0.map_into()), None, None, None)
}
pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self {
unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) }
}
/// Create a new 2-channel PWM
#[allow(unused_unsafe)]
pub fn new_2ch(
pwm: impl Peripheral<P = T> + 'd,
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)
pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self {
Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None)
}
/// Create a new 3-channel PWM
#[allow(unused_unsafe)]
pub fn new_3ch(
pwm: impl Peripheral<P = T> + 'd,
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
ch2: impl Peripheral<P = impl GpioPin> + 'd,
pwm: Peri<'d, T>,
ch0: Peri<'d, impl GpioPin>,
ch1: Peri<'d, impl GpioPin>,
ch2: Peri<'d, impl GpioPin>,
) -> Self {
unsafe {
into_ref!(ch0, ch1, ch2);
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
None,
)
}
unsafe { Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None) }
}
/// Create a new 4-channel PWM
#[allow(unused_unsafe)]
pub fn new_4ch(
pwm: impl Peripheral<P = T> + 'd,
ch0: impl Peripheral<P = impl GpioPin> + 'd,
ch1: impl Peripheral<P = impl GpioPin> + 'd,
ch2: impl Peripheral<P = impl GpioPin> + 'd,
ch3: impl Peripheral<P = impl GpioPin> + 'd,
pwm: Peri<'d, T>,
ch0: Peri<'d, impl GpioPin>,
ch1: Peri<'d, impl GpioPin>,
ch2: Peri<'d, impl GpioPin>,
ch3: Peri<'d, impl GpioPin>,
) -> Self {
unsafe {
into_ref!(ch0, ch1, ch2, ch3);
Self::new_inner(
pwm,
Some(ch0.map_into()),
Some(ch1.map_into()),
Some(ch2.map_into()),
Some(ch3.map_into()),
Some(ch0.into()),
Some(ch1.into()),
Some(ch2.into()),
Some(ch3.into()),
)
}
}
fn new_inner(
_pwm: impl Peripheral<P = T> + 'd,
ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>,
_pwm: Peri<'d, T>,
ch0: Option<Peri<'d, AnyPin>>,
ch1: Option<Peri<'d, AnyPin>>,
ch2: Option<Peri<'d, AnyPin>>,
ch3: Option<Peri<'d, AnyPin>>,
) -> Self {
into_ref!(_pwm);
let r = T::regs();
for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() {
@ -896,7 +859,7 @@ pub(crate) trait SealedInstance {
/// PWM peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static {
pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,11 +10,11 @@ use core::task::Poll;
use critical_section::{CriticalSection, Mutex};
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 crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, pac, Peripheral};
use crate::{interrupt, pac};
/// Interrupt handler.
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`.
pub struct Rng<'d, T: Instance> {
_peri: PeripheralRef<'d, T>,
_peri: Peri<'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.
pub fn new(
rng: impl Peripheral<P = T> + 'd,
rng: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self {
into_ref!(rng);
let this = Self { _peri: rng };
this.stop();
@ -250,7 +248,7 @@ pub(crate) trait SealedInstance {
/// RNG peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

@ -3,11 +3,12 @@
#![macro_use]
use core::future::poll_fn;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
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;
pub(crate) use vals::Psel as InputChannel;
@ -15,7 +16,7 @@ use crate::interrupt::InterruptExt;
use crate::pac::saadc::vals;
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::{interrupt, pac, peripherals, Peripheral};
use crate::{interrupt, pac, peripherals};
/// SAADC error
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -87,37 +88,32 @@ pub struct ChannelConfig<'d> {
/// Acquisition time in microseconds.
pub time: Time,
/// Positive channel to sample
p_channel: PeripheralRef<'d, AnyInput>,
p_channel: AnyInput<'d>,
/// An optional negative channel to sample
n_channel: Option<PeripheralRef<'d, AnyInput>>,
n_channel: Option<AnyInput<'d>>,
}
impl<'d> ChannelConfig<'d> {
/// Default configuration for single ended channel sampling.
pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
into_ref!(input);
pub fn single_ended(input: impl Input + 'd) -> Self {
Self {
reference: Reference::INTERNAL,
gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS,
time: Time::_10US,
p_channel: input.map_into(),
p_channel: input.degrade_saadc(),
n_channel: None,
}
}
/// Default configuration for differential channel sampling.
pub fn differential(
p_input: impl Peripheral<P = impl Input> + 'd,
n_input: impl Peripheral<P = impl Input> + 'd,
) -> Self {
into_ref!(p_input, n_input);
pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self {
Self {
reference: Reference::INTERNAL,
gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS,
time: Time::_10US,
p_channel: p_input.map_into(),
n_channel: Some(n_input.map_into()),
p_channel: p_input.degrade_saadc(),
n_channel: Some(n_input.degrade_saadc()),
}
}
}
@ -133,19 +129,17 @@ pub enum CallbackResult {
/// One-shot and continuous SAADC.
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> {
/// Create a new SAADC driver.
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,
config: Config,
channel_configs: [ChannelConfig; N],
) -> Self {
into_ref!(saadc);
let r = pac::SAADC;
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>(
&mut self,
timer: &mut T,
ppi_ch1: &mut impl ConfigurableChannel,
ppi_ch2: &mut impl ConfigurableChannel,
timer: Peri<'_, T>,
ppi_ch1: Peri<'_, impl ConfigurableChannel>,
ppi_ch2: Peri<'_, impl ConfigurableChannel>,
frequency: Frequency,
sample_counter: u32,
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.
#[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`.
///
/// This allows using several inputs in situations that might require
/// 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 {
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
/// them to be the same type, like putting them in an array.
pub struct AnyInput {
pub struct AnyInput<'a> {
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 {
self.channel
}
}
impl Input for AnyInput {}
impl Input for AnyInput<'_> {}
macro_rules! impl_saadc_input {
($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) => {
impl crate::saadc::SealedInput for $pin {
@ -696,12 +707,6 @@ macro_rules! impl_saadc_input {
}
}
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 embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
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};
@ -21,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals;
use crate::pac::spim::vals;
use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral};
use crate::{interrupt, pac};
/// SPIM error
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -100,73 +100,61 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// SPIM driver.
pub struct Spim<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
}
impl<'d, T: Instance> Spim<'d, T> {
/// Create a new SPIM driver.
pub fn new(
spim: impl Peripheral<P = T> + 'd,
spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd,
sck: Peri<'d, impl GpioPin>,
miso: Peri<'d, impl GpioPin>,
mosi: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(sck, miso, mosi);
Self::new_inner(
spim,
Some(sck.map_into()),
Some(miso.map_into()),
Some(mosi.map_into()),
config,
)
Self::new_inner(spim, Some(sck.into()), Some(miso.into()), Some(mosi.into()), config)
}
/// Create a new SPIM driver, capable of TX only (MOSI only).
pub fn new_txonly(
spim: impl Peripheral<P = T> + 'd,
spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd,
sck: Peri<'d, impl GpioPin>,
mosi: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(sck, mosi);
Self::new_inner(spim, Some(sck.map_into()), None, Some(mosi.map_into()), config)
Self::new_inner(spim, Some(sck.into()), None, Some(mosi.into()), config)
}
/// Create a new SPIM driver, capable of RX only (MISO only).
pub fn new_rxonly(
spim: impl Peripheral<P = T> + 'd,
spim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd,
sck: Peri<'d, impl GpioPin>,
miso: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(sck, miso);
Self::new_inner(spim, Some(sck.map_into()), Some(miso.map_into()), None, config)
Self::new_inner(spim, Some(sck.into()), Some(miso.into()), None, config)
}
/// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin.
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,
mosi: impl Peripheral<P = impl GpioPin> + 'd,
mosi: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(mosi);
Self::new_inner(spim, None, None, Some(mosi.map_into()), config)
Self::new_inner(spim, None, None, Some(mosi.into()), config)
}
fn new_inner(
spim: impl Peripheral<P = T> + 'd,
sck: Option<PeripheralRef<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>,
spim: Peri<'d, T>,
sck: Option<Peri<'d, AnyPin>>,
miso: Option<Peri<'d, AnyPin>>,
mosi: Option<Peri<'d, AnyPin>>,
config: Config,
) -> Self {
into_ref!(spim);
let r = T::regs();
// Configure pins
@ -511,7 +499,7 @@ pub(crate) trait SealedInstance {
/// SPIM peripheral instance
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static {
pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

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

View File

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

View File

@ -6,11 +6,11 @@
#![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::ppi::{Event, Task};
use crate::{pac, Peripheral};
pub(crate) trait SealedInstance {
/// The number of CC registers this instance has.
@ -20,7 +20,7 @@ pub(crate) trait SealedInstance {
/// Basic Timer instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: crate::interrupt::typelevel::Interrupt;
}
@ -84,7 +84,7 @@ pub enum Frequency {
/// Timer driver.
pub struct Timer<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'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
/// `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)
}
@ -100,13 +100,11 @@ impl<'d, T: Instance> Timer<'d, T> {
///
/// This can be useful for triggering tasks via PPI
/// `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)
}
fn new_inner(timer: impl Peripheral<P = T> + 'd, _is_counter: bool) -> Self {
into_ref!(timer);
fn new_inner(timer: Peri<'d, T>, _is_counter: bool) -> Self {
let regs = T::regs();
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
pub struct Cc<'d, T: Instance> {
n: usize,
_p: PeripheralRef<'d, T>,
_p: Peri<'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 embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")]
use embassy_time::{Duration, Instant};
@ -23,7 +23,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals;
use crate::pac::twim::vals;
use crate::util::slice_in_ram;
use crate::{gpio, interrupt, pac, Peripheral};
use crate::{gpio, interrupt, pac};
/// TWIM config.
#[non_exhaustive]
@ -114,20 +114,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// TWI driver.
pub struct Twim<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
}
impl<'d, T: Instance> Twim<'d, T> {
/// Create a new TWI driver.
pub fn new(
twim: impl Peripheral<P = T> + 'd,
twim: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd,
scl: impl Peripheral<P = impl GpioPin> + 'd,
sda: Peri<'d, impl GpioPin>,
scl: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(twim, sda, scl);
let r = T::regs();
// Configure pins
@ -847,7 +845,7 @@ pub(crate) trait SealedInstance {
/// TWIM peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static {
pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral.
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::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")]
use embassy_time::{Duration, Instant};
@ -19,7 +19,7 @@ use crate::interrupt::typelevel::Interrupt;
use crate::pac::gpio::vals as gpiovals;
use crate::pac::twis::vals;
use crate::util::slice_in_ram_or;
use crate::{gpio, interrupt, pac, Peripheral};
use crate::{gpio, interrupt, pac};
/// TWIS config.
#[non_exhaustive]
@ -141,20 +141,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
/// TWIS driver.
pub struct Twis<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
}
impl<'d, T: Instance> Twis<'d, T> {
/// Create a new TWIS driver.
pub fn new(
twis: impl Peripheral<P = T> + 'd,
twis: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd,
scl: impl Peripheral<P = impl GpioPin> + 'd,
sda: Peri<'d, impl GpioPin>,
scl: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(twis, sda, scl);
let r = T::regs();
// Configure pins
@ -791,7 +789,7 @@ pub(crate) trait SealedInstance {
/// TWIS peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static {
pub trait Instance: SealedInstance + PeripheralType + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

@ -19,7 +19,7 @@ use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
// Re-export SVD variants to allow user to directly set values.
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::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral};
use crate::{interrupt, pac};
/// UARTE config.
#[derive(Clone)]
@ -141,56 +141,54 @@ pub struct Uarte<'d, T: Instance> {
///
/// This can be obtained via [`Uarte::split`], or created directly.
pub struct UarteTx<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
}
/// Receiver part of the UARTE driver.
///
/// This can be obtained via [`Uarte::split`], or created directly.
pub struct UarteRx<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
}
impl<'d, T: Instance> Uarte<'d, T> {
/// Create a new UARTE without hardware flow control
pub fn new(
uarte: impl Peripheral<P = T> + 'd,
uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
txd: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, rxd, txd);
Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config)
}
/// Create a new UARTE with hardware flow control (RTS/CTS)
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,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd,
rts: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
txd: Peri<'d, impl GpioPin>,
cts: Peri<'d, impl GpioPin>,
rts: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, rxd, txd, cts, rts);
Self::new_inner(
uarte,
rxd.map_into(),
txd.map_into(),
Some(cts.map_into()),
Some(rts.map_into()),
rxd.into(),
txd.into(),
Some(cts.into()),
Some(rts.into()),
config,
)
}
fn new_inner(
uarte: PeripheralRef<'d, T>,
rxd: PeripheralRef<'d, AnyPin>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
rts: Option<PeripheralRef<'d, AnyPin>>,
uarte: Peri<'d, T>,
rxd: Peri<'d, AnyPin>,
txd: Peri<'d, AnyPin>,
cts: Option<Peri<'d, AnyPin>>,
rts: Option<Peri<'d, AnyPin>>,
config: Config,
) -> Self {
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.
pub fn split_with_idle<U: TimerInstance>(
self,
timer: impl Peripheral<P = U> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
timer: Peri<'d, U>,
ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) {
(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(
r: pac::uarte::Uarte,
txd: PeripheralRef<'_, AnyPin>,
cts: Option<PeripheralRef<'_, AnyPin>>,
) {
pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts: Option<Peri<'_, AnyPin>>) {
txd.set_high();
txd.conf().write(|w| {
w.set_dir(gpiovals::Dir::OUTPUT);
@ -306,11 +300,7 @@ pub(crate) fn configure_tx_pins(
r.psel().cts().write_value(cts.psel_bits());
}
pub(crate) fn configure_rx_pins(
r: pac::uarte::Uarte,
rxd: PeripheralRef<'_, AnyPin>,
rts: Option<PeripheralRef<'_, AnyPin>>,
) {
pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts: Option<Peri<'_, AnyPin>>) {
rxd.conf().write(|w| {
w.set_dir(gpiovals::Dir::INPUT);
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> {
/// Create a new tx-only UARTE without hardware flow control
pub fn new(
uarte: impl Peripheral<P = T> + 'd,
uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd,
txd: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, txd);
Self::new_inner(uarte, txd.map_into(), None, config)
Self::new_inner(uarte, txd.into(), None, config)
}
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
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,
txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd,
txd: Peri<'d, impl GpioPin>,
cts: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, txd, cts);
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
Self::new_inner(uarte, txd.into(), Some(cts.into()), config)
}
fn new_inner(
uarte: PeripheralRef<'d, T>,
txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>,
config: Config,
) -> Self {
fn new_inner(uarte: Peri<'d, T>, txd: Peri<'d, AnyPin>, cts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
let r = T::regs();
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> {
/// Create a new rx-only UARTE without hardware flow control
pub fn new(
uarte: impl Peripheral<P = T> + 'd,
uarte: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, rxd);
Self::new_inner(uarte, rxd.map_into(), None, config)
Self::new_inner(uarte, rxd.into(), None, config)
}
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
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,
rxd: impl Peripheral<P = impl GpioPin> + 'd,
rts: impl Peripheral<P = impl GpioPin> + 'd,
rxd: Peri<'d, impl GpioPin>,
rts: Peri<'d, impl GpioPin>,
config: Config,
) -> Self {
into_ref!(uarte, rxd, rts);
Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
Self::new_inner(uarte, rxd.into(), Some(rts.into()), config)
}
/// 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()
}
fn new_inner(
uarte: PeripheralRef<'d, T>,
rxd: PeripheralRef<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>,
config: Config,
) -> Self {
fn new_inner(uarte: Peri<'d, T>, rxd: Peri<'d, AnyPin>, rts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
let r = T::regs();
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.
pub fn with_idle<U: TimerInstance>(
self,
timer: impl Peripheral<P = U> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
timer: Peri<'d, U>,
ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
) -> UarteRxWithIdle<'d, T, U> {
let timer = Timer::new(timer);
into_ref!(ppi_ch1, ppi_ch2);
let r = T::regs();
// 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();
let mut ppi_ch1 = Ppi::new_one_to_two(
ppi_ch1.map_into(),
ppi_ch1.into(),
Event::from_reg(r.events_rxdrdy()),
timer.task_clear(),
timer.task_start(),
@ -625,7 +599,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
ppi_ch1.enable();
let mut ppi_ch2 = Ppi::new_one_to_one(
ppi_ch2.map_into(),
ppi_ch2.into(),
timer.cc(0).event_compare(),
Task::from_reg(r.tasks_stoprx()),
);
@ -992,7 +966,7 @@ pub(crate) trait SealedInstance {
/// UARTE peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
use core::task::Poll;
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_usb_driver as driver;
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::pac::usbd::vals;
use crate::util::slice_in_ram;
use crate::{interrupt, pac, Peripheral};
use crate::{interrupt, pac};
static BUS_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.
pub struct Driver<'d, T: Instance, V: VbusDetect> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
alloc_in: Allocator,
alloc_out: Allocator,
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> {
/// Create a new USB driver.
pub fn new(
usb: impl Peripheral<P = T> + 'd,
usb: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
vbus_detect: V,
) -> Self {
into_ref!(usb);
T::Interrupt::unpend();
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.
pub struct Bus<'d, T: Instance, V: VbusDetect> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
power_available: bool,
vbus_detect: V,
}
@ -592,7 +590,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
/// USB control pipe.
pub struct ControlPipe<'d, T: Instance> {
_p: PeripheralRef<'d, T>,
_p: Peri<'d, T>,
max_packet_size: u16,
}
@ -779,7 +777,7 @@ pub(crate) trait SealedInstance {
/// USB peripheral instance.
#[allow(private_bounds)]
pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

@ -3,9 +3,11 @@
//! This HAL implements a basic watchdog timer with 1..=8 handles.
//! Once the watchdog has been started, it cannot be stopped.
use core::marker::PhantomData;
use crate::pac::wdt::vals;
pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
use crate::peripherals;
use crate::{peripherals, Peri};
const MIN_TICKS: u32 = 15;
@ -61,7 +63,7 @@ impl Default for Config {
/// Watchdog driver.
pub struct Watchdog {
_private: (),
_wdt: Peri<'static, peripherals::WDT>,
}
impl Watchdog {
@ -74,9 +76,9 @@ impl Watchdog {
/// `N` must be between 1 and 8, inclusive.
#[inline]
pub fn try_new<const N: usize>(
wdt: peripherals::WDT,
wdt: Peri<'static, peripherals::WDT>,
config: Config,
) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> {
) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> {
assert!(N >= 1 && N <= 8);
let r = crate::pac::WDT;
@ -110,11 +112,19 @@ impl Watchdog {
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 {
handles[i] = WatchdogHandle { index: i as u8 };
handles[i] = WatchdogHandle {
_wdt: PhantomData,
index: i as u8,
};
handles[i].pet();
}
@ -155,6 +165,7 @@ impl Watchdog {
/// Watchdog handle.
pub struct WatchdogHandle {
_wdt: PhantomData<Peri<'static, peripherals::WDT>>,
index: u8,
}
@ -183,6 +194,9 @@ impl WatchdogHandle {
/// Watchdog must be initialized and `index` must be between `0` and `N-1`
/// where `N` is the handle count when initializing.
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::{peripherals, Peripheral, PeripheralRef};
use crate::{peripherals, Peri};
pub(crate) fn init() {
// Enable clocks for GPIO, PINT, and IOCON
@ -45,7 +45,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [initial output](Level).
#[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);
pin.set_as_output();
let mut result = Self { pin };
@ -90,7 +90,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Pull].
#[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);
pin.set_as_input();
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
/// reference to a type-erased pin called ["AnyPin"](AnyPin).
pub struct Flex<'d> {
pub(crate) pin: PeripheralRef<'d, AnyPin>,
pub(crate) pin: Peri<'d, AnyPin>,
}
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.
#[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
Self {
pin: pin.into_ref().map_into(),
}
pub fn new(pin: Peri<'d, impl Pin>) -> Self {
Self { pin: pin.into() }
}
/// 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
/// `embassy-nxp` crate due to the [SealedPin] trait.
#[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + 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(),
}
}
pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// Returns the pin number within a bank
#[inline]
fn pin(&self) -> u8 {
@ -252,8 +242,8 @@ impl AnyPin {
/// # Safety
///
/// 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 {
Self { pin_bank, pin_number }
pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> {
Peri::new_unchecked(Self { pin_bank, pin_number })
}
}
@ -289,7 +279,10 @@ macro_rules! impl_pin {
impl From<peripherals::$name> for crate::gpio::AnyPin {
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;
pub mod pint;
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
pub use embassy_hal_internal::Peri;
pub use lpc55_pac as pac;
/// 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 critical_section::Mutex;
use embassy_hal_internal::{Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{self, AnyPin, Level, SealedPin};
use crate::pac::interrupt;
use crate::pac_utils::*;
use crate::Peri;
struct PinInterrupt {
assigned: bool,
@ -107,14 +107,14 @@ pub(crate) fn init() {
#[must_use = "futures do nothing unless you `.await` or poll them"]
struct InputFuture<'d> {
#[allow(dead_code)]
pin: PeripheralRef<'d, AnyPin>,
pin: Peri<'d, AnyPin>,
interrupt_number: usize,
}
impl<'d> InputFuture<'d> {
/// 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> {
let pin = pin.into_ref().map_into();
fn new(pin: Peri<'d, impl gpio::Pin>, interrupt_on: InterruptOn) -> Option<Self> {
let pin = pin.into();
let interrupt_number = next_available_interrupt()?;
// 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
/// try to wait for more than 8 pins, this function will return `None`.
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(())
}
/// 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`.
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(())
}
/// 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`.
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(())
}
/// 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`.
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(())
}
/// 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`.
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(())
}
}

View File

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

View File

@ -8,20 +8,19 @@
//! This module provides functionality to poll BOOTSEL from an embassy application.
use crate::flash::in_ram;
use crate::Peri;
impl crate::peripherals::BOOTSEL {
/// Polls the BOOTSEL button. Returns true if the button is pressed.
///
/// 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
pub fn is_pressed(&mut self) -> bool {
let mut cs_status = Default::default();
/// Reads 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
/// task and for any DMAs from flash to complete
pub fn is_bootsel_pressed(_p: Peri<'_, crate::peripherals::BOOTSEL>) -> bool {
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
!cs_status.infrompad()
}
// bootsel is active low, so invert
!cs_status.infrompad()
}
mod ram_helpers {

View File

@ -7,13 +7,12 @@ use core::marker::PhantomData;
use core::sync::atomic::AtomicU16;
use core::sync::atomic::{AtomicU32, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef};
use pac::clocks::vals::*;
use crate::gpio::{AnyPin, SealedPin};
#[cfg(feature = "rp2040")]
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.
// 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) {
// match P::NR {
// 0 => self.gpin0 = Some((hz, gpin.map_into())),
// 1 => self.gpin1 = Some((hz, gpin.map_into())),
// 0 => self.gpin0 = Some((hz, gpin.into())),
// 1 => self.gpin1 = Some((hz, gpin.into())),
// _ => unreachable!(),
// }
// // 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.
pub struct Gpin<'d, T: GpinPin> {
gpin: PeripheralRef<'d, AnyPin>,
gpin: Peri<'d, AnyPin>,
_phantom: PhantomData<T>,
}
impl<'d, T: GpinPin> Gpin<'d, T> {
/// Create new gpin driver.
pub fn new(gpin: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(gpin);
pub fn new(gpin: Peri<'d, T>) -> Self {
#[cfg(feature = "rp2040")]
gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08));
@ -867,14 +864,10 @@ impl<'d, T: GpinPin> Gpin<'d, T> {
});
Gpin {
gpin: gpin.map_into(),
gpin: gpin.into(),
_phantom: PhantomData,
}
}
// fn map_into(self) -> Gpin<'d, AnyPin> {
// unsafe { core::mem::transmute(self) }
// }
}
impl<'d, T: GpinPin> Drop for Gpin<'d, T> {
@ -936,14 +929,12 @@ pub enum GpoutSrc {
/// General purpose clock output driver.
pub struct Gpout<'d, T: GpoutPin> {
gpout: PeripheralRef<'d, T>,
gpout: Peri<'d, T>,
}
impl<'d, T: GpoutPin> Gpout<'d, T> {
/// Create new general purpose clock output.
pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(gpout);
pub fn new(gpout: Peri<'d, T>) -> Self {
#[cfg(feature = "rp2040")]
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::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 pac::dma::vals::DataSize;
@ -42,7 +42,7 @@ pub(crate) unsafe fn init() {
///
/// SAFETY: Slice must point to a valid location reachable by DMA.
pub unsafe fn read<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a,
ch: Peri<'a, C>,
from: *const W,
to: *mut [W],
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.
pub unsafe fn write<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a,
ch: Peri<'a, C>,
from: *const [W],
to: *mut W,
dreq: vals::TreqSel,
@ -87,7 +87,7 @@ static mut DUMMY: u32 = 0;
///
/// SAFETY: Slice must point to a valid location reachable by DMA.
pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a,
ch: Peri<'a, C>,
to: *mut W,
len: usize,
dreq: vals::TreqSel,
@ -107,11 +107,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
/// DMA copy between slices.
///
/// SAFETY: Slices must point to locations reachable by DMA.
pub unsafe fn copy<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a,
from: &[W],
to: &mut [W],
) -> Transfer<'a, C> {
pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
let from_len = from.len();
let to_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>(
ch: impl Peripheral<P = C> + 'a,
ch: Peri<'a, C>,
from: *const u32,
to: *mut u32,
len: usize,
@ -137,8 +133,6 @@ fn copy_inner<'a, C: Channel>(
incr_write: bool,
dreq: vals::TreqSel,
) -> Transfer<'a, C> {
into_ref!(ch);
let p = ch.regs();
p.read_addr().write_value(from as u32);
@ -171,13 +165,11 @@ fn copy_inner<'a, C: Channel>(
/// DMA transfer driver.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Transfer<'a, C: Channel> {
channel: PeripheralRef<'a, C>,
channel: Peri<'a, C>,
}
impl<'a, C: Channel> Transfer<'a, C> {
pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self {
into_ref!(channel);
pub(crate) fn new(channel: Peri<'a, C>) -> Self {
Self { channel }
}
}
@ -219,7 +211,7 @@ trait SealedWord {}
/// DMA channel interface.
#[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.
fn number(&self) -> u8;
@ -227,11 +219,6 @@ pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Siz
fn regs(&self) -> pac::dma::Channel {
pac::DMA.ch(self.number() as _)
}
/// Convert into type-erased [AnyChannel].
fn degrade(self) -> AnyChannel {
AnyChannel { number: self.number() }
}
}
/// DMA word.
@ -287,7 +274,7 @@ macro_rules! channel {
impl From<peripherals::$name> for crate::dma::AnyChannel {
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::task::{Context, Poll};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embedded_storage::nor_flash::{
check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
ReadNorFlash,
@ -114,7 +114,7 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, '
/// Flash driver.
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)>,
}
@ -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> {
/// 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 {
dma: None,
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> {
/// 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 {
into_ref!(dma);
pub fn new(_flash: Peri<'d, T>, dma: Peri<'d, impl Channel>) -> Self {
Self {
dma: Some(dma.map_into()),
dma: Some(dma.into()),
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 _;
let transfer = unsafe {
crate::dma::read(
self.dma.as_mut().unwrap(),
self.dma.as_mut().unwrap().reborrow(),
XIP_AUX_BASE,
data,
pac::dma::vals::TreqSel::XIP_STREAM,
@ -965,7 +964,7 @@ trait SealedMode {}
/// Flash instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {}
pub trait Instance: SealedInstance + PeripheralType {}
/// Flash mode.
#[allow(private_bounds)]
pub trait Mode: SealedMode {}

View File

@ -5,13 +5,13 @@ use core::future::Future;
use core::pin::Pin as FuturePin;
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 crate::interrupt::InterruptExt;
use crate::pac::common::{Reg, RW};
use crate::pac::SIO;
use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
use crate::{interrupt, pac, peripherals, RegExt};
#[cfg(any(feature = "rp2040", feature = "rp235xa"))]
pub(crate) const BANK0_PIN_COUNT: usize = 30;
@ -115,7 +115,7 @@ pub struct Input<'d> {
impl<'d> Input<'d> {
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
#[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);
pin.set_as_input();
pin.set_pull(pull);
@ -266,11 +266,11 @@ fn IO_IRQ_QSPI() {
#[must_use = "futures do nothing unless you `.await` or poll them"]
struct InputFuture<'d> {
pin: PeripheralRef<'d, AnyPin>,
pin: Peri<'d, AnyPin>,
}
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;
// first, clear the INTR register bits. without this INTR will still
// contain reports of previous edges, causing the IRQ to fire early
@ -359,7 +359,7 @@ pub struct Output<'d> {
impl<'d> Output<'d> {
/// Create GPIO output driver for a [Pin] with the provided [Level].
#[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);
match initial_output {
Level::High => pin.set_high(),
@ -440,7 +440,7 @@ pub struct OutputOpenDrain<'d> {
impl<'d> OutputOpenDrain<'d> {
/// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level].
#[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);
pin.set_low();
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
/// mode.
pub struct Flex<'d> {
pin: PeripheralRef<'d, AnyPin>,
pin: Peri<'d, AnyPin>,
}
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
/// before the pin is put into output mode.
#[inline]
pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
into_ref!(pin);
pub fn new(pin: Peri<'d, impl Pin>) -> Self {
pin.pad_ctrl().write(|w| {
#[cfg(feature = "_rp235x")]
w.set_iso(false);
@ -606,7 +604,7 @@ impl<'d> Flex<'d> {
w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _);
});
Self { pin: pin.map_into() }
Self { pin: pin.into() }
}
#[inline]
@ -829,7 +827,7 @@ impl<'d> Drop for Flex<'d> {
/// Dormant wake driver.
pub struct DormantWake<'w> {
pin: PeripheralRef<'w, AnyPin>,
pin: Peri<'w, AnyPin>,
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].
#[allow(private_bounds)]
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
/// Degrade to a generic pin struct
fn degrade(self) -> AnyPin {
AnyPin {
pin_bank: self.pin_bank(),
}
}
pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
/// Returns the pin number within a bank
#[inline]
fn pin(&self) -> u8 {
@ -951,8 +942,8 @@ impl AnyPin {
/// # Safety
///
/// You must ensure that youre only using one instance of this type at a time.
pub unsafe fn steal(pin_bank: u8) -> Self {
Self { pin_bank }
pub unsafe fn steal(pin_bank: u8) -> Peri<'static, Self> {
Peri::new_unchecked(Self { pin_bank })
}
}
@ -979,7 +970,9 @@ macro_rules! impl_pin {
impl From<peripherals::$name> for crate::gpio::AnyPin {
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::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
use pac::i2c;
use crate::gpio::AnyPin;
use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral};
use crate::{interrupt, pac, peripherals};
/// I2C error abort reason
#[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> {
/// Create a new driver instance in blocking mode.
pub fn new_blocking(
peri: impl Peripheral<P = T> + 'd,
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
peri: Peri<'d, T>,
scl: Peri<'d, impl SclPin<T>>,
sda: Peri<'d, impl SdaPin<T>>,
config: Config,
) -> Self {
into_ref!(scl, sda);
Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
Self::new_inner(peri, scl.into(), sda.into(), config)
}
}
impl<'d, T: Instance> I2c<'d, T, Async> {
/// Create a new driver instance in async mode.
pub fn new_async(
peri: impl Peripheral<P = T> + 'd,
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
peri: Peri<'d, T>,
scl: Peri<'d, impl SclPin<T>>,
sda: Peri<'d, impl SdaPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
config: Config,
) -> Self {
into_ref!(scl, sda);
let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
let i2c = Self::new_inner(peri, scl.into(), sda.into(), config);
let r = T::regs();
@ -378,14 +375,7 @@ where
}
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
fn new_inner(
_peri: impl Peripheral<P = T> + 'd,
scl: PeripheralRef<'d, AnyPin>,
sda: PeripheralRef<'d, AnyPin>,
config: Config,
) -> Self {
into_ref!(_peri);
fn new_inner(_peri: Peri<'d, T>, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self {
let reset = T::reset();
crate::reset::reset(reset);
crate::reset::unreset_wait(reset);
@ -804,7 +794,7 @@ impl_mode!(Async);
/// I2C instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {
pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

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

View File

@ -54,7 +54,7 @@ pub mod pio;
pub(crate) mod relocate;
// Reexports
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
pub use embassy_hal_internal::{Peri, PeripheralType};
#[cfg(feature = "unstable-pac")]
pub use rp_pac as 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::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 RESUME_TOKEN: u32 = !0xDEADBEEF;
@ -139,7 +139,7 @@ unsafe fn SIO_IRQ_FIFO() {
}
/// 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
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 atomic_polyfill::{AtomicU64, AtomicU8};
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::extra::U8;
use fixed::FixedU32;
@ -235,7 +235,7 @@ impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
/// Type representing a PIO pin.
pub struct Pin<'l, PIO: Instance> {
pin: PeripheralRef<'l, AnyPin>,
pin: Peri<'l, AnyPin>,
pio: PhantomData<PIO>,
}
@ -360,7 +360,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
/// Prepare DMA transfer from RX FIFO.
pub fn dma_pull<'a, C: Channel, W: Word>(
&'a mut self,
ch: PeripheralRef<'a, C>,
ch: Peri<'a, C>,
data: &'a mut [W],
bswap: bool,
) -> 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.
pub fn dma_push<'a, C: Channel, W: Word>(
&'a mut self,
ch: PeripheralRef<'a, C>,
ch: Peri<'a, C>,
data: &'a [W],
bswap: bool,
) -> 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*
/// all [`StateMachine`]s for this block have been dropped. **Other members
/// 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> {
into_ref!(pin);
pub fn make_pio_pin(&mut self, pin: Peri<'d, impl PioPin + 'd>) -> Pin<'d, PIO> {
// enable the outputs
pin.pad_ctrl().write(|w| w.set_od(false));
// 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
PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
Pin {
pin: pin.into_ref().map_into(),
pin: pin.into(),
pio: PhantomData::default(),
}
}
@ -1304,7 +1302,7 @@ pub struct Pio<'d, PIO: Instance> {
impl<'d, PIO: Instance> Pio<'d, PIO> {
/// 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().used_pins.store(0, Ordering::Release);
PIO::Interrupt::unpend();
@ -1389,7 +1387,7 @@ trait SealedInstance {
/// PIO instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + Sized + Unpin {
pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin {
/// Interrupt for this peripheral.
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,
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>)
pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> {
@ -99,7 +99,7 @@ impl<'a, PIO: Instance> PioHD44780CommandSequenceProgram<'a, PIO> {
/// Pio backed HD44780 driver
pub struct PioHD44780<'l, P: Instance, const S: usize> {
dma: PeripheralRef<'l, AnyChannel>,
dma: Peri<'l, AnyChannel>,
sm: StateMachine<'l, P, S>,
buf: [u8; 40],
@ -111,19 +111,17 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
common: &mut Common<'l, P>,
mut sm: StateMachine<'l, P, S>,
mut irq: Irq<'l, P, S>,
dma: impl Peripheral<P = impl Channel> + 'l,
rs: impl PioPin,
rw: impl PioPin,
e: impl PioPin,
db4: impl PioPin,
db5: impl PioPin,
db6: impl PioPin,
db7: impl PioPin,
mut dma: Peri<'l, impl Channel>,
rs: Peri<'l, impl PioPin>,
rw: Peri<'l, impl PioPin>,
e: Peri<'l, impl PioPin>,
db4: Peri<'l, impl PioPin>,
db5: Peri<'l, impl PioPin>,
db6: Peri<'l, impl PioPin>,
db7: Peri<'l, impl PioPin>,
word_prg: &PioHD44780CommandWordProgram<'l, P>,
seq_prg: &PioHD44780CommandSequenceProgram<'l, P>,
) -> PioHD44780<'l, P, S> {
into_ref!(dma);
let rs = common.make_pio_pin(rs);
let rw = common.make_pio_pin(rw);
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;
Self {
dma: dma.map_into(),
dma: dma.into(),
sm,
buf: [0x20; 40],
}

View File

@ -6,16 +6,16 @@ use crate::dma::{AnyChannel, Channel, Transfer};
use crate::pio::{
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
pub struct PioI2sOutProgram<'a, PIO: Instance> {
prg: LoadedProgram<'a, PIO>,
pub struct PioI2sOutProgram<'d, PIO: Instance> {
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
pub fn new(common: &mut Common<'a, PIO>) -> Self {
pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!(
".side_set 2",
" 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
pub struct PioI2sOut<'a, P: Instance, const S: usize> {
dma: PeripheralRef<'a, AnyChannel>,
sm: StateMachine<'a, P, S>,
pub struct PioI2sOut<'d, P: Instance, const S: usize> {
dma: Peri<'d, AnyChannel>,
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
pub fn new(
common: &mut Common<'a, P>,
mut sm: StateMachine<'a, P, S>,
dma: impl Peripheral<P = impl Channel> + 'a,
data_pin: impl PioPin,
bit_clock_pin: impl PioPin,
lr_clock_pin: impl PioPin,
common: &mut Common<'d, P>,
mut sm: StateMachine<'d, P, S>,
dma: Peri<'d, impl Channel>,
data_pin: Peri<'d, impl PioPin>,
bit_clock_pin: Peri<'d, impl PioPin>,
lr_clock_pin: Peri<'d, impl PioPin>,
sample_rate: u32,
bit_depth: u32,
channels: u32,
program: &PioI2sOutProgram<'a, P>,
program: &PioI2sOutProgram<'d, P>,
) -> Self {
into_ref!(dma);
let data_pin = common.make_pio_pin(data_pin);
let bit_clock_pin = common.make_pio_pin(bit_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);
Self {
dma: dma.map_into(),
sm,
}
Self { dma: dma.into(), sm }
}
/// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer.

View File

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

View File

@ -4,9 +4,9 @@ use core::time::Duration;
use pio::InstructionOperands;
use crate::clocks;
use crate::gpio::Level;
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
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(
pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>,
pin: impl PioPin,
pin: Peri<'d, impl PioPin>,
program: &PioPwmProgram<'d, T>,
) -> Self {
let pin = pio.make_pio_pin(pin);

View File

@ -6,6 +6,7 @@ use crate::gpio::Pull;
use crate::pio::{
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.
pub struct PioEncoderProgram<'a, PIO: Instance> {
@ -33,8 +34,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
pub fn new(
pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>,
pin_a: impl PioPin,
pin_b: impl PioPin,
pin_a: Peri<'d, impl PioPin>,
pin_b: Peri<'d, impl PioPin>,
program: &PioEncoderProgram<'d, T>,
) -> Self {
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 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.
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>,
mut sm: StateMachine<'d, T, SM>,
irq: Irq<'d, T, SM>,
pin0: impl PioPin,
pin1: impl PioPin,
pin2: impl PioPin,
pin3: impl PioPin,
pin0: Peri<'d, impl PioPin>,
pin1: Peri<'d, impl PioPin>,
pin2: Peri<'d, impl PioPin>,
pin3: Peri<'d, impl PioPin>,
program: &PioStepperProgram<'d, T>,
) -> Self {
let pin0 = pio.make_pio_pin(pin0);

View File

@ -10,15 +10,16 @@ use crate::gpio::Level;
use crate::pio::{
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.
pub struct PioUartTxProgram<'a, PIO: Instance> {
prg: LoadedProgram<'a, PIO>,
pub struct PioUartTxProgram<'d, PIO: Instance> {
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
pub fn new(common: &mut Common<'a, PIO>) -> Self {
pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!(
r#"
.side_set 1 opt
@ -41,18 +42,18 @@ impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> {
}
/// PIO backed Uart transmitter
pub struct PioUartTx<'a, PIO: Instance, const SM: usize> {
sm_tx: StateMachine<'a, PIO, SM>,
pub struct PioUartTx<'d, PIO: Instance, const SM: usize> {
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.
pub fn new(
baud: u32,
common: &mut Common<'a, PIO>,
mut sm_tx: StateMachine<'a, PIO, SM>,
tx_pin: impl PioPin,
program: &PioUartTxProgram<'a, PIO>,
common: &mut Common<'d, PIO>,
mut sm_tx: StateMachine<'d, PIO, SM>,
tx_pin: Peri<'d, impl PioPin>,
program: &PioUartTxProgram<'d, PIO>,
) -> Self {
let tx_pin = common.make_pio_pin(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.
pub struct PioUartRxProgram<'a, PIO: Instance> {
prg: LoadedProgram<'a, PIO>,
pub struct PioUartRxProgram<'d, PIO: Instance> {
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
pub fn new(common: &mut Common<'a, PIO>) -> Self {
pub fn new(common: &mut Common<'d, PIO>) -> Self {
let prg = pio::pio_asm!(
r#"
; 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
pub struct PioUartRx<'a, PIO: Instance, const SM: usize> {
sm_rx: StateMachine<'a, PIO, SM>,
pub struct PioUartRx<'d, PIO: Instance, const SM: usize> {
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.
pub fn new(
baud: u32,
common: &mut Common<'a, PIO>,
mut sm_rx: StateMachine<'a, PIO, SM>,
rx_pin: impl PioPin,
program: &PioUartRxProgram<'a, PIO>,
common: &mut Common<'d, PIO>,
mut sm_rx: StateMachine<'d, PIO, SM>,
rx_pin: Peri<'d, impl PioPin>,
program: &PioUartRxProgram<'d, PIO>,
) -> Self {
let mut cfg = Config::default();
cfg.use_program(&program.prg, &[]);

View File

@ -9,7 +9,7 @@ use crate::dma::{AnyChannel, Channel};
use crate::pio::{
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 T2: u8 = 5; // data bit
@ -53,7 +53,7 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> {
/// Pio backed ws2812 driver
/// Const N is the number of ws2812 leds attached to this pin
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>,
}
@ -62,12 +62,10 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
pub fn new(
pio: &mut Common<'d, P>,
mut sm: StateMachine<'d, P, S>,
dma: impl Peripheral<P = impl Channel> + 'd,
pin: impl PioPin,
dma: Peri<'d, impl Channel>,
pin: Peri<'d, impl PioPin>,
program: &PioWs2812Program<'d, P>,
) -> Self {
into_ref!(dma);
// Setup sm0
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_enable(true);
Self {
dma: dma.map_into(),
sm,
}
Self { dma: dma.into(), sm }
}
/// Write a buffer of [smart_leds::RGB8] to the ws2812 string

View File

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

View File

@ -1,7 +1,7 @@
//! RTC driver.
mod filter;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
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
pub struct Rtc<'d, T: Instance> {
inner: PeripheralRef<'d, T>,
inner: Peri<'d, T>,
}
impl<'d, T: Instance> Rtc<'d, T> {
@ -23,9 +23,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
/// # Errors
///
/// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(inner);
pub fn new(inner: Peri<'d, T>) -> Self {
// Set the RTC divider
inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
@ -194,7 +192,7 @@ trait SealedInstance {
/// RTC peripheral instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {}
pub trait Instance: SealedInstance + PeripheralType {}
impl SealedInstance for crate::peripherals::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_futures::join::join;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::{Peri, PeripheralType};
pub use embedded_hal_02::spi::{Phase, Polarity};
use crate::dma::{AnyChannel, Channel};
use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
use crate::{pac, peripherals, Peripheral};
use crate::{pac, peripherals};
/// SPI errors.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -42,9 +42,9 @@ impl Default for Config {
/// SPI driver.
pub struct Spi<'d, T: Instance, M: Mode> {
inner: PeripheralRef<'d, T>,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
inner: Peri<'d, T>,
tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<Peri<'d, AnyChannel>>,
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> {
fn new_inner(
inner: impl Peripheral<P = T> + 'd,
clk: Option<PeripheralRef<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>,
miso: Option<PeripheralRef<'d, AnyPin>>,
cs: Option<PeripheralRef<'d, AnyPin>>,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
inner: Peri<'d, T>,
clk: Option<Peri<'d, AnyPin>>,
mosi: Option<Peri<'d, AnyPin>>,
miso: Option<Peri<'d, AnyPin>>,
cs: Option<Peri<'d, AnyPin>>,
tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<Peri<'d, AnyChannel>>,
config: Config,
) -> Self {
into_ref!(inner);
Self::apply_config(&inner, &config);
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
/// 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 (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> {
/// Create an SPI driver in blocking mode.
pub fn new_blocking(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: Peri<'d, impl MosiPin<T> + 'd>,
miso: Peri<'d, impl MisoPin<T> + 'd>,
config: Config,
) -> Self {
into_ref!(clk, mosi, miso);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(mosi.map_into()),
Some(miso.map_into()),
Some(clk.into()),
Some(mosi.into()),
Some(miso.into()),
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.
pub fn new_blocking_txonly(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: Peri<'d, impl MosiPin<T> + 'd>,
config: Config,
) -> Self {
into_ref!(clk, mosi);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(mosi.map_into()),
Some(clk.into()),
Some(mosi.into()),
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.
pub fn new_blocking_rxonly(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
miso: Peri<'d, impl MisoPin<T> + 'd>,
config: Config,
) -> Self {
into_ref!(clk, miso);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(clk.into()),
None,
Some(miso.map_into()),
Some(miso.into()),
None,
None,
None,
@ -336,43 +331,41 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
impl<'d, T: Instance> Spi<'d, T, Async> {
/// Create an SPI driver in async mode supporting DMA operations.
pub fn new(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
rx_dma: impl Peripheral<P = impl Channel> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: Peri<'d, impl MosiPin<T> + 'd>,
miso: Peri<'d, impl MisoPin<T> + 'd>,
tx_dma: Peri<'d, impl Channel>,
rx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx_dma, rx_dma, clk, mosi, miso);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(mosi.map_into()),
Some(miso.map_into()),
Some(clk.into()),
Some(mosi.into()),
Some(miso.into()),
None,
Some(tx_dma.map_into()),
Some(rx_dma.map_into()),
Some(tx_dma.into()),
Some(rx_dma.into()),
config,
)
}
/// Create an SPI driver in async mode supporting DMA write operations only.
pub fn new_txonly(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
mosi: Peri<'d, impl MosiPin<T> + 'd>,
tx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx_dma, clk, mosi);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(mosi.map_into()),
Some(clk.into()),
Some(mosi.into()),
None,
None,
Some(tx_dma.map_into()),
Some(tx_dma.into()),
None,
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.
pub fn new_rxonly(
inner: impl Peripheral<P = T> + 'd,
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
rx_dma: impl Peripheral<P = impl Channel> + 'd,
inner: Peri<'d, T>,
clk: Peri<'d, impl ClkPin<T> + 'd>,
miso: Peri<'d, impl MisoPin<T> + 'd>,
tx_dma: Peri<'d, impl Channel>,
rx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx_dma, rx_dma, clk, miso);
Self::new_inner(
inner,
Some(clk.map_into()),
Some(clk.into()),
None,
Some(miso.map_into()),
Some(miso.into()),
None,
Some(tx_dma.map_into()),
Some(rx_dma.map_into()),
Some(tx_dma.into()),
Some(rx_dma.into()),
config,
)
}
/// Write data to SPI using DMA.
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 {
// If we don't assign future to a variable, the data register pointer
// 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> {
// Start RX first. Transfer starts when TX starts, if RX
// 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 {
// If we don't assign future to a variable, the data register pointer
// 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)
};
let tx_ch = self.tx_dma.as_mut().unwrap();
let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
let tx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer
// 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> {
// Start RX first. Transfer starts when TX starts, if RX
// 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 {
// If we don't assign future to a variable, the data register pointer
// 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)
};
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
// is held across an await and makes the future non-Send.
let tx_transfer = async {
let p = self.inner.regs();
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() {
let write_bytes_len = rx.len() - tx.len();
@ -519,7 +511,7 @@ pub trait Mode: SealedMode {}
/// SPI instance trait.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {}
pub trait Instance: SealedInstance + PeripheralType {}
macro_rules! impl_instance {
($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::task::Poll;
use embassy_hal_internal::Peripheral;
use embassy_hal_internal::{Peri, PeripheralType};
use embassy_sync::waitqueue::AtomicWaker;
use rand_core::Error;
@ -20,7 +20,7 @@ trait SealedInstance {
/// TRNG peripheral instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {
pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this peripheral.
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> {
/// Create a new TRNG driver.
pub fn new(
_trng: impl Peripheral<P = T> + 'd,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
config: Config,
) -> Self {
pub fn new(_trng: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd, config: Config) -> Self {
let regs = T::regs();
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> {
/// Create a buffered UART instance.
pub fn new(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
config: Config,
) -> Self {
into_ref!(tx, rx);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config);
init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
Self {
@ -111,23 +109,21 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
/// Create a buffered UART instance with flow control.
pub fn new_with_rtscts(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
rts: Peri<'d, impl RtsPin<T>>,
cts: Peri<'d, impl CtsPin<T>>,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
config: Config,
) -> Self {
into_ref!(tx, rx, cts, rts);
super::Uart::<'d, T, Async>::init(
Some(tx.map_into()),
Some(rx.map_into()),
Some(rts.map_into()),
Some(cts.map_into()),
Some(tx.into()),
Some(rx.into()),
Some(rts.into()),
Some(cts.into()),
config,
);
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> {
/// Create a new buffered UART RX.
pub fn new(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, 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],
config: Config,
) -> Self {
into_ref!(rx);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config);
init_buffers::<T>(irq, None, Some(rx_buffer));
Self { phantom: PhantomData }
@ -200,16 +194,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
/// Create a new buffered UART RX with flow control.
pub fn new_with_rts(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
rx: Peri<'d, impl RxPin<T>>,
rts: Peri<'d, impl RtsPin<T>>,
rx_buffer: &'d mut [u8],
config: Config,
) -> Self {
into_ref!(rx, rts);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config);
init_buffers::<T>(irq, None, Some(rx_buffer));
Self { phantom: PhantomData }
@ -338,15 +330,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
impl<'d, T: Instance> BufferedUartTx<'d, T> {
/// Create a new buffered UART TX.
pub fn new(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, 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],
config: Config,
) -> Self {
into_ref!(tx);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config);
init_buffers::<T>(irq, Some(tx_buffer), None);
Self { phantom: PhantomData }
@ -354,16 +344,14 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
/// Create a new buffered UART TX with flow control.
pub fn new_with_cts(
_uart: impl Peripheral<P = T> + 'd,
_uart: Peri<'d, T>,
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
tx: Peri<'d, impl TxPin<T>>,
cts: Peri<'d, impl CtsPin<T>>,
tx_buffer: &'d mut [u8],
config: Config,
) -> Self {
into_ref!(tx, cts);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config);
init_buffers::<T>(irq, Some(tx_buffer), None);
Self { phantom: PhantomData }

View File

@ -5,7 +5,7 @@ use core::task::Poll;
use atomic_polyfill::{AtomicU16, Ordering};
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_time::{Delay, Timer};
use pac::uart::regs::Uartris;
@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel};
use crate::gpio::{AnyPin, SealedPin};
use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::pac::io::vals::{Inover, Outover};
use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
use crate::{interrupt, pac, peripherals, RegExt};
mod buffered;
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> {
/// UART TX driver.
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)>,
}
/// UART RX driver.
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)>,
}
impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
/// Create a new DMA-enabled UART which can only send data
pub fn new(
_uart: impl Peripheral<P = T> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
_uart: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T>>,
tx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx, tx_dma);
Uart::<T, M>::init(Some(tx.map_into()), None, None, None, config);
Self::new_inner(Some(tx_dma.map_into()))
Uart::<T, M>::init(Some(tx.into()), None, None, None, config);
Self::new_inner(Some(tx_dma.into()))
}
fn new_inner(tx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self {
fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
Self {
tx_dma,
phantom: PhantomData,
@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
impl<'d, T: Instance> UartTx<'d, T, Blocking> {
/// Create a new UART TX instance for blocking mode operations.
pub fn new_blocking(
_uart: impl Peripheral<P = T> + 'd,
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);
pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config);
Self::new_inner(None)
}
@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
impl<'d, T: Instance> UartTx<'d, T, Async> {
/// Write to UART TX from the provided buffer using DMA.
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 {
T::regs().uartdmacr().write_set(|reg| {
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> {
/// Create a new DMA-enabled UART which can only receive data
pub fn new(
_uart: impl Peripheral<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
_uart: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
rx_dma: impl Peripheral<P = impl Channel> + 'd,
rx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(rx, rx_dma);
Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config);
Self::new_inner(true, Some(rx_dma.map_into()))
Uart::<T, M>::init(None, Some(rx.into()), None, None, config);
Self::new_inner(true, Some(rx_dma.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());
if has_irq {
// 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> {
/// Create a new UART RX instance for blocking mode operations.
pub fn new_blocking(
_uart: impl Peripheral<P = T> + 'd,
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);
pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config);
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
// interrupt flags will have been raised, and those will be picked up immediately
// 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| {
w.set_oeim(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
// interrupt flags will have been raised, and those will be picked up immediately
// 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| {
w.set_oeim(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
// is held across an await and makes the future non-Send.
crate::dma::read(
&mut ch,
ch.reborrow(),
T::regs().uartdr().as_ptr() as *const _,
sbuffer,
T::RX_DREQ.into(),
@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
impl<'d, T: Instance> Uart<'d, T, Blocking> {
/// Create a new UART without hardware flow control
pub fn new_blocking(
uart: impl Peripheral<P = T> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
uart: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
config: Config,
) -> Self {
into_ref!(tx, rx);
Self::new_inner(
uart,
tx.map_into(),
rx.map_into(),
None,
None,
false,
None,
None,
config,
)
Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config)
}
/// Create a new UART with hardware flow control (RTS/CTS)
pub fn new_with_rtscts_blocking(
uart: impl Peripheral<P = T> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
uart: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
rts: Peri<'d, impl RtsPin<T>>,
cts: Peri<'d, impl CtsPin<T>>,
config: Config,
) -> Self {
into_ref!(tx, rx, cts, rts);
Self::new_inner(
uart,
tx.map_into(),
rx.map_into(),
Some(rts.map_into()),
Some(cts.map_into()),
tx.into(),
rx.into(),
Some(rts.into()),
Some(cts.into()),
false,
None,
None,
@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
impl<'d, T: Instance> Uart<'d, T, Async> {
/// Create a new DMA enabled UART without hardware flow control
pub fn new(
uart: impl Peripheral<P = T> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
uart: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
rx_dma: impl Peripheral<P = impl Channel> + 'd,
tx_dma: Peri<'d, impl Channel>,
rx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx, rx, tx_dma, rx_dma);
Self::new_inner(
uart,
tx.map_into(),
rx.map_into(),
tx.into(),
rx.into(),
None,
None,
true,
Some(tx_dma.map_into()),
Some(rx_dma.map_into()),
Some(tx_dma.into()),
Some(rx_dma.into()),
config,
)
}
/// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
pub fn new_with_rtscts(
uart: impl Peripheral<P = T> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
uart: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T>>,
rx: Peri<'d, impl RxPin<T>>,
rts: Peri<'d, impl RtsPin<T>>,
cts: Peri<'d, impl CtsPin<T>>,
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
tx_dma: impl Peripheral<P = impl Channel> + 'd,
rx_dma: impl Peripheral<P = impl Channel> + 'd,
tx_dma: Peri<'d, impl Channel>,
rx_dma: Peri<'d, impl Channel>,
config: Config,
) -> Self {
into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
Self::new_inner(
uart,
tx.map_into(),
rx.map_into(),
Some(rts.map_into()),
Some(cts.map_into()),
tx.into(),
rx.into(),
Some(rts.into()),
Some(cts.into()),
true,
Some(tx_dma.map_into()),
Some(rx_dma.map_into()),
Some(tx_dma.into()),
Some(rx_dma.into()),
config,
)
}
@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
fn new_inner(
_uart: impl Peripheral<P = T> + 'd,
mut tx: PeripheralRef<'d, AnyPin>,
mut rx: PeripheralRef<'d, AnyPin>,
mut rts: Option<PeripheralRef<'d, AnyPin>>,
mut cts: Option<PeripheralRef<'d, AnyPin>>,
_uart: Peri<'d, T>,
mut tx: Peri<'d, AnyPin>,
mut rx: Peri<'d, AnyPin>,
mut rts: Option<Peri<'d, AnyPin>>,
mut cts: Option<Peri<'d, AnyPin>>,
has_irq: bool,
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
tx_dma: Option<Peri<'d, AnyChannel>>,
rx_dma: Option<Peri<'d, AnyChannel>>,
config: Config,
) -> Self {
Self::init(
@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
}
fn init(
tx: Option<PeripheralRef<'_, AnyPin>>,
rx: Option<PeripheralRef<'_, AnyPin>>,
rts: Option<PeripheralRef<'_, AnyPin>>,
cts: Option<PeripheralRef<'_, AnyPin>>,
tx: Option<Peri<'_, AnyPin>>,
rx: Option<Peri<'_, AnyPin>>,
rts: Option<Peri<'_, AnyPin>>,
cts: Option<Peri<'_, AnyPin>>,
config: Config,
) {
let r = T::regs();
@ -1326,7 +1300,7 @@ impl_mode!(Async);
/// UART instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance {
pub trait Instance: SealedInstance + PeripheralType {
/// Interrupt for this instance.
type Interrupt: interrupt::typelevel::Interrupt;
}

View File

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

View File

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

View File

@ -23,7 +23,7 @@ mod fmt;
use core::mem::MaybeUninit;
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::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32::peripherals::IPCC;
@ -52,7 +52,7 @@ type PacketHeader = LinkedListNode;
/// Transport Layer for the Mailbox interface
pub struct TlMbox<'d> {
_ipcc: PeripheralRef<'d, IPCC>,
_ipcc: Peri<'d, IPCC>,
pub sys_subsystem: Sys,
pub mm_subsystem: MemoryManager,
@ -92,13 +92,11 @@ impl<'d> TlMbox<'d> {
/// Figure 66.
// TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem
pub fn init(
ipcc: impl Peripheral<P = IPCC> + 'd,
ipcc: Peri<'d, IPCC>,
_irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
+ interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
config: Config,
) -> Self {
into_ref!(ipcc);
// 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
// implementation

View File

@ -324,7 +324,7 @@ fn main() {
let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
flash_regions.extend(quote! {
#[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)]
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 {
#(#inits),*,
_mode: core::marker::PhantomData,

View File

@ -8,7 +8,7 @@ use super::{
};
use crate::dma::Transfer;
use crate::time::Hertz;
use crate::{pac, rcc, Peripheral};
use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300;
@ -154,8 +154,7 @@ pub enum Averaging {
impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd, sample_time: SampleTime, resolution: Resolution) -> Self {
embassy_hal_internal::into_ref!(adc);
pub fn new(adc: Peri<'d, T>, sample_time: SampleTime, resolution: Resolution) -> Self {
rcc::enable_and_reset::<T>();
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()
}
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
// previous DR values is read.
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().
pub async fn read_in_hw_order(
&mut self,
rx_dma: &mut impl RxDma<T>,
rx_dma: Peri<'_, impl RxDma<T>>,
hw_channel_selection: u32,
scandir: Scandir,
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.
pub async fn read(
&mut self,
rx_dma: &mut impl RxDma<T>,
rx_dma: Peri<'_, impl RxDma<T>>,
channel_sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
readings: &mut [u16],
) {

View File

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

View File

@ -3,14 +3,13 @@ use core::marker::PhantomData;
use core::task::Poll;
use embassy_futures::yield_now;
use embassy_hal_internal::into_ref;
use embassy_time::Instant;
use super::Resolution;
use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
use crate::interrupt::typelevel::Interrupt;
use crate::time::Hertz;
use crate::{interrupt, rcc, Peripheral};
use crate::{interrupt, rcc, Peri};
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> {
pub fn new(
adc: impl Peripheral<P = T> + 'd,
adc: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>();
//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::dma::Transfer;
use crate::time::Hertz;
use crate::{pac, rcc, Peripheral};
use crate::{pac, rcc, Peri};
/// Default VREF voltage used for sample conversion to millivolts.
pub const VREF_DEFAULT_MV: u32 = 3300;
@ -135,8 +135,7 @@ impl Prescaler {
impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
embassy_hal_internal::into_ref!(adc);
pub fn new(adc: Peri<'d, T>) -> Self {
rcc::enable_and_reset::<T>();
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}
///
/// let mut adc = Adc::new(p.ADC1);
/// let mut adc_pin0 = p.PA0.degrade_adc();
/// let mut adc_pin1 = p.PA1.degrade_adc();
/// let mut adc_pin0 = p.PA0.into();
/// let mut adc_pin1 = p.PA1.into();
/// let mut measurements = [0u16; 2];
///
/// adc.read_async(
@ -382,7 +381,7 @@ impl<'d, T: Instance> Adc<'d, T> {
/// ```
pub async fn read(
&mut self,
rx_dma: &mut impl RxDma<T>,
rx_dma: Peri<'_, impl RxDma<T>>,
sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
readings: &mut [u16],
) {

View File

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

View File

@ -2,13 +2,12 @@ use core::marker::PhantomData;
use core::mem;
use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_internal::{into_ref, Peripheral};
use stm32_metapac::adc::vals::SampleTime;
use crate::adc::{Adc, AdcChannel, Instance, RxDma};
use crate::dma::{Priority, ReadableRingBuffer, TransferOptions};
use crate::pac::adc::vals;
use crate::rcc;
use crate::{rcc, Peri};
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
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.
///
/// [`read`]: #method.read
pub fn into_ring_buffered(
self,
dma: impl Peripheral<P = impl RxDma<T>> + 'd,
dma_buf: &'d mut [u16],
) -> RingBufferedAdc<'d, T> {
pub fn into_ring_buffered(self, dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> RingBufferedAdc<'d, T> {
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
into_ref!(dma);
let opts: crate::dma::TransferOptions = TransferOptions {
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::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime};
use crate::time::Hertz;
use crate::{pac, rcc, Peripheral};
use crate::{pac, rcc, Peri};
const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);
@ -169,13 +169,13 @@ pub trait SealedInstance {
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;
}
pub struct Adc4<'d, T: Instance> {
#[allow(unused)]
adc: crate::PeripheralRef<'d, T>,
adc: crate::Peri<'d, T>,
}
#[derive(Debug)]
@ -186,8 +186,7 @@ pub enum Adc4Error {
impl<'d, T: Instance> Adc4<'d, T> {
/// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
embassy_hal_internal::into_ref!(adc);
pub fn new(adc: Peri<'d, T>) -> Self {
rcc::enable_and_reset::<T>();
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_pin1 = p.PC1;
/// let mut adc4_pin2 = p.PC0;
/// let mut degraded41 = adc4_pin1.degrade_adc();
/// let mut degraded42 = adc4_pin2.degrade_adc();
/// let mut.into()d41 = adc4_pin1.into();
/// let mut.into()d42 = adc4_pin2.into();
/// let mut measurements = [0u16; 2];
/// // not that the channels must be in ascending order
/// adc4.read(
/// &mut p.GPDMA1_CH1,
/// [
/// &mut degraded42,
/// &mut degraded41,
/// &mut.into()d42,
/// &mut.into()d41,
/// ]
/// .into_iter(),
/// &mut measurements,
@ -395,7 +394,7 @@ impl<'d, T: Instance> Adc4<'d, T> {
/// ```
pub async fn read(
&mut self,
rx_dma: &mut impl RxDma4<T>,
rx_dma: Peri<'_, impl RxDma4<T>>,
sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
readings: &mut [u16],
) -> Result<(), Adc4Error> {

View File

@ -2,7 +2,6 @@ use core::future::poll_fn;
use core::marker::PhantomData;
use core::task::Poll;
use embassy_hal_internal::into_ref;
#[cfg(adc_l0)]
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::interrupt::typelevel::Interrupt;
use crate::peripherals::ADC1;
use crate::{interrupt, rcc, Peripheral};
use crate::{interrupt, rcc, Peri};
pub const VDDA_CALIB_MV: u32 = 3300;
pub const VREF_INT: u32 = 1230;
@ -63,10 +62,9 @@ impl super::SealedAdcChannel<ADC1> for Temperature {
impl<'d, T: Instance> Adc<'d, T> {
pub fn new(
adc: impl Peripheral<P = T> + 'd,
adc: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self {
into_ref!(adc);
rcc::enable_and_reset::<T>();
// 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 crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
use crate::peripherals::ADC1;
use crate::time::Hertz;
use crate::{rcc, Peripheral};
use crate::{rcc, Peri};
mod ringbuffered_v2;
pub use ringbuffered_v2::{RingBufferedAdc, Sequence};
@ -97,8 +95,7 @@ impl<'d, T> Adc<'d, T>
where
T: Instance,
{
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(adc);
pub fn new(adc: Peri<'d, T>) -> Self {
rcc::enable_and_reset::<T>();
let presc = Prescaler::from_pclk2(T::frequency());

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
//! coordinate rotation digital computer (CORDIC)
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::{dma, peripherals, rcc};
@ -16,7 +16,7 @@ pub mod utils;
/// CORDIC driver
pub struct Cordic<'d, T: Instance> {
peri: PeripheralRef<'d, T>,
peri: Peri<'d, T>,
config: Config,
}
@ -137,7 +137,7 @@ trait SealedInstance {
/// CORDIC instance trait
#[allow(private_bounds)]
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral {}
pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral {}
/// CORDIC configuration
#[derive(Debug)]
@ -198,11 +198,9 @@ impl<'d, T: Instance> Cordic<'d, T> {
/// Note:
/// 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]
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>();
into_ref!(peri);
let mut instance = Self { peri, config };
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).
pub async fn async_calc_32bit(
&mut self,
write_dma: impl Peripheral<P = impl WriteDma<T>>,
read_dma: impl Peripheral<P = impl ReadDma<T>>,
mut write_dma: Peri<'_, impl WriteDma<T>>,
mut read_dma: Peri<'_, impl ReadDma<T>>,
arg: &[u32],
res: &mut [u32],
arg1_only: bool,
@ -393,8 +391,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
let active_res_buf = &mut res[..res_cnt];
into_ref!(write_dma, read_dma);
self.peri
.set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two });
@ -416,7 +412,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
unsafe {
let write_transfer = dma::Transfer::new_write(
&mut write_dma,
write_dma.reborrow(),
write_req,
arg,
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(
&mut read_dma,
read_dma.reborrow(),
read_req,
T::regs().rdata().as_ptr() as *mut _,
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.
pub async fn async_calc_16bit(
&mut self,
write_dma: impl Peripheral<P = impl WriteDma<T>>,
read_dma: impl Peripheral<P = impl ReadDma<T>>,
mut write_dma: Peri<'_, impl WriteDma<T>>,
mut read_dma: Peri<'_, impl ReadDma<T>>,
arg: &[u32],
res: &mut [u32],
) -> Result<usize, CordicError> {
@ -536,8 +532,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
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
self.peri.set_argument_count(AccessCount::One);
self.peri.set_result_count(AccessCount::One);
@ -557,7 +551,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
unsafe {
let write_transfer = dma::Transfer::new_write(
&mut write_dma,
write_dma.reborrow(),
write_req,
arg,
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(
&mut read_dma,
read_dma.reborrow(),
read_req,
T::regs().rdata().as_ptr() as *mut _,
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::peripherals::CRC;
use crate::{rcc, Peripheral};
use crate::{rcc, Peri};
/// CRC driver.
pub struct Crc<'d> {
_peri: PeripheralRef<'d, CRC>,
_peri: Peri<'d, CRC>,
}
impl<'d> Crc<'d> {
/// Instantiates the CRC32 peripheral and initializes it to default values.
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd) -> Self {
into_ref!(peripheral);
pub fn new(peripheral: Peri<'d, CRC>) -> Self {
// Note: enable and reset come from RccPeripheral.
// enable CRC clock in RCC.
rcc::enable_and_reset::<CRC>();
// Peripheral the peripheral
let mut instance = Self { _peri: peripheral };
instance.reset();
instance

View File

@ -1,13 +1,11 @@
use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::pac::crc::vals;
use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC;
use crate::{rcc, Peripheral};
use crate::{rcc, Peri};
/// CRC driver.
pub struct Crc<'d> {
_peripheral: PeripheralRef<'d, CRC>,
_peripheral: Peri<'d, CRC>,
_config: Config,
}
@ -80,11 +78,10 @@ pub enum PolySize {
impl<'d> Crc<'d> {
/// 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.
// reset to default values and enable CRC clock in RCC.
rcc::enable_and_reset::<CRC>();
into_ref!(peripheral);
let mut instance = Self {
_peripheral: peripheral,
_config: config,

View File

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

View File

@ -3,16 +3,15 @@
use core::marker::PhantomData;
use embassy_hal_internal::into_ref;
use crate::dma::ChannelAndRequest;
use crate::mode::{Async, Blocking, Mode as PeriMode};
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
use crate::pac::dac;
use crate::rcc::{self, RccPeripheral};
use crate::{peripherals, Peripheral};
use crate::{peripherals, Peri};
mod tsel;
use embassy_hal_internal::PeripheralType;
pub use tsel::TriggerSel;
/// 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
/// [`DacChannel::set_trigger()`].
pub fn new(
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);
pub fn new(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
pin.set_as_analog();
Self::new_inner(
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
/// [`DacChannel::set_trigger()`].
#[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 {
into_ref!(dma);
pub fn new_internal(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>) -> Self {
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
/// [`DacChannel::set_trigger()`].
pub fn new_blocking(peri: impl Peripheral<P = T> + 'd, pin: impl Peripheral<P = impl DacPin<T, C>> + 'd) -> Self {
into_ref!(pin);
pub fn new_blocking(peri: Peri<'d, T>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
pin.set_as_analog();
Self::new_inner(
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
/// [`DacChannel::set_trigger()`].
#[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)
}
}
impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> {
fn new_inner(
_peri: impl Peripheral<P = T> + 'd,
_peri: Peri<'d, T>,
dma: Option<ChannelAndRequest<'d>>,
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
) -> 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()`
/// method on the underlying channels.
pub fn new(
peri: impl Peripheral<P = T> + 'd,
dma_ch1: impl Peripheral<P = impl Dma<T, Ch1>> + 'd,
dma_ch2: impl Peripheral<P = impl Dma<T, Ch2>> + 'd,
pin_ch1: impl Peripheral<P = impl DacPin<T, Ch1> + crate::gpio::Pin> + 'd,
pin_ch2: impl Peripheral<P = impl DacPin<T, Ch2> + crate::gpio::Pin> + 'd,
peri: Peri<'d, T>,
dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
) -> Self {
into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
pin_ch1.set_as_analog();
pin_ch2.set_as_analog();
Self::new_inner(
@ -429,11 +420,10 @@ impl<'d, T: Instance> Dac<'d, T, Async> {
/// method on the underlying channels.
#[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_ch1: impl Peripheral<P = impl Dma<T, Ch1>> + 'd,
dma_ch2: impl Peripheral<P = impl Dma<T, Ch2>> + 'd,
peri: Peri<'d, T>,
dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
) -> Self {
into_ref!(dma_ch1, dma_ch2);
Self::new_inner(
peri,
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()`
/// method on the underlying channels.
pub fn new_blocking(
peri: impl Peripheral<P = T> + 'd,
pin_ch1: impl Peripheral<P = impl DacPin<T, Ch1> + crate::gpio::Pin> + 'd,
pin_ch2: impl Peripheral<P = impl DacPin<T, Ch2> + crate::gpio::Pin> + 'd,
peri: Peri<'d, T>,
pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
) -> Self {
into_ref!(pin_ch1, pin_ch2);
pin_ch1.set_as_analog();
pin_ch2.set_as_analog();
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()`
/// method on the underlying channels.
#[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)
}
}
impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> {
fn new_inner(
_peri: impl Peripheral<P = T> + 'd,
_peri: Peri<'d, T>,
dma_ch1: Option<ChannelAndRequest<'d>>,
dma_ch2: Option<ChannelAndRequest<'d>>,
#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
@ -572,7 +561,7 @@ trait SealedInstance {
/// DAC instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {}
pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
/// Channel 1 marker type.
pub enum Ch1 {}

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ pub(crate) use util::*;
pub(crate) mod ringbuffer;
pub mod word;
use embassy_hal_internal::{impl_peripheral, Peripheral};
use embassy_hal_internal::{impl_peripheral, PeripheralType};
use crate::interrupt;
@ -51,17 +51,7 @@ pub(crate) trait ChannelInterrupt {
/// DMA channel.
#[allow(private_bounds)]
pub trait Channel: SealedChannel + Peripheral<P = Self> + 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() }
}
}
pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {}
macro_rules! dma_channel_impl {
($channel_peri:ident, $index:expr) => {
@ -79,8 +69,10 @@ macro_rules! dma_channel_impl {
impl crate::dma::Channel for crate::peripherals::$channel_peri {}
impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel {
fn from(x: crate::peripherals::$channel_peri) -> Self {
crate::dma::Channel::degrade(x)
fn from(val: crate::peripherals::$channel_peri) -> Self {
Self {
id: crate::dma::SealedChannel::id(&val),
}
}
}
};

View File

@ -1,13 +1,12 @@
use embassy_hal_internal::PeripheralRef;
use super::word::Word;
use super::{AnyChannel, Request, Transfer, TransferOptions};
use crate::Peri;
/// Convenience wrapper, contains a channel and a request number.
///
/// Commonly used in peripheral drivers that own DMA channels.
pub(crate) struct ChannelAndRequest<'d> {
pub channel: PeripheralRef<'d, AnyChannel>,
pub channel: Peri<'d, AnyChannel>,
pub request: Request,
}
@ -18,7 +17,7 @@ impl<'d> ChannelAndRequest<'d> {
buf: &'a mut [W],
options: TransferOptions,
) -> 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>(
@ -27,7 +26,7 @@ impl<'d> ChannelAndRequest<'d> {
buf: *mut [W],
options: TransferOptions,
) -> 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>(
@ -36,7 +35,7 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut W,
options: TransferOptions,
) -> 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>(
@ -45,7 +44,7 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut PW,
options: TransferOptions,
) -> 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)]
@ -56,6 +55,13 @@ impl<'d> ChannelAndRequest<'d> {
peri_addr: *mut W,
options: TransferOptions,
) -> 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 embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_hal_internal::PeripheralType;
//use crate::gpio::{AnyPin, SealedPin};
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
use crate::rcc::{self, RccPeripheral};
use crate::{peripherals, Peripheral};
use crate::{peripherals, Peri};
/// Performs a busy-wait delay for a specified number of microseconds.
pub fn blocking_delay_ms(ms: u32) {
@ -69,14 +69,12 @@ impl From<PacketType> for u8 {
/// DSIHOST driver.
pub struct DsiHost<'d, T: Instance> {
_peri: PhantomData<&'d mut T>,
_te: PeripheralRef<'d, AnyPin>,
_te: Peri<'d, AnyPin>,
}
impl<'d, T: Instance> DsiHost<'d, T> {
/// 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 {
into_ref!(te);
pub fn new(_peri: Peri<'d, T>, te: Peri<'d, impl TePin<T>>) -> Self {
rcc::enable_and_reset::<T>();
// Set Tearing Enable pin according to CubeMx example
@ -88,7 +86,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
*/
Self {
_peri: PhantomData,
_te: te.map_into(),
_te: te.into(),
}
}
@ -412,7 +410,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral {
/// DSI instance trait.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + RccPeripheral + 'static {}
pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
pin_trait!(TePin, Instance);

View File

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

View File

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

View File

@ -6,7 +6,7 @@ mod tx_desc;
use core::marker::PhantomData;
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};
pub(crate) use self::rx_desc::{RDes, RDesRing};
@ -15,6 +15,7 @@ use super::*;
#[cfg(eth_v1a)]
use crate::gpio::Pull;
use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
use crate::interrupt;
use crate::interrupt::InterruptExt;
#[cfg(eth_v1a)]
use crate::pac::AFIO;
@ -22,7 +23,6 @@ use crate::pac::AFIO;
use crate::pac::SYSCFG;
use crate::pac::{ETH, RCC};
use crate::rcc::SealedRccPeripheral;
use crate::{interrupt, Peripheral};
/// Interrupt handler.
pub struct InterruptHandler {}
@ -47,11 +47,11 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandl
/// Ethernet driver.
pub struct Ethernet<'d, T: Instance, P: Phy> {
_peri: PeripheralRef<'d, T>,
_peri: Peri<'d, T>,
pub(crate) tx: TDesRing<'d>,
pub(crate) rx: RDesRing<'d>,
pins: [PeripheralRef<'d, AnyPin>; 9],
pins: [Peri<'d, AnyPin>; 9],
pub(crate) phy: P,
pub(crate) station_management: EthernetStationManagement<T>,
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
pub fn new<const TX: usize, const RX: usize>(
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,
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
crs: impl Peripheral<P = impl CRSPin<T>> + 'd,
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
ref_clk: Peri<'d, impl RefClkPin<T>>,
mdio: Peri<'d, impl MDIOPin<T>>,
mdc: Peri<'d, impl MDCPin<T>>,
crs: Peri<'d, impl CRSPin<T>>,
rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: Peri<'d, impl RXD1Pin<T>>,
tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P,
mac_addr: [u8; 6],
) -> Self {
into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
// Enable the necessary Clocks
#[cfg(eth_v1a)]
critical_section::with(|_| {
@ -213,15 +211,15 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
};
let pins = [
ref_clk.map_into(),
mdio.map_into(),
mdc.map_into(),
crs.map_into(),
rx_d0.map_into(),
rx_d1.map_into(),
tx_d0.map_into(),
tx_d1.map_into(),
tx_en.map_into(),
ref_clk.into(),
mdio.into(),
mdc.into(),
crs.into(),
rx_d0.into(),
rx_d1.into(),
tx_d0.into(),
tx_d1.into(),
tx_en.into(),
];
let mut this = Self {

View File

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

View File

@ -5,13 +5,13 @@ use core::marker::PhantomData;
use core::pin::Pin;
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 crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull};
use crate::pac::exti::regs::Lines;
use crate::pac::EXTI;
use crate::{interrupt, pac, peripherals, Peripheral};
use crate::{interrupt, pac, peripherals, Peri};
const EXTI_COUNT: usize = 16;
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> {
/// Create an EXTI input.
pub fn new<T: GpioPin>(
pin: impl Peripheral<P = T> + 'd,
ch: impl Peripheral<P = T::ExtiChannel> + 'd,
pull: Pull,
) -> Self {
into_ref!(pin, ch);
pub fn new<T: GpioPin>(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull) -> Self {
// Needed if using AnyPin+AnyChannel.
assert_eq!(pin.pin(), ch.number());
@ -338,23 +332,12 @@ trait SealedChannel {}
/// EXTI channel trait.
#[allow(private_bounds)]
pub trait Channel: SealedChannel + Sized {
pub trait Channel: PeripheralType + SealedChannel + Sized {
/// Get the EXTI channel number.
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.
pub struct AnyChannel {
@ -377,6 +360,14 @@ macro_rules! impl_exti {
$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