WIP: Make unborrow safe to use
This commit is contained in:
parent
ffbd9363f2
commit
65a82d02d1
@ -9,7 +9,7 @@ mod macros;
|
|||||||
pub mod ratio;
|
pub mod ratio;
|
||||||
pub mod ring_buffer;
|
pub mod ring_buffer;
|
||||||
mod unborrow;
|
mod unborrow;
|
||||||
pub use unborrow::Unborrow;
|
pub use unborrow::{Unborrow, Unborrowed};
|
||||||
|
|
||||||
/// Low power blocking wait loop using WFE/SEV.
|
/// Low power blocking wait loop using WFE/SEV.
|
||||||
pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) {
|
pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) {
|
||||||
|
@ -24,8 +24,11 @@ macro_rules! peripherals {
|
|||||||
unsafe impl $crate::Unborrow for $name {
|
unsafe impl $crate::Unborrow for $name {
|
||||||
type Target = $name;
|
type Target = $name;
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn unborrow(self) -> $name {
|
fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
|
||||||
self
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
$crate::Unborrowed::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
@ -80,7 +83,7 @@ macro_rules! peripherals {
|
|||||||
macro_rules! unborrow {
|
macro_rules! unborrow {
|
||||||
($($name:ident),*) => {
|
($($name:ident),*) => {
|
||||||
$(
|
$(
|
||||||
let mut $name = unsafe { $name.unborrow() };
|
let mut $name = $name.unborrow();
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,8 +94,11 @@ macro_rules! unsafe_impl_unborrow {
|
|||||||
unsafe impl $crate::Unborrow for $type {
|
unsafe impl $crate::Unborrow for $type {
|
||||||
type Target = $type;
|
type Target = $type;
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn unborrow(self) -> Self::Target {
|
fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
|
||||||
self
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
$crate::Unborrowed::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,45 @@
|
|||||||
|
use core::marker::PhantomData;
|
||||||
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
/// This is essentially a `&mut T`, but it is the size of `T` not the size
|
||||||
|
/// of a pointer. This is useful if T is a zero sized type.
|
||||||
|
pub struct Unborrowed<'a, T> {
|
||||||
|
inner: T,
|
||||||
|
_lifetime: PhantomData<&'a mut T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Unborrowed<'a, T> {
|
||||||
|
pub fn new(inner: T) -> Self {
|
||||||
|
Self {
|
||||||
|
inner,
|
||||||
|
_lifetime: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn into_inner(self) -> T {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Deref for Unborrowed<'a, T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> DerefMut for Unborrowed<'a, T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unsafely unborrow an owned singleton out of a `&mut`.
|
/// Unsafely unborrow an owned singleton out of a `&mut`.
|
||||||
///
|
///
|
||||||
/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
|
/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
|
||||||
/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T.
|
/// Unborrowing an owned `T` yields an `Unborrowed<'static, T>`.
|
||||||
|
/// Unborrowing a `&'a mut T` yields an `Unborrowed<'a, T>`.
|
||||||
///
|
///
|
||||||
/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
|
/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
|
||||||
/// to store pointers in the borrowed case.
|
/// to store pointers in the borrowed case.
|
||||||
@ -15,17 +53,33 @@ pub unsafe trait Unborrow {
|
|||||||
type Target;
|
type Target;
|
||||||
|
|
||||||
/// Unborrow a value.
|
/// Unborrow a value.
|
||||||
///
|
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
||||||
/// Safety: This returns a copy of a singleton that's normally not
|
where
|
||||||
/// copiable. The returned copy must ONLY be used while the lifetime of `self` is
|
Self: 'a;
|
||||||
/// valid, as if it were accessed through `self` every time.
|
|
||||||
unsafe fn unborrow(self) -> Self::Target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
|
unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T {
|
||||||
type Target = T::Target;
|
type Target = T::Target;
|
||||||
unsafe fn unborrow(self) -> Self::Target {
|
|
||||||
T::unborrow(core::ptr::read(self))
|
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
// Safety: This returns a copy of a singleton that's normally not
|
||||||
|
// copiable. The returned copy must ONLY be used while the lifetime of `self` is
|
||||||
|
// valid, as if it were accessed through `self` every time.
|
||||||
|
T::unborrow(unsafe { core::ptr::read(self) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +92,11 @@ macro_rules! unsafe_impl_unborrow_tuples {
|
|||||||
),+
|
),+
|
||||||
{
|
{
|
||||||
type Target = ($($t),+);
|
type Target = ($($t),+);
|
||||||
unsafe fn unborrow(self) -> Self::Target {
|
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
||||||
self
|
where
|
||||||
|
Self: 'a
|
||||||
|
{
|
||||||
|
Unborrowed::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,11 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
|
|||||||
|
|
||||||
unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt {
|
unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt {
|
||||||
type Target = #name_interrupt;
|
type Target = #name_interrupt;
|
||||||
unsafe fn unborrow(self) -> #name_interrupt {
|
fn unborrow<'a>(self) -> ::embassy_hal_common::Unborrowed<'a, #name_interrupt>
|
||||||
self
|
where
|
||||||
|
Self: 'a
|
||||||
|
{
|
||||||
|
::embassy_hal_common::Unborrowed::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -147,7 +147,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
|||||||
timer.cc(0).short_compare_stop();
|
timer.cc(0).short_compare_stop();
|
||||||
|
|
||||||
let mut ppi_ch1 = Ppi::new_one_to_two(
|
let mut ppi_ch1 = Ppi::new_one_to_two(
|
||||||
ppi_ch1.degrade(),
|
//TODO: Avoid into_inner?
|
||||||
|
unsafe { ppi_ch1.into_inner() }.degrade(),
|
||||||
Event::from_reg(&r.events_rxdrdy),
|
Event::from_reg(&r.events_rxdrdy),
|
||||||
timer.task_clear(),
|
timer.task_clear(),
|
||||||
timer.task_start(),
|
timer.task_start(),
|
||||||
@ -155,14 +156,16 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
|||||||
ppi_ch1.enable();
|
ppi_ch1.enable();
|
||||||
|
|
||||||
let mut ppi_ch2 = Ppi::new_one_to_one(
|
let mut ppi_ch2 = Ppi::new_one_to_one(
|
||||||
ppi_ch2.degrade(),
|
//TODO: Avoid into_inner?
|
||||||
|
unsafe { ppi_ch2.into_inner() }.degrade(),
|
||||||
timer.cc(0).event_compare(),
|
timer.cc(0).event_compare(),
|
||||||
Task::from_reg(&r.tasks_stoprx),
|
Task::from_reg(&r.tasks_stoprx),
|
||||||
);
|
);
|
||||||
ppi_ch2.enable();
|
ppi_ch2.enable();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner {
|
//TODO: Avoid into_inner?
|
||||||
|
inner: PeripheralMutex::new(unsafe { irq.into_inner() }, &mut state.0, move || StateInner {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
timer,
|
timer,
|
||||||
_ppi_ch1: ppi_ch1,
|
_ppi_ch1: ppi_ch1,
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use core::hint::unreachable_unchecked;
|
use core::hint::unreachable_unchecked;
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
use embassy_hal_common::{unborrow, unsafe_impl_unborrow, Unborrowed};
|
||||||
|
|
||||||
use self::sealed::Pin as _;
|
use self::sealed::Pin as _;
|
||||||
use crate::pac::p0 as gpio;
|
use crate::pac::p0 as gpio;
|
||||||
@ -194,8 +193,7 @@ fn convert_pull(pull: Pull) -> PULL_A {
|
|||||||
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
|
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
|
||||||
/// mode.
|
/// mode.
|
||||||
pub struct Flex<'d, T: Pin> {
|
pub struct Flex<'d, T: Pin> {
|
||||||
pub(crate) pin: T,
|
pub(crate) pin: Unborrowed<'d, T>,
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> Flex<'d, T> {
|
impl<'d, T: Pin> Flex<'d, T> {
|
||||||
@ -207,10 +205,7 @@ impl<'d, T: Pin> Flex<'d, T> {
|
|||||||
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
|
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
|
||||||
unborrow!(pin);
|
unborrow!(pin);
|
||||||
// Pin will be in disconnected state.
|
// Pin will be in disconnected state.
|
||||||
Self {
|
Self { pin }
|
||||||
pin,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Put the pin into input mode.
|
/// Put the pin into input mode.
|
||||||
@ -421,6 +416,20 @@ impl AnyPin {
|
|||||||
pub unsafe fn steal(pin_port: u8) -> Self {
|
pub unsafe fn steal(pin_port: u8) -> Self {
|
||||||
Self { pin_port }
|
Self { pin_port }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unborrow_and_degrade<'a>(pin: impl Unborrow<Target = impl Pin + 'a> + 'a) -> Unborrowed<'a, Self> {
|
||||||
|
Unborrowed::new(AnyPin {
|
||||||
|
pin_port: pin.unborrow().pin_port(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unborrow_and_degrade {
|
||||||
|
($($name:ident),*) => {
|
||||||
|
$(
|
||||||
|
let $name = $crate::gpio::AnyPin::unborrow_and_degrade($name);
|
||||||
|
)*
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_impl_unborrow!(AnyPin);
|
unsafe_impl_unborrow!(AnyPin);
|
||||||
@ -438,10 +447,13 @@ pub(crate) trait PselBits {
|
|||||||
fn psel_bits(&self) -> u32;
|
fn psel_bits(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PselBits for Option<AnyPin> {
|
impl<'a, P: Pin> PselBits for Option<Unborrowed<'a, P>> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn psel_bits(&self) -> u32 {
|
fn psel_bits(&self) -> u32 {
|
||||||
self.as_ref().map_or(1u32 << 31, Pin::psel_bits)
|
match self {
|
||||||
|
Some(pin) => pin.psel_bits(),
|
||||||
|
None => 1u32 << 31,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@
|
|||||||
//! many tasks and events, but any single task or event can only be coupled with one channel.
|
//! many tasks and events, but any single task or event can only be coupled with one channel.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
use embassy_hal_common::unsafe_impl_unborrow;
|
use embassy_hal_common::{unsafe_impl_unborrow, Unborrowed};
|
||||||
|
|
||||||
use crate::{peripherals, Unborrow};
|
use crate::{peripherals, Unborrow};
|
||||||
|
|
||||||
@ -28,12 +27,11 @@ mod dppi;
|
|||||||
mod ppi;
|
mod ppi;
|
||||||
|
|
||||||
pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
|
pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
|
||||||
ch: C,
|
ch: Unborrowed<'d, C>,
|
||||||
#[cfg(feature = "_dppi")]
|
#[cfg(feature = "_dppi")]
|
||||||
events: [Event; EVENT_COUNT],
|
events: [Event; EVENT_COUNT],
|
||||||
#[cfg(feature = "_dppi")]
|
#[cfg(feature = "_dppi")]
|
||||||
tasks: [Task; TASK_COUNT],
|
tasks: [Task; TASK_COUNT],
|
||||||
phantom: PhantomData<&'d mut C>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
|
const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
|
|
||||||
use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
|
use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
|
||||||
@ -29,10 +27,7 @@ impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
|
|||||||
let n = ch.number();
|
let n = ch.number();
|
||||||
r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
||||||
|
|
||||||
Self {
|
Self { ch }
|
||||||
ch,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,10 +40,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
|||||||
r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
|
r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
|
||||||
r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
||||||
|
|
||||||
Self {
|
Self { ch }
|
||||||
ch,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,10 +55,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
|
|||||||
r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) });
|
r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) });
|
||||||
r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) });
|
r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) });
|
||||||
|
|
||||||
Self {
|
Self { ch }
|
||||||
ch,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
|
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::Unborrowed;
|
||||||
|
|
||||||
use crate::gpio::sealed::Pin as _;
|
use crate::gpio::sealed::Pin as _;
|
||||||
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
|
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
|
||||||
@ -17,20 +17,20 @@ use crate::{pac, Unborrow};
|
|||||||
pub struct SimplePwm<'d, T: Instance> {
|
pub struct SimplePwm<'d, T: Instance> {
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
duty: [u16; 4],
|
duty: [u16; 4],
|
||||||
ch0: Option<AnyPin>,
|
ch0: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch1: Option<AnyPin>,
|
ch1: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch2: Option<AnyPin>,
|
ch2: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch3: Option<AnyPin>,
|
ch3: Option<Unborrowed<'d, AnyPin>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
ch0: Option<AnyPin>,
|
ch0: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch1: Option<AnyPin>,
|
ch1: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch2: Option<AnyPin>,
|
ch2: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch3: Option<AnyPin>,
|
ch3: Option<Unborrowed<'d, AnyPin>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@ -55,8 +55,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
|||||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
unborrow!(ch0);
|
unborrow_and_degrade!(ch0);
|
||||||
Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config)
|
Self::new_inner(pwm, Some(ch0), None, None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 2-channel PWM
|
/// Create a new 2-channel PWM
|
||||||
@ -67,8 +67,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
|||||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
unborrow!(ch0, ch1);
|
unborrow_and_degrade!(ch0, ch1);
|
||||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None, config)
|
Self::new_inner(pwm, Some(ch0), Some(ch1), None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 3-channel PWM
|
/// Create a new 3-channel PWM
|
||||||
@ -80,15 +80,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
|||||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
unborrow!(ch0, ch1, ch2);
|
unborrow_and_degrade!(ch0, ch1, ch2);
|
||||||
Self::new_inner(
|
Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None, config)
|
||||||
pwm,
|
|
||||||
Some(ch0.degrade()),
|
|
||||||
Some(ch1.degrade()),
|
|
||||||
Some(ch2.degrade()),
|
|
||||||
None,
|
|
||||||
config,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 4-channel PWM
|
/// Create a new 4-channel PWM
|
||||||
@ -101,23 +94,16 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
|||||||
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
unborrow!(ch0, ch1, ch2, ch3);
|
unborrow_and_degrade!(ch0, ch1, ch2, ch3);
|
||||||
Self::new_inner(
|
Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3), config)
|
||||||
pwm,
|
|
||||||
Some(ch0.degrade()),
|
|
||||||
Some(ch1.degrade()),
|
|
||||||
Some(ch2.degrade()),
|
|
||||||
Some(ch3.degrade()),
|
|
||||||
config,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_pwm: impl Unborrow<Target = T> + 'd,
|
_pwm: impl Unborrow<Target = T> + 'd,
|
||||||
ch0: Option<AnyPin>,
|
ch0: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch1: Option<AnyPin>,
|
ch1: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch2: Option<AnyPin>,
|
ch2: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch3: Option<AnyPin>,
|
ch3: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
@ -574,8 +560,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
|
|||||||
/// Create a new 1-channel PWM
|
/// Create a new 1-channel PWM
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self {
|
pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self {
|
||||||
unborrow!(ch0);
|
unsafe {
|
||||||
Self::new_inner(pwm, Some(ch0.degrade()), None, None, None)
|
unborrow_and_degrade!(ch0);
|
||||||
|
Self::new_inner(pwm, Some(ch0), None, None, None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 2-channel PWM
|
/// Create a new 2-channel PWM
|
||||||
@ -585,8 +573,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
|
|||||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(ch0, ch1);
|
unborrow_and_degrade!(ch0, ch1);
|
||||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None)
|
Self::new_inner(pwm, Some(ch0), Some(ch1), None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 3-channel PWM
|
/// Create a new 3-channel PWM
|
||||||
@ -597,8 +585,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
|
|||||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(ch0, ch1, ch2);
|
unsafe {
|
||||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), Some(ch2.degrade()), None)
|
unborrow_and_degrade!(ch0, ch1, ch2);
|
||||||
|
Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 4-channel PWM
|
/// Create a new 4-channel PWM
|
||||||
@ -610,22 +600,18 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
|
|||||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(ch0, ch1, ch2, ch3);
|
unsafe {
|
||||||
Self::new_inner(
|
unborrow_and_degrade!(ch0, ch1, ch2, ch3);
|
||||||
pwm,
|
Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3))
|
||||||
Some(ch0.degrade()),
|
}
|
||||||
Some(ch1.degrade()),
|
|
||||||
Some(ch2.degrade()),
|
|
||||||
Some(ch3.degrade()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_pwm: impl Unborrow<Target = T> + 'd,
|
_pwm: impl Unborrow<Target = T> + 'd,
|
||||||
ch0: Option<AnyPin>,
|
ch0: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch1: Option<AnyPin>,
|
ch1: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch2: Option<AnyPin>,
|
ch2: Option<Unborrowed<'d, AnyPin>>,
|
||||||
ch3: Option<AnyPin>,
|
ch3: Option<Unborrowed<'d, AnyPin>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use core::marker::PhantomData;
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy::waitqueue::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
use crate::gpio::sealed::Pin as _;
|
use crate::gpio::sealed::Pin as _;
|
||||||
@ -49,8 +49,8 @@ impl<'d> Qdec<'d> {
|
|||||||
b: impl Unborrow<Target = impl GpioPin> + 'd,
|
b: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(a, b);
|
unborrow_and_degrade!(a, b);
|
||||||
Self::new_inner(qdec, irq, a.degrade(), b.degrade(), None, config)
|
Self::new_inner(qdec, irq, a, b, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_led(
|
pub fn new_with_led(
|
||||||
@ -61,16 +61,16 @@ impl<'d> Qdec<'d> {
|
|||||||
led: impl Unborrow<Target = impl GpioPin> + 'd,
|
led: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(a, b, led);
|
unborrow_and_degrade!(a, b, led);
|
||||||
Self::new_inner(qdec, irq, a.degrade(), b.degrade(), Some(led.degrade()), config)
|
Self::new_inner(qdec, irq, a, b, Some(led), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_t: impl Unborrow<Target = QDEC> + 'd,
|
_t: impl Unborrow<Target = QDEC> + 'd,
|
||||||
irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
|
irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
|
||||||
a: AnyPin,
|
a: Unborrowed<'d, AnyPin>,
|
||||||
b: AnyPin,
|
b: Unborrowed<'d, AnyPin>,
|
||||||
led: Option<AnyPin>,
|
led: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_hal_common::drop::DropBomb;
|
use embassy_hal_common::drop::DropBomb;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
use crate::gpio::sealed::Pin as _;
|
use crate::gpio::sealed::Pin as _;
|
||||||
@ -63,9 +62,8 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
|
pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
|
||||||
irq: T::Interrupt,
|
irq: Unborrowed<'d, T::Interrupt>,
|
||||||
dpm_enabled: bool,
|
dpm_enabled: bool,
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
||||||
@ -84,12 +82,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
let sck = sck.degrade();
|
unborrow_and_degrade!(sck, csn, io0, io1, io2, io3);
|
||||||
let csn = csn.degrade();
|
|
||||||
let io0 = io0.degrade();
|
|
||||||
let io1 = io1.degrade();
|
|
||||||
let io2 = io2.degrade();
|
|
||||||
let io3 = io3.degrade();
|
|
||||||
|
|
||||||
for pin in [&sck, &csn, &io0, &io1, &io2, &io3] {
|
for pin in [&sck, &csn, &io0, &io1, &io2, &io3] {
|
||||||
pin.set_high();
|
pin.set_high();
|
||||||
@ -143,7 +136,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
let mut res = Self {
|
let mut res = Self {
|
||||||
dpm_enabled: config.deep_power_down.is_some(),
|
dpm_enabled: config.deep_power_down.is_some(),
|
||||||
irq,
|
irq,
|
||||||
phantom: PhantomData,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
r.events_ready.reset();
|
r.events_ready.reset();
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::sync::atomic::{AtomicPtr, Ordering};
|
use core::sync::atomic::{AtomicPtr, Ordering};
|
||||||
use core::task::Poll;
|
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::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
use crate::interrupt::InterruptExt;
|
use crate::interrupt::InterruptExt;
|
||||||
@ -34,8 +33,7 @@ struct State {
|
|||||||
///
|
///
|
||||||
/// It has a non-blocking API, and a blocking api through `rand`.
|
/// It has a non-blocking API, and a blocking api through `rand`.
|
||||||
pub struct Rng<'d> {
|
pub struct Rng<'d> {
|
||||||
irq: interrupt::RNG,
|
irq: Unborrowed<'d, interrupt::RNG>,
|
||||||
phantom: PhantomData<(&'d mut RNG, &'d mut interrupt::RNG)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Rng<'d> {
|
impl<'d> Rng<'d> {
|
||||||
@ -48,10 +46,7 @@ impl<'d> Rng<'d> {
|
|||||||
pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self {
|
pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
|
|
||||||
let this = Self {
|
let this = Self { irq };
|
||||||
irq,
|
|
||||||
phantom: PhantomData,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.stop();
|
this.stop();
|
||||||
this.disable_irq();
|
this.disable_irq();
|
||||||
|
@ -5,7 +5,7 @@ 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::unborrow;
|
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||||
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};
|
||||||
@ -77,12 +77,7 @@ pub struct ChannelConfig<'d> {
|
|||||||
/// internal voltage.
|
/// internal voltage.
|
||||||
pub struct VddInput;
|
pub struct VddInput;
|
||||||
|
|
||||||
unsafe impl Unborrow for VddInput {
|
unsafe_impl_unborrow!(VddInput);
|
||||||
type Target = VddInput;
|
|
||||||
unsafe fn unborrow(self) -> Self::Target {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sealed::Input for VddInput {
|
impl sealed::Input for VddInput {
|
||||||
#[cfg(not(feature = "_nrf9160"))]
|
#[cfg(not(feature = "_nrf9160"))]
|
||||||
@ -102,12 +97,7 @@ impl Input for VddInput {}
|
|||||||
pub struct VddhDiv5Input;
|
pub struct VddhDiv5Input;
|
||||||
|
|
||||||
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
||||||
unsafe impl Unborrow for VddhDiv5Input {
|
unsafe_impl_unborrow!(VddhDiv5Input);
|
||||||
type Target = VddhDiv5Input;
|
|
||||||
unsafe fn unborrow(self) -> Self::Target {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
||||||
impl sealed::Input for VddhDiv5Input {
|
impl sealed::Input for VddhDiv5Input {
|
||||||
|
@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_embedded_hal::SetConfig;
|
use embassy_embedded_hal::SetConfig;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
||||||
@ -60,15 +60,8 @@ impl<'d, T: Instance> Spim<'d, T> {
|
|||||||
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(sck, miso, mosi);
|
unborrow_and_degrade!(sck, miso, mosi);
|
||||||
Self::new_inner(
|
Self::new_inner(spim, irq, sck, Some(miso), Some(mosi), config)
|
||||||
spim,
|
|
||||||
irq,
|
|
||||||
sck.degrade(),
|
|
||||||
Some(miso.degrade()),
|
|
||||||
Some(mosi.degrade()),
|
|
||||||
config,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_txonly(
|
pub fn new_txonly(
|
||||||
@ -78,8 +71,8 @@ impl<'d, T: Instance> Spim<'d, T> {
|
|||||||
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(sck, mosi);
|
unborrow_and_degrade!(sck, mosi);
|
||||||
Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config)
|
Self::new_inner(spim, irq, sck, None, Some(mosi), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_rxonly(
|
pub fn new_rxonly(
|
||||||
@ -89,16 +82,16 @@ impl<'d, T: Instance> Spim<'d, T> {
|
|||||||
miso: impl Unborrow<Target = impl GpioPin> + 'd,
|
miso: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(sck, miso);
|
unborrow_and_degrade!(sck, miso);
|
||||||
Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config)
|
Self::new_inner(spim, irq, sck, Some(miso), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_spim: impl Unborrow<Target = T> + 'd,
|
_spim: impl Unborrow<Target = T> + 'd,
|
||||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||||
sck: AnyPin,
|
sck: Unborrowed<'d, AnyPin>,
|
||||||
miso: Option<AnyPin>,
|
miso: Option<Unborrowed<'d, AnyPin>>,
|
||||||
mosi: Option<AnyPin>,
|
mosi: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
//! Temperature sensor interface.
|
//! Temperature sensor interface.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
use core::task::Poll;
|
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::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
use fixed::types::I30F2;
|
use fixed::types::I30F2;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
@ -15,8 +14,7 @@ use crate::{interrupt, pac, Unborrow};
|
|||||||
|
|
||||||
/// Integrated temperature sensor.
|
/// Integrated temperature sensor.
|
||||||
pub struct Temp<'d> {
|
pub struct Temp<'d> {
|
||||||
_temp: PhantomData<&'d TEMP>,
|
_irq: Unborrowed<'d, interrupt::TEMP>,
|
||||||
_irq: interrupt::TEMP,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
@ -33,10 +31,7 @@ impl<'d> Temp<'d> {
|
|||||||
WAKER.wake();
|
WAKER.wake();
|
||||||
});
|
});
|
||||||
irq.enable();
|
irq.enable();
|
||||||
Self {
|
Self { _irq: irq }
|
||||||
_temp: PhantomData,
|
|
||||||
_irq: irq,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an asynchronous temperature measurement. The returned future
|
/// Perform an asynchronous temperature measurement. The returned future
|
||||||
|
@ -18,7 +18,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_hal_common::drop::OnDrop;
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::{unborrow, Unborrowed};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use pac::uarte0::RegisterBlock;
|
use pac::uarte0::RegisterBlock;
|
||||||
// Re-export SVD variants to allow user to directly set values.
|
// Re-export SVD variants to allow user to directly set values.
|
||||||
@ -89,8 +89,8 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd, txd);
|
unborrow_and_degrade!(rxd, txd);
|
||||||
Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config)
|
Self::new_inner(uarte, irq, rxd, txd, None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
||||||
@ -103,25 +103,17 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd, txd, cts, rts);
|
unborrow_and_degrade!(rxd, txd, cts, rts);
|
||||||
Self::new_inner(
|
Self::new_inner(uarte, irq, rxd, txd, Some(cts), Some(rts), config)
|
||||||
uarte,
|
|
||||||
irq,
|
|
||||||
rxd.degrade(),
|
|
||||||
txd.degrade(),
|
|
||||||
Some(cts.degrade()),
|
|
||||||
Some(rts.degrade()),
|
|
||||||
config,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_uarte: impl Unborrow<Target = T> + 'd,
|
_uarte: impl Unborrow<Target = T> + 'd,
|
||||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||||
rxd: AnyPin,
|
rxd: Unborrowed<'d, AnyPin>,
|
||||||
txd: AnyPin,
|
txd: Unborrowed<'d, AnyPin>,
|
||||||
cts: Option<AnyPin>,
|
cts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
rts: Option<AnyPin>,
|
rts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
@ -250,8 +242,8 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
|||||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(txd);
|
unborrow_and_degrade!(txd);
|
||||||
Self::new_inner(uarte, irq, txd.degrade(), None, config)
|
Self::new_inner(uarte, irq, txd, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
|
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
|
||||||
@ -262,15 +254,15 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
|||||||
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(txd, cts);
|
unborrow_and_degrade!(txd, cts);
|
||||||
Self::new_inner(uarte, irq, txd.degrade(), Some(cts.degrade()), config)
|
Self::new_inner(uarte, irq, txd, Some(cts), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_uarte: impl Unborrow<Target = T> + 'd,
|
_uarte: impl Unborrow<Target = T> + 'd,
|
||||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||||
txd: AnyPin,
|
txd: Unborrowed<'d, AnyPin>,
|
||||||
cts: Option<AnyPin>,
|
cts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
@ -442,8 +434,8 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
|||||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd);
|
unborrow_and_degrade!(rxd);
|
||||||
Self::new_inner(uarte, irq, rxd.degrade(), None, config)
|
Self::new_inner(uarte, irq, rxd, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
|
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
|
||||||
@ -454,15 +446,15 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
|||||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd, rts);
|
unborrow_and_degrade!(rxd, rts);
|
||||||
Self::new_inner(uarte, irq, rxd.degrade(), Some(rts.degrade()), config)
|
Self::new_inner(uarte, irq, rxd, Some(rts), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_uarte: impl Unborrow<Target = T> + 'd,
|
_uarte: impl Unborrow<Target = T> + 'd,
|
||||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||||
rxd: AnyPin,
|
rxd: Unborrowed<'d, AnyPin>,
|
||||||
rts: Option<AnyPin>,
|
rts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(irq);
|
unborrow!(irq);
|
||||||
@ -685,19 +677,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd, txd);
|
unborrow_and_degrade!(rxd, txd);
|
||||||
Self::new_inner(
|
Self::new_inner(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, None, None, config)
|
||||||
uarte,
|
|
||||||
timer,
|
|
||||||
ppi_ch1,
|
|
||||||
ppi_ch2,
|
|
||||||
irq,
|
|
||||||
rxd.degrade(),
|
|
||||||
txd.degrade(),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
config,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
||||||
@ -713,17 +694,17 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
unborrow!(rxd, txd, cts, rts);
|
unborrow_and_degrade!(rxd, txd, cts, rts);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
uarte,
|
uarte,
|
||||||
timer,
|
timer,
|
||||||
ppi_ch1,
|
ppi_ch1,
|
||||||
ppi_ch2,
|
ppi_ch2,
|
||||||
irq,
|
irq,
|
||||||
rxd.degrade(),
|
rxd,
|
||||||
txd.degrade(),
|
txd,
|
||||||
Some(cts.degrade()),
|
Some(cts),
|
||||||
Some(rts.degrade()),
|
Some(rts),
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -734,10 +715,10 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||||
rxd: AnyPin,
|
rxd: Unborrowed<'d, AnyPin>,
|
||||||
txd: AnyPin,
|
txd: Unborrowed<'d, AnyPin>,
|
||||||
cts: Option<AnyPin>,
|
cts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
rts: Option<AnyPin>,
|
rts: Option<Unborrowed<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let baudrate = config.baudrate;
|
let baudrate = config.baudrate;
|
||||||
@ -763,7 +744,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||||||
timer.cc(0).short_compare_stop();
|
timer.cc(0).short_compare_stop();
|
||||||
|
|
||||||
let mut ppi_ch1 = Ppi::new_one_to_two(
|
let mut ppi_ch1 = Ppi::new_one_to_two(
|
||||||
ppi_ch1.degrade(),
|
unsafe { ppi_ch1.into_inner() }.degrade(),
|
||||||
Event::from_reg(&r.events_rxdrdy),
|
Event::from_reg(&r.events_rxdrdy),
|
||||||
timer.task_clear(),
|
timer.task_clear(),
|
||||||
timer.task_start(),
|
timer.task_start(),
|
||||||
@ -771,7 +752,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
|||||||
ppi_ch1.enable();
|
ppi_ch1.enable();
|
||||||
|
|
||||||
let mut ppi_ch2 = Ppi::new_one_to_one(
|
let mut ppi_ch2 = Ppi::new_one_to_one(
|
||||||
ppi_ch2.degrade(),
|
unsafe { ppi_ch2.into_inner() }.degrade(),
|
||||||
timer.cc(0).event_compare(),
|
timer.cc(0).event_compare(),
|
||||||
Task::from_reg(&r.tasks_stoprx),
|
Task::from_reg(&r.tasks_stoprx),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user