Remove Peripheral trait, rename PeripheralRef->Peri.
This commit is contained in:
parent
9edf5b7f04
commit
d41eeeae79
@ -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 {
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(_) => {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {}
|
||||
};
|
||||
}
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"))]
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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")]
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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| {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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() };
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 you’re 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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() }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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 you’re 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"))]
|
||||
|
||||
@ -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,
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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],
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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, &[]);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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() };
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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],
|
||||
) {
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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],
|
||||
) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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],
|
||||
) {
|
||||
|
||||
@ -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],
|
||||
) {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user