diff --git a/embassy-cortex-m/src/peripheral.rs b/embassy-cortex-m/src/peripheral.rs index 6a03bfb9..c5fa20e7 100644 --- a/embassy-cortex-m/src/peripheral.rs +++ b/embassy-cortex-m/src/peripheral.rs @@ -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::{unborrow, Unborrow, Unborrowed}; use crate::interrupt::{Interrupt, InterruptExt, Priority}; @@ -33,8 +33,7 @@ impl StateStorage { /// a safe way. pub struct PeripheralMutex<'a, S: PeripheralState> { state: *mut S, - _phantom: PhantomData<&'a mut S>, - irq: S::Interrupt, + irq: Unborrowed<'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, init: impl FnOnce() -> S) -> Self { - if can_be_preempted(&irq) { + pub fn new( + irq: impl Unborrow + 'a, + storage: &'a mut StateStorage, + init: impl FnOnce() -> S, + ) -> Self { + unborrow!(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 diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs index 7ed823c5..06e8d0c8 100644 --- a/embassy-hal-common/src/unborrow.rs +++ b/embassy-hal-common/src/unborrow.rs @@ -16,6 +16,16 @@ impl<'a, T> Unborrowed<'a, T> { } } + pub fn map_into(self) -> Unborrowed<'a, U> + where + T: Into, + { + Unborrowed { + inner: self.inner.into(), + _lifetime: PhantomData, + } + } + pub unsafe fn into_inner(self) -> T { self.inner } diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs index d7d39969..49991db1 100644 --- a/embassy-lora/src/stm32wl/mod.rs +++ b/embassy-lora/src/stm32wl/mod.rs @@ -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::{unborrow, Unborrowed}; use embassy_stm32::dma::NoDma; use embassy_stm32::gpio::{AnyPin, Output}; use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO}; @@ -30,35 +30,35 @@ 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>); -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: Unborrowed<'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, + state: &'d mut SubGhzState<'d>, + radio: SubGhz<'d, NoDma, NoDma>, + switch: RadioSwitch<'d>, + irq: impl Unborrow + 'd, ) -> Self { unborrow!(irq); @@ -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 for RadioError { +impl From 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 } } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 3699ad0f..b6a21caa 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -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::{unborrow, Unborrow, Unborrowed}; pub use embassy_macros::cortex_m_interrupt as interrupt; pub mod config { diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 7da0d30c..e36761ac 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -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::{unborrow, Unborrow, Unborrowed}; pub use embassy_macros::cortex_m_interrupt as interrupt; #[cfg(feature = "unstable-pac")] pub use rp2040_pac2 as pac; diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index b54fd3ff..6c0de2de 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -1,19 +1,17 @@ -use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; pub use bxcan; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use crate::gpio::sealed::AFType; use crate::rcc::RccPeripheral; use crate::{peripherals, Unborrow}; -pub struct Can<'d, T: Instance + bxcan::Instance> { - phantom: PhantomData<&'d mut T>, - can: bxcan::Can, +pub struct Can<'d, T: Instance> { + can: bxcan::Can>, } -impl<'d, T: Instance + bxcan::Instance> Can<'d, T> { +impl<'d, T: Instance> Can<'d, T> { pub fn new( peri: impl Unborrow + 'd, rx: impl Unborrow> + 'd, @@ -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; +impl<'d, T: Instance> Deref for Can<'d, T> { + type Target = bxcan::Can>; 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>(Unborrowed<'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; } }; diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 87133714..85abf22d 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -1,6 +1,4 @@ -use core::marker::PhantomData; - -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use crate::pac::CRC as PAC_CRC; use crate::peripherals::CRC; @@ -8,24 +6,21 @@ use crate::rcc::sealed::RccPeripheral; use crate::Unborrow; pub struct Crc<'d> { - _peripheral: CRC, - _phantom: PhantomData<&'d mut CRC>, + _peri: Unborrowed<'d, CRC>, } impl<'d> Crc<'d> { /// Instantiates the CRC32 peripheral and initializes it to default values. pub fn new(peripheral: impl Unborrow + 'd) -> Self { + unborrow!(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, - }; + let mut instance = Self { _peri: peripheral }; instance.reset(); instance } diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index 63f24e4e..06da29c1 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs @@ -1,6 +1,4 @@ -use core::marker::PhantomData; - -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use crate::pac::crc::vals; use crate::pac::CRC as PAC_CRC; @@ -9,8 +7,7 @@ use crate::rcc::sealed::RccPeripheral; use crate::Unborrow; pub struct Crc<'d> { - _peripheral: CRC, - _phantom: PhantomData<&'d mut CRC>, + _peripheral: Unborrowed<'d, CRC>, _config: Config, } @@ -79,7 +76,6 @@ impl<'d> Crc<'d> { unborrow!(peripheral); let mut instance = Self { _peripheral: peripheral, - _phantom: PhantomData, _config: config, }; CRC::reset(); diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac/v2.rs index ba7856a5..798eefbf 100644 --- a/embassy-stm32/src/dac/v2.rs +++ b/embassy-stm32/src/dac/v2.rs @@ -1,6 +1,4 @@ -use core::marker::PhantomData; - -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use crate::dac::{DacPin, Instance}; use crate::pac::dac; @@ -90,7 +88,7 @@ pub enum Value { pub struct Dac<'d, T: Instance> { channels: u8, - phantom: PhantomData<&'d mut T>, + _peri: Unborrowed<'d, T>, } macro_rules! enable { @@ -116,7 +114,7 @@ impl<'d, T: Instance> Dac<'d, T> { Self::new_inner(peri, 2) } - fn new_inner(_peri: T, channels: u8) -> Self { + fn new_inner(peri: Unborrowed<'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 diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index f4ca93a7..bcf72349 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -1,8 +1,7 @@ -use core::marker::PhantomData; use core::task::Poll; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use crate::gpio::sealed::AFType; @@ -82,9 +81,8 @@ macro_rules! config_pins { } pub struct Dcmi<'d, T: Instance, Dma: FrameDma> { - inner: T, - dma: Dma, - phantom: PhantomData<&'d mut T>, + inner: Unborrowed<'d, T>, + dma: Unborrowed<'d, Dma>, } impl<'d, T, Dma> Dcmi<'d, T, Dma> @@ -301,9 +299,9 @@ where } fn new_inner( - peri: T, - dma: Dma, - irq: T::Interrupt, + peri: Unborrowed<'d, T>, + dma: Unborrowed<'d, Dma>, + irq: Unborrowed<'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 ()) { diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 02d6ca0f..fe2bf900 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -8,7 +8,6 @@ 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}; @@ -207,6 +206,8 @@ impl Default for TransferOptions { } mod transfers { + use embassy_hal_common::Unborrowed; + use super::*; #[allow(unused)] @@ -255,17 +256,13 @@ mod transfers { } pub(crate) struct Transfer<'a, C: Channel> { - channel: C, - _phantom: PhantomData<&'a mut C>, + channel: Unborrowed<'a, C>, } impl<'a, C: Channel> Transfer<'a, C> { pub(crate) fn new(channel: impl Unborrow + 'a) -> Self { unborrow!(channel); - Self { - channel, - _phantom: PhantomData, - } + Self { channel } } } diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 7985acc5..f2cdd909 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -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::{unborrow, Unborrowed}; use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; use crate::gpio::sealed::{AFType, Pin as __GpioPin}; @@ -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: [Unborrowed<'d, AnyPin>; 9], _phy: P, clock_range: Cr, phy_addr: u8, @@ -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 { diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 2b1caf99..c67a0307 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -4,7 +4,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::{unborrow, Unborrowed}; use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; use crate::gpio::sealed::{AFType, Pin as _}; @@ -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: [Unborrowed<'d, AnyPin>; 9], _phy: P, clock_range: u8, phy_addr: u8, @@ -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 { diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 2047f70e..bd64fdd7 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -1,6 +1,4 @@ -use core::marker::PhantomData; - -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; pub use crate::pac::{ERASE_SIZE, ERASE_VALUE, FLASH_BASE, FLASH_SIZE, WRITE_SIZE}; @@ -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: Unborrowed<'d, FLASH>, } impl<'d> Flash<'d> { - pub fn new(p: impl Unborrow) -> Self { + pub fn new(p: impl Unborrow + 'd) -> Self { unborrow!(p); - Self { - _inner: p, - _phantom: PhantomData, - } + Self { _inner: p } } - pub fn unlock(p: impl Unborrow) -> Self { + pub fn unlock(p: impl Unborrow + 'd) -> Self { let flash = Self::new(p); unsafe { family::unlock() }; diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 3bdaccce..92cd2bb2 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -1,8 +1,7 @@ #![macro_use] use core::convert::Infallible; -use core::marker::PhantomData; -use embassy_hal_common::{impl_unborrow, unborrow}; +use embassy_hal_common::{impl_unborrow, unborrow, Unborrowed}; use crate::pac::gpio::{self, vals}; use crate::{pac, peripherals, Unborrow}; @@ -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: Unborrowed<'d, T>, } impl<'d, T: Pin> Flex<'d, T> { @@ -27,10 +25,7 @@ impl<'d, T: Pin> Flex<'d, T> { pub fn new(pin: impl Unborrow + 'd) -> Self { unborrow!(pin); // Pin will be in disconnected state. - Self { - pin, - phantom: PhantomData, - } + Self { pin } } /// Put the pin into input mode. @@ -626,7 +621,7 @@ pub(crate) mod sealed { } } -pub trait Pin: sealed::Pin + Sized + 'static { +pub trait Pin: Into + sealed::Pin + Sized + 'static { #[cfg(feature = "exti")] type ExtiChannel: crate::exti::Channel; @@ -699,6 +694,12 @@ foreach_pin!( $port_num * 16 + $pin_num } } + + impl From for AnyPin { + fn from(x: peripherals::$pin_name) -> Self { + x.degrade() + } + } }; ); diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 108ea7e3..ec7fec15 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -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::{unborrow, Unborrowed}; use futures::future::poll_fn; use crate::dma::NoDma; @@ -32,15 +31,15 @@ impl State { } pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { - phantom: PhantomData<&'d mut T>, - tx_dma: TXDMA, + _peri: Unborrowed<'d, T>, + tx_dma: Unborrowed<'d, TXDMA>, #[allow(dead_code)] - rx_dma: RXDMA, + rx_dma: Unborrowed<'d, RXDMA>, } impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { pub fn new( - _peri: impl Unborrow + 'd, + peri: impl Unborrow + 'd, scl: impl Unborrow> + 'd, sda: impl Unborrow> + 'd, irq: impl Unborrow + 'd, @@ -48,7 +47,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { rx_dma: impl Unborrow + 'd, freq: Hertz, ) -> Self { - unborrow!(irq, scl, sda, tx_dma, rx_dma); + unborrow!(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, } diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 8b816858..f58ab2f9 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -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::{unborrow, Unborrow, Unborrowed}; pub use embassy_macros::cortex_m_interrupt as interrupt; #[cfg(feature = "unstable-pac")] pub use stm32_metapac as pac; diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/pwm/simple_pwm.rs index 60aa110c..137d3145 100644 --- a/embassy-stm32/src/pwm/simple_pwm.rs +++ b/embassy-stm32/src/pwm/simple_pwm.rs @@ -1,6 +1,4 @@ -use core::marker::PhantomData; - -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use super::*; #[allow(unused_imports)] @@ -9,8 +7,7 @@ use crate::time::Hertz; use crate::Unborrow; pub struct SimplePwm<'d, T> { - phantom: PhantomData<&'d mut T>, - inner: T, + inner: Unborrowed<'d, T>, } macro_rules! config_pins { @@ -83,10 +80,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { configure_pins(); - let mut this = Self { - inner: tim, - phantom: PhantomData, - }; + let mut this = Self { inner: tim }; this.inner.set_frequency(freq); this.inner.start(); diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 5b3558c9..967fa71f 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -1,10 +1,9 @@ #![macro_use] -use core::marker::PhantomData; use core::task::Poll; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use rand_core::{CryptoRng, RngCore}; @@ -19,8 +18,7 @@ pub enum Error { } pub struct Rng<'d, T: Instance> { - _inner: T, - _phantom: PhantomData<&'d mut T>, + _inner: Unborrowed<'d, T>, } impl<'d, T: Instance> Rng<'d, T> { @@ -28,10 +26,7 @@ impl<'d, T: Instance> Rng<'d, T> { T::enable(); T::reset(); unborrow!(inner); - let mut random = Self { - _inner: inner, - _phantom: PhantomData, - }; + let mut random = Self { _inner: inner }; random.reset(); random } diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index d9450974..fbb48263 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -1,18 +1,17 @@ #![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::{unborrow, Unborrowed}; 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; @@ -176,12 +175,19 @@ impl Default for Config { } /// Sdmmc device -pub struct Sdmmc<'d, T: Instance, P: Pins, Dma = NoDma> { - sdmmc: PhantomData<&'d mut T>, - pins: P, - irq: T::Interrupt, +pub struct Sdmmc<'d, T: Instance, Dma = NoDma> { + _peri: Unborrowed<'d, T>, + irq: Unborrowed<'d, T::Interrupt>, + dma: Unborrowed<'d, Dma>, + + clk: Unborrowed<'d, AnyPin>, + cmd: Unborrowed<'d, AnyPin>, + d0: Unborrowed<'d, AnyPin>, + d1: Option>, + d2: Option>, + d3: Option>, + 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, Dma = NoDma> { } #[cfg(sdmmc_v1)] -impl<'d, T: Instance, P: Pins, Dma: SdmmcDma> Sdmmc<'d, T, P, Dma> { - pub fn new( - _peripheral: impl Unborrow + 'd, - pins: impl Unborrow + 'd, +impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { + pub fn new_1bit( + sdmmc: impl Unborrow + 'd, irq: impl Unborrow + 'd, - config: Config, dma: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + cmd: impl Unborrow> + 'd, + d0: impl Unborrow> + 'd, + config: Config, ) -> Self { - unborrow!(irq, pins, dma); - pins.configure(); + unborrow!(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 Unborrow + 'd, + irq: impl Unborrow + 'd, + dma: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + cmd: impl Unborrow> + 'd, + d0: impl Unborrow> + 'd, + d1: impl Unborrow> + 'd, + d2: impl Unborrow> + 'd, + d3: impl Unborrow> + 'd, + config: Config, + ) -> Self { + unborrow!(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 Unborrow + 'd, + irq: impl Unborrow + 'd, + dma: impl Unborrow + 'd, + clk: Unborrowed<'d, AnyPin>, + cmd: Unborrowed<'d, AnyPin>, + d0: Unborrowed<'d, AnyPin>, + d1: Option>, + d2: Option>, + d3: Option>, + config: Config, + ) -> Self { + unborrow!(sdmmc, irq, dma); T::enable(); T::reset(); @@ -213,11 +302,18 @@ impl<'d, T: Instance, P: Pins, Dma: SdmmcDma> 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, Dma: SdmmcDma> Sdmmc<'d, T, P, Dma> { } #[cfg(sdmmc_v2)] -impl<'d, T: Instance, P: Pins> Sdmmc<'d, T, P, NoDma> { - pub fn new( - _peripheral: impl Unborrow + 'd, - pins: impl Unborrow + 'd, +impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { + pub fn new_1bit( + sdmmc: impl Unborrow + 'd, irq: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + cmd: impl Unborrow> + 'd, + d0: impl Unborrow> + 'd, config: Config, ) -> Self { - unborrow!(irq, pins); - pins.configure(); + unborrow!(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 Unborrow + 'd, + irq: impl Unborrow + 'd, + clk: impl Unborrow> + 'd, + cmd: impl Unborrow> + 'd, + d0: impl Unborrow> + 'd, + d1: impl Unborrow> + 'd, + d2: impl Unborrow> + 'd, + d3: impl Unborrow> + 'd, + config: Config, + ) -> Self { + unborrow!(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 Unborrow + 'd, + irq: impl Unborrow + 'd, + clk: Unborrowed<'d, AnyPin>, + cmd: Unborrowed<'d, AnyPin>, + d0: Unborrowed<'d, AnyPin>, + d1: Option>, + d2: Option>, + d3: Option>, + config: Config, + ) -> Self { + unborrow!(sdmmc, irq); T::enable(); T::reset(); @@ -247,11 +422,18 @@ impl<'d, T: Instance, P: Pins> Sdmmc<'d, T, P, NoDma> { irq.enable(); Self { - sdmmc: PhantomData, - pins, + _peri: sdmmc, irq, + dma: NoDma.unborrow(), + + 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> Sdmmc<'d, T, P, NoDma> { } } -impl<'d, T: Instance, P: Pins, Dma: SdmmcDma> Sdmmc<'d, T, P, Dma> { +impl<'d, T: Instance, Dma: SdmmcDma> 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, Dma: SdmmcDma> 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, Dma: SdmmcDma> 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, Dma: SdmmcDma> Sdmmc<'d, T, P, Dma> { } } -impl<'d, T: Instance, P: Pins, 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: sealed::Pins + 'static { - const BUSWIDTH: BusWidth; - - fn configure(&mut self); - fn deconfigure(&mut self); -} - -impl sealed::Pins for (CLK, CMD, D0, D1, D2, D3) -where - T: Instance, - CLK: CkPin, - CMD: CmdPin, - D0: D0Pin, - D1: D1Pin, - D2: D2Pin, - D3: D3Pin, -{ -} - -impl sealed::Pins for (CLK, CMD, D0) -where - T: Instance, - CLK: CkPin, - CMD: CmdPin, - D0: D0Pin, -{ -} - -impl Pins for (CLK, CMD, D0, D1, D2, D3) -where - T: Instance, - CLK: CkPin, - CMD: CmdPin, - D0: D0Pin, - D1: D1Pin, - D2: D2Pin, - D3: D3Pin, -{ - 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 Pins for (CLK, CMD, D0) -where - T: Instance, - CLK: CkPin, - CMD: CmdPin, - D0: D0Pin, -{ - 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 { diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a02f4492..595957b2 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -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::{unborrow, Unborrowed}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; use futures::future::join; @@ -73,13 +72,13 @@ impl Config { } pub struct Spi<'d, T: Instance, Tx, Rx> { - sck: Option, - mosi: Option, - miso: Option, - txdma: Tx, - rxdma: Rx, + _peri: Unborrowed<'d, T>, + sck: Option>, + mosi: Option>, + miso: Option>, + txdma: Unborrowed<'d, Tx>, + rxdma: Unborrowed<'d, Rx>, current_word_size: WordSize, - phantom: PhantomData<&'d mut T>, } impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { @@ -93,7 +92,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { freq: Hertz, config: Config, ) -> Self { - unborrow!(sck, mosi, miso); + unborrow!(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, @@ -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, @@ -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 + 'd, - sck: Option, - mosi: Option, - miso: Option, + peri: impl Unborrow + 'd, + sck: Option>, + mosi: Option>, + miso: Option>, txdma: impl Unborrow + 'd, rxdma: impl Unborrow + 'd, freq: Hertz, config: Config, ) -> Self { - unborrow!(txdma, rxdma); + unborrow!(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: Unborrow + sealed::Instance + RccPeripheral {} pin_trait!(SckPin, Instance); pin_trait!(MosiPin, Instance); pin_trait!(MisoPin, Instance); diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index a893e4b8..6b12378d 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use crate::dma::NoDma; use crate::gpio::sealed::AFType; @@ -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: Unborrowed<'d, TxDma>, } pub struct UartRx<'d, T: Instance, RxDma = NoDma> { phantom: PhantomData<&'d mut T>, - rx_dma: RxDma, + rx_dma: Unborrowed<'d, RxDma>, } impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { - fn new(tx_dma: TxDma) -> Self { + fn new(tx_dma: Unborrowed<'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: Unborrowed<'d, RxDma>) -> Self { Self { rx_dma, phantom: PhantomData, @@ -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), } diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs index 66567026..752ad57b 100644 --- a/examples/stm32f4/src/bin/sdmmc.rs +++ b/examples/stm32f4/src/bin/sdmmc.rs @@ -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 diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs index 011e1fd9..be1c2b15 100644 --- a/examples/stm32f7/src/bin/sdmmc.rs +++ b/examples/stm32f7/src/bin/sdmmc.rs @@ -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 diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index fc19d84e..e54f1bb6 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -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::{unborrow, Config, Peripherals, Unborrow, Unborrowed}; use {defmt_rtt as _, panic_probe as _}; pub fn config() -> Config { @@ -49,8 +47,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { } } pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { - phantom: PhantomData<&'d mut T>, - inner: T, + inner: Unborrowed<'d, T>, } impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { @@ -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(); diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs index 787f700a..163807d8 100644 --- a/examples/stm32h7/src/bin/sdmmc.rs +++ b/examples/stm32h7/src/bin/sdmmc.rs @@ -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(), );