nrf: replace PhantomData usages with PeripheralRef.
This commit is contained in:
parent
19d1ef0e29
commit
709df0dc1d
@ -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`.
|
||||
///
|
||||
/// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an
|
||||
|
@ -15,14 +15,13 @@
|
||||
|
||||
use core::cmp::min;
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::WakerRegistration;
|
||||
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
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;
|
||||
// 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};
|
||||
@ -54,7 +53,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
|
||||
}
|
||||
|
||||
struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
|
||||
phantom: PhantomData<&'d mut U>,
|
||||
_peri: PeripheralRef<'d, U>,
|
||||
timer: Timer<'d, T>,
|
||||
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>,
|
||||
_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> {
|
||||
pub fn new(
|
||||
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,
|
||||
ppi_ch1: 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],
|
||||
tx_buffer: &'d mut [u8],
|
||||
) -> 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();
|
||||
|
||||
@ -163,7 +162,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
||||
|
||||
Self {
|
||||
inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner {
|
||||
phantom: PhantomData,
|
||||
_peri: peri,
|
||||
timer,
|
||||
_ppi_ch1: ppi_ch1,
|
||||
_ppi_ch2: ppi_ch2,
|
||||
|
@ -1,10 +1,9 @@
|
||||
use core::convert::Infallible;
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::impl_peripheral;
|
||||
use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
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> {
|
||||
pin_port: u8,
|
||||
phantom: PhantomData<&'a mut AnyPin>,
|
||||
pin: PeripheralRef<'a, 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> Drop for PortInputFuture<'a> {
|
||||
fn drop(&mut self) {
|
||||
let pin = unsafe { AnyPin::steal(self.pin_port) };
|
||||
pin.conf().modify(|_, w| w.sense().disabled());
|
||||
self.pin.conf().modify(|_, w| w.sense().disabled());
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,10 +323,9 @@ impl<'a> Future for PortInputFuture<'a> {
|
||||
type 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 pin.conf().read().sense().is_disabled() {
|
||||
if self.pin.conf().read().sense().is_disabled() {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
@ -354,22 +358,12 @@ impl<'d, T: GpioPin> Input<'d, T> {
|
||||
impl<'d, T: GpioPin> Flex<'d, T> {
|
||||
pub async fn wait_for_high(&mut self) {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
.await
|
||||
PortInputFuture::new(&mut self.pin).await
|
||||
}
|
||||
|
||||
pub async fn wait_for_low(&mut self) {
|
||||
self.pin.conf().modify(|_, w| w.sense().low());
|
||||
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
.await
|
||||
PortInputFuture::new(&mut self.pin).await
|
||||
}
|
||||
|
||||
pub async fn wait_for_rising_edge(&mut self) {
|
||||
@ -388,11 +382,7 @@ impl<'d, T: GpioPin> Flex<'d, T> {
|
||||
} else {
|
||||
self.pin.conf().modify(|_, w| w.sense().high());
|
||||
}
|
||||
PortInputFuture {
|
||||
pin_port: self.pin.pin_port(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
.await
|
||||
PortInputFuture::new(&mut self.pin).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//! Nvmcerature sensor interface.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::{ptr, slice};
|
||||
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{
|
||||
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
|
||||
};
|
||||
@ -31,14 +30,13 @@ impl NorFlashError for Error {
|
||||
}
|
||||
|
||||
pub struct Nvmc<'d> {
|
||||
_p: PhantomData<&'d NVMC>,
|
||||
_p: PeripheralRef<'d, NVMC>,
|
||||
}
|
||||
|
||||
impl<'d> Nvmc<'d> {
|
||||
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
|
||||
into_ref!(_p);
|
||||
|
||||
Self { _p: PhantomData }
|
||||
Self { _p }
|
||||
}
|
||||
|
||||
fn regs() -> &'static pac::nvmc::RegisterBlock {
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
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
|
||||
/// to simply set a duty cycle across up to four channels.
|
||||
pub struct SimplePwm<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
duty: [u16; 4],
|
||||
ch0: 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
|
||||
/// to up to four channels, as well as repeat that sequence n times.
|
||||
pub struct SequencePwm<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
ch0: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch1: 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>>,
|
||||
config: Config,
|
||||
) -> Result<Self, Error> {
|
||||
into_ref!(_pwm);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
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) });
|
||||
|
||||
Ok(Self {
|
||||
phantom: PhantomData,
|
||||
_peri: _pwm,
|
||||
ch0,
|
||||
ch1,
|
||||
ch2,
|
||||
@ -639,6 +640,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
|
||||
ch2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
) -> Self {
|
||||
into_ref!(_pwm);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
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()) });
|
||||
|
||||
let pwm = Self {
|
||||
phantom: PhantomData,
|
||||
_peri: _pwm,
|
||||
ch0,
|
||||
ch1,
|
||||
ch2,
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Quadrature decoder interface
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
@ -15,7 +14,7 @@ use crate::{interrupt, pac, Peripheral};
|
||||
|
||||
/// Quadrature decoder
|
||||
pub struct Qdec<'d> {
|
||||
phantom: PhantomData<&'d QDEC>,
|
||||
_p: PeripheralRef<'d, QDEC>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
@ -66,14 +65,14 @@ impl<'d> Qdec<'d> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_t: impl Peripheral<P = QDEC> + 'd,
|
||||
p: impl Peripheral<P = QDEC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::QDEC> + 'd,
|
||||
a: PeripheralRef<'d, AnyPin>,
|
||||
b: PeripheralRef<'d, AnyPin>,
|
||||
led: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(p, irq);
|
||||
let r = Self::regs();
|
||||
|
||||
// Select pins.
|
||||
@ -131,7 +130,7 @@ impl<'d> Qdec<'d> {
|
||||
});
|
||||
irq.enable();
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: p }
|
||||
}
|
||||
|
||||
/// Perform an asynchronous read of the decoder.
|
||||
|
@ -1,11 +1,10 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
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 pac::{saadc, SAADC};
|
||||
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::resolution::VAL_A;
|
||||
|
||||
use self::sealed::Input as _;
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
|
||||
@ -26,7 +26,7 @@ pub enum Error {}
|
||||
|
||||
/// One-shot and continuous SAADC.
|
||||
pub struct Saadc<'d, const N: usize> {
|
||||
phantom: PhantomData<&'d mut peripherals::SAADC>,
|
||||
_p: PeripheralRef<'d, peripherals::SAADC>,
|
||||
}
|
||||
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
@ -66,63 +66,11 @@ pub struct ChannelConfig<'d> {
|
||||
/// Acquisition time in microseconds.
|
||||
pub time: Time,
|
||||
/// Positive channel to sample
|
||||
p_channel: InputChannel,
|
||||
p_channel: PeripheralRef<'d, AnyInput>,
|
||||
/// An optional negative channel to sample
|
||||
n_channel: Option<InputChannel>,
|
||||
|
||||
phantom: PhantomData<&'d ()>,
|
||||
n_channel: Option<PeripheralRef<'d, AnyInput>>,
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
/// Default configuration for single ended channel sampling.
|
||||
pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
|
||||
@ -132,9 +80,8 @@ impl<'d> ChannelConfig<'d> {
|
||||
gain: Gain::GAIN1_6,
|
||||
resistor: Resistor::BYPASS,
|
||||
time: Time::_10US,
|
||||
p_channel: input.channel(),
|
||||
p_channel: input.map_into(),
|
||||
n_channel: None,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
/// Default configuration for differential channel sampling.
|
||||
@ -148,9 +95,8 @@ impl<'d> ChannelConfig<'d> {
|
||||
gain: Gain::GAIN1_6,
|
||||
resistor: Resistor::BYPASS,
|
||||
time: Time::_10US,
|
||||
p_channel: p_input.channel(),
|
||||
n_channel: Some(n_input.channel()),
|
||||
phantom: PhantomData,
|
||||
p_channel: p_input.map_into(),
|
||||
n_channel: Some(n_input.map_into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,12 +113,12 @@ pub enum SamplerState {
|
||||
|
||||
impl<'d, const N: usize> Saadc<'d, N> {
|
||||
pub fn new(
|
||||
_saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
|
||||
saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::SAADC> + 'd,
|
||||
config: Config,
|
||||
channel_configs: [ChannelConfig; N],
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(saadc, irq);
|
||||
|
||||
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()));
|
||||
|
||||
for (i, cc) in channel_configs.iter().enumerate() {
|
||||
r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_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].pselp.write(|w| w.pselp().variant(cc.p_channel.channel()));
|
||||
if let Some(n_channel) = &cc.n_channel {
|
||||
r.ch[i]
|
||||
.pseln
|
||||
.write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) });
|
||||
}
|
||||
r.ch[i].config.write(|w| {
|
||||
w.refsel().variant(cc.reference.into());
|
||||
@ -215,7 +163,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: saadc }
|
||||
}
|
||||
|
||||
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.
|
||||
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 {
|
||||
AnyInput {
|
||||
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 {
|
||||
($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 {
|
||||
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);
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
@ -31,7 +30,7 @@ pub enum Error {
|
||||
///
|
||||
/// For more details about EasyDMA, consult the module documentation.
|
||||
pub struct Spim<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
@ -94,14 +93,14 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_spim: impl Peripheral<P = T> + 'd,
|
||||
spim: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
sck: PeripheralRef<'d, AnyPin>,
|
||||
miso: Option<PeripheralRef<'d, AnyPin>>,
|
||||
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(spim, irq);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
@ -181,7 +180,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: spim }
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
|
@ -5,7 +5,7 @@ use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
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 crate::interrupt::{Interrupt, InterruptExt};
|
||||
@ -95,7 +95,8 @@ impl TimerType for Awaitable {}
|
||||
impl TimerType for 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> {
|
||||
@ -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.
|
||||
///
|
||||
/// 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 mut this = Self { phantom: PhantomData };
|
||||
let mut this = Self {
|
||||
_p: timer,
|
||||
_i: PhantomData,
|
||||
};
|
||||
|
||||
// Stop the timer before doing anything else,
|
||||
// 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 {
|
||||
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.
|
||||
/// 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,
|
||||
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.
|
||||
///
|
||||
/// 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();
|
||||
}
|
||||
}
|
||||
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.
|
||||
pub fn read(&self) -> u32 {
|
||||
T::regs().cc[self.n].read().cc().bits()
|
||||
|
@ -7,7 +7,6 @@
|
||||
//! - nRF52832: Section 33
|
||||
//! - nRF52840: Section 6.31
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::compiler_fence;
|
||||
use core::sync::atomic::Ordering::SeqCst;
|
||||
use core::task::Poll;
|
||||
@ -16,7 +15,7 @@ use core::task::Poll;
|
||||
use embassy::time::{Duration, Instant};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
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.
|
||||
pub struct Twim<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Twim<'d, T> {
|
||||
pub fn new(
|
||||
_twim: impl Peripheral<P = T> + 'd,
|
||||
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 {
|
||||
into_ref!(irq, sda, scl);
|
||||
into_ref!(twim, irq, sda, scl);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
@ -136,7 +135,7 @@ impl<'d, T: Instance> Twim<'d, T> {
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: twim }
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
|
@ -13,7 +13,6 @@
|
||||
//! memory may be used given that buffers are passed in directly to its read and write
|
||||
//! methods.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
@ -63,7 +62,6 @@ pub enum Error {
|
||||
///
|
||||
/// For more details about EasyDMA, consult the module documentation.
|
||||
pub struct Uarte<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx: UarteTx<'d, T>,
|
||||
rx: UarteRx<'d, T>,
|
||||
}
|
||||
@ -71,13 +69,13 @@ pub struct Uarte<'d, T: Instance> {
|
||||
/// Transmitter interface to the UARTE peripheral obtained
|
||||
/// via [Uarte]::split.
|
||||
pub struct UarteTx<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
/// Receiver interface to the UARTE peripheral obtained
|
||||
/// via [Uarte]::split.
|
||||
pub struct UarteRx<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Uarte<'d, T> {
|
||||
@ -116,7 +114,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Peripheral<P = T> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: PeripheralRef<'d, AnyPin>,
|
||||
txd: PeripheralRef<'d, AnyPin>,
|
||||
@ -124,7 +122,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(uarte, irq);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
@ -161,9 +159,10 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
s.tx_rx_refcount.store(2, Ordering::Relaxed);
|
||||
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
tx: UarteTx { phantom: PhantomData },
|
||||
rx: UarteRx { phantom: PhantomData },
|
||||
tx: UarteTx {
|
||||
_p: unsafe { uarte.clone_unchecked() },
|
||||
},
|
||||
rx: UarteRx { _p: uarte },
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,13 +266,13 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Peripheral<P = T> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
txd: PeripheralRef<'d, AnyPin>,
|
||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(uarte, irq);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
@ -299,7 +298,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
||||
let s = T::state();
|
||||
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: uarte }
|
||||
}
|
||||
|
||||
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||
@ -459,13 +458,13 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Peripheral<P = T> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: PeripheralRef<'d, AnyPin>,
|
||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
into_ref!(uarte, irq);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
@ -491,7 +490,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
||||
let s = T::state();
|
||||
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> {
|
||||
|
@ -7,7 +7,7 @@ use core::task::Poll;
|
||||
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
pub use embassy_usb;
|
||||
use embassy_usb::driver::{self, EndpointError, Event, Unsupported};
|
||||
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
|
||||
@ -38,7 +38,7 @@ pub trait UsbSupply {
|
||||
}
|
||||
|
||||
pub struct Driver<'d, T: Instance, P: UsbSupply> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
alloc_in: Allocator,
|
||||
alloc_out: Allocator,
|
||||
usb_supply: P,
|
||||
@ -166,14 +166,14 @@ impl UsbSupply for SignalledSupply {
|
||||
}
|
||||
|
||||
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 {
|
||||
into_ref!(irq);
|
||||
pub fn new(usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd, usb_supply: P) -> Self {
|
||||
into_ref!(usb, irq);
|
||||
irq.set_handler(Self::on_interrupt);
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
_p: usb,
|
||||
alloc_in: Allocator::new(),
|
||||
alloc_out: Allocator::new(),
|
||||
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 {
|
||||
phantom: PhantomData,
|
||||
_p: unsafe { self._p.clone_unchecked() },
|
||||
power_available: false,
|
||||
usb_supply: self.usb_supply,
|
||||
},
|
||||
ControlPipe {
|
||||
_phantom: PhantomData,
|
||||
_p: self._p,
|
||||
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> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
power_available: bool,
|
||||
usb_supply: P,
|
||||
}
|
||||
@ -746,7 +746,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
|
||||
}
|
||||
|
||||
pub struct ControlPipe<'d, T: Instance> {
|
||||
_phantom: PhantomData<&'d mut T>,
|
||||
_p: PeripheralRef<'d, T>,
|
||||
max_packet_size: u16,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user