Update embassy-stm32

This commit is contained in:
Dario Nieuwenhuis 2022-07-23 01:29:35 +02:00
parent e0521ea249
commit 8a9d2f59af
26 changed files with 433 additions and 361 deletions

View File

@ -1,9 +1,9 @@
//! Peripheral interrupt handling specific to cortex-m devices. //! Peripheral interrupt handling specific to cortex-m devices.
use core::marker::PhantomData;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use cortex_m::peripheral::scb::VectActive; use cortex_m::peripheral::scb::VectActive;
use cortex_m::peripheral::{NVIC, SCB}; use cortex_m::peripheral::{NVIC, SCB};
use embassy_hal_common::{unborrow, Unborrow, Unborrowed};
use crate::interrupt::{Interrupt, InterruptExt, Priority}; use crate::interrupt::{Interrupt, InterruptExt, Priority};
@ -33,8 +33,7 @@ impl<S> StateStorage<S> {
/// a safe way. /// a safe way.
pub struct PeripheralMutex<'a, S: PeripheralState> { pub struct PeripheralMutex<'a, S: PeripheralState> {
state: *mut S, state: *mut S,
_phantom: PhantomData<&'a mut S>, irq: Unborrowed<'a, S::Interrupt>,
irq: S::Interrupt,
} }
/// Whether `irq` can be preempted by the current 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. /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state.
/// ///
/// Registers `on_interrupt` as the `irq`'s handler, and enables it. /// 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 { pub fn new(
if can_be_preempted(&irq) { irq: impl Unborrow<Target = S::Interrupt> + 'a,
storage: &'a mut StateStorage<S>,
init: impl FnOnce() -> S,
) -> Self {
unborrow!(irq);
if can_be_preempted(&*irq) {
panic!( panic!(
"`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps" "`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.set_handler_context(state_ptr as *mut ());
irq.enable(); irq.enable();
Self { Self { irq, state: state_ptr }
irq,
state: state_ptr,
_phantom: PhantomData,
}
} }
/// Access the peripheral state ensuring interrupts are disabled so that the state can be /// Access the peripheral state ensuring interrupts are disabled so that the state can be

View File

@ -16,6 +16,16 @@ impl<'a, T> Unborrowed<'a, T> {
} }
} }
pub fn map_into<U>(self) -> Unborrowed<'a, U>
where
T: Into<U>,
{
Unborrowed {
inner: self.inner.into(),
_lifetime: PhantomData,
}
}
pub unsafe fn into_inner(self) -> T { pub unsafe fn into_inner(self) -> T {
self.inner self.inner
} }

View File

@ -3,7 +3,7 @@ use core::future::Future;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use embassy::channel::signal::Signal; use embassy::channel::signal::Signal;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_stm32::dma::NoDma; use embassy_stm32::dma::NoDma;
use embassy_stm32::gpio::{AnyPin, Output}; use embassy_stm32::gpio::{AnyPin, Output};
use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO}; use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO};
@ -30,35 +30,35 @@ pub struct RadioError;
static IRQ: Signal<(Status, u16)> = Signal::new(); static IRQ: Signal<(Status, u16)> = Signal::new();
struct StateInner<'a> { struct StateInner<'d> {
radio: SubGhz<'a, NoDma, NoDma>, radio: SubGhz<'d, NoDma, NoDma>,
switch: RadioSwitch<'a>, switch: RadioSwitch<'d>,
} }
/// External state storage for the radio state /// External state storage for the radio state
pub struct SubGhzState<'a>(MaybeUninit<StateInner<'a>>); pub struct SubGhzState<'a>(MaybeUninit<StateInner<'a>>);
impl<'a> SubGhzState<'a> { impl<'d> SubGhzState<'d> {
pub const fn new() -> Self { pub const fn new() -> Self {
Self(MaybeUninit::uninit()) Self(MaybeUninit::uninit())
} }
} }
/// The radio peripheral keeping the radio state and owning the radio IRQ. /// The radio peripheral keeping the radio state and owning the radio IRQ.
pub struct SubGhzRadio<'a> { pub struct SubGhzRadio<'d> {
state: *mut StateInner<'a>, state: *mut StateInner<'d>,
_irq: SUBGHZ_RADIO, _irq: Unborrowed<'d, SUBGHZ_RADIO>,
} }
impl<'a> SubGhzRadio<'a> { impl<'d> SubGhzRadio<'d> {
/// Create a new instance of a SubGhz radio for LoRaWAN. /// Create a new instance of a SubGhz radio for LoRaWAN.
/// ///
/// # Safety /// # Safety
/// Do not leak self or futures /// Do not leak self or futures
pub unsafe fn new( pub unsafe fn new(
state: &'a mut SubGhzState<'a>, state: &'d mut SubGhzState<'d>,
radio: SubGhz<'a, NoDma, NoDma>, radio: SubGhz<'d, NoDma, NoDma>,
switch: RadioSwitch<'a>, switch: RadioSwitch<'d>,
irq: impl Unborrow<Target = SUBGHZ_RADIO>, irq: impl Unborrow<Target = SUBGHZ_RADIO> + 'd,
) -> Self { ) -> Self {
unborrow!(irq); unborrow!(irq);
@ -73,7 +73,7 @@ impl<'a> SubGhzRadio<'a> {
// This is safe because we only get interrupts when configured for, so // 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 // 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. // 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(); state.on_interrupt();
}); });
irq.set_handler_context(state_ptr as *mut ()); 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 /// Configure radio settings in preparation for TX or RX
pub(crate) fn configure(&mut self) -> Result<(), RadioError> { pub(crate) fn configure(&mut self) -> Result<(), RadioError> {
trace!("Configuring STM32WL SUBGHZ radio"); 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 { fn from(_: embassy_stm32::spi::Error) -> Self {
RadioError RadioError
} }
} }
impl<'a> Timings for SubGhzRadio<'a> { impl<'d> Timings for SubGhzRadio<'d> {
fn get_rx_window_offset_ms(&self) -> i32 { fn get_rx_window_offset_ms(&self) -> i32 {
-200 -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. /// Represents the radio switch found on STM32WL based boards, used to control the radio for transmission or reception.
pub struct RadioSwitch<'a> { pub struct RadioSwitch<'d> {
ctrl1: Output<'a, AnyPin>, ctrl1: Output<'d, AnyPin>,
ctrl2: Output<'a, AnyPin>, ctrl2: Output<'d, AnyPin>,
ctrl3: Output<'a, AnyPin>, ctrl3: Output<'d, AnyPin>,
} }
impl<'a> RadioSwitch<'a> { impl<'d> RadioSwitch<'d> {
pub fn new(ctrl1: Output<'a, AnyPin>, ctrl2: Output<'a, AnyPin>, ctrl3: Output<'a, AnyPin>) -> Self { pub fn new(ctrl1: Output<'d, AnyPin>, ctrl2: Output<'d, AnyPin>, ctrl3: Output<'d, AnyPin>) -> Self {
Self { ctrl1, ctrl2, ctrl3 } Self { ctrl1, ctrl2, ctrl3 }
} }

View File

@ -135,7 +135,7 @@ pub use chip::pac;
pub(crate) use chip::pac; pub(crate) use chip::pac;
pub use chip::{peripherals, Peripherals}; pub use chip::{peripherals, Peripherals};
pub use embassy_cortex_m::executor; 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 use embassy_macros::cortex_m_interrupt as interrupt;
pub mod config { pub mod config {

View File

@ -17,7 +17,7 @@ mod reset;
// Reexports // Reexports
pub use embassy_cortex_m::executor; 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 use embassy_macros::cortex_m_interrupt as interrupt;
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use rp2040_pac2 as pac; pub use rp2040_pac2 as pac;

View File

@ -1,19 +1,17 @@
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
pub use bxcan; pub use bxcan;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{peripherals, Unborrow}; use crate::{peripherals, Unborrow};
pub struct Can<'d, T: Instance + bxcan::Instance> { pub struct Can<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, can: bxcan::Can<BxcanInstance<'d, T>>,
can: bxcan::Can<T>,
} }
impl<'d, T: Instance + bxcan::Instance> Can<'d, T> { impl<'d, T: Instance> Can<'d, T> {
pub fn new( pub fn new(
peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
rx: impl Unborrow<Target = impl RxPin<T>> + 'd, rx: impl Unborrow<Target = impl RxPin<T>> + 'd,
@ -30,32 +28,29 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
T::reset(); T::reset();
Self { Self {
phantom: PhantomData, can: bxcan::Can::builder(BxcanInstance(peri)).enable(),
can: bxcan::Can::builder(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) { fn drop(&mut self) {
// Cannot call `free()` because it moves the instance. // Cannot call `free()` because it moves the instance.
// Manually reset the peripheral. // Manually reset the peripheral.
unsafe { unsafe { T::regs().mcr().write(|w| w.set_reset(true)) }
T::regs().mcr().write(|w| w.set_reset(true));
}
T::disable(); T::disable();
} }
} }
impl<'d, T: Instance + bxcan::Instance> Deref for Can<'d, T> { impl<'d, T: Instance> Deref for Can<'d, T> {
type Target = bxcan::Can<T>; type Target = bxcan::Can<BxcanInstance<'d, T>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.can &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 { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.can &mut self.can
} }
@ -63,15 +58,25 @@ impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
pub(crate) mod sealed { pub(crate) mod sealed {
pub trait Instance { pub trait Instance {
const REGISTERS: *mut bxcan::RegisterBlock;
fn regs() -> &'static crate::pac::can::Can; fn regs() -> &'static crate::pac::can::Can;
} }
} }
pub trait Instance: sealed::Instance + RccPeripheral {} 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!( foreach_peripheral!(
(can, $inst:ident) => { (can, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl sealed::Instance for peripherals::$inst {
const REGISTERS: *mut bxcan::RegisterBlock = crate::pac::$inst.0 as *mut _;
fn regs() -> &'static crate::pac::can::Can { fn regs() -> &'static crate::pac::can::Can {
&crate::pac::$inst &crate::pac::$inst
} }
@ -79,15 +84,12 @@ foreach_peripheral!(
impl Instance for peripherals::$inst {} 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!( foreach_peripheral!(
(can, CAN) => { (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; const NUM_FILTER_BANKS: u8 = 14;
} }
}; };
@ -102,19 +104,19 @@ foreach_peripheral!(
))] { ))] {
// Most L4 devices and some F7 devices use the name "CAN1" // Most L4 devices and some F7 devices use the name "CAN1"
// even if there is no "CAN2" peripheral. // 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; const NUM_FILTER_BANKS: u8 = 14;
} }
} else { } else {
unsafe impl bxcan::FilterOwner for peripherals::CAN1 { unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN1> {
const NUM_FILTER_BANKS: u8 = 28; 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) => { (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; const NUM_FILTER_BANKS: u8 = 14;
} }
}; };

View File

@ -1,6 +1,4 @@
use core::marker::PhantomData; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_hal_common::unborrow;
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC; use crate::peripherals::CRC;
@ -8,24 +6,21 @@ use crate::rcc::sealed::RccPeripheral;
use crate::Unborrow; use crate::Unborrow;
pub struct Crc<'d> { pub struct Crc<'d> {
_peripheral: CRC, _peri: Unborrowed<'d, CRC>,
_phantom: PhantomData<&'d mut CRC>,
} }
impl<'d> Crc<'d> { impl<'d> Crc<'d> {
/// Instantiates the CRC32 peripheral and initializes it to default values. /// 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 Unborrow<Target = CRC> + 'd) -> Self {
unborrow!(peripheral);
// Note: enable and reset come from RccPeripheral. // Note: enable and reset come from RccPeripheral.
// enable CRC clock in RCC. // enable CRC clock in RCC.
CRC::enable(); CRC::enable();
// Reset CRC to default values. // Reset CRC to default values.
CRC::reset(); CRC::reset();
// Unborrow the peripheral // Unborrow the peripheral
unborrow!(peripheral); let mut instance = Self { _peri: peripheral };
let mut instance = Self {
_peripheral: peripheral,
_phantom: PhantomData,
};
instance.reset(); instance.reset();
instance instance
} }

View File

@ -1,6 +1,4 @@
use core::marker::PhantomData; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_hal_common::unborrow;
use crate::pac::crc::vals; use crate::pac::crc::vals;
use crate::pac::CRC as PAC_CRC; use crate::pac::CRC as PAC_CRC;
@ -9,8 +7,7 @@ use crate::rcc::sealed::RccPeripheral;
use crate::Unborrow; use crate::Unborrow;
pub struct Crc<'d> { pub struct Crc<'d> {
_peripheral: CRC, _peripheral: Unborrowed<'d, CRC>,
_phantom: PhantomData<&'d mut CRC>,
_config: Config, _config: Config,
} }
@ -79,7 +76,6 @@ impl<'d> Crc<'d> {
unborrow!(peripheral); unborrow!(peripheral);
let mut instance = Self { let mut instance = Self {
_peripheral: peripheral, _peripheral: peripheral,
_phantom: PhantomData,
_config: config, _config: config,
}; };
CRC::reset(); CRC::reset();

View File

@ -1,6 +1,4 @@
use core::marker::PhantomData; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_hal_common::unborrow;
use crate::dac::{DacPin, Instance}; use crate::dac::{DacPin, Instance};
use crate::pac::dac; use crate::pac::dac;
@ -90,7 +88,7 @@ pub enum Value {
pub struct Dac<'d, T: Instance> { pub struct Dac<'d, T: Instance> {
channels: u8, channels: u8,
phantom: PhantomData<&'d mut T>, _peri: Unborrowed<'d, T>,
} }
macro_rules! enable { macro_rules! enable {
@ -116,7 +114,7 @@ impl<'d, T: Instance> Dac<'d, T> {
Self::new_inner(peri, 2) Self::new_inner(peri, 2)
} }
fn new_inner(_peri: T, channels: u8) -> Self { fn new_inner(peri: Unborrowed<'d, T>, channels: u8) -> Self {
unsafe { unsafe {
// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock
// configuration. // configuration.
@ -144,10 +142,7 @@ impl<'d, T: Instance> Dac<'d, T> {
} }
} }
Self { Self { channels, _peri: peri }
channels,
phantom: PhantomData,
}
} }
/// Check the channel is configured /// Check the channel is configured

View File

@ -1,8 +1,7 @@
use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
@ -82,9 +81,8 @@ macro_rules! config_pins {
} }
pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> { pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
inner: T, inner: Unborrowed<'d, T>,
dma: Dma, dma: Unborrowed<'d, Dma>,
phantom: PhantomData<&'d mut T>,
} }
impl<'d, T, Dma> Dcmi<'d, T, Dma> impl<'d, T, Dma> Dcmi<'d, T, Dma>
@ -301,9 +299,9 @@ where
} }
fn new_inner( fn new_inner(
peri: T, peri: Unborrowed<'d, T>,
dma: Dma, dma: Unborrowed<'d, Dma>,
irq: T::Interrupt, irq: Unborrowed<'d, T::Interrupt>,
config: Config, config: Config,
use_embedded_synchronization: bool, use_embedded_synchronization: bool,
edm: u8, edm: u8,
@ -327,11 +325,7 @@ where
irq.unpend(); irq.unpend();
irq.enable(); irq.enable();
Self { Self { inner: peri, dma }
inner: peri,
dma,
phantom: PhantomData,
}
} }
unsafe fn on_interrupt(_: *mut ()) { unsafe fn on_interrupt(_: *mut ()) {

View File

@ -8,7 +8,6 @@ mod dmamux;
mod gpdma; mod gpdma;
use core::future::Future; use core::future::Future;
use core::marker::PhantomData;
use core::mem; use core::mem;
use core::pin::Pin; use core::pin::Pin;
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
@ -207,6 +206,8 @@ impl Default for TransferOptions {
} }
mod transfers { mod transfers {
use embassy_hal_common::Unborrowed;
use super::*; use super::*;
#[allow(unused)] #[allow(unused)]
@ -255,17 +256,13 @@ mod transfers {
} }
pub(crate) struct Transfer<'a, C: Channel> { pub(crate) struct Transfer<'a, C: Channel> {
channel: C, channel: Unborrowed<'a, C>,
_phantom: PhantomData<&'a mut C>,
} }
impl<'a, C: Channel> Transfer<'a, C> { impl<'a, C: Channel> Transfer<'a, C> {
pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self { pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self {
unborrow!(channel); unborrow!(channel);
Self { Self { channel }
channel,
_phantom: PhantomData,
}
} }
} }

View File

@ -6,7 +6,7 @@ use core::task::Waker;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 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 embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 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> { pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>, state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
pins: [AnyPin; 9], pins: [Unborrowed<'d, AnyPin>; 9],
_phy: P, _phy: P,
clock_range: Cr, clock_range: Cr,
phy_addr: u8, phy_addr: u8,
@ -207,15 +207,15 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
}; };
let pins = [ let pins = [
ref_clk.degrade(), ref_clk.map_into(),
mdio.degrade(), mdio.map_into(),
mdc.degrade(), mdc.map_into(),
crs.degrade(), crs.map_into(),
rx_d0.degrade(), rx_d0.map_into(),
rx_d1.degrade(), rx_d1.map_into(),
tx_d0.degrade(), tx_d0.map_into(),
tx_d1.degrade(), tx_d1.map_into(),
tx_en.degrade(), tx_en.map_into(),
]; ];
let mut this = Self { let mut this = Self {

View File

@ -4,7 +4,7 @@ use core::task::Waker;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 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 embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
use crate::gpio::sealed::{AFType, Pin as _}; 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> { pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>, state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
pins: [AnyPin; 9], pins: [Unborrowed<'d, AnyPin>; 9],
_phy: P, _phy: P,
clock_range: u8, clock_range: u8,
phy_addr: 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 = [ let pins = [
ref_clk.degrade(), ref_clk.map_into(),
mdio.degrade(), mdio.map_into(),
mdc.degrade(), mdc.map_into(),
crs.degrade(), crs.map_into(),
rx_d0.degrade(), rx_d0.map_into(),
rx_d1.degrade(), rx_d1.map_into(),
tx_d0.degrade(), tx_d0.map_into(),
tx_d1.degrade(), tx_d1.map_into(),
tx_en.degrade(), tx_en.map_into(),
]; ];
let mut this = Self { let mut this = Self {

View File

@ -1,6 +1,4 @@
use core::marker::PhantomData; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_hal_common::unborrow;
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
pub use crate::pac::{ERASE_SIZE, ERASE_VALUE, FLASH_BASE, FLASH_SIZE, WRITE_SIZE}; 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; mod family;
pub struct Flash<'d> { pub struct Flash<'d> {
_inner: FLASH, _inner: Unborrowed<'d, FLASH>,
_phantom: PhantomData<&'d mut FLASH>,
} }
impl<'d> Flash<'d> { impl<'d> Flash<'d> {
pub fn new(p: impl Unborrow<Target = FLASH>) -> Self { pub fn new(p: impl Unborrow<Target = FLASH> + 'd) -> Self {
unborrow!(p); unborrow!(p);
Self { Self { _inner: p }
_inner: p,
_phantom: PhantomData,
}
} }
pub fn unlock(p: impl Unborrow<Target = FLASH>) -> Self { pub fn unlock(p: impl Unborrow<Target = FLASH> + 'd) -> Self {
let flash = Self::new(p); let flash = Self::new(p);
unsafe { family::unlock() }; unsafe { family::unlock() };

View File

@ -1,8 +1,7 @@
#![macro_use] #![macro_use]
use core::convert::Infallible; 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::gpio::{self, vals};
use crate::{pac, peripherals, Unborrow}; 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 /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
/// mode. /// mode.
pub struct Flex<'d, T: Pin> { pub struct Flex<'d, T: Pin> {
pub(crate) pin: T, pub(crate) pin: Unborrowed<'d, T>,
phantom: PhantomData<&'d mut T>,
} }
impl<'d, T: Pin> Flex<'d, T> { impl<'d, T: Pin> Flex<'d, T> {
@ -27,10 +25,7 @@ impl<'d, T: Pin> Flex<'d, T> {
pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
unborrow!(pin); unborrow!(pin);
// Pin will be in disconnected state. // Pin will be in disconnected state.
Self { Self { pin }
pin,
phantom: PhantomData,
}
} }
/// Put the pin into input mode. /// Put the pin into input mode.
@ -626,7 +621,7 @@ pub(crate) mod sealed {
} }
} }
pub trait Pin: sealed::Pin + Sized + 'static { pub trait Pin: Into<AnyPin> + sealed::Pin + Sized + 'static {
#[cfg(feature = "exti")] #[cfg(feature = "exti")]
type ExtiChannel: crate::exti::Channel; type ExtiChannel: crate::exti::Channel;
@ -699,6 +694,12 @@ foreach_pin!(
$port_num * 16 + $pin_num $port_num * 16 + $pin_num
} }
} }
impl From<peripherals::$pin_name> for AnyPin {
fn from(x: peripherals::$pin_name) -> Self {
x.degrade()
}
}
}; };
); );

View File

@ -1,12 +1,11 @@
use core::cmp; use core::cmp;
use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use atomic_polyfill::{AtomicUsize, Ordering}; use atomic_polyfill::{AtomicUsize, Ordering};
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::dma::NoDma; use crate::dma::NoDma;
@ -32,15 +31,15 @@ impl State {
} }
pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
phantom: PhantomData<&'d mut T>, _peri: Unborrowed<'d, T>,
tx_dma: TXDMA, tx_dma: Unborrowed<'d, TXDMA>,
#[allow(dead_code)] #[allow(dead_code)]
rx_dma: RXDMA, rx_dma: Unborrowed<'d, RXDMA>,
} }
impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
pub fn new( pub fn new(
_peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
scl: impl Unborrow<Target = impl SclPin<T>> + 'd, scl: impl Unborrow<Target = impl SclPin<T>> + 'd,
sda: impl Unborrow<Target = impl SdaPin<T>> + 'd, sda: impl Unborrow<Target = impl SdaPin<T>> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
@ -48,7 +47,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
rx_dma: impl Unborrow<Target = RXDMA> + 'd, rx_dma: impl Unborrow<Target = RXDMA> + 'd,
freq: Hertz, freq: Hertz,
) -> Self { ) -> Self {
unborrow!(irq, scl, sda, tx_dma, rx_dma); unborrow!(peri, irq, scl, sda, tx_dma, rx_dma);
T::enable(); T::enable();
T::reset(); T::reset();
@ -88,7 +87,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
irq.enable(); irq.enable();
Self { Self {
phantom: PhantomData, _peri: peri,
tx_dma, tx_dma,
rx_dma, rx_dma,
} }

View File

@ -75,7 +75,7 @@ pub(crate) mod _generated {
// Reexports // Reexports
pub use _generated::{peripherals, Peripherals}; pub use _generated::{peripherals, Peripherals};
pub use embassy_cortex_m::executor; 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 use embassy_macros::cortex_m_interrupt as interrupt;
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use stm32_metapac as pac; pub use stm32_metapac as pac;

View File

@ -1,6 +1,4 @@
use core::marker::PhantomData; use embassy_hal_common::{unborrow, Unborrowed};
use embassy_hal_common::unborrow;
use super::*; use super::*;
#[allow(unused_imports)] #[allow(unused_imports)]
@ -9,8 +7,7 @@ use crate::time::Hertz;
use crate::Unborrow; use crate::Unborrow;
pub struct SimplePwm<'d, T> { pub struct SimplePwm<'d, T> {
phantom: PhantomData<&'d mut T>, inner: Unborrowed<'d, T>,
inner: T,
} }
macro_rules! config_pins { macro_rules! config_pins {
@ -83,10 +80,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
configure_pins(); configure_pins();
let mut this = Self { let mut this = Self { inner: tim };
inner: tim,
phantom: PhantomData,
};
this.inner.set_frequency(freq); this.inner.set_frequency(freq);
this.inner.start(); this.inner.start();

View File

@ -1,10 +1,9 @@
#![macro_use] #![macro_use]
use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use futures::future::poll_fn; use futures::future::poll_fn;
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
@ -19,8 +18,7 @@ pub enum Error {
} }
pub struct Rng<'d, T: Instance> { pub struct Rng<'d, T: Instance> {
_inner: T, _inner: Unborrowed<'d, T>,
_phantom: PhantomData<&'d mut T>,
} }
impl<'d, T: Instance> Rng<'d, T> { impl<'d, T: Instance> Rng<'d, T> {
@ -28,10 +26,7 @@ impl<'d, T: Instance> Rng<'d, T> {
T::enable(); T::enable();
T::reset(); T::reset();
unborrow!(inner); unborrow!(inner);
let mut random = Self { let mut random = Self { _inner: inner };
_inner: inner,
_phantom: PhantomData,
};
random.reset(); random.reset();
random random
} }

View File

@ -1,18 +1,17 @@
#![macro_use] #![macro_use]
use core::default::Default; use core::default::Default;
use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy::waitqueue::AtomicWaker; use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use futures::future::poll_fn; use futures::future::poll_fn;
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::{Pull, Speed}; use crate::gpio::{AnyPin, Pull, Speed};
use crate::interrupt::{Interrupt, InterruptExt}; use crate::interrupt::{Interrupt, InterruptExt};
use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::pac::sdmmc::Sdmmc as RegBlock;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
@ -176,12 +175,19 @@ impl Default for Config {
} }
/// Sdmmc device /// Sdmmc device
pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> { pub struct Sdmmc<'d, T: Instance, Dma = NoDma> {
sdmmc: PhantomData<&'d mut T>, _peri: Unborrowed<'d, T>,
pins: P, irq: Unborrowed<'d, T::Interrupt>,
irq: T::Interrupt, dma: Unborrowed<'d, Dma>,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config, config: Config,
dma: Dma,
/// Current clock to card /// Current clock to card
clock: Hertz, clock: Hertz,
/// Current signalling scheme to card /// Current signalling scheme to card
@ -191,16 +197,99 @@ pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
} }
#[cfg(sdmmc_v1)] #[cfg(sdmmc_v1)]
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> {
pub fn new( pub fn new_1bit(
_peripheral: impl Unborrow<Target = T> + 'd, sdmmc: impl Unborrow<Target = T> + 'd,
pins: impl Unborrow<Target = P> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
config: Config,
dma: impl Unborrow<Target = Dma> + 'd, dma: impl Unborrow<Target = Dma> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
config: Config,
) -> Self { ) -> Self {
unborrow!(irq, pins, dma); unborrow!(clk, cmd, d0);
pins.configure();
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<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
dma: impl Unborrow<Target = Dma> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + '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,
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<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
dma: impl Unborrow<Target = Dma> + 'd,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config,
) -> Self {
unborrow!(sdmmc, irq, dma);
T::enable(); T::enable();
T::reset(); T::reset();
@ -213,11 +302,18 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
irq.enable(); irq.enable();
Self { Self {
sdmmc: PhantomData, _peri: sdmmc,
pins,
irq, irq,
config,
dma, dma,
clk,
cmd,
d0,
d1,
d2,
d3,
config,
clock, clock,
signalling: Default::default(), signalling: Default::default(),
card: None, card: None,
@ -226,15 +322,94 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
} }
#[cfg(sdmmc_v2)] #[cfg(sdmmc_v2)]
impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> { impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
pub fn new( pub fn new_1bit(
_peripheral: impl Unborrow<Target = T> + 'd, sdmmc: impl Unborrow<Target = T> + 'd,
pins: impl Unborrow<Target = P> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd, irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(irq, pins); unborrow!(clk, cmd, d0);
pins.configure();
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<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + '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,
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<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config,
) -> Self {
unborrow!(sdmmc, irq);
T::enable(); T::enable();
T::reset(); T::reset();
@ -247,11 +422,18 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
irq.enable(); irq.enable();
Self { Self {
sdmmc: PhantomData, _peri: sdmmc,
pins,
irq, irq,
dma: NoDma.unborrow(),
clk,
cmd,
d0,
d1,
d2,
d3,
config, config,
dma: NoDma,
clock, clock,
signalling: Default::default(), signalling: Default::default(),
card: None, 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)] #[inline(always)]
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> { pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
let inner = T::inner(); let inner = T::inner();
let freq = freq.into(); let freq = freq.into();
let bus_width = match self.d3.is_some() {
true => BusWidth::Four,
false => BusWidth::One,
};
inner inner
.init_card( .init_card(
freq, freq,
P::BUSWIDTH, bus_width,
&mut self.card, &mut self.card,
&mut self.signalling, &mut self.signalling,
T::frequency(), T::frequency(),
&mut self.clock, &mut self.clock,
T::state(), T::state(),
self.config.data_transfer_timeout, self.config.data_transfer_timeout,
&mut self.dma, &mut *self.dma,
) )
.await .await
} }
@ -295,7 +482,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
card_capacity, card_capacity,
state, state,
self.config.data_transfer_timeout, self.config.data_transfer_timeout,
&mut self.dma, &mut *self.dma,
) )
.await .await
} }
@ -314,7 +501,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
card, card,
state, state,
self.config.data_transfer_timeout, self.config.data_transfer_timeout,
&mut self.dma, &mut *self.dma,
) )
.await .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) { fn drop(&mut self) {
self.irq.disable(); self.irq.disable();
let inner = T::inner(); let inner = T::inner();
unsafe { inner.on_drop() }; 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!( foreach_peripheral!(
(sdmmc, $inst:ident) => { (sdmmc, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl sealed::Instance for peripherals::$inst {

View File

@ -1,10 +1,9 @@
#![macro_use] #![macro_use]
use core::marker::PhantomData;
use core::ptr; use core::ptr;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
use futures::future::join; use futures::future::join;
@ -73,13 +72,13 @@ impl Config {
} }
pub struct Spi<'d, T: Instance, Tx, Rx> { pub struct Spi<'d, T: Instance, Tx, Rx> {
sck: Option<AnyPin>, _peri: Unborrowed<'d, T>,
mosi: Option<AnyPin>, sck: Option<Unborrowed<'d, AnyPin>>,
miso: Option<AnyPin>, mosi: Option<Unborrowed<'d, AnyPin>>,
txdma: Tx, miso: Option<Unborrowed<'d, AnyPin>>,
rxdma: Rx, txdma: Unborrowed<'d, Tx>,
rxdma: Unborrowed<'d, Rx>,
current_word_size: WordSize, current_word_size: WordSize,
phantom: PhantomData<&'d mut T>,
} }
impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 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, freq: Hertz,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(sck, mosi, miso); unborrow!(peri, sck, mosi, miso);
unsafe { unsafe {
sck.set_as_af(sck.af_num(), AFType::OutputPushPull); sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
#[cfg(any(spi_v2, spi_v3, spi_v4))] #[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( Self::new_inner(
peri, peri,
Some(sck.degrade()), Some(sck.map_into()),
Some(mosi.degrade()), Some(mosi.map_into()),
Some(miso.degrade()), Some(miso.map_into()),
txdma, txdma,
rxdma, rxdma,
freq, freq,
@ -139,9 +138,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Self::new_inner( Self::new_inner(
peri, peri,
Some(sck.degrade()), Some(sck.map_into()),
None, None,
Some(miso.degrade()), Some(miso.map_into()),
txdma, txdma,
rxdma, rxdma,
freq, freq,
@ -170,8 +169,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
Self::new_inner( Self::new_inner(
peri, peri,
Some(sck.degrade()), Some(sck.map_into()),
Some(mosi.degrade()), Some(mosi.map_into()),
None, None,
txdma, txdma,
rxdma, rxdma,
@ -181,16 +180,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
fn new_inner( fn new_inner(
_peri: impl Unborrow<Target = T> + 'd, peri: impl Unborrow<Target = T> + 'd,
sck: Option<AnyPin>, sck: Option<Unborrowed<'d, AnyPin>>,
mosi: Option<AnyPin>, mosi: Option<Unborrowed<'d, AnyPin>>,
miso: Option<AnyPin>, miso: Option<Unborrowed<'d, AnyPin>>,
txdma: impl Unborrow<Target = Tx> + 'd, txdma: impl Unborrow<Target = Tx> + 'd,
rxdma: impl Unborrow<Target = Rx> + 'd, rxdma: impl Unborrow<Target = Rx> + 'd,
freq: Hertz, freq: Hertz,
config: Config, config: Config,
) -> Self { ) -> Self {
unborrow!(txdma, rxdma); unborrow!(peri, txdma, rxdma);
let pclk = T::frequency(); let pclk = T::frequency();
let br = compute_baud_rate(pclk, freq.into()); let br = compute_baud_rate(pclk, freq.into());
@ -280,13 +279,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
} }
Self { Self {
_peri: peri,
sck, sck,
mosi, mosi,
miso, miso,
txdma, txdma,
rxdma, rxdma,
current_word_size: WordSize::EightBit, 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 u8 {}
impl Word for u16 {} impl Word for u16 {}
pub trait Instance: sealed::Instance + RccPeripheral {} pub trait Instance: Unborrow<Target = Self> + sealed::Instance + RccPeripheral {}
pin_trait!(SckPin, Instance); pin_trait!(SckPin, Instance);
pin_trait!(MosiPin, Instance); pin_trait!(MosiPin, Instance);
pin_trait!(MisoPin, Instance); pin_trait!(MisoPin, Instance);

View File

@ -2,7 +2,7 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy_hal_common::unborrow; use embassy_hal_common::{unborrow, Unborrowed};
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
@ -72,23 +72,22 @@ pub enum Error {
} }
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
phantom: PhantomData<&'d mut T>,
tx: UartTx<'d, T, TxDma>, tx: UartTx<'d, T, TxDma>,
rx: UartRx<'d, T, RxDma>, rx: UartRx<'d, T, RxDma>,
} }
pub struct UartTx<'d, T: Instance, TxDma = NoDma> { pub struct UartTx<'d, T: Instance, TxDma = NoDma> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
tx_dma: TxDma, tx_dma: Unborrowed<'d, TxDma>,
} }
pub struct UartRx<'d, T: Instance, RxDma = NoDma> { pub struct UartRx<'d, T: Instance, RxDma = NoDma> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
rx_dma: RxDma, rx_dma: Unborrowed<'d, RxDma>,
} }
impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
fn new(tx_dma: TxDma) -> Self { fn new(tx_dma: Unborrowed<'d, TxDma>) -> Self {
Self { Self {
tx_dma, tx_dma,
phantom: PhantomData, phantom: PhantomData,
@ -134,7 +133,7 @@ impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
} }
impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> { impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
fn new(rx_dma: RxDma) -> Self { fn new(rx_dma: Unborrowed<'d, RxDma>) -> Self {
Self { Self {
rx_dma, rx_dma,
phantom: PhantomData, phantom: PhantomData,
@ -234,7 +233,6 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
} }
Self { Self {
phantom: PhantomData,
tx: UartTx::new(tx_dma), tx: UartTx::new(tx_dma),
rx: UartRx::new(rx_dma), rx: UartRx::new(rx_dma),
} }

View File

@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
let irq = interrupt::take!(SDIO); let irq = interrupt::take!(SDIO);
let mut sdmmc = Sdmmc::new( let mut sdmmc = Sdmmc::new_4bit(
p.SDIO, p.SDIO,
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
irq, irq,
Default::default(),
p.DMA2_CH3, p.DMA2_CH3,
p.PC12,
p.PD2,
p.PC8,
p.PC9,
p.PC10,
p.PC11,
Default::default(),
); );
// Should print 400kHz for initialization // Should print 400kHz for initialization

View File

@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
let irq = interrupt::take!(SDMMC1); let irq = interrupt::take!(SDMMC1);
let mut sdmmc = Sdmmc::new( let mut sdmmc = Sdmmc::new_4bit(
p.SDMMC1, p.SDMMC1,
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
irq, irq,
Default::default(),
p.DMA2_CH3, p.DMA2_CH3,
p.PC12,
p.PD2,
p.PC8,
p.PC9,
p.PC10,
p.PC11,
Default::default(),
); );
// Should print 400kHz for initialization // Should print 400kHz for initialization

View File

@ -2,8 +2,6 @@
#![no_main] #![no_main]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
use core::marker::PhantomData;
use defmt::*; use defmt::*;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy::time::{Duration, Timer}; use embassy::time::{Duration, Timer};
@ -11,7 +9,7 @@ use embassy_stm32::gpio::low_level::AFType;
use embassy_stm32::gpio::Speed; use embassy_stm32::gpio::Speed;
use embassy_stm32::pwm::*; use embassy_stm32::pwm::*;
use embassy_stm32::time::{khz, mhz, Hertz}; 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 _}; use {defmt_rtt as _, panic_probe as _};
pub fn config() -> Config { pub fn config() -> Config {
@ -49,8 +47,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
} }
} }
pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
phantom: PhantomData<&'d mut T>, inner: Unborrowed<'d, T>,
inner: T,
} }
impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'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); ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
} }
let mut this = Self { let mut this = Self { inner: tim };
inner: tim,
phantom: PhantomData,
};
this.set_freq(freq); this.set_freq(freq);
this.inner.start(); this.inner.start();

View File

@ -21,10 +21,15 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
let irq = interrupt::take!(SDMMC1); let irq = interrupt::take!(SDMMC1);
let mut sdmmc = Sdmmc::new( let mut sdmmc = Sdmmc::new_4bit(
p.SDMMC1, p.SDMMC1,
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
irq, irq,
p.PC12,
p.PD2,
p.PC8,
p.PC9,
p.PC10,
p.PC11,
Default::default(), Default::default(),
); );