mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 23:02:30 +00:00
Merge #842
842: WIP: Make unborrow safe to use r=Dirbaio a=GrantM11235 The basic idea is that `Unborrow::unborrow` is now safe to call and returns an `Unborrowed<'a, T>` which impls `Deref` and `DerefMut` ```rust /// 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>, } ``` ## Todo - [x] Update other crates - [x] embassy-cortex-m - [x] embassy-hal-common - [x] embassy-lora - [x] embassy-nrf - [x] embassy-rp - [x] embassy-stm32 - [x] Remove usage of the unsafe `into_inner` method if possible - [x] Review and amend docs for `Unborrow` and `Unborrowed` Co-authored-by: Grant Miller <GrantM11235@gmail.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
commit
e61e36a815
@ -3,7 +3,7 @@ use core::{mem, ptr};
|
||||
|
||||
use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embassy_hal_common::Unborrow;
|
||||
use embassy_hal_common::Peripheral;
|
||||
pub use embassy_macros::cortex_m_interrupt_take as take;
|
||||
|
||||
/// Implementation detail, do not use outside embassy crates.
|
||||
@ -32,7 +32,7 @@ unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
|
||||
|
||||
/// Represents an interrupt type that can be configured by embassy to handle
|
||||
/// interrupts.
|
||||
pub unsafe trait Interrupt: Unborrow<Target = Self> {
|
||||
pub unsafe trait Interrupt: Peripheral<P = Self> {
|
||||
/// Return the NVIC interrupt number for this interrupt.
|
||||
fn number(&self) -> u16;
|
||||
/// Steal an instance of this interrupt
|
||||
|
@ -1,9 +1,9 @@
|
||||
//! Peripheral interrupt handling specific to cortex-m devices.
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use cortex_m::peripheral::scb::VectActive;
|
||||
use cortex_m::peripheral::{NVIC, SCB};
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
|
||||
use crate::interrupt::{Interrupt, InterruptExt, Priority};
|
||||
|
||||
@ -33,8 +33,7 @@ impl<S> StateStorage<S> {
|
||||
/// a safe way.
|
||||
pub struct PeripheralMutex<'a, S: PeripheralState> {
|
||||
state: *mut S,
|
||||
_phantom: PhantomData<&'a mut S>,
|
||||
irq: S::Interrupt,
|
||||
irq: PeripheralRef<'a, S::Interrupt>,
|
||||
}
|
||||
|
||||
/// Whether `irq` can be preempted by the current interrupt.
|
||||
@ -62,8 +61,14 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
|
||||
/// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state.
|
||||
///
|
||||
/// Registers `on_interrupt` as the `irq`'s handler, and enables it.
|
||||
pub fn new(irq: S::Interrupt, storage: &'a mut StateStorage<S>, init: impl FnOnce() -> S) -> Self {
|
||||
if can_be_preempted(&irq) {
|
||||
pub fn new(
|
||||
irq: impl Peripheral<P = S::Interrupt> + 'a,
|
||||
storage: &'a mut StateStorage<S>,
|
||||
init: impl FnOnce() -> S,
|
||||
) -> Self {
|
||||
into_ref!(irq);
|
||||
|
||||
if can_be_preempted(&*irq) {
|
||||
panic!(
|
||||
"`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"
|
||||
);
|
||||
@ -88,11 +93,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
|
||||
irq.set_handler_context(state_ptr as *mut ());
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
irq,
|
||||
state: state_ptr,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
Self { irq, state: state_ptr }
|
||||
}
|
||||
|
||||
/// Access the peripheral state ensuring interrupts are disabled so that the state can be
|
||||
|
@ -6,10 +6,10 @@ pub(crate) mod fmt;
|
||||
|
||||
pub mod drop;
|
||||
mod macros;
|
||||
mod peripheral;
|
||||
pub mod ratio;
|
||||
pub mod ring_buffer;
|
||||
mod unborrow;
|
||||
pub use unborrow::Unborrow;
|
||||
pub use peripheral::{Peripheral, PeripheralRef};
|
||||
|
||||
/// Low power blocking wait loop using WFE/SEV.
|
||||
pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) {
|
||||
|
@ -21,13 +21,7 @@ macro_rules! peripherals {
|
||||
}
|
||||
|
||||
$(#[$cfg])?
|
||||
unsafe impl $crate::Unborrow for $name {
|
||||
type Target = $name;
|
||||
#[inline]
|
||||
unsafe fn unborrow(self) -> $name {
|
||||
self
|
||||
}
|
||||
}
|
||||
$crate::impl_peripheral!($name);
|
||||
)*
|
||||
}
|
||||
|
||||
@ -77,22 +71,23 @@ macro_rules! peripherals {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unborrow {
|
||||
macro_rules! into_ref {
|
||||
($($name:ident),*) => {
|
||||
$(
|
||||
let mut $name = unsafe { $name.unborrow() };
|
||||
let mut $name = $name.into_ref();
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unsafe_impl_unborrow {
|
||||
macro_rules! impl_peripheral {
|
||||
($type:ident) => {
|
||||
unsafe impl $crate::Unborrow for $type {
|
||||
type Target = $type;
|
||||
impl $crate::Peripheral for $type {
|
||||
type P = $type;
|
||||
|
||||
#[inline]
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
$type { ..*self }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
173
embassy-hal-common/src/peripheral.rs
Normal file
173
embassy-hal-common/src/peripheral.rs
Normal file
@ -0,0 +1,173 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
/// An exclusive reference to a peripheral.
|
||||
///
|
||||
/// This is functionally the same as a `&'a mut T`. The reason for having a
|
||||
/// dedicated struct is memory efficiency:
|
||||
///
|
||||
/// Peripheral singletons are typically either zero-sized (for concrete peripehrals
|
||||
/// like `PA9` or `Spi4`) or very small (for example `AnyPin` which is 1 byte).
|
||||
/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized.
|
||||
/// PeripheralRef stores a copy of `T` instead, so it's the same size.
|
||||
///
|
||||
/// 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 PeripheralRef<'a, T> {
|
||||
inner: T,
|
||||
_lifetime: PhantomData<&'a mut T>,
|
||||
}
|
||||
|
||||
impl<'a, T> PeripheralRef<'a, T> {
|
||||
#[inline]
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
_lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// `Into` impl to convert from `T` to `U`.
|
||||
///
|
||||
/// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`.
|
||||
#[inline]
|
||||
pub fn map_into<U>(self) -> PeripheralRef<'a, U>
|
||||
where
|
||||
T: Into<U>,
|
||||
{
|
||||
PeripheralRef {
|
||||
inner: self.inner.into(),
|
||||
_lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for PeripheralRef<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for PeripheralRef<'a, T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for any type that can be used as a peripheral of type `P`.
|
||||
///
|
||||
/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`),
|
||||
/// or borrowed peripherals (e.g. `&mut TWISPI0`).
|
||||
///
|
||||
/// For example, if you have a driver with a constructor like this:
|
||||
///
|
||||
/// ```ignore
|
||||
/// impl<'d, T: Instance> Twim<'d, T> {
|
||||
/// pub fn new(
|
||||
/// 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 { .. }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`):
|
||||
///
|
||||
/// ```ignore
|
||||
/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
|
||||
/// ```
|
||||
///
|
||||
/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long
|
||||
/// as the borrows last:
|
||||
///
|
||||
/// ```ignore
|
||||
/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
|
||||
/// ```
|
||||
///
|
||||
/// # Implementation details, for HAL authors
|
||||
///
|
||||
/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral<P = ..>` in
|
||||
/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`,
|
||||
/// and storing that in the driver struct.
|
||||
///
|
||||
/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
|
||||
/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
|
||||
pub trait Peripheral: Sized {
|
||||
/// Peripheral singleton type
|
||||
type P;
|
||||
|
||||
/// 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 `into_ref()` instead. It returns a
|
||||
/// `PeripheralRef`, which allows the borrow checker to enforce this at compile time.
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P;
|
||||
|
||||
/// Convert a value into a `PeripheralRef`.
|
||||
///
|
||||
/// When called on an owned `T`, yields a `PeripheralRef<'static, T>`.
|
||||
/// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`.
|
||||
#[inline]
|
||||
fn into_ref<'a>(mut self) -> PeripheralRef<'a, Self::P>
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
PeripheralRef::new(unsafe { self.clone_unchecked() })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, T: DerefMut> Peripheral for T
|
||||
where
|
||||
T::Target: Peripheral,
|
||||
{
|
||||
type P = <T::Target as Peripheral>::P;
|
||||
|
||||
#[inline]
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
self.deref_mut().clone_unchecked()
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/// Unsafely unborrow an owned singleton out of a `&mut`.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
|
||||
/// to store pointers in the borrowed case.
|
||||
///
|
||||
/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
|
||||
/// immediate UB when copied, and must not cause UB when copies are later used, provided they
|
||||
/// are only used according the [`Self::unborrow`] safety contract.
|
||||
///
|
||||
pub unsafe trait Unborrow {
|
||||
/// Unborrow result type
|
||||
type Target;
|
||||
|
||||
/// Unborrow a value.
|
||||
///
|
||||
/// 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.
|
||||
unsafe fn unborrow(self) -> Self::Target;
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
|
||||
type Target = T::Target;
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
T::unborrow(core::ptr::read(self))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! unsafe_impl_unborrow_tuples {
|
||||
($($t:ident),+) => {
|
||||
unsafe impl<$($t),+> Unborrow for ($($t),+)
|
||||
where
|
||||
$(
|
||||
$t: Unborrow<Target = $t>
|
||||
),+
|
||||
{
|
||||
type Target = ($($t),+);
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
unsafe_impl_unborrow_tuples!(A, B);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
|
||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
|
@ -3,7 +3,7 @@ use core::future::Future;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use embassy::channel::signal::Signal;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_stm32::dma::NoDma;
|
||||
use embassy_stm32::gpio::{AnyPin, Output};
|
||||
use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO};
|
||||
@ -12,7 +12,7 @@ use embassy_stm32::subghz::{
|
||||
LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk,
|
||||
Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
|
||||
};
|
||||
use embassy_stm32::Unborrow;
|
||||
use embassy_stm32::Peripheral;
|
||||
use lorawan_device::async_device::radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig};
|
||||
use lorawan_device::async_device::Timings;
|
||||
|
||||
@ -30,37 +30,37 @@ pub struct RadioError;
|
||||
|
||||
static IRQ: Signal<(Status, u16)> = Signal::new();
|
||||
|
||||
struct StateInner<'a> {
|
||||
radio: SubGhz<'a, NoDma, NoDma>,
|
||||
switch: RadioSwitch<'a>,
|
||||
struct StateInner<'d> {
|
||||
radio: SubGhz<'d, NoDma, NoDma>,
|
||||
switch: RadioSwitch<'d>,
|
||||
}
|
||||
|
||||
/// External state storage for the radio state
|
||||
pub struct SubGhzState<'a>(MaybeUninit<StateInner<'a>>);
|
||||
impl<'a> SubGhzState<'a> {
|
||||
impl<'d> SubGhzState<'d> {
|
||||
pub const fn new() -> Self {
|
||||
Self(MaybeUninit::uninit())
|
||||
}
|
||||
}
|
||||
|
||||
/// The radio peripheral keeping the radio state and owning the radio IRQ.
|
||||
pub struct SubGhzRadio<'a> {
|
||||
state: *mut StateInner<'a>,
|
||||
_irq: SUBGHZ_RADIO,
|
||||
pub struct SubGhzRadio<'d> {
|
||||
state: *mut StateInner<'d>,
|
||||
_irq: PeripheralRef<'d, SUBGHZ_RADIO>,
|
||||
}
|
||||
|
||||
impl<'a> SubGhzRadio<'a> {
|
||||
impl<'d> SubGhzRadio<'d> {
|
||||
/// Create a new instance of a SubGhz radio for LoRaWAN.
|
||||
///
|
||||
/// # Safety
|
||||
/// Do not leak self or futures
|
||||
pub unsafe fn new(
|
||||
state: &'a mut SubGhzState<'a>,
|
||||
radio: SubGhz<'a, NoDma, NoDma>,
|
||||
switch: RadioSwitch<'a>,
|
||||
irq: impl Unborrow<Target = SUBGHZ_RADIO>,
|
||||
state: &'d mut SubGhzState<'d>,
|
||||
radio: SubGhz<'d, NoDma, NoDma>,
|
||||
switch: RadioSwitch<'d>,
|
||||
irq: impl Peripheral<P = SUBGHZ_RADIO> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(irq);
|
||||
into_ref!(irq);
|
||||
|
||||
let mut inner = StateInner { radio, switch };
|
||||
inner.radio.reset();
|
||||
@ -73,7 +73,7 @@ impl<'a> SubGhzRadio<'a> {
|
||||
// This is safe because we only get interrupts when configured for, so
|
||||
// the radio will be awaiting on the signal at this point. If not, the ISR will
|
||||
// anyway only adjust the state in the IRQ signal state.
|
||||
let state = &mut *(p as *mut StateInner<'a>);
|
||||
let state = &mut *(p as *mut StateInner<'d>);
|
||||
state.on_interrupt();
|
||||
});
|
||||
irq.set_handler_context(state_ptr as *mut ());
|
||||
@ -86,7 +86,7 @@ impl<'a> SubGhzRadio<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StateInner<'a> {
|
||||
impl<'d> StateInner<'d> {
|
||||
/// Configure radio settings in preparation for TX or RX
|
||||
pub(crate) fn configure(&mut self) -> Result<(), RadioError> {
|
||||
trace!("Configuring STM32WL SUBGHZ radio");
|
||||
@ -272,13 +272,13 @@ impl PhyRxTx for SubGhzRadio<'static> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<embassy_stm32::spi::Error> for RadioError {
|
||||
impl From<embassy_stm32::spi::Error> for RadioError {
|
||||
fn from(_: embassy_stm32::spi::Error) -> Self {
|
||||
RadioError
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Timings for SubGhzRadio<'a> {
|
||||
impl<'d> Timings for SubGhzRadio<'d> {
|
||||
fn get_rx_window_offset_ms(&self) -> i32 {
|
||||
-200
|
||||
}
|
||||
@ -288,14 +288,14 @@ impl<'a> Timings for SubGhzRadio<'a> {
|
||||
}
|
||||
|
||||
/// Represents the radio switch found on STM32WL based boards, used to control the radio for transmission or reception.
|
||||
pub struct RadioSwitch<'a> {
|
||||
ctrl1: Output<'a, AnyPin>,
|
||||
ctrl2: Output<'a, AnyPin>,
|
||||
ctrl3: Output<'a, AnyPin>,
|
||||
pub struct RadioSwitch<'d> {
|
||||
ctrl1: Output<'d, AnyPin>,
|
||||
ctrl2: Output<'d, AnyPin>,
|
||||
ctrl3: Output<'d, AnyPin>,
|
||||
}
|
||||
|
||||
impl<'a> RadioSwitch<'a> {
|
||||
pub fn new(ctrl1: Output<'a, AnyPin>, ctrl2: Output<'a, AnyPin>, ctrl3: Output<'a, AnyPin>) -> Self {
|
||||
impl<'d> RadioSwitch<'d> {
|
||||
pub fn new(ctrl1: Output<'d, AnyPin>, ctrl2: Output<'d, AnyPin>, ctrl3: Output<'d, AnyPin>) -> Self {
|
||||
Self { ctrl1, ctrl2, ctrl3 }
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,7 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt {
|
||||
type Target = #name_interrupt;
|
||||
unsafe fn unborrow(self) -> #name_interrupt {
|
||||
self
|
||||
}
|
||||
}
|
||||
::embassy_hal_common::impl_peripheral!(#name_interrupt);
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -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::{low_power_wait_until, unborrow};
|
||||
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};
|
||||
@ -32,7 +31,7 @@ use crate::interrupt::InterruptExt;
|
||||
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
|
||||
use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
enum RxState {
|
||||
@ -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,20 +77,20 @@ 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 Unborrow<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
rts: impl Unborrow<Target = impl GpioPin> + '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,
|
||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
rx_buffer: &'d mut [u8],
|
||||
tx_buffer: &'d mut [u8],
|
||||
) -> Self {
|
||||
unborrow!(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();
|
||||
|
||||
@ -147,7 +146,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
||||
timer.cc(0).short_compare_stop();
|
||||
|
||||
let mut ppi_ch1 = Ppi::new_one_to_two(
|
||||
ppi_ch1.degrade(),
|
||||
ppi_ch1.map_into(),
|
||||
Event::from_reg(&r.events_rxdrdy),
|
||||
timer.task_clear(),
|
||||
timer.task_start(),
|
||||
@ -155,7 +154,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
||||
ppi_ch1.enable();
|
||||
|
||||
let mut ppi_ch2 = Ppi::new_one_to_one(
|
||||
ppi_ch2.degrade(),
|
||||
ppi_ch2.map_into(),
|
||||
timer.cc(0).event_compare(),
|
||||
Task::from_reg(&r.tasks_stoprx),
|
||||
);
|
||||
@ -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,
|
||||
|
@ -2,15 +2,14 @@
|
||||
|
||||
use core::convert::Infallible;
|
||||
use core::hint::unreachable_unchecked;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
|
||||
use self::sealed::Pin as _;
|
||||
use crate::pac::p0 as gpio;
|
||||
use crate::pac::p0::pin_cnf::{DRIVE_A, PULL_A};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
/// A GPIO port with up to 32 pins.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
@ -39,7 +38,7 @@ pub struct Input<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Input<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
pin.set_as_input(pull);
|
||||
|
||||
@ -119,7 +118,7 @@ pub struct Output<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
match initial_output {
|
||||
Level::High => pin.set_high(),
|
||||
@ -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
|
||||
/// mode.
|
||||
pub struct Flex<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
pub(crate) pin: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Flex<'d, T> {
|
||||
@ -204,13 +202,10 @@ impl<'d, T: Pin> Flex<'d, T> {
|
||||
/// The pin remains disconnected. The initial output level is unspecified, but can be changed
|
||||
/// before the pin is put into output mode.
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
unborrow!(pin);
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
|
||||
into_ref!(pin);
|
||||
// Pin will be in disconnected state.
|
||||
Self {
|
||||
pin,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
/// Put the pin into input mode.
|
||||
@ -379,7 +374,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized + 'static {
|
||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
|
||||
/// Number of the pin within the port (0..31)
|
||||
#[inline]
|
||||
fn pin(&self) -> u8 {
|
||||
@ -423,7 +418,7 @@ impl AnyPin {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_impl_unborrow!(AnyPin);
|
||||
impl_peripheral!(AnyPin);
|
||||
impl Pin for AnyPin {}
|
||||
impl sealed::Pin for AnyPin {
|
||||
#[inline]
|
||||
@ -438,10 +433,13 @@ pub(crate) trait PselBits {
|
||||
fn psel_bits(&self) -> u32;
|
||||
}
|
||||
|
||||
impl PselBits for Option<AnyPin> {
|
||||
impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> {
|
||||
#[inline]
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,6 +461,12 @@ macro_rules! impl_pin {
|
||||
$port_num * 32 + $pin_num
|
||||
}
|
||||
}
|
||||
|
||||
impl From<peripherals::$type> for crate::gpio::AnyPin {
|
||||
fn from(val: peripherals::$type) -> Self {
|
||||
crate::gpio::Pin::degrade(val)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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::unsafe_impl_unborrow;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,7 +404,7 @@ pub trait Channel: sealed::Channel + Sized {
|
||||
pub struct AnyChannel {
|
||||
number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyChannel);
|
||||
impl_peripheral!(AnyChannel);
|
||||
impl sealed::Channel for AnyChannel {}
|
||||
impl Channel for AnyChannel {
|
||||
fn number(&self) -> usize {
|
||||
|
@ -135,7 +135,7 @@ pub use chip::pac;
|
||||
pub(crate) use chip::pac;
|
||||
pub use chip::{peripherals, Peripherals};
|
||||
pub use embassy_cortex_m::executor;
|
||||
pub use embassy_hal_common::{unborrow, Unborrow};
|
||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
pub use embassy_macros::cortex_m_interrupt as interrupt;
|
||||
|
||||
pub mod config {
|
||||
|
@ -1,15 +1,14 @@
|
||||
//! Nvmcerature sensor interface.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::{ptr, slice};
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{
|
||||
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
|
||||
};
|
||||
|
||||
use crate::peripherals::NVMC;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE;
|
||||
@ -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 Unborrow<Target = NVMC> + 'd) -> Self {
|
||||
unborrow!(_p);
|
||||
|
||||
Self { _p: PhantomData }
|
||||
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
|
||||
into_ref!(_p);
|
||||
Self { _p }
|
||||
}
|
||||
|
||||
fn regs() -> &'static pac::nvmc::RegisterBlock {
|
||||
|
@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
|
||||
use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
|
||||
const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
|
||||
@ -13,13 +11,13 @@ fn regs() -> &'static pac::dppic::RegisterBlock {
|
||||
}
|
||||
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
|
||||
pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
|
||||
Ppi::new_many_to_many(ch, [event], [task])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
|
||||
pub fn new_one_to_two(ch: impl Unborrow<Target = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
|
||||
pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
|
||||
Ppi::new_many_to_many(ch, [event], [task1, task2])
|
||||
}
|
||||
}
|
||||
@ -28,11 +26,11 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
|
||||
Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
|
||||
{
|
||||
pub fn new_many_to_many(
|
||||
ch: impl Unborrow<Target = C> + 'd,
|
||||
ch: impl Peripheral<P = C> + 'd,
|
||||
events: [Event; EVENT_COUNT],
|
||||
tasks: [Task; TASK_COUNT],
|
||||
) -> Self {
|
||||
unborrow!(ch);
|
||||
into_ref!(ch);
|
||||
|
||||
let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
|
||||
for task in tasks {
|
||||
@ -48,12 +46,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
|
||||
unsafe { event.publish_reg().write_volatile(val) }
|
||||
}
|
||||
|
||||
Self {
|
||||
ch,
|
||||
events,
|
||||
tasks,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { ch, events, tasks }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,11 @@
|
||||
//! 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 embassy_hal_common::unsafe_impl_unborrow;
|
||||
use embassy_hal_common::{impl_peripheral, PeripheralRef};
|
||||
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
#[cfg(feature = "_dppi")]
|
||||
mod dppi;
|
||||
@ -28,12 +27,11 @@ mod dppi;
|
||||
mod ppi;
|
||||
|
||||
pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
|
||||
ch: C,
|
||||
ch: PeripheralRef<'d, C>,
|
||||
#[cfg(feature = "_dppi")]
|
||||
events: [Event; EVENT_COUNT],
|
||||
#[cfg(feature = "_dppi")]
|
||||
tasks: [Task; TASK_COUNT],
|
||||
phantom: PhantomData<&'d mut C>,
|
||||
}
|
||||
|
||||
const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
|
||||
@ -89,16 +87,16 @@ pub(crate) mod sealed {
|
||||
pub trait Group {}
|
||||
}
|
||||
|
||||
pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized {
|
||||
pub trait Channel: sealed::Channel + Peripheral<P = Self> + Sized {
|
||||
/// Returns the number of the channel
|
||||
fn number(&self) -> usize;
|
||||
}
|
||||
|
||||
pub trait ConfigurableChannel: Channel {
|
||||
pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {
|
||||
fn degrade(self) -> AnyConfigurableChannel;
|
||||
}
|
||||
|
||||
pub trait StaticChannel: Channel {
|
||||
pub trait StaticChannel: Channel + Into<AnyStaticChannel> {
|
||||
fn degrade(self) -> AnyStaticChannel;
|
||||
}
|
||||
|
||||
@ -119,7 +117,7 @@ pub trait Group: sealed::Group + Sized {
|
||||
pub struct AnyStaticChannel {
|
||||
pub(crate) number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyStaticChannel);
|
||||
impl_peripheral!(AnyStaticChannel);
|
||||
impl sealed::Channel for AnyStaticChannel {}
|
||||
impl Channel for AnyStaticChannel {
|
||||
fn number(&self) -> usize {
|
||||
@ -137,7 +135,7 @@ impl StaticChannel for AnyStaticChannel {
|
||||
pub struct AnyConfigurableChannel {
|
||||
pub(crate) number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyConfigurableChannel);
|
||||
impl_peripheral!(AnyConfigurableChannel);
|
||||
impl sealed::Channel for AnyConfigurableChannel {}
|
||||
impl Channel for AnyConfigurableChannel {
|
||||
fn number(&self) -> usize {
|
||||
@ -169,6 +167,12 @@ macro_rules! impl_ppi_channel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<peripherals::$type> for crate::ppi::AnyStaticChannel {
|
||||
fn from(val: peripherals::$type) -> Self {
|
||||
crate::ppi::StaticChannel::degrade(val)
|
||||
}
|
||||
}
|
||||
};
|
||||
($type:ident, $number:expr => configurable) => {
|
||||
impl_ppi_channel!($type, $number);
|
||||
@ -180,6 +184,12 @@ macro_rules! impl_ppi_channel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel {
|
||||
fn from(val: peripherals::$type) -> Self {
|
||||
crate::ppi::ConfigurableChannel::degrade(val)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -189,7 +199,7 @@ macro_rules! impl_ppi_channel {
|
||||
pub struct AnyGroup {
|
||||
number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyGroup);
|
||||
impl_peripheral!(AnyGroup);
|
||||
impl sealed::Group for AnyGroup {}
|
||||
impl Group for AnyGroup {
|
||||
fn number(&self) -> usize {
|
||||
|
@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
|
||||
use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
impl Task {
|
||||
fn reg_val(&self) -> u32 {
|
||||
@ -22,40 +20,34 @@ fn regs() -> &'static pac::ppi::RegisterBlock {
|
||||
|
||||
#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
|
||||
impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
|
||||
pub fn new_zero_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self {
|
||||
unborrow!(ch);
|
||||
pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
let r = regs();
|
||||
let n = ch.number();
|
||||
r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
||||
|
||||
Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { ch }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self {
|
||||
unborrow!(ch);
|
||||
pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
let r = regs();
|
||||
let n = ch.number();
|
||||
r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
|
||||
r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
|
||||
|
||||
Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { ch }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
|
||||
pub fn new_one_to_two(ch: impl Unborrow<Target = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
|
||||
unborrow!(ch);
|
||||
pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
let r = regs();
|
||||
let n = ch.number();
|
||||
@ -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.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) });
|
||||
|
||||
Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { ch }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,35 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
|
||||
use crate::interrupt::Interrupt;
|
||||
use crate::ppi::{Event, Task};
|
||||
use crate::util::slice_in_ram_or;
|
||||
use crate::{pac, Unborrow};
|
||||
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<AnyPin>,
|
||||
ch1: Option<AnyPin>,
|
||||
ch2: Option<AnyPin>,
|
||||
ch3: Option<AnyPin>,
|
||||
ch0: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
}
|
||||
|
||||
/// 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>,
|
||||
ch0: Option<AnyPin>,
|
||||
ch1: Option<AnyPin>,
|
||||
ch2: Option<AnyPin>,
|
||||
ch3: Option<AnyPin>,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
ch0: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@ -51,41 +50,41 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
||||
/// Create a new 1-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_1ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, Error> {
|
||||
unborrow!(ch0);
|
||||
Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config)
|
||||
into_ref!(ch0);
|
||||
Self::new_inner(pwm, Some(ch0.map_into()), None, None, None, config)
|
||||
}
|
||||
|
||||
/// Create a new 2-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_2ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, Error> {
|
||||
unborrow!(ch0, ch1);
|
||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None, config)
|
||||
into_ref!(ch0, ch1);
|
||||
Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config)
|
||||
}
|
||||
|
||||
/// Create a new 3-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_3ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch2: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, Error> {
|
||||
unborrow!(ch0, ch1, ch2);
|
||||
into_ref!(ch0, ch1, ch2);
|
||||
Self::new_inner(
|
||||
pwm,
|
||||
Some(ch0.degrade()),
|
||||
Some(ch1.degrade()),
|
||||
Some(ch2.degrade()),
|
||||
Some(ch0.map_into()),
|
||||
Some(ch1.map_into()),
|
||||
Some(ch2.map_into()),
|
||||
None,
|
||||
config,
|
||||
)
|
||||
@ -94,32 +93,34 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
|
||||
/// Create a new 4-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_4ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch2: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch3: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Result<Self, Error> {
|
||||
unborrow!(ch0, ch1, ch2, ch3);
|
||||
into_ref!(ch0, ch1, ch2, ch3);
|
||||
Self::new_inner(
|
||||
pwm,
|
||||
Some(ch0.degrade()),
|
||||
Some(ch1.degrade()),
|
||||
Some(ch2.degrade()),
|
||||
Some(ch3.degrade()),
|
||||
Some(ch0.map_into()),
|
||||
Some(ch1.map_into()),
|
||||
Some(ch2.map_into()),
|
||||
Some(ch3.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: Option<AnyPin>,
|
||||
ch1: Option<AnyPin>,
|
||||
ch2: Option<AnyPin>,
|
||||
ch3: Option<AnyPin>,
|
||||
_pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
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,
|
||||
@ -573,60 +574,74 @@ pub enum CounterMode {
|
||||
impl<'d, T: Instance> SimplePwm<'d, T> {
|
||||
/// Create a new 1-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self {
|
||||
unborrow!(ch0);
|
||||
Self::new_inner(pwm, Some(ch0.degrade()), None, None, None)
|
||||
pub fn new_1ch(pwm: impl Peripheral<P = T> + 'd, ch0: impl Peripheral<P = impl GpioPin> + 'd) -> Self {
|
||||
unsafe {
|
||||
into_ref!(ch0);
|
||||
Self::new_inner(pwm, Some(ch0.map_into()), None, None, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new 2-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_2ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(ch0, ch1);
|
||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None)
|
||||
into_ref!(ch0, ch1);
|
||||
Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None)
|
||||
}
|
||||
|
||||
/// Create a new 3-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_3ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch2: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(ch0, ch1, ch2);
|
||||
Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), Some(ch2.degrade()), None)
|
||||
unsafe {
|
||||
into_ref!(ch0, ch1, ch2);
|
||||
Self::new_inner(
|
||||
pwm,
|
||||
Some(ch0.map_into()),
|
||||
Some(ch1.map_into()),
|
||||
Some(ch2.map_into()),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new 4-channel PWM
|
||||
#[allow(unused_unsafe)]
|
||||
pub fn new_4ch(
|
||||
pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
ch3: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch2: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
ch3: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(ch0, ch1, ch2, ch3);
|
||||
Self::new_inner(
|
||||
pwm,
|
||||
Some(ch0.degrade()),
|
||||
Some(ch1.degrade()),
|
||||
Some(ch2.degrade()),
|
||||
Some(ch3.degrade()),
|
||||
)
|
||||
unsafe {
|
||||
into_ref!(ch0, ch1, ch2, ch3);
|
||||
Self::new_inner(
|
||||
pwm,
|
||||
Some(ch0.map_into()),
|
||||
Some(ch1.map_into()),
|
||||
Some(ch2.map_into()),
|
||||
Some(ch3.map_into()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_pwm: impl Unborrow<Target = T> + 'd,
|
||||
ch0: Option<AnyPin>,
|
||||
ch1: Option<AnyPin>,
|
||||
ch2: Option<AnyPin>,
|
||||
ch3: Option<AnyPin>,
|
||||
_pwm: impl Peripheral<P = T> + 'd,
|
||||
ch0: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
ch3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
) -> Self {
|
||||
into_ref!(_pwm);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
if let Some(pin) = &ch0 {
|
||||
@ -654,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,
|
||||
@ -813,7 +828,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,20 @@
|
||||
//! Quadrature decoder interface
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin};
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::peripherals::QDEC;
|
||||
use crate::{interrupt, pac, Unborrow};
|
||||
use crate::{interrupt, pac, Peripheral};
|
||||
|
||||
/// Quadrature decoder
|
||||
pub struct Qdec<'d> {
|
||||
phantom: PhantomData<&'d QDEC>,
|
||||
_p: PeripheralRef<'d, QDEC>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
@ -43,37 +42,37 @@ static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
impl<'d> Qdec<'d> {
|
||||
pub fn new(
|
||||
qdec: impl Unborrow<Target = QDEC> + 'd,
|
||||
irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
|
||||
a: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
b: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
qdec: impl Peripheral<P = QDEC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::QDEC> + 'd,
|
||||
a: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
b: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(a, b);
|
||||
Self::new_inner(qdec, irq, a.degrade(), b.degrade(), None, config)
|
||||
into_ref!(a, b);
|
||||
Self::new_inner(qdec, irq, a.map_into(), b.map_into(), None, config)
|
||||
}
|
||||
|
||||
pub fn new_with_led(
|
||||
qdec: impl Unborrow<Target = QDEC> + 'd,
|
||||
irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
|
||||
a: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
b: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
led: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
qdec: impl Peripheral<P = QDEC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::QDEC> + 'd,
|
||||
a: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
b: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
led: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(a, b, led);
|
||||
Self::new_inner(qdec, irq, a.degrade(), b.degrade(), Some(led.degrade()), config)
|
||||
into_ref!(a, b, led);
|
||||
Self::new_inner(qdec, irq, a.map_into(), b.map_into(), Some(led.map_into()), config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_t: impl Unborrow<Target = QDEC> + 'd,
|
||||
irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
|
||||
a: AnyPin,
|
||||
b: AnyPin,
|
||||
led: Option<AnyPin>,
|
||||
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 {
|
||||
unborrow!(irq);
|
||||
into_ref!(p, irq);
|
||||
let r = Self::regs();
|
||||
|
||||
// Select pins.
|
||||
@ -131,7 +130,7 @@ impl<'d> Qdec<'d> {
|
||||
});
|
||||
irq.enable();
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
Self { _p: p }
|
||||
}
|
||||
|
||||
/// Perform an asynchronous read of the decoder.
|
||||
|
@ -1,20 +1,18 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::DropBomb;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{self, Pin as GpioPin};
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
pub use crate::pac::qspi::ifconfig0::{
|
||||
ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
|
||||
};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
// TODO
|
||||
// - config:
|
||||
@ -63,38 +61,38 @@ pub enum Error {
|
||||
}
|
||||
|
||||
pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
|
||||
irq: T::Interrupt,
|
||||
irq: PeripheralRef<'d, T::Interrupt>,
|
||||
dpm_enabled: bool,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
||||
pub fn new(
|
||||
_qspi: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sck: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
csn: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
io0: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
io1: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
io2: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
io3: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
_qspi: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
csn: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
io0: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
io1: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
io2: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
io3: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Qspi<'d, T, FLASH_SIZE> {
|
||||
unborrow!(irq, sck, csn, io0, io1, io2, io3);
|
||||
into_ref!(irq, sck, csn, io0, io1, io2, io3);
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
let sck = sck.degrade();
|
||||
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] {
|
||||
pin.set_high();
|
||||
pin.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
}
|
||||
sck.set_high();
|
||||
csn.set_high();
|
||||
io0.set_high();
|
||||
io1.set_high();
|
||||
io2.set_high();
|
||||
io3.set_high();
|
||||
sck.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
csn.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
io0.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
io1.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
io2.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
io3.conf().write(|w| w.dir().output().drive().h0h1());
|
||||
|
||||
r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) });
|
||||
r.psel.csn.write(|w| unsafe { w.bits(csn.psel_bits()) });
|
||||
@ -143,7 +141,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
||||
let mut res = Self {
|
||||
dpm_enabled: config.deep_power_down.is_some(),
|
||||
irq,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
|
||||
r.events_ready.reset();
|
||||
@ -536,7 +533,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::peripherals::RNG;
|
||||
use crate::{interrupt, pac, Unborrow};
|
||||
use crate::{interrupt, pac, Peripheral};
|
||||
|
||||
impl RNG {
|
||||
fn regs() -> &'static pac::rng::RegisterBlock {
|
||||
@ -34,8 +33,7 @@ struct State {
|
||||
///
|
||||
/// It has a non-blocking API, and a blocking api through `rand`.
|
||||
pub struct Rng<'d> {
|
||||
irq: interrupt::RNG,
|
||||
phantom: PhantomData<(&'d mut RNG, &'d mut interrupt::RNG)>,
|
||||
irq: PeripheralRef<'d, interrupt::RNG>,
|
||||
}
|
||||
|
||||
impl<'d> Rng<'d> {
|
||||
@ -45,13 +43,10 @@ impl<'d> Rng<'d> {
|
||||
/// e.g. using `mem::forget`.
|
||||
///
|
||||
/// The synchronous API is safe.
|
||||
pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self {
|
||||
unborrow!(irq);
|
||||
pub fn new(_rng: impl Peripheral<P = RNG> + 'd, irq: impl Peripheral<P = interrupt::RNG> + 'd) -> Self {
|
||||
into_ref!(irq);
|
||||
|
||||
let this = Self {
|
||||
irq,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
let this = Self { irq };
|
||||
|
||||
this.stop();
|
||||
this.disable_irq();
|
||||
|
@ -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::unborrow;
|
||||
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,10 +13,11 @@ 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};
|
||||
use crate::{interrupt, pac, peripherals, Unborrow};
|
||||
use crate::{interrupt, pac, peripherals, Peripheral};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -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,106 +66,37 @@ 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;
|
||||
|
||||
unsafe impl Unborrow for VddInput {
|
||||
type Target = VddInput;
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
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"))]
|
||||
unsafe impl Unborrow for VddhDiv5Input {
|
||||
type Target = VddhDiv5Input;
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
unsafe impl Unborrow for AnyInput {
|
||||
type Target = AnyInput;
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
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 Unborrow<Target = impl Input> + 'd) -> Self {
|
||||
unborrow!(input);
|
||||
pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
|
||||
into_ref!(input);
|
||||
Self {
|
||||
reference: Reference::INTERNAL,
|
||||
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.
|
||||
pub fn differential(
|
||||
p_input: impl Unborrow<Target = impl Input> + 'd,
|
||||
n_input: impl Unborrow<Target = impl Input> + 'd,
|
||||
p_input: impl Peripheral<P = impl Input> + 'd,
|
||||
n_input: impl Peripheral<P = impl Input> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(p_input, n_input);
|
||||
into_ref!(p_input, n_input);
|
||||
Self {
|
||||
reference: Reference::INTERNAL,
|
||||
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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,12 +113,12 @@ pub enum SamplerState {
|
||||
|
||||
impl<'d, const N: usize> Saadc<'d, N> {
|
||||
pub fn new(
|
||||
_saadc: impl Unborrow<Target = peripherals::SAADC> + 'd,
|
||||
irq: impl Unborrow<Target = interrupt::SAADC> + 'd,
|
||||
saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::SAADC> + 'd,
|
||||
config: Config,
|
||||
channel_configs: [ChannelConfig; N],
|
||||
) -> Self {
|
||||
unborrow!(irq);
|
||||
into_ref!(saadc, irq);
|
||||
|
||||
let r = unsafe { &*SAADC::ptr() };
|
||||
|
||||
@ -199,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());
|
||||
@ -230,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 ()) {
|
||||
@ -689,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 + Unborrow<Target = Self> + Sized {
|
||||
pub trait Input: sealed::Input + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static {
|
||||
fn degrade_saadc(self) -> AnyInput {
|
||||
AnyInput {
|
||||
channel: self.channel(),
|
||||
@ -697,13 +630,57 @@ pub trait Input: sealed::Input + Unborrow<Target = Self> + Sized {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyInput {
|
||||
channel: InputChannel,
|
||||
}
|
||||
|
||||
impl_peripheral!(AnyInput);
|
||||
|
||||
impl sealed::Input for AnyInput {
|
||||
fn channel(&self) -> InputChannel {
|
||||
self.channel
|
||||
}
|
||||
}
|
||||
|
||||
impl Input for AnyInput {}
|
||||
|
||||
macro_rules! impl_saadc_input {
|
||||
($pin:ident, $ch:ident) => {
|
||||
impl crate::saadc::sealed::Input for crate::peripherals::$pin {
|
||||
impl_saadc_input!(@local, crate::peripherals::$pin, $ch);
|
||||
};
|
||||
(@local, $pin:ty, $ch:ident) => {
|
||||
impl crate::saadc::sealed::Input for $pin {
|
||||
fn channel(&self) -> crate::saadc::InputChannel {
|
||||
crate::saadc::InputChannel::$ch
|
||||
}
|
||||
}
|
||||
impl crate::saadc::Input for crate::peripherals::$pin {}
|
||||
impl crate::saadc::Input for $pin {}
|
||||
|
||||
impl From<$pin> for crate::saadc::AnyInput {
|
||||
fn from(val: $pin) -> Self {
|
||||
crate::saadc::Input::degrade_saadc(val)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
|
||||
/// internal voltage.
|
||||
pub struct VddInput;
|
||||
|
||||
impl_peripheral!(VddInput);
|
||||
#[cfg(not(feature = "_nrf9160"))]
|
||||
impl_saadc_input!(@local, VddInput, VDD);
|
||||
#[cfg(feature = "_nrf9160")]
|
||||
impl_saadc_input!(@local, VddInput, VDDGPIO);
|
||||
|
||||
/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
|
||||
/// VDDH / 5 voltage.
|
||||
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
||||
pub struct VddhDiv5Input;
|
||||
|
||||
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
||||
impl_peripheral!(VddhDiv5Input);
|
||||
|
||||
#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
|
||||
impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5);
|
||||
|
@ -1,11 +1,10 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
use futures::future::poll_fn;
|
||||
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
||||
@ -15,7 +14,7 @@ use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -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]
|
||||
@ -53,55 +52,55 @@ impl Default for Config {
|
||||
|
||||
impl<'d, T: Instance> Spim<'d, T> {
|
||||
pub fn new(
|
||||
spim: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sck: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
miso: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
spim: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, miso, mosi);
|
||||
into_ref!(sck, miso, mosi);
|
||||
Self::new_inner(
|
||||
spim,
|
||||
irq,
|
||||
sck.degrade(),
|
||||
Some(miso.degrade()),
|
||||
Some(mosi.degrade()),
|
||||
sck.map_into(),
|
||||
Some(miso.map_into()),
|
||||
Some(mosi.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_txonly(
|
||||
spim: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sck: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
mosi: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
spim: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, mosi);
|
||||
Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config)
|
||||
into_ref!(sck, mosi);
|
||||
Self::new_inner(spim, irq, sck.map_into(), None, Some(mosi.map_into()), config)
|
||||
}
|
||||
|
||||
pub fn new_rxonly(
|
||||
spim: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sck: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
miso: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
spim: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, miso);
|
||||
Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config)
|
||||
into_ref!(sck, miso);
|
||||
Self::new_inner(spim, irq, sck.map_into(), Some(miso.map_into()), None, config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_spim: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sck: AnyPin,
|
||||
miso: Option<AnyPin>,
|
||||
mosi: Option<AnyPin>,
|
||||
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 {
|
||||
unborrow!(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 ()) {
|
||||
@ -386,7 +385,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,27 @@
|
||||
//! Temperature sensor interface.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use fixed::types::I30F2;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::peripherals::TEMP;
|
||||
use crate::{interrupt, pac, Unborrow};
|
||||
use crate::{interrupt, pac, Peripheral};
|
||||
|
||||
/// Integrated temperature sensor.
|
||||
pub struct Temp<'d> {
|
||||
_temp: PhantomData<&'d TEMP>,
|
||||
_irq: interrupt::TEMP,
|
||||
_irq: PeripheralRef<'d, interrupt::TEMP>,
|
||||
}
|
||||
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
impl<'d> Temp<'d> {
|
||||
pub fn new(_t: impl Unborrow<Target = TEMP> + 'd, irq: impl Unborrow<Target = interrupt::TEMP> + 'd) -> Self {
|
||||
unborrow!(_t, irq);
|
||||
pub fn new(_t: impl Peripheral<P = TEMP> + 'd, irq: impl Peripheral<P = interrupt::TEMP> + 'd) -> Self {
|
||||
into_ref!(_t, irq);
|
||||
|
||||
// Enable interrupt that signals temperature values
|
||||
irq.disable();
|
||||
@ -33,10 +31,7 @@ impl<'d> Temp<'d> {
|
||||
WAKER.wake();
|
||||
});
|
||||
irq.enable();
|
||||
Self {
|
||||
_temp: PhantomData,
|
||||
_irq: irq,
|
||||
}
|
||||
Self { _irq: irq }
|
||||
}
|
||||
|
||||
/// Perform an asynchronous temperature measurement. The returned future
|
||||
|
@ -5,12 +5,12 @@ use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::ppi::{Event, Task};
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
pub(crate) mod sealed {
|
||||
|
||||
@ -28,7 +28,7 @@ pub(crate) mod sealed {
|
||||
pub trait TimerType {}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {}
|
||||
@ -95,15 +95,13 @@ 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> {
|
||||
pub fn new_awaitable(
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(irq);
|
||||
pub fn new_awaitable(timer: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd) -> Self {
|
||||
into_ref!(irq);
|
||||
|
||||
irq.set_handler(Self::on_interrupt);
|
||||
irq.unpend();
|
||||
@ -117,7 +115,7 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> {
|
||||
///
|
||||
/// This can be useful for triggering tasks via PPI
|
||||
/// `Uarte` uses this internally.
|
||||
pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
pub fn new(timer: impl Peripheral<P = T> + 'd) -> Self {
|
||||
Self::new_irqless(timer)
|
||||
}
|
||||
}
|
||||
@ -126,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 Unborrow<Target = 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.
|
||||
@ -233,7 +236,8 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
|
||||
}
|
||||
Cc {
|
||||
n,
|
||||
phantom: PhantomData,
|
||||
_p: self._p.reborrow(),
|
||||
_i: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,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`.
|
||||
@ -284,9 +289,9 @@ impl<'a, T: Instance> Cc<'a, T, Awaitable> {
|
||||
on_drop.defuse();
|
||||
}
|
||||
}
|
||||
impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {}
|
||||
impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {}
|
||||
|
||||
impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> {
|
||||
impl<'d, T: Instance, I: TimerType> Cc<'d, T, I> {
|
||||
/// Get the current value stored in the register.
|
||||
pub fn read(&self) -> u32 {
|
||||
T::regs().cc[self.n].read().cc().bits()
|
||||
|
@ -7,7 +7,6 @@
|
||||
//! - nRF52832: Section 33
|
||||
//! - nRF52840: Section 6.31
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::compiler_fence;
|
||||
use core::sync::atomic::Ordering::SeqCst;
|
||||
use core::task::Poll;
|
||||
@ -16,14 +15,14 @@ use core::task::Poll;
|
||||
use embassy::time::{Duration, Instant};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
|
||||
use crate::gpio::Pin as GpioPin;
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::util::{slice_in_ram, slice_in_ram_or};
|
||||
use crate::{gpio, pac, Unborrow};
|
||||
use crate::{gpio, pac, Peripheral};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Frequency {
|
||||
@ -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 Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
sda: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
scl: impl Unborrow<Target = impl GpioPin> + '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 {
|
||||
unborrow!(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 ()) {
|
||||
@ -707,7 +706,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,11 @@
|
||||
//! 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;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
use pac::uarte0::RegisterBlock;
|
||||
// Re-export SVD variants to allow user to directly set values.
|
||||
@ -31,7 +30,7 @@ use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
|
||||
use crate::util::slice_in_ram_or;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
#[derive(Clone)]
|
||||
#[non_exhaustive]
|
||||
@ -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,60 +69,60 @@ 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> {
|
||||
/// Create a new UARTE without hardware flow control
|
||||
pub fn new(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd, txd);
|
||||
Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config)
|
||||
into_ref!(rxd, txd);
|
||||
Self::new_inner(uarte, irq, rxd.map_into(), txd.map_into(), None, None, config)
|
||||
}
|
||||
|
||||
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
||||
pub fn new_with_rtscts(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd, txd, cts, rts);
|
||||
into_ref!(rxd, txd, cts, rts);
|
||||
Self::new_inner(
|
||||
uarte,
|
||||
irq,
|
||||
rxd.degrade(),
|
||||
txd.degrade(),
|
||||
Some(cts.degrade()),
|
||||
Some(rts.degrade()),
|
||||
rxd.map_into(),
|
||||
txd.map_into(),
|
||||
Some(cts.map_into()),
|
||||
Some(rts.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: AnyPin,
|
||||
txd: AnyPin,
|
||||
cts: Option<AnyPin>,
|
||||
rts: Option<AnyPin>,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: PeripheralRef<'d, AnyPin>,
|
||||
txd: PeripheralRef<'d, AnyPin>,
|
||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(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 },
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,35 +244,35 @@ fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) {
|
||||
impl<'d, T: Instance> UarteTx<'d, T> {
|
||||
/// Create a new tx-only UARTE without hardware flow control
|
||||
pub fn new(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(txd);
|
||||
Self::new_inner(uarte, irq, txd.degrade(), None, config)
|
||||
into_ref!(txd);
|
||||
Self::new_inner(uarte, irq, txd.map_into(), None, config)
|
||||
}
|
||||
|
||||
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
|
||||
pub fn new_with_rtscts(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(txd, cts);
|
||||
Self::new_inner(uarte, irq, txd.degrade(), Some(cts.degrade()), config)
|
||||
into_ref!(txd, cts);
|
||||
Self::new_inner(uarte, irq, txd.map_into(), Some(cts.map_into()), config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
txd: AnyPin,
|
||||
cts: Option<AnyPin>,
|
||||
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 {
|
||||
unborrow!(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> {
|
||||
@ -437,35 +436,35 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> {
|
||||
impl<'d, T: Instance> UarteRx<'d, T> {
|
||||
/// Create a new rx-only UARTE without hardware flow control
|
||||
pub fn new(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd);
|
||||
Self::new_inner(uarte, irq, rxd.degrade(), None, config)
|
||||
into_ref!(rxd);
|
||||
Self::new_inner(uarte, irq, rxd.map_into(), None, config)
|
||||
}
|
||||
|
||||
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
|
||||
pub fn new_with_rtscts(
|
||||
uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd, rts);
|
||||
Self::new_inner(uarte, irq, rxd.degrade(), Some(rts.degrade()), config)
|
||||
into_ref!(rxd, rts);
|
||||
Self::new_inner(uarte, irq, rxd.map_into(), Some(rts.map_into()), config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_uarte: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
rxd: AnyPin,
|
||||
rts: Option<AnyPin>,
|
||||
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 {
|
||||
unborrow!(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> {
|
||||
@ -676,24 +675,24 @@ pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
|
||||
impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
||||
/// Create a new UARTE without hardware flow control
|
||||
pub fn new(
|
||||
uarte: impl Unborrow<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: 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,
|
||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd, txd);
|
||||
into_ref!(rxd, txd);
|
||||
Self::new_inner(
|
||||
uarte,
|
||||
timer,
|
||||
ppi_ch1,
|
||||
ppi_ch2,
|
||||
irq,
|
||||
rxd.degrade(),
|
||||
txd.degrade(),
|
||||
rxd.map_into(),
|
||||
txd.map_into(),
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
@ -702,42 +701,42 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
||||
|
||||
/// Create a new UARTE with hardware flow control (RTS/CTS)
|
||||
pub fn new_with_rtscts(
|
||||
uarte: impl Unborrow<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
txd: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
cts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
rts: impl Unborrow<Target = impl GpioPin> + 'd,
|
||||
uarte: 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,
|
||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(rxd, txd, cts, rts);
|
||||
into_ref!(rxd, txd, cts, rts);
|
||||
Self::new_inner(
|
||||
uarte,
|
||||
timer,
|
||||
ppi_ch1,
|
||||
ppi_ch2,
|
||||
irq,
|
||||
rxd.degrade(),
|
||||
txd.degrade(),
|
||||
Some(cts.degrade()),
|
||||
Some(rts.degrade()),
|
||||
rxd.map_into(),
|
||||
txd.map_into(),
|
||||
Some(cts.map_into()),
|
||||
Some(rts.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
uarte: impl Unborrow<Target = U> + 'd,
|
||||
timer: impl Unborrow<Target = T> + 'd,
|
||||
ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
|
||||
irq: impl Unborrow<Target = U::Interrupt> + 'd,
|
||||
rxd: AnyPin,
|
||||
txd: AnyPin,
|
||||
cts: Option<AnyPin>,
|
||||
rts: Option<AnyPin>,
|
||||
uarte: 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,
|
||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
||||
rxd: PeripheralRef<'d, AnyPin>,
|
||||
txd: PeripheralRef<'d, AnyPin>,
|
||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
let baudrate = config.baudrate;
|
||||
@ -745,7 +744,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
||||
|
||||
let mut timer = Timer::new(timer);
|
||||
|
||||
unborrow!(ppi_ch1, ppi_ch2);
|
||||
into_ref!(ppi_ch1, ppi_ch2);
|
||||
|
||||
let r = U::regs();
|
||||
|
||||
@ -763,7 +762,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
||||
timer.cc(0).short_compare_stop();
|
||||
|
||||
let mut ppi_ch1 = Ppi::new_one_to_two(
|
||||
ppi_ch1.degrade(),
|
||||
ppi_ch1.map_into(),
|
||||
Event::from_reg(&r.events_rxdrdy),
|
||||
timer.task_clear(),
|
||||
timer.task_start(),
|
||||
@ -771,7 +770,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
|
||||
ppi_ch1.enable();
|
||||
|
||||
let mut ppi_ch2 = Ppi::new_one_to_one(
|
||||
ppi_ch2.degrade(),
|
||||
ppi_ch2.map_into(),
|
||||
timer.cc(0).event_compare(),
|
||||
Task::from_reg(&r.tasks_stoprx),
|
||||
);
|
||||
@ -958,7 +957,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use core::task::Poll;
|
||||
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unborrow;
|
||||
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};
|
||||
@ -17,7 +17,7 @@ use pac::usbd::RegisterBlock;
|
||||
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::util::slice_in_ram;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
static BUS_WAKER: AtomicWaker = NEW_AW;
|
||||
@ -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,18 +166,14 @@ impl UsbSupply for SignalledSupply {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> {
|
||||
pub fn new(
|
||||
_usb: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
usb_supply: P,
|
||||
) -> Self {
|
||||
unborrow!(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,
|
||||
@ -273,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,
|
||||
},
|
||||
)
|
||||
@ -289,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,
|
||||
}
|
||||
@ -750,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,
|
||||
}
|
||||
|
||||
@ -950,7 +946,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send {
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
|
||||
type Interrupt: Interrupt;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
#![macro_use]
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::pin::Pin as FuturePin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::common::{Reg, RW};
|
||||
use crate::pac::SIO;
|
||||
use crate::{interrupt, pac, peripherals, Unborrow};
|
||||
use crate::{interrupt, pac, peripherals, Peripheral};
|
||||
|
||||
const PIN_COUNT: usize = 30;
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
@ -61,7 +61,7 @@ pub struct Input<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Input<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
pin.set_as_input();
|
||||
pin.set_pull(pull);
|
||||
@ -177,13 +177,13 @@ unsafe fn IO_IRQ_BANK0() {
|
||||
}
|
||||
|
||||
struct InputFuture<'a, T: Pin> {
|
||||
pin: &'a mut T,
|
||||
pin: PeripheralRef<'a, T>,
|
||||
level: InterruptTrigger,
|
||||
phantom: PhantomData<&'a mut AnyPin>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> InputFuture<'d, T> {
|
||||
pub fn new(pin: &'d mut T, level: InterruptTrigger) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, level: InterruptTrigger) -> Self {
|
||||
into_ref!(pin);
|
||||
unsafe {
|
||||
let irq = interrupt::IO_IRQ_BANK0::steal();
|
||||
irq.disable();
|
||||
@ -215,11 +215,7 @@ impl<'d, T: Pin> InputFuture<'d, T> {
|
||||
irq.enable();
|
||||
}
|
||||
|
||||
Self {
|
||||
pin,
|
||||
level,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin, level }
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +290,7 @@ pub struct Output<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
match initial_output {
|
||||
Level::High => pin.set_high(),
|
||||
@ -355,7 +351,7 @@ pub struct OutputOpenDrain<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> OutputOpenDrain<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
pin.set_low();
|
||||
match initial_output {
|
||||
@ -419,14 +415,13 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
|
||||
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
|
||||
/// mode.
|
||||
pub struct Flex<'d, T: Pin> {
|
||||
pin: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
pin: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Flex<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
unborrow!(pin);
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
|
||||
into_ref!(pin);
|
||||
|
||||
unsafe {
|
||||
pin.pad_ctrl().write(|w| {
|
||||
@ -438,10 +433,7 @@ impl<'d, T: Pin> Flex<'d, T> {
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
pin,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -655,7 +647,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Pin: Unborrow<Target = Self> + sealed::Pin {
|
||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
|
||||
/// Degrade to a generic pin struct
|
||||
fn degrade(self) -> AnyPin {
|
||||
AnyPin {
|
||||
@ -667,7 +659,9 @@ pub trait Pin: Unborrow<Target = Self> + sealed::Pin {
|
||||
pub struct AnyPin {
|
||||
pin_bank: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyPin);
|
||||
|
||||
impl_peripheral!(AnyPin);
|
||||
|
||||
impl Pin for AnyPin {}
|
||||
impl sealed::Pin for AnyPin {
|
||||
fn pin_bank(&self) -> u8 {
|
||||
@ -685,6 +679,12 @@ macro_rules! impl_pin {
|
||||
($bank as u8) * 32 + $pin_num
|
||||
}
|
||||
}
|
||||
|
||||
impl From<peripherals::$name> for crate::gpio::AnyPin {
|
||||
fn from(val: peripherals::$name) -> Self {
|
||||
crate::gpio::Pin::degrade(val)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ mod reset;
|
||||
// Reexports
|
||||
|
||||
pub use embassy_cortex_m::executor;
|
||||
pub use embassy_hal_common::{unborrow, Unborrow};
|
||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
pub use embassy_macros::cortex_m_interrupt as interrupt;
|
||||
#[cfg(feature = "unstable-pac")]
|
||||
pub use rp2040_pac2 as pac;
|
||||
|
@ -1,12 +1,10 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Phase, Polarity};
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin};
|
||||
use crate::{pac, peripherals, Unborrow};
|
||||
use crate::{pac, peripherals, Peripheral};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -33,8 +31,7 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
pub struct Spi<'d, T: Instance> {
|
||||
inner: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
inner: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
fn div_roundup(a: u32, b: u32) -> u32 {
|
||||
@ -62,52 +59,52 @@ fn calc_prescs(freq: u32) -> (u8, u8) {
|
||||
|
||||
impl<'d, T: Instance> Spi<'d, T> {
|
||||
pub fn new(
|
||||
inner: impl Unborrow<Target = T> + 'd,
|
||||
clk: impl Unborrow<Target = impl ClkPin<T>> + 'd,
|
||||
mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd,
|
||||
miso: impl Unborrow<Target = impl MisoPin<T>> + 'd,
|
||||
inner: impl Peripheral<P = T> + 'd,
|
||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
||||
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
|
||||
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(clk, mosi, miso);
|
||||
into_ref!(clk, mosi, miso);
|
||||
Self::new_inner(
|
||||
inner,
|
||||
Some(clk.degrade()),
|
||||
Some(mosi.degrade()),
|
||||
Some(miso.degrade()),
|
||||
Some(clk.map_into()),
|
||||
Some(mosi.map_into()),
|
||||
Some(miso.map_into()),
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_txonly(
|
||||
inner: impl Unborrow<Target = T> + 'd,
|
||||
clk: impl Unborrow<Target = impl ClkPin<T>> + 'd,
|
||||
mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd,
|
||||
inner: impl Peripheral<P = T> + 'd,
|
||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
||||
mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(clk, mosi);
|
||||
Self::new_inner(inner, Some(clk.degrade()), Some(mosi.degrade()), None, None, config)
|
||||
into_ref!(clk, mosi);
|
||||
Self::new_inner(inner, Some(clk.map_into()), Some(mosi.map_into()), None, None, config)
|
||||
}
|
||||
|
||||
pub fn new_rxonly(
|
||||
inner: impl Unborrow<Target = T> + 'd,
|
||||
clk: impl Unborrow<Target = impl ClkPin<T>> + 'd,
|
||||
miso: impl Unborrow<Target = impl MisoPin<T>> + 'd,
|
||||
inner: impl Peripheral<P = T> + 'd,
|
||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
||||
miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(clk, miso);
|
||||
Self::new_inner(inner, Some(clk.degrade()), None, Some(miso.degrade()), None, config)
|
||||
into_ref!(clk, miso);
|
||||
Self::new_inner(inner, Some(clk.map_into()), None, Some(miso.map_into()), None, config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
inner: impl Unborrow<Target = T> + 'd,
|
||||
clk: Option<AnyPin>,
|
||||
mosi: Option<AnyPin>,
|
||||
miso: Option<AnyPin>,
|
||||
cs: Option<AnyPin>,
|
||||
inner: impl Peripheral<P = T> + 'd,
|
||||
clk: Option<PeripheralRef<'d, AnyPin>>,
|
||||
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
||||
miso: Option<PeripheralRef<'d, AnyPin>>,
|
||||
cs: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(inner);
|
||||
into_ref!(inner);
|
||||
|
||||
unsafe {
|
||||
let p = inner.regs();
|
||||
@ -137,10 +134,7 @@ impl<'d, T: Instance> Spi<'d, T> {
|
||||
pin.io().ctrl().write(|w| w.set_funcsel(1));
|
||||
}
|
||||
}
|
||||
Self {
|
||||
inner,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||
|
@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use gpio::Pin;
|
||||
|
||||
use crate::{gpio, pac, peripherals, Unborrow};
|
||||
use crate::{gpio, pac, peripherals, Peripheral};
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
@ -23,20 +21,19 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
pub struct Uart<'d, T: Instance> {
|
||||
inner: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
inner: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Uart<'d, T> {
|
||||
pub fn new(
|
||||
inner: impl Unborrow<Target = T> + 'd,
|
||||
tx: impl Unborrow<Target = impl TxPin<T>> + 'd,
|
||||
rx: impl Unborrow<Target = impl RxPin<T>> + 'd,
|
||||
cts: impl Unborrow<Target = impl CtsPin<T>> + 'd,
|
||||
rts: impl Unborrow<Target = impl RtsPin<T>> + 'd,
|
||||
inner: impl Peripheral<P = T> + 'd,
|
||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
|
||||
rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(inner, tx, rx, cts, rts);
|
||||
into_ref!(inner, tx, rx, cts, rts);
|
||||
|
||||
unsafe {
|
||||
let p = inner.regs();
|
||||
@ -78,10 +75,7 @@ impl<'d, T: Instance> Uart<'d, T> {
|
||||
cts.io().ctrl().write(|w| w.set_funcsel(2));
|
||||
rts.io().ctrl().write(|w| w.set_funcsel(2));
|
||||
}
|
||||
Self {
|
||||
inner,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn send(&mut self, data: &[u8]) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{AdcPin, Instance};
|
||||
use crate::rcc::get_freqs;
|
||||
use crate::time::Hertz;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub const VDDA_CALIB_MV: u32 = 3300;
|
||||
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
||||
@ -91,8 +91,8 @@ pub struct Adc<'d, T: Instance> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Adc<'d, T> {
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
unborrow!(_peri);
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
into_ref!(_peri);
|
||||
T::enable();
|
||||
T::reset();
|
||||
unsafe {
|
||||
|
@ -1,11 +1,11 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{AdcPin, Instance};
|
||||
use crate::time::Hertz;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub const VDDA_CALIB_MV: u32 = 3000;
|
||||
|
||||
@ -159,8 +159,8 @@ impl<'d, T> Adc<'d, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
unborrow!(_peri);
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
into_ref!(_peri);
|
||||
enable();
|
||||
|
||||
let presc = unsafe { Prescaler::from_pclk2(crate::rcc::get_freqs().apb2) };
|
||||
|
@ -1,10 +1,10 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{AdcPin, Instance};
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub const VDDA_CALIB_MV: u32 = 3000;
|
||||
|
||||
@ -208,8 +208,8 @@ pub struct Adc<'d, T: Instance> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Adc<'d, T> {
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
unborrow!(_peri);
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||
into_ref!(_peri);
|
||||
enable();
|
||||
unsafe {
|
||||
T::regs().cr().modify(|reg| {
|
||||
|
@ -7,7 +7,7 @@ use pac::adccommon::vals::Presc;
|
||||
|
||||
use super::{AdcPin, Instance};
|
||||
use crate::time::Hertz;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
pub enum Resolution {
|
||||
SixteenBit,
|
||||
@ -322,8 +322,8 @@ pub struct Adc<'d, T: Instance> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
|
||||
embassy_hal_common::unborrow!(_peri);
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
|
||||
embassy_hal_common::into_ref!(_peri);
|
||||
T::enable();
|
||||
T::reset();
|
||||
|
||||
|
@ -1,25 +1,23 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
pub use bxcan;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
pub struct Can<'d, T: Instance + bxcan::Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
can: bxcan::Can<T>,
|
||||
pub struct Can<'d, T: Instance> {
|
||||
can: bxcan::Can<BxcanInstance<'d, T>>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
|
||||
impl<'d, T: Instance> Can<'d, T> {
|
||||
pub fn new(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
rx: impl Unborrow<Target = impl RxPin<T>> + 'd,
|
||||
tx: impl Unborrow<Target = impl TxPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(peri, rx, tx);
|
||||
into_ref!(peri, rx, tx);
|
||||
|
||||
unsafe {
|
||||
rx.set_as_af(rx.af_num(), AFType::Input);
|
||||
@ -30,32 +28,29 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
|
||||
T::reset();
|
||||
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
can: bxcan::Can::builder(peri).enable(),
|
||||
can: bxcan::Can::builder(BxcanInstance(peri)).enable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance + bxcan::Instance> Drop for Can<'d, T> {
|
||||
impl<'d, T: Instance> Drop for Can<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
// Cannot call `free()` because it moves the instance.
|
||||
// Manually reset the peripheral.
|
||||
unsafe {
|
||||
T::regs().mcr().write(|w| w.set_reset(true));
|
||||
}
|
||||
unsafe { T::regs().mcr().write(|w| w.set_reset(true)) }
|
||||
T::disable();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance + bxcan::Instance> Deref for Can<'d, T> {
|
||||
type Target = bxcan::Can<T>;
|
||||
impl<'d, T: Instance> Deref for Can<'d, T> {
|
||||
type Target = bxcan::Can<BxcanInstance<'d, T>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.can
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
|
||||
impl<'d, T: Instance> DerefMut for Can<'d, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.can
|
||||
}
|
||||
@ -63,15 +58,25 @@ impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
|
||||
|
||||
pub(crate) mod sealed {
|
||||
pub trait Instance {
|
||||
const REGISTERS: *mut bxcan::RegisterBlock;
|
||||
|
||||
fn regs() -> &'static crate::pac::can::Can;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance: sealed::Instance + RccPeripheral {}
|
||||
|
||||
pub struct BxcanInstance<'a, T>(PeripheralRef<'a, T>);
|
||||
|
||||
unsafe impl<'d, T: Instance> bxcan::Instance for BxcanInstance<'d, T> {
|
||||
const REGISTERS: *mut bxcan::RegisterBlock = T::REGISTERS;
|
||||
}
|
||||
|
||||
foreach_peripheral!(
|
||||
(can, $inst:ident) => {
|
||||
impl sealed::Instance for peripherals::$inst {
|
||||
const REGISTERS: *mut bxcan::RegisterBlock = crate::pac::$inst.0 as *mut _;
|
||||
|
||||
fn regs() -> &'static crate::pac::can::Can {
|
||||
&crate::pac::$inst
|
||||
}
|
||||
@ -79,15 +84,12 @@ foreach_peripheral!(
|
||||
|
||||
impl Instance for peripherals::$inst {}
|
||||
|
||||
unsafe impl bxcan::Instance for peripherals::$inst {
|
||||
const REGISTERS: *mut bxcan::RegisterBlock = crate::pac::$inst.0 as *mut _;
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
foreach_peripheral!(
|
||||
(can, CAN) => {
|
||||
unsafe impl bxcan::FilterOwner for peripherals::CAN {
|
||||
unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN> {
|
||||
const NUM_FILTER_BANKS: u8 = 14;
|
||||
}
|
||||
};
|
||||
@ -102,19 +104,19 @@ foreach_peripheral!(
|
||||
))] {
|
||||
// Most L4 devices and some F7 devices use the name "CAN1"
|
||||
// even if there is no "CAN2" peripheral.
|
||||
unsafe impl bxcan::FilterOwner for peripherals::CAN1 {
|
||||
unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN1> {
|
||||
const NUM_FILTER_BANKS: u8 = 14;
|
||||
}
|
||||
} else {
|
||||
unsafe impl bxcan::FilterOwner for peripherals::CAN1 {
|
||||
unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN1> {
|
||||
const NUM_FILTER_BANKS: u8 = 28;
|
||||
}
|
||||
unsafe impl bxcan::MasterInstance for peripherals::CAN1 {}
|
||||
unsafe impl<'d> bxcan::MasterInstance for BxcanInstance<'d, peripherals::CAN1> {}
|
||||
}
|
||||
}
|
||||
};
|
||||
(can, CAN3) => {
|
||||
unsafe impl bxcan::FilterOwner for peripherals::CAN3 {
|
||||
unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN3> {
|
||||
const NUM_FILTER_BANKS: u8 = 14;
|
||||
}
|
||||
};
|
||||
|
@ -1,31 +1,26 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::CRC as PAC_CRC;
|
||||
use crate::peripherals::CRC;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub struct Crc<'d> {
|
||||
_peripheral: CRC,
|
||||
_phantom: PhantomData<&'d mut CRC>,
|
||||
_peri: PeripheralRef<'d, CRC>,
|
||||
}
|
||||
|
||||
impl<'d> Crc<'d> {
|
||||
/// Instantiates the CRC32 peripheral and initializes it to default values.
|
||||
pub fn new(peripheral: impl Unborrow<Target = CRC> + 'd) -> Self {
|
||||
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd) -> Self {
|
||||
into_ref!(peripheral);
|
||||
|
||||
// Note: enable and reset come from RccPeripheral.
|
||||
// enable CRC clock in RCC.
|
||||
CRC::enable();
|
||||
// Reset CRC to default values.
|
||||
CRC::reset();
|
||||
// Unborrow the peripheral
|
||||
unborrow!(peripheral);
|
||||
let mut instance = Self {
|
||||
_peripheral: peripheral,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
// Peripheral the peripheral
|
||||
let mut instance = Self { _peri: peripheral };
|
||||
instance.reset();
|
||||
instance
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::crc::vals;
|
||||
use crate::pac::CRC as PAC_CRC;
|
||||
use crate::peripherals::CRC;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub struct Crc<'d> {
|
||||
_peripheral: CRC,
|
||||
_phantom: PhantomData<&'d mut CRC>,
|
||||
_peripheral: PeripheralRef<'d, CRC>,
|
||||
_config: Config,
|
||||
}
|
||||
|
||||
@ -70,16 +67,15 @@ pub enum PolySize {
|
||||
|
||||
impl<'d> Crc<'d> {
|
||||
/// Instantiates the CRC32 peripheral and initializes it to default values.
|
||||
pub fn new(peripheral: impl Unborrow<Target = CRC> + 'd, config: Config) -> Self {
|
||||
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self {
|
||||
// Note: enable and reset come from RccPeripheral.
|
||||
// enable CRC clock in RCC.
|
||||
CRC::enable();
|
||||
// Reset CRC to default values.
|
||||
CRC::reset();
|
||||
unborrow!(peripheral);
|
||||
into_ref!(peripheral);
|
||||
let mut instance = Self {
|
||||
_peripheral: peripheral,
|
||||
_phantom: PhantomData,
|
||||
_config: config,
|
||||
};
|
||||
CRC::reset();
|
||||
|
@ -1,10 +1,8 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::dac::{DacPin, Instance};
|
||||
use crate::pac::dac;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -90,7 +88,7 @@ pub enum Value {
|
||||
|
||||
pub struct Dac<'d, T: Instance> {
|
||||
channels: u8,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
macro_rules! enable {
|
||||
@ -102,21 +100,21 @@ macro_rules! enable {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Dac<'d, T> {
|
||||
pub fn new_1ch(peri: impl Unborrow<Target = T> + 'd, _ch1: impl Unborrow<Target = impl DacPin<T, 1>> + 'd) -> Self {
|
||||
unborrow!(peri);
|
||||
pub fn new_1ch(peri: impl Peripheral<P = T> + 'd, _ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd) -> Self {
|
||||
into_ref!(peri);
|
||||
Self::new_inner(peri, 1)
|
||||
}
|
||||
|
||||
pub fn new_2ch(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
_ch1: impl Unborrow<Target = impl DacPin<T, 1>> + 'd,
|
||||
_ch2: impl Unborrow<Target = impl DacPin<T, 2>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
_ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd,
|
||||
_ch2: impl Peripheral<P = impl DacPin<T, 2>> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(peri);
|
||||
into_ref!(peri);
|
||||
Self::new_inner(peri, 2)
|
||||
}
|
||||
|
||||
fn new_inner(_peri: T, channels: u8) -> Self {
|
||||
fn new_inner(peri: PeripheralRef<'d, T>, channels: u8) -> Self {
|
||||
unsafe {
|
||||
// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock
|
||||
// configuration.
|
||||
@ -144,10 +142,7 @@ impl<'d, T: Instance> Dac<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
channels,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { channels, _peri: peri }
|
||||
}
|
||||
|
||||
/// Check the channel is configured
|
||||
|
@ -1,14 +1,13 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::gpio::Speed;
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
/// The level on the VSync pin when the data is not valid on the parallel interface.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@ -70,7 +69,7 @@ impl Default for Config {
|
||||
|
||||
macro_rules! config_pins {
|
||||
($($pin:ident),*) => {
|
||||
unborrow!($($pin),*);
|
||||
into_ref!($($pin),*);
|
||||
// NOTE(unsafe) Exclusive access to the registers
|
||||
critical_section::with(|_| unsafe {
|
||||
$(
|
||||
@ -82,9 +81,8 @@ macro_rules! config_pins {
|
||||
}
|
||||
|
||||
pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
|
||||
inner: T,
|
||||
dma: Dma,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
inner: PeripheralRef<'d, T>,
|
||||
dma: PeripheralRef<'d, Dma>,
|
||||
}
|
||||
|
||||
impl<'d, T, Dma> Dcmi<'d, T, Dma>
|
||||
@ -93,23 +91,23 @@ where
|
||||
Dma: FrameDma<T>,
|
||||
{
|
||||
pub fn new_8bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
|
||||
config_pins!(v_sync, h_sync, pixclk);
|
||||
|
||||
@ -117,25 +115,25 @@ where
|
||||
}
|
||||
|
||||
pub fn new_10bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
|
||||
config_pins!(v_sync, h_sync, pixclk);
|
||||
|
||||
@ -143,27 +141,27 @@ where
|
||||
}
|
||||
|
||||
pub fn new_12bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
|
||||
d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
|
||||
v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
|
||||
d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
|
||||
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
|
||||
config_pins!(v_sync, h_sync, pixclk);
|
||||
|
||||
@ -171,29 +169,29 @@ where
|
||||
}
|
||||
|
||||
pub fn new_14bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
|
||||
d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
|
||||
d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
|
||||
d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
|
||||
v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
|
||||
d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
|
||||
d12: impl Peripheral<P = impl D12Pin<T>> + 'd,
|
||||
d13: impl Peripheral<P = impl D13Pin<T>> + 'd,
|
||||
v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
|
||||
h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
|
||||
config_pins!(v_sync, h_sync, pixclk);
|
||||
|
||||
@ -201,21 +199,21 @@ where
|
||||
}
|
||||
|
||||
pub fn new_es_8bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
|
||||
config_pins!(pixclk);
|
||||
|
||||
@ -223,23 +221,23 @@ where
|
||||
}
|
||||
|
||||
pub fn new_es_10bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
|
||||
config_pins!(pixclk);
|
||||
|
||||
@ -247,25 +245,25 @@ where
|
||||
}
|
||||
|
||||
pub fn new_es_12bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
|
||||
d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
|
||||
d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
|
||||
config_pins!(pixclk);
|
||||
|
||||
@ -273,27 +271,27 @@ where
|
||||
}
|
||||
|
||||
pub fn new_es_14bit(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
|
||||
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
|
||||
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
|
||||
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
|
||||
d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
|
||||
d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
|
||||
d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
|
||||
d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
|
||||
d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
|
||||
d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
|
||||
d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
|
||||
d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
|
||||
d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
|
||||
d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
|
||||
pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
|
||||
d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
|
||||
d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
|
||||
d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
|
||||
d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
|
||||
d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
|
||||
d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
|
||||
d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
|
||||
d12: impl Peripheral<P = impl D12Pin<T>> + 'd,
|
||||
d13: impl Peripheral<P = impl D13Pin<T>> + 'd,
|
||||
pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(peri, dma, irq);
|
||||
into_ref!(peri, dma, irq);
|
||||
config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
|
||||
config_pins!(pixclk);
|
||||
|
||||
@ -301,9 +299,9 @@ where
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
peri: T,
|
||||
dma: Dma,
|
||||
irq: T::Interrupt,
|
||||
peri: PeripheralRef<'d, T>,
|
||||
dma: PeripheralRef<'d, Dma>,
|
||||
irq: PeripheralRef<'d, T::Interrupt>,
|
||||
config: Config,
|
||||
use_embedded_synchronization: bool,
|
||||
edm: u8,
|
||||
@ -327,11 +325,7 @@ where
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
inner: peri,
|
||||
dma,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { inner: peri, dma }
|
||||
}
|
||||
|
||||
unsafe fn on_interrupt(_: *mut ()) {
|
||||
|
@ -8,16 +8,15 @@ mod dmamux;
|
||||
mod gpdma;
|
||||
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::mem;
|
||||
use core::pin::Pin;
|
||||
use core::task::{Context, Poll, Waker};
|
||||
|
||||
#[cfg(dmamux)]
|
||||
pub use dmamux::*;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{impl_peripheral, into_ref};
|
||||
|
||||
use crate::Unborrow;
|
||||
#[cfg(dmamux)]
|
||||
pub use self::dmamux::*;
|
||||
use crate::Peripheral;
|
||||
|
||||
#[cfg(feature = "unstable-pac")]
|
||||
pub mod low_level {
|
||||
@ -207,17 +206,19 @@ impl Default for TransferOptions {
|
||||
}
|
||||
|
||||
mod transfers {
|
||||
use embassy_hal_common::PeripheralRef;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn read<'a, W: Word>(
|
||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||
request: Request,
|
||||
reg_addr: *mut W,
|
||||
buf: &'a mut [W],
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
|
||||
unborrow!(channel);
|
||||
into_ref!(channel);
|
||||
|
||||
unsafe { channel.start_read::<W>(request, reg_addr, buf, Default::default()) };
|
||||
|
||||
@ -226,13 +227,13 @@ mod transfers {
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn write<'a, W: Word>(
|
||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||
request: Request,
|
||||
buf: &'a [W],
|
||||
reg_addr: *mut W,
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
|
||||
unborrow!(channel);
|
||||
into_ref!(channel);
|
||||
|
||||
unsafe { channel.start_write::<W>(request, buf, reg_addr, Default::default()) };
|
||||
|
||||
@ -241,13 +242,13 @@ mod transfers {
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn write_repeated<'a, W: Word>(
|
||||
channel: impl Unborrow<Target = impl Channel> + 'a,
|
||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||
request: Request,
|
||||
repeated: W,
|
||||
count: usize,
|
||||
reg_addr: *mut W,
|
||||
) -> impl Future<Output = ()> + 'a {
|
||||
unborrow!(channel);
|
||||
into_ref!(channel);
|
||||
|
||||
unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr, Default::default()) };
|
||||
|
||||
@ -255,17 +256,13 @@ mod transfers {
|
||||
}
|
||||
|
||||
pub(crate) struct Transfer<'a, C: Channel> {
|
||||
channel: C,
|
||||
_phantom: PhantomData<&'a mut C>,
|
||||
channel: PeripheralRef<'a, C>,
|
||||
}
|
||||
|
||||
impl<'a, C: Channel> Transfer<'a, C> {
|
||||
pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self {
|
||||
unborrow!(channel);
|
||||
Self {
|
||||
channel,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self {
|
||||
into_ref!(channel);
|
||||
Self { channel }
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,17 +287,11 @@ mod transfers {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Channel: sealed::Channel + Unborrow<Target = Self> + 'static {}
|
||||
pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static {}
|
||||
|
||||
pub struct NoDma;
|
||||
|
||||
unsafe impl Unborrow for NoDma {
|
||||
type Target = NoDma;
|
||||
|
||||
unsafe fn unborrow(self) -> Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl_peripheral!(NoDma);
|
||||
|
||||
// safety: must be called only once at startup
|
||||
pub(crate) unsafe fn init() {
|
||||
|
@ -6,7 +6,7 @@ use core::task::Waker;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
|
||||
|
||||
use crate::gpio::sealed::{AFType, Pin as __GpioPin};
|
||||
@ -16,7 +16,7 @@ use crate::pac::AFIO;
|
||||
#[cfg(any(eth_v1b, eth_v1c))]
|
||||
use crate::pac::SYSCFG;
|
||||
use crate::pac::{ETH, RCC};
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
mod descriptors;
|
||||
mod rx_desc;
|
||||
@ -36,7 +36,7 @@ impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
|
||||
|
||||
pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
|
||||
state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
|
||||
pins: [AnyPin; 9],
|
||||
pins: [PeripheralRef<'d, AnyPin>; 9],
|
||||
_phy: P,
|
||||
clock_range: Cr,
|
||||
phy_addr: u8,
|
||||
@ -86,22 +86,22 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
|
||||
/// safety: the returned instance is not leak-safe
|
||||
pub unsafe fn new(
|
||||
state: &'d mut State<'d, T, TX, RX>,
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
|
||||
ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
|
||||
mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
|
||||
mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
|
||||
crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
|
||||
rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
|
||||
rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
|
||||
tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
|
||||
tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
|
||||
tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
interrupt: impl Peripheral<P = crate::interrupt::ETH> + 'd,
|
||||
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
|
||||
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
|
||||
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
|
||||
crs: impl Peripheral<P = impl CRSPin<T>> + 'd,
|
||||
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
|
||||
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
|
||||
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
|
||||
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
|
||||
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
|
||||
phy: P,
|
||||
mac_addr: [u8; 6],
|
||||
phy_addr: u8,
|
||||
) -> Self {
|
||||
unborrow!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
||||
into_ref!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
||||
|
||||
// Enable the necessary Clocks
|
||||
// NOTE(unsafe) We have exclusive access to the registers
|
||||
@ -207,15 +207,15 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
|
||||
};
|
||||
|
||||
let pins = [
|
||||
ref_clk.degrade(),
|
||||
mdio.degrade(),
|
||||
mdc.degrade(),
|
||||
crs.degrade(),
|
||||
rx_d0.degrade(),
|
||||
rx_d1.degrade(),
|
||||
tx_d0.degrade(),
|
||||
tx_d1.degrade(),
|
||||
tx_en.degrade(),
|
||||
ref_clk.map_into(),
|
||||
mdio.map_into(),
|
||||
mdc.map_into(),
|
||||
crs.map_into(),
|
||||
rx_d0.map_into(),
|
||||
rx_d1.map_into(),
|
||||
tx_d0.map_into(),
|
||||
tx_d1.map_into(),
|
||||
tx_en.map_into(),
|
||||
];
|
||||
|
||||
let mut this = Self {
|
||||
@ -370,7 +370,7 @@ struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd) -> Self {
|
||||
Self {
|
||||
_peri: PhantomData,
|
||||
desc_ring: DescriptorRing::new(),
|
||||
|
@ -4,13 +4,13 @@ use core::task::Waker;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
|
||||
|
||||
use crate::gpio::sealed::{AFType, Pin as _};
|
||||
use crate::gpio::{AnyPin, Speed};
|
||||
use crate::pac::{ETH, RCC, SYSCFG};
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
mod descriptors;
|
||||
use descriptors::DescriptorRing;
|
||||
@ -25,7 +25,7 @@ impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
|
||||
}
|
||||
pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
|
||||
state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
|
||||
pins: [AnyPin; 9],
|
||||
pins: [PeripheralRef<'d, AnyPin>; 9],
|
||||
_phy: P,
|
||||
clock_range: u8,
|
||||
phy_addr: u8,
|
||||
@ -48,22 +48,22 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
|
||||
/// safety: the returned instance is not leak-safe
|
||||
pub unsafe fn new(
|
||||
state: &'d mut State<'d, T, TX, RX>,
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
|
||||
ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
|
||||
mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
|
||||
mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
|
||||
crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
|
||||
rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
|
||||
rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
|
||||
tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
|
||||
tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
|
||||
tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
interrupt: impl Peripheral<P = crate::interrupt::ETH> + 'd,
|
||||
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
|
||||
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
|
||||
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
|
||||
crs: impl Peripheral<P = impl CRSPin<T>> + 'd,
|
||||
rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
|
||||
rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
|
||||
tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
|
||||
tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
|
||||
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
|
||||
phy: P,
|
||||
mac_addr: [u8; 6],
|
||||
phy_addr: u8,
|
||||
) -> Self {
|
||||
unborrow!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
||||
into_ref!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
||||
|
||||
// Enable the necessary Clocks
|
||||
// NOTE(unsafe) We have exclusive access to the registers
|
||||
@ -143,15 +143,15 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
|
||||
};
|
||||
|
||||
let pins = [
|
||||
ref_clk.degrade(),
|
||||
mdio.degrade(),
|
||||
mdc.degrade(),
|
||||
crs.degrade(),
|
||||
rx_d0.degrade(),
|
||||
rx_d1.degrade(),
|
||||
tx_d0.degrade(),
|
||||
tx_d1.degrade(),
|
||||
tx_en.degrade(),
|
||||
ref_clk.map_into(),
|
||||
mdio.map_into(),
|
||||
mdc.map_into(),
|
||||
crs.map_into(),
|
||||
rx_d0.map_into(),
|
||||
rx_d1.map_into(),
|
||||
tx_d0.map_into(),
|
||||
tx_d1.map_into(),
|
||||
tx_en.map_into(),
|
||||
];
|
||||
|
||||
let mut this = Self {
|
||||
@ -316,7 +316,7 @@ struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
|
||||
pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
pub fn new(_peri: impl Peripheral<P = T> + 'd) -> Self {
|
||||
Self {
|
||||
_peri: PhantomData,
|
||||
desc_ring: DescriptorRing::new(),
|
||||
|
@ -4,12 +4,12 @@ use core::pin::Pin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unsafe_impl_unborrow;
|
||||
use embassy_hal_common::impl_peripheral;
|
||||
|
||||
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
||||
use crate::pac::exti::regs::Lines;
|
||||
use crate::pac::EXTI;
|
||||
use crate::{interrupt, pac, peripherals, Unborrow};
|
||||
use crate::{interrupt, pac, peripherals, Peripheral};
|
||||
|
||||
const EXTI_COUNT: usize = 16;
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
@ -86,7 +86,7 @@ pub struct ExtiInput<'d, T: GpioPin> {
|
||||
impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {}
|
||||
|
||||
impl<'d, T: GpioPin> ExtiInput<'d, T> {
|
||||
pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
|
||||
pub fn new(pin: Input<'d, T>, _ch: impl Peripheral<P = T::ExtiChannel> + 'd) -> Self {
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
@ -320,7 +320,7 @@ pub trait Channel: sealed::Channel + Sized {
|
||||
pub struct AnyChannel {
|
||||
number: u8,
|
||||
}
|
||||
unsafe_impl_unborrow!(AnyChannel);
|
||||
impl_peripheral!(AnyChannel);
|
||||
impl sealed::Channel for AnyChannel {}
|
||||
impl Channel for AnyChannel {
|
||||
fn number(&self) -> usize {
|
||||
|
@ -1,11 +1,9 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
|
||||
|
||||
pub use crate::pac::{ERASE_SIZE, ERASE_VALUE, FLASH_BASE, FLASH_SIZE, WRITE_SIZE};
|
||||
use crate::peripherals::FLASH;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
const FLASH_END: usize = FLASH_BASE + FLASH_SIZE;
|
||||
|
||||
#[cfg_attr(any(flash_wl, flash_wb, flash_l0, flash_l1, flash_l4), path = "l.rs")]
|
||||
@ -16,20 +14,16 @@ const FLASH_END: usize = FLASH_BASE + FLASH_SIZE;
|
||||
mod family;
|
||||
|
||||
pub struct Flash<'d> {
|
||||
_inner: FLASH,
|
||||
_phantom: PhantomData<&'d mut FLASH>,
|
||||
_inner: PeripheralRef<'d, FLASH>,
|
||||
}
|
||||
|
||||
impl<'d> Flash<'d> {
|
||||
pub fn new(p: impl Unborrow<Target = FLASH>) -> Self {
|
||||
unborrow!(p);
|
||||
Self {
|
||||
_inner: p,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
pub fn new(p: impl Peripheral<P = FLASH> + 'd) -> Self {
|
||||
into_ref!(p);
|
||||
Self { _inner: p }
|
||||
}
|
||||
|
||||
pub fn unlock(p: impl Unborrow<Target = FLASH>) -> Self {
|
||||
pub fn unlock(p: impl Peripheral<P = FLASH> + 'd) -> Self {
|
||||
let flash = Self::new(p);
|
||||
|
||||
unsafe { family::unlock() };
|
||||
|
@ -1,10 +1,10 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::gpio::{Pull, Speed};
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
mod pins;
|
||||
pub use pins::*;
|
||||
@ -39,7 +39,7 @@ where
|
||||
|
||||
macro_rules! config_pins {
|
||||
($($pin:ident),*) => {
|
||||
unborrow!($($pin),*);
|
||||
into_ref!($($pin),*);
|
||||
$(
|
||||
$pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
$pin.set_speed(Speed::VeryHigh);
|
||||
@ -57,12 +57,12 @@ macro_rules! fmc_sdram_constructor {
|
||||
ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*]
|
||||
)) => {
|
||||
pub fn $name<CHIP: stm32_fmc::SdramChip>(
|
||||
_instance: impl Unborrow<Target = T> + 'd,
|
||||
$($addr_pin_name: impl Unborrow<Target = impl $addr_signal<T>> + 'd),*,
|
||||
$($ba_pin_name: impl Unborrow<Target = impl $ba_signal<T>> + 'd),*,
|
||||
$($d_pin_name: impl Unborrow<Target = impl $d_signal<T>> + 'd),*,
|
||||
$($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal<T>> + 'd),*,
|
||||
$($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal<T>> + 'd),*,
|
||||
_instance: impl Peripheral<P = T> + 'd,
|
||||
$($addr_pin_name: impl Peripheral<P = impl $addr_signal<T>> + 'd),*,
|
||||
$($ba_pin_name: impl Peripheral<P = impl $ba_signal<T>> + 'd),*,
|
||||
$($d_pin_name: impl Peripheral<P = impl $d_signal<T>> + 'd),*,
|
||||
$($nbl_pin_name: impl Peripheral<P = impl $nbl_signal<T>> + 'd),*,
|
||||
$($ctrl_pin_name: impl Peripheral<P = impl $ctrl_signal<T>> + 'd),*,
|
||||
chip: CHIP
|
||||
) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
#![macro_use]
|
||||
use core::convert::Infallible;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::gpio::{self, vals};
|
||||
use crate::{pac, peripherals, Unborrow};
|
||||
use crate::{pac, peripherals, Peripheral};
|
||||
|
||||
/// GPIO flexible pin.
|
||||
///
|
||||
@ -13,8 +12,7 @@ use crate::{pac, peripherals, Unborrow};
|
||||
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
|
||||
/// mode.
|
||||
pub struct Flex<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
pub(crate) pin: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Flex<'d, T> {
|
||||
@ -24,13 +22,10 @@ impl<'d, T: Pin> Flex<'d, T> {
|
||||
/// before the pin is put into output mode.
|
||||
///
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
unborrow!(pin);
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
|
||||
into_ref!(pin);
|
||||
// Pin will be in disconnected state.
|
||||
Self {
|
||||
pin,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
/// Put the pin into input mode.
|
||||
@ -285,7 +280,7 @@ pub struct Input<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Input<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
pin.set_as_input(pull);
|
||||
Self { pin }
|
||||
@ -340,7 +335,7 @@ pub struct Output<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, speed: Speed) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
match initial_output {
|
||||
Level::High => pin.set_high(),
|
||||
@ -400,7 +395,7 @@ pub struct OutputOpenDrain<'d, T: Pin> {
|
||||
|
||||
impl<'d, T: Pin> OutputOpenDrain<'d, T> {
|
||||
#[inline]
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self {
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
|
||||
match initial_output {
|
||||
@ -626,7 +621,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Pin: sealed::Pin + Sized + 'static {
|
||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
|
||||
#[cfg(feature = "exti")]
|
||||
type ExtiChannel: crate::exti::Channel;
|
||||
|
||||
@ -673,7 +668,7 @@ impl AnyPin {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_impl_unborrow!(AnyPin);
|
||||
impl_peripheral!(AnyPin);
|
||||
impl Pin for AnyPin {
|
||||
#[cfg(feature = "exti")]
|
||||
type ExtiChannel = crate::exti::AnyChannel;
|
||||
@ -699,6 +694,12 @@ foreach_pin!(
|
||||
$port_num * 16 + $pin_num
|
||||
}
|
||||
}
|
||||
|
||||
impl From<peripherals::$pin_name> for AnyPin {
|
||||
fn from(x: peripherals::$pin_name) -> Self {
|
||||
x.degrade()
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
||||
use crate::pac::i2c;
|
||||
use crate::time::Hertz;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub struct State {}
|
||||
|
||||
@ -23,12 +23,12 @@ pub struct I2c<'d, T: Instance> {
|
||||
|
||||
impl<'d, T: Instance> I2c<'d, T> {
|
||||
pub fn new(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
scl: impl Unborrow<Target = impl SclPin<T>> + 'd,
|
||||
sda: impl Unborrow<Target = impl SdaPin<T>> + 'd,
|
||||
_peri: impl Peripheral<P = T> + 'd,
|
||||
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
|
||||
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
unborrow!(scl, sda);
|
||||
into_ref!(scl, sda);
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
|
@ -1,12 +1,11 @@
|
||||
use core::cmp;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use atomic_polyfill::{AtomicUsize, Ordering};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::dma::NoDma;
|
||||
@ -15,7 +14,7 @@ use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::pac::i2c;
|
||||
use crate::time::Hertz;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub struct State {
|
||||
waker: AtomicWaker,
|
||||
@ -32,23 +31,23 @@ impl State {
|
||||
}
|
||||
|
||||
pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx_dma: TXDMA,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
tx_dma: PeripheralRef<'d, TXDMA>,
|
||||
#[allow(dead_code)]
|
||||
rx_dma: RXDMA,
|
||||
rx_dma: PeripheralRef<'d, RXDMA>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
||||
pub fn new(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
scl: impl Unborrow<Target = impl SclPin<T>> + 'd,
|
||||
sda: impl Unborrow<Target = impl SdaPin<T>> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
tx_dma: impl Unborrow<Target = TXDMA> + 'd,
|
||||
rx_dma: impl Unborrow<Target = RXDMA> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
|
||||
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
tx_dma: impl Peripheral<P = TXDMA> + 'd,
|
||||
rx_dma: impl Peripheral<P = RXDMA> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
unborrow!(irq, scl, sda, tx_dma, rx_dma);
|
||||
into_ref!(peri, irq, scl, sda, tx_dma, rx_dma);
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
@ -88,7 +87,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
_peri: peri,
|
||||
tx_dma,
|
||||
rx_dma,
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ pub(crate) mod _generated {
|
||||
// Reexports
|
||||
pub use _generated::{peripherals, Peripherals};
|
||||
pub use embassy_cortex_m::executor;
|
||||
pub use embassy_hal_common::{unborrow, Unborrow};
|
||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
pub use embassy_macros::cortex_m_interrupt as interrupt;
|
||||
#[cfg(feature = "unstable-pac")]
|
||||
pub use stm32_metapac as pac;
|
||||
|
@ -1,21 +1,18 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use super::*;
|
||||
#[allow(unused_imports)]
|
||||
use crate::gpio::sealed::{AFType, Pin};
|
||||
use crate::time::Hertz;
|
||||
use crate::Unborrow;
|
||||
use crate::Peripheral;
|
||||
|
||||
pub struct SimplePwm<'d, T> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
inner: T,
|
||||
inner: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
macro_rules! config_pins {
|
||||
($($pin:ident),*) => {
|
||||
unborrow!($($pin),*);
|
||||
into_ref!($($pin),*);
|
||||
// NOTE(unsafe) Exclusive access to the registers
|
||||
critical_section::with(|_| unsafe {
|
||||
$(
|
||||
@ -30,8 +27,8 @@ macro_rules! config_pins {
|
||||
|
||||
impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
|
||||
pub fn new_1ch(
|
||||
tim: impl Unborrow<Target = T> + 'd,
|
||||
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
|
||||
tim: impl Peripheral<P = T> + 'd,
|
||||
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
Self::new_inner(tim, freq, move || {
|
||||
@ -40,9 +37,9 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
|
||||
}
|
||||
|
||||
pub fn new_2ch(
|
||||
tim: impl Unborrow<Target = T> + 'd,
|
||||
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
|
||||
tim: impl Peripheral<P = T> + 'd,
|
||||
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
Self::new_inner(tim, freq, move || {
|
||||
@ -51,10 +48,10 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
|
||||
}
|
||||
|
||||
pub fn new_3ch(
|
||||
tim: impl Unborrow<Target = T> + 'd,
|
||||
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
|
||||
tim: impl Peripheral<P = T> + 'd,
|
||||
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
Self::new_inner(tim, freq, move || {
|
||||
@ -63,11 +60,11 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
|
||||
}
|
||||
|
||||
pub fn new_4ch(
|
||||
tim: impl Unborrow<Target = T> + 'd,
|
||||
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
|
||||
ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd,
|
||||
tim: impl Peripheral<P = T> + 'd,
|
||||
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
|
||||
ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
Self::new_inner(tim, freq, move || {
|
||||
@ -75,18 +72,15 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
|
||||
})
|
||||
}
|
||||
|
||||
fn new_inner(tim: impl Unborrow<Target = T> + 'd, freq: Hertz, configure_pins: impl FnOnce()) -> Self {
|
||||
unborrow!(tim);
|
||||
fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, configure_pins: impl FnOnce()) -> Self {
|
||||
into_ref!(tim);
|
||||
|
||||
T::enable();
|
||||
<T as crate::rcc::sealed::RccPeripheral>::reset();
|
||||
|
||||
configure_pins();
|
||||
|
||||
let mut this = Self {
|
||||
inner: tim,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
let mut this = Self { inner: tim };
|
||||
|
||||
this.inner.set_frequency(freq);
|
||||
this.inner.start();
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
pub use pll::PllConfig;
|
||||
use stm32_metapac::rcc::vals::{Mco1, Mco2};
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::pac::rcc::vals::{Adcsel, Ckpersel, Dppre, Hpre, Hsidiv, Pllsrc, Sw, T
|
||||
use crate::pac::{PWR, RCC, SYSCFG};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
/// HSI speed
|
||||
pub const HSI_FREQ: Hertz = Hertz(64_000_000);
|
||||
@ -385,12 +385,12 @@ pub struct Mco<'d, T: McoInstance> {
|
||||
|
||||
impl<'d, T: McoInstance> Mco<'d, T> {
|
||||
pub fn new(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
pin: impl Unborrow<Target = impl McoPin<T>> + 'd,
|
||||
_peri: impl Peripheral<P = T> + 'd,
|
||||
pin: impl Peripheral<P = impl McoPin<T>> + 'd,
|
||||
source: impl McoSource<Raw = T::Source>,
|
||||
prescaler: McoClock,
|
||||
) -> Self {
|
||||
unborrow!(pin);
|
||||
into_ref!(pin);
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
|
||||
|
@ -1,14 +1,13 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
use crate::{pac, peripherals, Unborrow};
|
||||
use crate::{pac, peripherals, Peripheral};
|
||||
|
||||
pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
@ -19,19 +18,15 @@ pub enum Error {
|
||||
}
|
||||
|
||||
pub struct Rng<'d, T: Instance> {
|
||||
_inner: T,
|
||||
_phantom: PhantomData<&'d mut T>,
|
||||
_inner: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Rng<'d, T> {
|
||||
pub fn new(inner: impl Unborrow<Target = T> + 'd) -> Self {
|
||||
pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self {
|
||||
T::enable();
|
||||
T::reset();
|
||||
unborrow!(inner);
|
||||
let mut random = Self {
|
||||
_inner: inner,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
into_ref!(inner);
|
||||
let mut random = Self { _inner: inner };
|
||||
random.reset();
|
||||
random
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::default::Default;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use futures::future::poll_fn;
|
||||
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
|
||||
|
||||
use crate::dma::NoDma;
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::gpio::{Pull, Speed};
|
||||
use crate::gpio::sealed::{AFType, Pin};
|
||||
use crate::gpio::{AnyPin, Pull, Speed};
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::pac::sdmmc::Sdmmc as RegBlock;
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::time::Hertz;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
/// The signalling scheme used on the SDMMC bus
|
||||
#[non_exhaustive]
|
||||
@ -176,12 +175,19 @@ impl Default for Config {
|
||||
}
|
||||
|
||||
/// Sdmmc device
|
||||
pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
|
||||
sdmmc: PhantomData<&'d mut T>,
|
||||
pins: P,
|
||||
irq: T::Interrupt,
|
||||
pub struct Sdmmc<'d, T: Instance, Dma = NoDma> {
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
irq: PeripheralRef<'d, T::Interrupt>,
|
||||
dma: PeripheralRef<'d, Dma>,
|
||||
|
||||
clk: PeripheralRef<'d, AnyPin>,
|
||||
cmd: PeripheralRef<'d, AnyPin>,
|
||||
d0: PeripheralRef<'d, AnyPin>,
|
||||
d1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
|
||||
config: Config,
|
||||
dma: Dma,
|
||||
/// Current clock to card
|
||||
clock: Hertz,
|
||||
/// Current signalling scheme to card
|
||||
@ -191,16 +197,99 @@ pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
|
||||
}
|
||||
|
||||
#[cfg(sdmmc_v1)]
|
||||
impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
pub fn new(
|
||||
_peripheral: impl Unborrow<Target = T> + 'd,
|
||||
pins: impl Unborrow<Target = P> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
|
||||
pub fn new_1bit(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
clk: impl Peripheral<P = impl CkPin<T>> + 'd,
|
||||
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
config: Config,
|
||||
dma: impl Unborrow<Target = Dma> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(irq, pins, dma);
|
||||
pins.configure();
|
||||
into_ref!(clk, cmd, d0);
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk.set_speed(Speed::VeryHigh);
|
||||
cmd.set_speed(Speed::VeryHigh);
|
||||
d0.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
irq,
|
||||
dma,
|
||||
clk.map_into(),
|
||||
cmd.map_into(),
|
||||
d0.map_into(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_4bit(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
clk: impl Peripheral<P = impl CkPin<T>> + 'd,
|
||||
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(clk, cmd, d0, d1, d2, d3);
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk.set_speed(Speed::VeryHigh);
|
||||
cmd.set_speed(Speed::VeryHigh);
|
||||
d0.set_speed(Speed::VeryHigh);
|
||||
d1.set_speed(Speed::VeryHigh);
|
||||
d2.set_speed(Speed::VeryHigh);
|
||||
d3.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
irq,
|
||||
dma,
|
||||
clk.map_into(),
|
||||
cmd.map_into(),
|
||||
d0.map_into(),
|
||||
Some(d1.map_into()),
|
||||
Some(d2.map_into()),
|
||||
Some(d3.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
dma: impl Peripheral<P = Dma> + 'd,
|
||||
clk: PeripheralRef<'d, AnyPin>,
|
||||
cmd: PeripheralRef<'d, AnyPin>,
|
||||
d0: PeripheralRef<'d, AnyPin>,
|
||||
d1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(sdmmc, irq, dma);
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
@ -213,11 +302,18 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
sdmmc: PhantomData,
|
||||
pins,
|
||||
_peri: sdmmc,
|
||||
irq,
|
||||
config,
|
||||
dma,
|
||||
|
||||
clk,
|
||||
cmd,
|
||||
d0,
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
|
||||
config,
|
||||
clock,
|
||||
signalling: Default::default(),
|
||||
card: None,
|
||||
@ -226,15 +322,94 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
}
|
||||
|
||||
#[cfg(sdmmc_v2)]
|
||||
impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
|
||||
pub fn new(
|
||||
_peripheral: impl Unborrow<Target = T> + 'd,
|
||||
pins: impl Unborrow<Target = P> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
|
||||
pub fn new_1bit(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
clk: impl Peripheral<P = impl CkPin<T>> + 'd,
|
||||
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(irq, pins);
|
||||
pins.configure();
|
||||
into_ref!(clk, cmd, d0);
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk.set_speed(Speed::VeryHigh);
|
||||
cmd.set_speed(Speed::VeryHigh);
|
||||
d0.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
irq,
|
||||
clk.map_into(),
|
||||
cmd.map_into(),
|
||||
d0.map_into(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_4bit(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
clk: impl Peripheral<P = impl CkPin<T>> + 'd,
|
||||
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
|
||||
d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
|
||||
d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
|
||||
d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
|
||||
d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(clk, cmd, d0, d1, d2, d3);
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk.set_speed(Speed::VeryHigh);
|
||||
cmd.set_speed(Speed::VeryHigh);
|
||||
d0.set_speed(Speed::VeryHigh);
|
||||
d1.set_speed(Speed::VeryHigh);
|
||||
d2.set_speed(Speed::VeryHigh);
|
||||
d3.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
irq,
|
||||
clk.map_into(),
|
||||
cmd.map_into(),
|
||||
d0.map_into(),
|
||||
Some(d1.map_into()),
|
||||
Some(d2.map_into()),
|
||||
Some(d3.map_into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
sdmmc: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
clk: PeripheralRef<'d, AnyPin>,
|
||||
cmd: PeripheralRef<'d, AnyPin>,
|
||||
d0: PeripheralRef<'d, AnyPin>,
|
||||
d1: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d2: Option<PeripheralRef<'d, AnyPin>>,
|
||||
d3: Option<PeripheralRef<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(sdmmc, irq);
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
@ -247,11 +422,18 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
|
||||
irq.enable();
|
||||
|
||||
Self {
|
||||
sdmmc: PhantomData,
|
||||
pins,
|
||||
_peri: sdmmc,
|
||||
irq,
|
||||
dma: NoDma.into_ref(),
|
||||
|
||||
clk,
|
||||
cmd,
|
||||
d0,
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
|
||||
config,
|
||||
dma: NoDma,
|
||||
clock,
|
||||
signalling: Default::default(),
|
||||
card: None,
|
||||
@ -259,23 +441,28 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
|
||||
#[inline(always)]
|
||||
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
|
||||
let inner = T::inner();
|
||||
let freq = freq.into();
|
||||
|
||||
let bus_width = match self.d3.is_some() {
|
||||
true => BusWidth::Four,
|
||||
false => BusWidth::One,
|
||||
};
|
||||
|
||||
inner
|
||||
.init_card(
|
||||
freq,
|
||||
P::BUSWIDTH,
|
||||
bus_width,
|
||||
&mut self.card,
|
||||
&mut self.signalling,
|
||||
T::frequency(),
|
||||
&mut self.clock,
|
||||
T::state(),
|
||||
self.config.data_transfer_timeout,
|
||||
&mut self.dma,
|
||||
&mut *self.dma,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -295,7 +482,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
card_capacity,
|
||||
state,
|
||||
self.config.data_transfer_timeout,
|
||||
&mut self.dma,
|
||||
&mut *self.dma,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -314,7 +501,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
card,
|
||||
state,
|
||||
self.config.data_transfer_timeout,
|
||||
&mut self.dma,
|
||||
&mut *self.dma,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -345,12 +532,26 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, P: Pins<T>, Dma> Drop for Sdmmc<'d, T, P, Dma> {
|
||||
impl<'d, T: Instance, Dma> Drop for Sdmmc<'d, T, Dma> {
|
||||
fn drop(&mut self) {
|
||||
self.irq.disable();
|
||||
let inner = T::inner();
|
||||
unsafe { inner.on_drop() };
|
||||
self.pins.deconfigure();
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
self.clk.set_as_disconnected();
|
||||
self.cmd.set_as_disconnected();
|
||||
self.d0.set_as_disconnected();
|
||||
if let Some(x) = &mut self.d1 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d2 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d3 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1296,114 +1497,6 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Pins<T: Instance>: sealed::Pins<T> + 'static {
|
||||
const BUSWIDTH: BusWidth;
|
||||
|
||||
fn configure(&mut self);
|
||||
fn deconfigure(&mut self);
|
||||
}
|
||||
|
||||
impl<T, CLK, CMD, D0, D1, D2, D3> sealed::Pins<T> for (CLK, CMD, D0, D1, D2, D3)
|
||||
where
|
||||
T: Instance,
|
||||
CLK: CkPin<T>,
|
||||
CMD: CmdPin<T>,
|
||||
D0: D0Pin<T>,
|
||||
D1: D1Pin<T>,
|
||||
D2: D2Pin<T>,
|
||||
D3: D3Pin<T>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, CLK, CMD, D0> sealed::Pins<T> for (CLK, CMD, D0)
|
||||
where
|
||||
T: Instance,
|
||||
CLK: CkPin<T>,
|
||||
CMD: CmdPin<T>,
|
||||
D0: D0Pin<T>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, CLK, CMD, D0, D1, D2, D3> Pins<T> for (CLK, CMD, D0, D1, D2, D3)
|
||||
where
|
||||
T: Instance,
|
||||
CLK: CkPin<T>,
|
||||
CMD: CmdPin<T>,
|
||||
D0: D0Pin<T>,
|
||||
D1: D1Pin<T>,
|
||||
D2: D2Pin<T>,
|
||||
D3: D3Pin<T>,
|
||||
{
|
||||
const BUSWIDTH: BusWidth = BusWidth::Four;
|
||||
|
||||
fn configure(&mut self) {
|
||||
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d1_pin.set_as_af_pull(d1_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d2_pin.set_as_af_pull(d2_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d3_pin.set_as_af_pull(d3_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk_pin.set_speed(Speed::VeryHigh);
|
||||
cmd_pin.set_speed(Speed::VeryHigh);
|
||||
d0_pin.set_speed(Speed::VeryHigh);
|
||||
d1_pin.set_speed(Speed::VeryHigh);
|
||||
d2_pin.set_speed(Speed::VeryHigh);
|
||||
d3_pin.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
}
|
||||
|
||||
fn deconfigure(&mut self) {
|
||||
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk_pin.set_as_disconnected();
|
||||
cmd_pin.set_as_disconnected();
|
||||
d0_pin.set_as_disconnected();
|
||||
d1_pin.set_as_disconnected();
|
||||
d2_pin.set_as_disconnected();
|
||||
d3_pin.set_as_disconnected();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CLK, CMD, D0> Pins<T> for (CLK, CMD, D0)
|
||||
where
|
||||
T: Instance,
|
||||
CLK: CkPin<T>,
|
||||
CMD: CmdPin<T>,
|
||||
D0: D0Pin<T>,
|
||||
{
|
||||
const BUSWIDTH: BusWidth = BusWidth::One;
|
||||
|
||||
fn configure(&mut self) {
|
||||
let (clk_pin, cmd_pin, d0_pin) = self;
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
|
||||
cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
|
||||
|
||||
clk_pin.set_speed(Speed::VeryHigh);
|
||||
cmd_pin.set_speed(Speed::VeryHigh);
|
||||
d0_pin.set_speed(Speed::VeryHigh);
|
||||
});
|
||||
}
|
||||
|
||||
fn deconfigure(&mut self) {
|
||||
let (clk_pin, cmd_pin, d0_pin) = self;
|
||||
|
||||
critical_section::with(|_| unsafe {
|
||||
clk_pin.set_as_disconnected();
|
||||
cmd_pin.set_as_disconnected();
|
||||
d0_pin.set_as_disconnected();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach_peripheral!(
|
||||
(sdmmc, $inst:ident) => {
|
||||
impl sealed::Instance for peripherals::$inst {
|
||||
|
@ -1,10 +1,9 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
use futures::future::join;
|
||||
|
||||
@ -15,7 +14,7 @@ use crate::gpio::AnyPin;
|
||||
use crate::pac::spi::{regs, vals, Spi as Regs};
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::time::Hertz;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -73,27 +72,27 @@ impl Config {
|
||||
}
|
||||
|
||||
pub struct Spi<'d, T: Instance, Tx, Rx> {
|
||||
sck: Option<AnyPin>,
|
||||
mosi: Option<AnyPin>,
|
||||
miso: Option<AnyPin>,
|
||||
txdma: Tx,
|
||||
rxdma: Rx,
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
sck: Option<PeripheralRef<'d, AnyPin>>,
|
||||
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
||||
miso: Option<PeripheralRef<'d, AnyPin>>,
|
||||
txdma: PeripheralRef<'d, Tx>,
|
||||
rxdma: PeripheralRef<'d, Rx>,
|
||||
current_word_size: WordSize,
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
pub fn new(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
sck: impl Unborrow<Target = impl SckPin<T>> + 'd,
|
||||
mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd,
|
||||
miso: impl Unborrow<Target = impl MisoPin<T>> + 'd,
|
||||
txdma: impl Unborrow<Target = Tx> + 'd,
|
||||
rxdma: impl Unborrow<Target = Rx> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
sck: impl Peripheral<P = impl SckPin<T>> + 'd,
|
||||
mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
|
||||
miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
|
||||
txdma: impl Peripheral<P = Tx> + 'd,
|
||||
rxdma: impl Peripheral<P = Rx> + 'd,
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, mosi, miso);
|
||||
into_ref!(peri, sck, mosi, miso);
|
||||
unsafe {
|
||||
sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
|
||||
#[cfg(any(spi_v2, spi_v3, spi_v4))]
|
||||
@ -108,9 +107,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
|
||||
Self::new_inner(
|
||||
peri,
|
||||
Some(sck.degrade()),
|
||||
Some(mosi.degrade()),
|
||||
Some(miso.degrade()),
|
||||
Some(sck.map_into()),
|
||||
Some(mosi.map_into()),
|
||||
Some(miso.map_into()),
|
||||
txdma,
|
||||
rxdma,
|
||||
freq,
|
||||
@ -119,15 +118,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
}
|
||||
|
||||
pub fn new_rxonly(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
sck: impl Unborrow<Target = impl SckPin<T>> + 'd,
|
||||
miso: impl Unborrow<Target = impl MisoPin<T>> + 'd,
|
||||
txdma: impl Unborrow<Target = Tx> + 'd, // TODO remove
|
||||
rxdma: impl Unborrow<Target = Rx> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
sck: impl Peripheral<P = impl SckPin<T>> + 'd,
|
||||
miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
|
||||
txdma: impl Peripheral<P = Tx> + 'd, // TODO remove
|
||||
rxdma: impl Peripheral<P = Rx> + 'd,
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, miso);
|
||||
into_ref!(sck, miso);
|
||||
unsafe {
|
||||
sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
|
||||
#[cfg(any(spi_v2, spi_v3, spi_v4))]
|
||||
@ -139,9 +138,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
|
||||
Self::new_inner(
|
||||
peri,
|
||||
Some(sck.degrade()),
|
||||
Some(sck.map_into()),
|
||||
None,
|
||||
Some(miso.degrade()),
|
||||
Some(miso.map_into()),
|
||||
txdma,
|
||||
rxdma,
|
||||
freq,
|
||||
@ -150,15 +149,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
}
|
||||
|
||||
pub fn new_txonly(
|
||||
peri: impl Unborrow<Target = T> + 'd,
|
||||
sck: impl Unborrow<Target = impl SckPin<T>> + 'd,
|
||||
mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd,
|
||||
txdma: impl Unborrow<Target = Tx> + 'd,
|
||||
rxdma: impl Unborrow<Target = Rx> + 'd, // TODO remove
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
sck: impl Peripheral<P = impl SckPin<T>> + 'd,
|
||||
mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
|
||||
txdma: impl Peripheral<P = Tx> + 'd,
|
||||
rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(sck, mosi);
|
||||
into_ref!(sck, mosi);
|
||||
unsafe {
|
||||
sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
|
||||
#[cfg(any(spi_v2, spi_v3, spi_v4))]
|
||||
@ -170,8 +169,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
|
||||
Self::new_inner(
|
||||
peri,
|
||||
Some(sck.degrade()),
|
||||
Some(mosi.degrade()),
|
||||
Some(sck.map_into()),
|
||||
Some(mosi.map_into()),
|
||||
None,
|
||||
txdma,
|
||||
rxdma,
|
||||
@ -181,16 +180,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
sck: Option<AnyPin>,
|
||||
mosi: Option<AnyPin>,
|
||||
miso: Option<AnyPin>,
|
||||
txdma: impl Unborrow<Target = Tx> + 'd,
|
||||
rxdma: impl Unborrow<Target = Rx> + 'd,
|
||||
peri: impl Peripheral<P = T> + 'd,
|
||||
sck: Option<PeripheralRef<'d, AnyPin>>,
|
||||
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
||||
miso: Option<PeripheralRef<'d, AnyPin>>,
|
||||
txdma: impl Peripheral<P = Tx> + 'd,
|
||||
rxdma: impl Peripheral<P = Rx> + 'd,
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(txdma, rxdma);
|
||||
into_ref!(peri, txdma, rxdma);
|
||||
|
||||
let pclk = T::frequency();
|
||||
let br = compute_baud_rate(pclk, freq.into());
|
||||
@ -280,13 +279,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
||||
}
|
||||
|
||||
Self {
|
||||
_peri: peri,
|
||||
sck,
|
||||
mosi,
|
||||
miso,
|
||||
txdma,
|
||||
rxdma,
|
||||
current_word_size: WordSize::EightBit,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -995,7 +994,7 @@ pub trait Word: Copy + 'static + sealed::Word + Default + crate::dma::Word {}
|
||||
impl Word for u8 {}
|
||||
impl Word for u16 {}
|
||||
|
||||
pub trait Instance: sealed::Instance + RccPeripheral {}
|
||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
|
||||
pin_trait!(SckPin, Instance);
|
||||
pin_trait!(MosiPin, Instance);
|
||||
pin_trait!(MisoPin, Instance);
|
||||
|
@ -83,7 +83,7 @@ use crate::peripherals::SUBGHZSPI;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi, MODE_0};
|
||||
use crate::time::Hertz;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
/// Passthrough for SPI errors (for now)
|
||||
pub type Error = crate::spi::Error;
|
||||
@ -211,12 +211,12 @@ impl<'d, Tx, Rx> SubGhz<'d, Tx, Rx> {
|
||||
/// This will reset the radio and the SPI bus, and enable the peripheral
|
||||
/// clock.
|
||||
pub fn new(
|
||||
peri: impl Unborrow<Target = SUBGHZSPI> + 'd,
|
||||
sck: impl Unborrow<Target = impl SckPin<SUBGHZSPI>> + 'd,
|
||||
mosi: impl Unborrow<Target = impl MosiPin<SUBGHZSPI>> + 'd,
|
||||
miso: impl Unborrow<Target = impl MisoPin<SUBGHZSPI>> + 'd,
|
||||
txdma: impl Unborrow<Target = Tx> + 'd,
|
||||
rxdma: impl Unborrow<Target = Rx> + 'd,
|
||||
peri: impl Peripheral<P = SUBGHZSPI> + 'd,
|
||||
sck: impl Peripheral<P = impl SckPin<SUBGHZSPI>> + 'd,
|
||||
mosi: impl Peripheral<P = impl MosiPin<SUBGHZSPI>> + 'd,
|
||||
miso: impl Peripheral<P = impl MisoPin<SUBGHZSPI>> + 'd,
|
||||
txdma: impl Peripheral<P = Tx> + 'd,
|
||||
rxdma: impl Peripheral<P = Rx> + 'd,
|
||||
) -> Self {
|
||||
Self::pulse_radio_reset();
|
||||
|
||||
|
@ -39,11 +39,11 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||
pub fn new(
|
||||
state: &'d mut State<'d, T>,
|
||||
_uart: Uart<'d, T, NoDma, NoDma>,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
tx_buffer: &'d mut [u8],
|
||||
rx_buffer: &'d mut [u8],
|
||||
) -> BufferedUart<'d, T> {
|
||||
unborrow!(irq);
|
||||
into_ref!(irq);
|
||||
|
||||
let r = T::regs();
|
||||
unsafe {
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::dma::NoDma;
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::interrupt::Interrupt;
|
||||
use crate::pac::usart::{regs, vals};
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum DataBits {
|
||||
@ -72,23 +72,22 @@ pub enum Error {
|
||||
}
|
||||
|
||||
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx: UartTx<'d, T, TxDma>,
|
||||
rx: UartRx<'d, T, RxDma>,
|
||||
}
|
||||
|
||||
pub struct UartTx<'d, T: Instance, TxDma = NoDma> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
tx_dma: TxDma,
|
||||
tx_dma: PeripheralRef<'d, TxDma>,
|
||||
}
|
||||
|
||||
pub struct UartRx<'d, T: Instance, RxDma = NoDma> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
rx_dma: RxDma,
|
||||
rx_dma: PeripheralRef<'d, RxDma>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
|
||||
fn new(tx_dma: TxDma) -> Self {
|
||||
fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self {
|
||||
Self {
|
||||
tx_dma,
|
||||
phantom: PhantomData,
|
||||
@ -134,7 +133,7 @@ impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
|
||||
fn new(rx_dma: RxDma) -> Self {
|
||||
fn new(rx_dma: PeripheralRef<'d, RxDma>) -> Self {
|
||||
Self {
|
||||
rx_dma,
|
||||
phantom: PhantomData,
|
||||
@ -190,14 +189,14 @@ impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||
pub fn new(
|
||||
_inner: impl Unborrow<Target = T> + 'd,
|
||||
rx: impl Unborrow<Target = impl RxPin<T>> + 'd,
|
||||
tx: impl Unborrow<Target = impl TxPin<T>> + 'd,
|
||||
tx_dma: impl Unborrow<Target = TxDma> + 'd,
|
||||
rx_dma: impl Unborrow<Target = RxDma> + 'd,
|
||||
_inner: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||
tx_dma: impl Peripheral<P = TxDma> + 'd,
|
||||
rx_dma: impl Peripheral<P = RxDma> + 'd,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
unborrow!(_inner, rx, tx, tx_dma, rx_dma);
|
||||
into_ref!(_inner, rx, tx, tx_dma, rx_dma);
|
||||
|
||||
T::enable();
|
||||
T::reset();
|
||||
@ -234,7 +233,6 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||
}
|
||||
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
tx: UartTx::new(tx_dma),
|
||||
rx: UartRx::new(rx_dma),
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use core::task::Poll;
|
||||
use atomic_polyfill::{AtomicBool, AtomicU8};
|
||||
use embassy::time::{block_for, Duration};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};
|
||||
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
|
||||
use futures::future::poll_fn;
|
||||
@ -20,7 +20,7 @@ use crate::gpio::sealed::AFType;
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::pac::usb::regs;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::{pac, Unborrow};
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
const EP_COUNT: usize = 8;
|
||||
|
||||
@ -125,12 +125,12 @@ pub struct Driver<'d, T: Instance> {
|
||||
|
||||
impl<'d, T: Instance> Driver<'d, T> {
|
||||
pub fn new(
|
||||
_usb: impl Unborrow<Target = T> + 'd,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
dp: impl Unborrow<Target = impl DpPin<T>> + 'd,
|
||||
dm: impl Unborrow<Target = impl DmPin<T>> + 'd,
|
||||
_usb: impl Peripheral<P = T> + 'd,
|
||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
||||
dp: impl Peripheral<P = impl DpPin<T>> + 'd,
|
||||
dm: impl Peripheral<P = impl DmPin<T>> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(irq, dp, dm);
|
||||
into_ref!(irq, dp, dm);
|
||||
irq.set_handler(Self::on_interrupt);
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
@ -1,14 +1,14 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_hal_common::into_ref;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::{peripherals, Unborrow};
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
macro_rules! config_ulpi_pins {
|
||||
($($pin:ident),*) => {
|
||||
unborrow!($($pin),*);
|
||||
into_ref!($($pin),*);
|
||||
// NOTE(unsafe) Exclusive access to the registers
|
||||
critical_section::with(|_| unsafe {
|
||||
$(
|
||||
@ -43,11 +43,11 @@ pub struct UsbOtg<'d, T: Instance> {
|
||||
impl<'d, T: Instance> UsbOtg<'d, T> {
|
||||
/// Initializes USB OTG peripheral with internal Full-Speed PHY
|
||||
pub fn new_fs(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
dp: impl Unborrow<Target = impl DpPin<T>> + 'd,
|
||||
dm: impl Unborrow<Target = impl DmPin<T>> + 'd,
|
||||
_peri: impl Peripheral<P = T> + 'd,
|
||||
dp: impl Peripheral<P = impl DpPin<T>> + 'd,
|
||||
dm: impl Peripheral<P = impl DmPin<T>> + 'd,
|
||||
) -> Self {
|
||||
unborrow!(dp, dm);
|
||||
into_ref!(dp, dm);
|
||||
|
||||
unsafe {
|
||||
dp.set_as_af(dp.af_num(), AFType::OutputPushPull);
|
||||
@ -62,19 +62,19 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
|
||||
|
||||
/// Initializes USB OTG peripheral with external High-Speed PHY
|
||||
pub fn new_hs_ulpi(
|
||||
_peri: impl Unborrow<Target = T> + 'd,
|
||||
ulpi_clk: impl Unborrow<Target = impl UlpiClkPin<T>> + 'd,
|
||||
ulpi_dir: impl Unborrow<Target = impl UlpiDirPin<T>> + 'd,
|
||||
ulpi_nxt: impl Unborrow<Target = impl UlpiNxtPin<T>> + 'd,
|
||||
ulpi_stp: impl Unborrow<Target = impl UlpiStpPin<T>> + 'd,
|
||||
ulpi_d0: impl Unborrow<Target = impl UlpiD0Pin<T>> + 'd,
|
||||
ulpi_d1: impl Unborrow<Target = impl UlpiD1Pin<T>> + 'd,
|
||||
ulpi_d2: impl Unborrow<Target = impl UlpiD2Pin<T>> + 'd,
|
||||
ulpi_d3: impl Unborrow<Target = impl UlpiD3Pin<T>> + 'd,
|
||||
ulpi_d4: impl Unborrow<Target = impl UlpiD4Pin<T>> + 'd,
|
||||
ulpi_d5: impl Unborrow<Target = impl UlpiD5Pin<T>> + 'd,
|
||||
ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd,
|
||||
ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd,
|
||||
_peri: impl Peripheral<P = T> + 'd,
|
||||
ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd,
|
||||
ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd,
|
||||
ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd,
|
||||
ulpi_stp: impl Peripheral<P = impl UlpiStpPin<T>> + 'd,
|
||||
ulpi_d0: impl Peripheral<P = impl UlpiD0Pin<T>> + 'd,
|
||||
ulpi_d1: impl Peripheral<P = impl UlpiD1Pin<T>> + 'd,
|
||||
ulpi_d2: impl Peripheral<P = impl UlpiD2Pin<T>> + 'd,
|
||||
ulpi_d3: impl Peripheral<P = impl UlpiD3Pin<T>> + 'd,
|
||||
ulpi_d4: impl Peripheral<P = impl UlpiD4Pin<T>> + 'd,
|
||||
ulpi_d5: impl Peripheral<P = impl UlpiD5Pin<T>> + 'd,
|
||||
ulpi_d6: impl Peripheral<P = impl UlpiD6Pin<T>> + 'd,
|
||||
ulpi_d7: impl Peripheral<P = impl UlpiD7Pin<T>> + 'd,
|
||||
) -> Self {
|
||||
config_ulpi_pins!(
|
||||
ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::{unborrow, Unborrow};
|
||||
use embassy_hal_common::{into_ref, Peripheral};
|
||||
use stm32_metapac::iwdg::vals::{Key, Pr};
|
||||
|
||||
use crate::rcc::LSI_FREQ;
|
||||
@ -27,8 +27,8 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
|
||||
///
|
||||
/// [Self] has to be started with [Self::unleash()].
|
||||
/// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval.
|
||||
pub fn new(_instance: impl Unborrow<Target = T> + 'd, timeout_us: u32) -> Self {
|
||||
unborrow!(_instance);
|
||||
pub fn new(_instance: impl Peripheral<P = T> + 'd, timeout_us: u32) -> Self {
|
||||
into_ref!(_instance);
|
||||
|
||||
// Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
|
||||
// This iterates from 4 (2^2) to 256 (2^8).
|
||||
|
@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||
|
||||
let irq = interrupt::take!(SDIO);
|
||||
|
||||
let mut sdmmc = Sdmmc::new(
|
||||
let mut sdmmc = Sdmmc::new_4bit(
|
||||
p.SDIO,
|
||||
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
|
||||
irq,
|
||||
Default::default(),
|
||||
p.DMA2_CH3,
|
||||
p.PC12,
|
||||
p.PD2,
|
||||
p.PC8,
|
||||
p.PC9,
|
||||
p.PC10,
|
||||
p.PC11,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
// Should print 400kHz for initialization
|
||||
|
@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||
|
||||
let irq = interrupt::take!(SDMMC1);
|
||||
|
||||
let mut sdmmc = Sdmmc::new(
|
||||
let mut sdmmc = Sdmmc::new_4bit(
|
||||
p.SDMMC1,
|
||||
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
|
||||
irq,
|
||||
Default::default(),
|
||||
p.DMA2_CH3,
|
||||
p.PC12,
|
||||
p.PD2,
|
||||
p.PC8,
|
||||
p.PC9,
|
||||
p.PC10,
|
||||
p.PC11,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
// Should print 400kHz for initialization
|
||||
|
@ -2,8 +2,6 @@
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use defmt::*;
|
||||
use embassy::executor::Spawner;
|
||||
use embassy::time::{Duration, Timer};
|
||||
@ -11,7 +9,7 @@ use embassy_stm32::gpio::low_level::AFType;
|
||||
use embassy_stm32::gpio::Speed;
|
||||
use embassy_stm32::pwm::*;
|
||||
use embassy_stm32::time::{khz, mhz, Hertz};
|
||||
use embassy_stm32::{unborrow, Config, Peripherals, Unborrow};
|
||||
use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef, Peripherals};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
pub fn config() -> Config {
|
||||
@ -49,20 +47,19 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
||||
}
|
||||
}
|
||||
pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
inner: T,
|
||||
inner: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
|
||||
pub fn new(
|
||||
tim: impl Unborrow<Target = T> + 'd,
|
||||
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
|
||||
ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd,
|
||||
tim: impl Peripheral<P = T> + 'd,
|
||||
ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
|
||||
ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
|
||||
ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
|
||||
ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
|
||||
freq: Hertz,
|
||||
) -> Self {
|
||||
unborrow!(tim, ch1, ch2, ch3, ch4);
|
||||
into_ref!(tim, ch1, ch2, ch3, ch4);
|
||||
|
||||
T::enable();
|
||||
<T as embassy_stm32::rcc::low_level::RccPeripheral>::reset();
|
||||
@ -78,10 +75,7 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
|
||||
ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
|
||||
}
|
||||
|
||||
let mut this = Self {
|
||||
inner: tim,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
let mut this = Self { inner: tim };
|
||||
|
||||
this.set_freq(freq);
|
||||
this.inner.start();
|
||||
|
@ -21,10 +21,15 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||
|
||||
let irq = interrupt::take!(SDMMC1);
|
||||
|
||||
let mut sdmmc = Sdmmc::new(
|
||||
let mut sdmmc = Sdmmc::new_4bit(
|
||||
p.SDMMC1,
|
||||
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
|
||||
irq,
|
||||
p.PC12,
|
||||
p.PD2,
|
||||
p.PC8,
|
||||
p.PC9,
|
||||
p.PC10,
|
||||
p.PC11,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user