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`.
|
/// 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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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 ()) {
|
||||||
|
@ -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()
|
||||||
|
@ -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 ()) {
|
||||||
|
@ -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> {
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user