nrf: replace PhantomData usages with PeripheralRef.

This commit is contained in:
Dario Nieuwenhuis 2022-07-23 15:13:47 +02:00
parent 19d1ef0e29
commit 709df0dc1d
12 changed files with 180 additions and 164 deletions

View File

@ -27,6 +27,36 @@ impl<'a, T> PeripheralRef<'a, T> {
} }
} }
/// 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 `reborrow()` instead. It returns a
/// `PeripheralRef` that borrows `self`, which allows the borrow checker
/// to enforce this at compile time.
pub unsafe fn clone_unchecked(&mut self) -> PeripheralRef<'a, T>
where
T: Peripheral<P = T>,
{
PeripheralRef::new(self.inner.clone_unchecked())
}
/// Reborrow into a "child" PeripheralRef.
///
/// `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, so user code can't use both at the same time.
PeripheralRef::new(unsafe { self.inner.clone_unchecked() })
}
/// Map the inner peripheral using `Into`. /// Map the inner peripheral using `Into`.
/// ///
/// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an

View File

@ -15,14 +15,13 @@
use core::cmp::min; use core::cmp::min;
use core::future::Future; use core::future::Future;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::WakerRegistration; use embassy::waitqueue::WakerRegistration;
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::ring_buffer::RingBuffer; use embassy_hal_common::ring_buffer::RingBuffer;
use embassy_hal_common::{into_ref, low_power_wait_until}; use embassy_hal_common::{into_ref, low_power_wait_until, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
// Re-export SVD variants to allow user to directly set values // Re-export SVD variants to allow user to directly set values
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
@ -54,7 +53,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
} }
struct StateInner<'d, U: UarteInstance, T: TimerInstance> { struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
phantom: PhantomData<&'d mut U>, _peri: PeripheralRef<'d, U>,
timer: Timer<'d, T>, timer: Timer<'d, T>,
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>,
_ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>,
@ -78,7 +77,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {
impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
pub fn new( pub fn new(
state: &'d mut State<'d, U, T>, state: &'d mut State<'d, U, T>,
_uarte: impl Peripheral<P = U> + 'd, peri: impl Peripheral<P = U> + 'd,
timer: impl Peripheral<P = T> + 'd, timer: impl Peripheral<P = T> + 'd,
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
@ -91,7 +90,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
rx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8],
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
) -> Self { ) -> Self {
into_ref!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); into_ref!(peri, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts);
let r = U::regs(); let r = U::regs();
@ -163,7 +162,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
Self { Self {
inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner {
phantom: PhantomData, _peri: peri,
timer, timer,
_ppi_ch1: ppi_ch1, _ppi_ch1: ppi_ch1,
_ppi_ch2: ppi_ch2, _ppi_ch2: ppi_ch2,

View File

@ -1,10 +1,9 @@
use core::convert::Infallible; use core::convert::Infallible;
use core::future::Future; use core::future::Future;
use core::marker::PhantomData;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::impl_peripheral; use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
@ -301,16 +300,22 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
// ======================= // =======================
pub(crate) struct PortInputFuture<'a> { pub(crate) struct PortInputFuture<'a> {
pin_port: u8, pin: PeripheralRef<'a, AnyPin>,
phantom: PhantomData<&'a mut AnyPin>, }
impl<'a> PortInputFuture<'a> {
fn new(pin: impl Peripheral<P = impl GpioPin> + 'a) -> Self {
Self {
pin: pin.into_ref().map_into(),
}
}
} }
impl<'a> Unpin for PortInputFuture<'a> {} impl<'a> Unpin for PortInputFuture<'a> {}
impl<'a> Drop for PortInputFuture<'a> { impl<'a> Drop for PortInputFuture<'a> {
fn drop(&mut self) { fn drop(&mut self) {
let pin = unsafe { AnyPin::steal(self.pin_port) }; self.pin.conf().modify(|_, w| w.sense().disabled());
pin.conf().modify(|_, w| w.sense().disabled());
} }
} }
@ -318,10 +323,9 @@ impl<'a> Future for PortInputFuture<'a> {
type Output = (); type Output = ();
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
PORT_WAKERS[self.pin_port as usize].register(cx.waker()); PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker());
let pin = unsafe { AnyPin::steal(self.pin_port) }; if self.pin.conf().read().sense().is_disabled() {
if pin.conf().read().sense().is_disabled() {
Poll::Ready(()) Poll::Ready(())
} else { } else {
Poll::Pending Poll::Pending
@ -354,22 +358,12 @@ impl<'d, T: GpioPin> Input<'d, T> {
impl<'d, T: GpioPin> Flex<'d, T> { impl<'d, T: GpioPin> Flex<'d, T> {
pub async fn wait_for_high(&mut self) { pub async fn wait_for_high(&mut self) {
self.pin.conf().modify(|_, w| w.sense().high()); self.pin.conf().modify(|_, w| w.sense().high());
PortInputFuture::new(&mut self.pin).await
PortInputFuture {
pin_port: self.pin.pin_port(),
phantom: PhantomData,
}
.await
} }
pub async fn wait_for_low(&mut self) { pub async fn wait_for_low(&mut self) {
self.pin.conf().modify(|_, w| w.sense().low()); self.pin.conf().modify(|_, w| w.sense().low());
PortInputFuture::new(&mut self.pin).await
PortInputFuture {
pin_port: self.pin.pin_port(),
phantom: PhantomData,
}
.await
} }
pub async fn wait_for_rising_edge(&mut self) { pub async fn wait_for_rising_edge(&mut self) {
@ -388,11 +382,7 @@ impl<'d, T: GpioPin> Flex<'d, T> {
} else { } else {
self.pin.conf().modify(|_, w| w.sense().high()); self.pin.conf().modify(|_, w| w.sense().high());
} }
PortInputFuture { PortInputFuture::new(&mut self.pin).await
pin_port: self.pin.pin_port(),
phantom: PhantomData,
}
.await
} }
} }

View File

@ -1,9 +1,8 @@
//! Nvmcerature sensor interface. //! Nvmcerature sensor interface.
use core::marker::PhantomData;
use core::{ptr, slice}; use core::{ptr, slice};
use embassy_hal_common::into_ref; use embassy_hal_common::{into_ref, PeripheralRef};
use embedded_storage::nor_flash::{ use embedded_storage::nor_flash::{
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
}; };
@ -31,14 +30,13 @@ impl NorFlashError for Error {
} }
pub struct Nvmc<'d> { pub struct Nvmc<'d> {
_p: PhantomData<&'d NVMC>, _p: PeripheralRef<'d, NVMC>,
} }
impl<'d> Nvmc<'d> { impl<'d> Nvmc<'d> {
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self { pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
into_ref!(_p); into_ref!(_p);
Self { _p }
Self { _p: PhantomData }
} }
fn regs() -> &'static pac::nvmc::RegisterBlock { fn regs() -> &'static pac::nvmc::RegisterBlock {

View File

@ -1,6 +1,5 @@
#![macro_use] #![macro_use]
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
@ -15,7 +14,7 @@ use crate::{pac, Peripheral};
/// SimplePwm is the traditional pwm interface you're probably used to, allowing /// SimplePwm is the traditional pwm interface you're probably used to, allowing
/// to simply set a duty cycle across up to four channels. /// to simply set a duty cycle across up to four channels.
pub struct SimplePwm<'d, T: Instance> { pub struct SimplePwm<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _peri: PeripheralRef<'d, T>,
duty: [u16; 4], duty: [u16; 4],
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<PeripheralRef<'d, AnyPin>>,
@ -26,7 +25,7 @@ pub struct SimplePwm<'d, T: Instance> {
/// SequencePwm allows you to offload the updating of a sequence of duty cycles /// SequencePwm allows you to offload the updating of a sequence of duty cycles
/// to up to four channels, as well as repeat that sequence n times. /// to up to four channels, as well as repeat that sequence n times.
pub struct SequencePwm<'d, T: Instance> { pub struct SequencePwm<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _peri: PeripheralRef<'d, T>,
ch0: Option<PeripheralRef<'d, AnyPin>>, ch0: Option<PeripheralRef<'d, AnyPin>>,
ch1: Option<PeripheralRef<'d, AnyPin>>, ch1: Option<PeripheralRef<'d, AnyPin>>,
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<PeripheralRef<'d, AnyPin>>,
@ -120,6 +119,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
into_ref!(_pwm);
let r = T::regs(); let r = T::regs();
if let Some(pin) = &ch0 { if let Some(pin) = &ch0 {
@ -168,7 +169,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) }); r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) });
Ok(Self { Ok(Self {
phantom: PhantomData, _peri: _pwm,
ch0, ch0,
ch1, ch1,
ch2, ch2,
@ -639,6 +640,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
ch2: Option<PeripheralRef<'d, AnyPin>>, ch2: Option<PeripheralRef<'d, AnyPin>>,
ch3: Option<PeripheralRef<'d, AnyPin>>, ch3: Option<PeripheralRef<'d, AnyPin>>,
) -> Self { ) -> Self {
into_ref!(_pwm);
let r = T::regs(); let r = T::regs();
if let Some(pin) = &ch0 { if let Some(pin) = &ch0 {
@ -666,7 +669,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) });
let pwm = Self { let pwm = Self {
phantom: PhantomData, _peri: _pwm,
ch0, ch0,
ch1, ch1,
ch2, ch2,

View File

@ -1,6 +1,5 @@
//! Quadrature decoder interface //! Quadrature decoder interface
use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
@ -15,7 +14,7 @@ use crate::{interrupt, pac, Peripheral};
/// Quadrature decoder /// Quadrature decoder
pub struct Qdec<'d> { pub struct Qdec<'d> {
phantom: PhantomData<&'d QDEC>, _p: PeripheralRef<'d, QDEC>,
} }
#[non_exhaustive] #[non_exhaustive]
@ -66,14 +65,14 @@ impl<'d> Qdec<'d> {
} }
fn new_inner( fn new_inner(
_t: impl Peripheral<P = QDEC> + 'd, p: impl Peripheral<P = QDEC> + 'd,
irq: impl Peripheral<P = interrupt::QDEC> + 'd, irq: impl Peripheral<P = interrupt::QDEC> + 'd,
a: PeripheralRef<'d, AnyPin>, a: PeripheralRef<'d, AnyPin>,
b: PeripheralRef<'d, AnyPin>, b: PeripheralRef<'d, AnyPin>,
led: Option<PeripheralRef<'d, AnyPin>>, led: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(p, irq);
let r = Self::regs(); let r = Self::regs();
// Select pins. // Select pins.
@ -131,7 +130,7 @@ impl<'d> Qdec<'d> {
}); });
irq.enable(); irq.enable();
Self { phantom: PhantomData } Self { _p: p }
} }
/// Perform an asynchronous read of the decoder. /// Perform an asynchronous read of the decoder.

View File

@ -1,11 +1,10 @@
#![macro_use] #![macro_use]
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::{impl_peripheral, into_ref}; use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
use pac::{saadc, SAADC}; use pac::{saadc, SAADC};
use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
@ -14,6 +13,7 @@ pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel;
use saadc::oversample::OVERSAMPLE_A; use saadc::oversample::OVERSAMPLE_A;
use saadc::resolution::VAL_A; use saadc::resolution::VAL_A;
use self::sealed::Input as _;
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::timer::{Frequency, Instance as TimerInstance, Timer};
@ -26,7 +26,7 @@ pub enum Error {}
/// One-shot and continuous SAADC. /// One-shot and continuous SAADC.
pub struct Saadc<'d, const N: usize> { pub struct Saadc<'d, const N: usize> {
phantom: PhantomData<&'d mut peripherals::SAADC>, _p: PeripheralRef<'d, peripherals::SAADC>,
} }
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
@ -66,63 +66,11 @@ pub struct ChannelConfig<'d> {
/// Acquisition time in microseconds. /// Acquisition time in microseconds.
pub time: Time, pub time: Time,
/// Positive channel to sample /// Positive channel to sample
p_channel: InputChannel, p_channel: PeripheralRef<'d, AnyInput>,
/// An optional negative channel to sample /// An optional negative channel to sample
n_channel: Option<InputChannel>, n_channel: Option<PeripheralRef<'d, AnyInput>>,
phantom: PhantomData<&'d ()>,
} }
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
/// internal voltage.
pub struct VddInput;
impl_peripheral!(VddInput);
impl sealed::Input for VddInput {
#[cfg(not(feature = "_nrf9160"))]
fn channel(&self) -> InputChannel {
InputChannel::VDD
}
#[cfg(feature = "_nrf9160")]
fn channel(&self) -> InputChannel {
InputChannel::VDDGPIO
}
}
impl Input for VddInput {}
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
/// VDDH / 5 voltage.
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
pub struct VddhDiv5Input;
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
impl_peripheral!(VddhDiv5Input);
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
impl sealed::Input for VddhDiv5Input {
fn channel(&self) -> InputChannel {
InputChannel::VDDHDIV5
}
}
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
impl Input for VddhDiv5Input {}
pub struct AnyInput {
channel: InputChannel,
}
impl_peripheral!(AnyInput);
impl sealed::Input for AnyInput {
fn channel(&self) -> InputChannel {
self.channel
}
}
impl Input for AnyInput {}
impl<'d> ChannelConfig<'d> { impl<'d> ChannelConfig<'d> {
/// Default configuration for single ended channel sampling. /// Default configuration for single ended channel sampling.
pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self { pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
@ -132,9 +80,8 @@ impl<'d> ChannelConfig<'d> {
gain: Gain::GAIN1_6, gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS, resistor: Resistor::BYPASS,
time: Time::_10US, time: Time::_10US,
p_channel: input.channel(), p_channel: input.map_into(),
n_channel: None, n_channel: None,
phantom: PhantomData,
} }
} }
/// Default configuration for differential channel sampling. /// Default configuration for differential channel sampling.
@ -148,9 +95,8 @@ impl<'d> ChannelConfig<'d> {
gain: Gain::GAIN1_6, gain: Gain::GAIN1_6,
resistor: Resistor::BYPASS, resistor: Resistor::BYPASS,
time: Time::_10US, time: Time::_10US,
p_channel: p_input.channel(), p_channel: p_input.map_into(),
n_channel: Some(n_input.channel()), n_channel: Some(n_input.map_into()),
phantom: PhantomData,
} }
} }
} }
@ -167,12 +113,12 @@ pub enum SamplerState {
impl<'d, const N: usize> Saadc<'d, N> { impl<'d, const N: usize> Saadc<'d, N> {
pub fn new( pub fn new(
_saadc: impl Peripheral<P = peripherals::SAADC> + 'd, saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
irq: impl Peripheral<P = interrupt::SAADC> + 'd, irq: impl Peripheral<P = interrupt::SAADC> + 'd,
config: Config, config: Config,
channel_configs: [ChannelConfig; N], channel_configs: [ChannelConfig; N],
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(saadc, irq);
let r = unsafe { &*SAADC::ptr() }; let r = unsafe { &*SAADC::ptr() };
@ -184,9 +130,11 @@ impl<'d, const N: usize> Saadc<'d, N> {
r.oversample.write(|w| w.oversample().variant(oversample.into())); r.oversample.write(|w| w.oversample().variant(oversample.into()));
for (i, cc) in channel_configs.iter().enumerate() { for (i, cc) in channel_configs.iter().enumerate() {
r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel)); r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel.channel()));
if let Some(n_channel) = cc.n_channel { if let Some(n_channel) = &cc.n_channel {
r.ch[i].pseln.write(|w| unsafe { w.pseln().bits(n_channel as u8) }); r.ch[i]
.pseln
.write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) });
} }
r.ch[i].config.write(|w| { r.ch[i].config.write(|w| {
w.refsel().variant(cc.reference.into()); w.refsel().variant(cc.reference.into());
@ -215,7 +163,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
irq.unpend(); irq.unpend();
irq.enable(); irq.enable();
Self { phantom: PhantomData } Self { _p: saadc }
} }
fn on_interrupt(_ctx: *mut ()) { fn on_interrupt(_ctx: *mut ()) {
@ -674,7 +622,7 @@ pub(crate) mod sealed {
} }
/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
pub trait Input: sealed::Input + Peripheral<P = Self> + Sized { pub trait Input: sealed::Input + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static {
fn degrade_saadc(self) -> AnyInput { fn degrade_saadc(self) -> AnyInput {
AnyInput { AnyInput {
channel: self.channel(), channel: self.channel(),
@ -682,13 +630,57 @@ pub trait Input: sealed::Input + Peripheral<P = Self> + Sized {
} }
} }
pub struct AnyInput {
channel: InputChannel,
}
impl_peripheral!(AnyInput);
impl sealed::Input for AnyInput {
fn channel(&self) -> InputChannel {
self.channel
}
}
impl Input for AnyInput {}
macro_rules! impl_saadc_input { macro_rules! impl_saadc_input {
($pin:ident, $ch:ident) => { ($pin:ident, $ch:ident) => {
impl crate::saadc::sealed::Input for crate::peripherals::$pin { impl_saadc_input!(@local, crate::peripherals::$pin, $ch);
};
(@local, $pin:ty, $ch:ident) => {
impl crate::saadc::sealed::Input for $pin {
fn channel(&self) -> crate::saadc::InputChannel { fn channel(&self) -> crate::saadc::InputChannel {
crate::saadc::InputChannel::$ch crate::saadc::InputChannel::$ch
} }
} }
impl crate::saadc::Input for crate::peripherals::$pin {} impl crate::saadc::Input for $pin {}
impl From<$pin> for crate::saadc::AnyInput {
fn from(val: $pin) -> Self {
crate::saadc::Input::degrade_saadc(val)
}
}
}; };
} }
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
/// internal voltage.
pub struct VddInput;
impl_peripheral!(VddInput);
#[cfg(not(feature = "_nrf9160"))]
impl_saadc_input!(@local, VddInput, VDD);
#[cfg(feature = "_nrf9160")]
impl_saadc_input!(@local, VddInput, VDDGPIO);
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
/// VDDH / 5 voltage.
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
pub struct VddhDiv5Input;
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
impl_peripheral!(VddhDiv5Input);
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5);

View File

@ -1,6 +1,5 @@
#![macro_use] #![macro_use]
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
@ -31,7 +30,7 @@ pub enum Error {
/// ///
/// For more details about EasyDMA, consult the module documentation. /// For more details about EasyDMA, consult the module documentation.
pub struct Spim<'d, T: Instance> { pub struct Spim<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
} }
#[non_exhaustive] #[non_exhaustive]
@ -94,14 +93,14 @@ impl<'d, T: Instance> Spim<'d, T> {
} }
fn new_inner( fn new_inner(
_spim: impl Peripheral<P = T> + 'd, spim: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd,
sck: PeripheralRef<'d, AnyPin>, sck: PeripheralRef<'d, AnyPin>,
miso: Option<PeripheralRef<'d, AnyPin>>, miso: Option<PeripheralRef<'d, AnyPin>>,
mosi: Option<PeripheralRef<'d, AnyPin>>, mosi: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(spim, irq);
let r = T::regs(); let r = T::regs();
@ -181,7 +180,7 @@ impl<'d, T: Instance> Spim<'d, T> {
irq.unpend(); irq.unpend();
irq.enable(); irq.enable();
Self { phantom: PhantomData } Self { _p: spim }
} }
fn on_interrupt(_: *mut ()) { fn on_interrupt(_: *mut ()) {

View File

@ -5,7 +5,7 @@ use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::into_ref; use embassy_hal_common::{into_ref, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::interrupt::{Interrupt, InterruptExt}; use crate::interrupt::{Interrupt, InterruptExt};
@ -95,7 +95,8 @@ impl TimerType for Awaitable {}
impl TimerType for NotAwaitable {} impl TimerType for NotAwaitable {}
pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> {
phantom: PhantomData<(&'d mut T, I)>, _p: PeripheralRef<'d, T>,
_i: PhantomData<I>,
} }
impl<'d, T: Instance> Timer<'d, T, Awaitable> { impl<'d, T: Instance> Timer<'d, T, Awaitable> {
@ -123,10 +124,15 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
/// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work.
/// ///
/// This is used by the public constructors. /// This is used by the public constructors.
fn new_irqless(_timer: impl Peripheral<P = T> + 'd) -> Self { fn new_irqless(timer: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(timer);
let regs = T::regs(); let regs = T::regs();
let mut this = Self { phantom: PhantomData }; let mut this = Self {
_p: timer,
_i: PhantomData,
};
// Stop the timer before doing anything else, // Stop the timer before doing anything else,
// since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification.
@ -230,7 +236,8 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
} }
Cc { Cc {
n, n,
phantom: PhantomData, _p: self._p.reborrow(),
_i: PhantomData,
} }
} }
} }
@ -242,12 +249,13 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
/// ///
/// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register.
/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register
pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { pub struct Cc<'d, T: Instance, I: TimerType = NotAwaitable> {
n: usize, n: usize,
phantom: PhantomData<(&'a mut T, I)>, _p: PeripheralRef<'d, T>,
_i: PhantomData<I>,
} }
impl<'a, T: Instance> Cc<'a, T, Awaitable> { impl<'d, T: Instance> Cc<'d, T, Awaitable> {
/// Wait until the timer's counter reaches the value stored in this register. /// Wait until the timer's counter reaches the value stored in this register.
/// ///
/// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`. /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`.
@ -281,9 +289,9 @@ impl<'a, T: Instance> Cc<'a, T, Awaitable> {
on_drop.defuse(); on_drop.defuse();
} }
} }
impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {}
impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { impl<'d, T: Instance, I: TimerType> Cc<'d, T, I> {
/// Get the current value stored in the register. /// Get the current value stored in the register.
pub fn read(&self) -> u32 { pub fn read(&self) -> u32 {
T::regs().cc[self.n].read().cc().bits() T::regs().cc[self.n].read().cc().bits()

View File

@ -7,7 +7,6 @@
//! - nRF52832: Section 33 //! - nRF52832: Section 33
//! - nRF52840: Section 6.31 //! - nRF52840: Section 6.31
use core::future::Future; use core::future::Future;
use core::marker::PhantomData;
use core::sync::atomic::compiler_fence; use core::sync::atomic::compiler_fence;
use core::sync::atomic::Ordering::SeqCst; use core::sync::atomic::Ordering::SeqCst;
use core::task::Poll; use core::task::Poll;
@ -16,7 +15,7 @@ use core::task::Poll;
use embassy::time::{Duration, Instant}; use embassy::time::{Duration, Instant};
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_common::into_ref; use embassy_hal_common::{into_ref, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
@ -75,18 +74,18 @@ pub enum Error {
/// ///
/// For more details about EasyDMA, consult the module documentation. /// For more details about EasyDMA, consult the module documentation.
pub struct Twim<'d, T: Instance> { pub struct Twim<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
} }
impl<'d, T: Instance> Twim<'d, T> { impl<'d, T: Instance> Twim<'d, T> {
pub fn new( pub fn new(
_twim: impl Peripheral<P = T> + 'd, twim: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd, sda: impl Peripheral<P = impl GpioPin> + 'd,
scl: impl Peripheral<P = impl GpioPin> + 'd, scl: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq, sda, scl); into_ref!(twim, irq, sda, scl);
let r = T::regs(); let r = T::regs();
@ -136,7 +135,7 @@ impl<'d, T: Instance> Twim<'d, T> {
irq.unpend(); irq.unpend();
irq.enable(); irq.enable();
Self { phantom: PhantomData } Self { _p: twim }
} }
fn on_interrupt(_: *mut ()) { fn on_interrupt(_: *mut ()) {

View File

@ -13,7 +13,6 @@
//! memory may be used given that buffers are passed in directly to its read and write //! memory may be used given that buffers are passed in directly to its read and write
//! methods. //! methods.
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
@ -63,7 +62,6 @@ pub enum Error {
/// ///
/// For more details about EasyDMA, consult the module documentation. /// For more details about EasyDMA, consult the module documentation.
pub struct Uarte<'d, T: Instance> { pub struct Uarte<'d, T: Instance> {
phantom: PhantomData<&'d mut T>,
tx: UarteTx<'d, T>, tx: UarteTx<'d, T>,
rx: UarteRx<'d, T>, rx: UarteRx<'d, T>,
} }
@ -71,13 +69,13 @@ pub struct Uarte<'d, T: Instance> {
/// Transmitter interface to the UARTE peripheral obtained /// Transmitter interface to the UARTE peripheral obtained
/// via [Uarte]::split. /// via [Uarte]::split.
pub struct UarteTx<'d, T: Instance> { pub struct UarteTx<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
} }
/// Receiver interface to the UARTE peripheral obtained /// Receiver interface to the UARTE peripheral obtained
/// via [Uarte]::split. /// via [Uarte]::split.
pub struct UarteRx<'d, T: Instance> { pub struct UarteRx<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
} }
impl<'d, T: Instance> Uarte<'d, T> { impl<'d, T: Instance> Uarte<'d, T> {
@ -116,7 +114,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
} }
fn new_inner( fn new_inner(
_uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd,
rxd: PeripheralRef<'d, AnyPin>, rxd: PeripheralRef<'d, AnyPin>,
txd: PeripheralRef<'d, AnyPin>, txd: PeripheralRef<'d, AnyPin>,
@ -124,7 +122,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(uarte, irq);
let r = T::regs(); let r = T::regs();
@ -161,9 +159,10 @@ impl<'d, T: Instance> Uarte<'d, T> {
s.tx_rx_refcount.store(2, Ordering::Relaxed); s.tx_rx_refcount.store(2, Ordering::Relaxed);
Self { Self {
phantom: PhantomData, tx: UarteTx {
tx: UarteTx { phantom: PhantomData }, _p: unsafe { uarte.clone_unchecked() },
rx: UarteRx { phantom: PhantomData }, },
rx: UarteRx { _p: uarte },
} }
} }
@ -267,13 +266,13 @@ impl<'d, T: Instance> UarteTx<'d, T> {
} }
fn new_inner( fn new_inner(
_uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd,
txd: PeripheralRef<'d, AnyPin>, txd: PeripheralRef<'d, AnyPin>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(uarte, irq);
let r = T::regs(); let r = T::regs();
@ -299,7 +298,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
let s = T::state(); let s = T::state();
s.tx_rx_refcount.store(1, Ordering::Relaxed); s.tx_rx_refcount.store(1, Ordering::Relaxed);
Self { phantom: PhantomData } Self { _p: uarte }
} }
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
@ -459,13 +458,13 @@ impl<'d, T: Instance> UarteRx<'d, T> {
} }
fn new_inner( fn new_inner(
_uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd,
rxd: PeripheralRef<'d, AnyPin>, rxd: PeripheralRef<'d, AnyPin>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<PeripheralRef<'d, AnyPin>>,
config: Config, config: Config,
) -> Self { ) -> Self {
into_ref!(irq); into_ref!(uarte, irq);
let r = T::regs(); let r = T::regs();
@ -491,7 +490,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
let s = T::state(); let s = T::state();
s.tx_rx_refcount.store(1, Ordering::Relaxed); s.tx_rx_refcount.store(1, Ordering::Relaxed);
Self { phantom: PhantomData } Self { _p: uarte }
} }
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {

View File

@ -7,7 +7,7 @@ use core::task::Poll;
use cortex_m::peripheral::NVIC; use cortex_m::peripheral::NVIC;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::into_ref; use embassy_hal_common::{into_ref, PeripheralRef};
pub use embassy_usb; pub use embassy_usb;
use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; use embassy_usb::driver::{self, EndpointError, Event, Unsupported};
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
@ -38,7 +38,7 @@ pub trait UsbSupply {
} }
pub struct Driver<'d, T: Instance, P: UsbSupply> { pub struct Driver<'d, T: Instance, P: UsbSupply> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
alloc_in: Allocator, alloc_in: Allocator,
alloc_out: Allocator, alloc_out: Allocator,
usb_supply: P, usb_supply: P,
@ -166,14 +166,14 @@ impl UsbSupply for SignalledSupply {
} }
impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> { impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> {
pub fn new(_usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd, usb_supply: P) -> Self { pub fn new(usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd, usb_supply: P) -> Self {
into_ref!(irq); into_ref!(usb, irq);
irq.set_handler(Self::on_interrupt); irq.set_handler(Self::on_interrupt);
irq.unpend(); irq.unpend();
irq.enable(); irq.enable();
Self { Self {
phantom: PhantomData, _p: usb,
alloc_in: Allocator::new(), alloc_in: Allocator::new(),
alloc_out: Allocator::new(), alloc_out: Allocator::new(),
usb_supply, usb_supply,
@ -269,15 +269,15 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P>
})) }))
} }
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
( (
Bus { Bus {
phantom: PhantomData, _p: unsafe { self._p.clone_unchecked() },
power_available: false, power_available: false,
usb_supply: self.usb_supply, usb_supply: self.usb_supply,
}, },
ControlPipe { ControlPipe {
_phantom: PhantomData, _p: self._p,
max_packet_size: control_max_packet_size, max_packet_size: control_max_packet_size,
}, },
) )
@ -285,7 +285,7 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P>
} }
pub struct Bus<'d, T: Instance, P: UsbSupply> { pub struct Bus<'d, T: Instance, P: UsbSupply> {
phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
power_available: bool, power_available: bool,
usb_supply: P, usb_supply: P,
} }
@ -746,7 +746,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
} }
pub struct ControlPipe<'d, T: Instance> { pub struct ControlPipe<'d, T: Instance> {
_phantom: PhantomData<&'d mut T>, _p: PeripheralRef<'d, T>,
max_packet_size: u16, max_packet_size: u16,
} }