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`.
///
/// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an

View file

@ -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,

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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,

View file

@ -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.

View file

@ -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);

View file

@ -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 ()) {

View file

@ -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()

View file

@ -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 ()) {

View file

@ -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> {

View file

@ -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,
}