Update embassy-stm32
This commit is contained in:
parent
e0521ea249
commit
8a9d2f59af
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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 ()) {
|
||||||
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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() };
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user