mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-30 22:01:11 +00:00
SPI type erasure (#2334)
* Move SPI peripheral type to the last position * Implement AnySpi * Convert peripheral types * Add new_typed constructors * Implement PDMA * Fix conditional * Clean up constructors * Fix test * Move stuff to utils * Extract any macros * Merge PeripheralMarker defs into peripherals macro * Changelogs * Implement fn degrade * Changelog num * Fix typo * Rename type-erased dma channel * Remove degrade fn * Remove utils * Explain peripherals macro
This commit is contained in:
parent
f2aa3f9863
commit
a754e411b1
@ -13,10 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- A new config option `PLACE_ANON_IN_RAM` to improve performance (especially for interrupts) at the cost of RAM usage (#2331)
|
||||
- Add burst transfer support to DMA buffers (#2336)
|
||||
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
|
||||
- Added `AnySpi` and `AnySpiDmaChannel`. (#2334)
|
||||
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
|
||||
|
||||
### Changed
|
||||
|
||||
- Peripheral type erasure for SPI (#2334)
|
||||
|
||||
### Fixed
|
||||
|
||||
### Removed
|
||||
|
@ -22,3 +22,26 @@ For example:
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Peripheral types are now optional
|
||||
|
||||
You no longer have to specify the peripheral instance in the driver's type for the following
|
||||
peripherals:
|
||||
|
||||
- SPI (both master and slave)
|
||||
|
||||
```diff
|
||||
-Spi<'static, SPI2, FullDuplexMode>
|
||||
+Spi<'static, FullDuplexMode>
|
||||
|
||||
-SpiDma<'static, SPI2, HalfDuplexMode, Blocking>
|
||||
+SpiDma<'static, HalfDuplexMode, Blocking>
|
||||
```
|
||||
|
||||
Note that you may still specify the instance if you need to. To do this, we provide `_typed`
|
||||
versions of the constructors (for example: `new_typed`, `new_half_duplex_typed`). Please note that
|
||||
the peripheral instance has been moved to the last generic parameter position.
|
||||
|
||||
```rust
|
||||
let spi: Spi<'static, FullDuplexMode, SPI2> = Spi::new_typed(peripherals.SPI2, 1.MHz(), SpiMode::Mode0);
|
||||
```
|
||||
|
@ -366,6 +366,15 @@ macro_rules! ImplSpiChannel {
|
||||
}
|
||||
}
|
||||
|
||||
impl DmaChannelConvert<AnySpiDmaChannel> for [<Spi $num DmaChannel>] {
|
||||
fn degrade_rx(rx: SpiDmaRxChannelImpl<Self>) -> SpiDmaRxChannelImpl<AnySpiDmaChannelInner> {
|
||||
SpiDmaRxChannelImpl(rx.0.into())
|
||||
}
|
||||
fn degrade_tx(tx: SpiDmaTxChannelImpl<Self>) -> SpiDmaTxChannelImpl<AnySpiDmaChannelInner> {
|
||||
SpiDmaTxChannelImpl(tx.0.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::private::Sealed for [<Spi $num DmaChannel>] {}
|
||||
|
||||
#[doc = concat!("Creates a channel for SPI", $num)]
|
||||
@ -897,3 +906,39 @@ where
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A marker for SPI-compatible type-erased DMA channels.
|
||||
pub struct AnySpiDmaChannel;
|
||||
|
||||
impl crate::private::Sealed for AnySpiDmaChannel {}
|
||||
|
||||
impl DmaChannel for AnySpiDmaChannel {
|
||||
type Rx = SpiDmaRxChannelImpl<AnySpiDmaChannelInner>;
|
||||
type Tx = SpiDmaTxChannelImpl<AnySpiDmaChannelInner>;
|
||||
}
|
||||
|
||||
crate::any_enum! {
|
||||
#[doc(hidden)]
|
||||
pub enum AnySpiDmaChannelInner {
|
||||
Spi2(Spi2DmaChannel),
|
||||
Spi3(Spi3DmaChannel),
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::private::Sealed for AnySpiDmaChannelInner {}
|
||||
|
||||
impl PdmaChannel for AnySpiDmaChannelInner {
|
||||
type RegisterBlock = SpiRegisterBlock;
|
||||
|
||||
delegate::delegate! {
|
||||
to match self {
|
||||
AnySpiDmaChannelInner::Spi2(channel) => channel,
|
||||
AnySpiDmaChannelInner::Spi3(channel) => channel,
|
||||
} {
|
||||
fn register_block(&self) -> &SpiRegisterBlock;
|
||||
fn tx_waker(&self) -> &'static AtomicWaker;
|
||||
fn rx_waker(&self) -> &'static AtomicWaker;
|
||||
fn is_compatible_with(&self, peripheral: &impl PeripheralMarker) -> bool;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1545,12 +1545,6 @@ mod private {
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralMarker for I2S0 {
|
||||
fn peripheral(&self) -> crate::system::Peripheral {
|
||||
crate::system::Peripheral::I2s0
|
||||
}
|
||||
}
|
||||
|
||||
impl RegBlock for I2S0 {
|
||||
fn register_block(&self) -> &RegisterBlock {
|
||||
unsafe { &*I2S0::PTR.cast::<RegisterBlock>() }
|
||||
@ -1650,13 +1644,6 @@ mod private {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(i2s1)]
|
||||
impl PeripheralMarker for I2S1 {
|
||||
fn peripheral(&self) -> crate::system::Peripheral {
|
||||
crate::system::Peripheral::I2s1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(i2s1)]
|
||||
impl RegBlock for I2S1 {
|
||||
fn register_block(&self) -> &RegisterBlock {
|
||||
|
@ -136,13 +136,7 @@ pub mod asynch {
|
||||
}
|
||||
|
||||
mod private {
|
||||
use crate::{dma::PeripheralMarker, peripherals::LCD_CAM};
|
||||
|
||||
impl PeripheralMarker for LCD_CAM {
|
||||
fn peripheral(&self) -> crate::system::Peripheral {
|
||||
crate::system::Peripheral::LcdCam
|
||||
}
|
||||
}
|
||||
use crate::peripherals::LCD_CAM;
|
||||
|
||||
pub(crate) struct Instance;
|
||||
|
||||
|
@ -142,7 +142,6 @@ mod fmt;
|
||||
|
||||
#[cfg(riscv)]
|
||||
pub use esp_riscv_rt::{self, entry, riscv};
|
||||
pub use procmacros as macros;
|
||||
#[cfg(xtensa)]
|
||||
pub use xtensa_lx;
|
||||
#[cfg(xtensa)]
|
||||
@ -241,6 +240,8 @@ pub mod debugger;
|
||||
#[doc(hidden)]
|
||||
pub mod sync;
|
||||
|
||||
pub mod macros;
|
||||
|
||||
/// State of the CPU saved when entering exception or interrupt
|
||||
pub mod trapframe {
|
||||
#[cfg(riscv)]
|
||||
@ -449,26 +450,6 @@ unsafe extern "C" fn stack_chk_fail() {
|
||||
panic!("Stack corruption detected");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Helper macro for checking doctest code snippets
|
||||
#[macro_export]
|
||||
macro_rules! before_snippet {
|
||||
() => {
|
||||
r#"
|
||||
# #![no_std]
|
||||
# use esp_hal::prelude::*;
|
||||
# use procmacros::handler;
|
||||
# use esp_hal::interrupt;
|
||||
# #[panic_handler]
|
||||
# fn panic(_ : &core::panic::PanicInfo) -> ! {
|
||||
# loop {}
|
||||
# }
|
||||
# fn main() {
|
||||
# let mut peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
"#
|
||||
};
|
||||
}
|
||||
|
||||
use crate::{
|
||||
clock::{Clocks, CpuClock},
|
||||
config::{WatchdogConfig, WatchdogStatus},
|
||||
|
115
esp-hal/src/macros.rs
Normal file
115
esp-hal/src/macros.rs
Normal file
@ -0,0 +1,115 @@
|
||||
//! Macros used by the HAL.
|
||||
//!
|
||||
//! Most of the macros in this module are hidden and intended for internal use
|
||||
//! only. For the list of public macros, see the [procmacros](https://docs.rs/esp-hal-procmacros/latest/esp_hal_procmacros/)
|
||||
//! documentation.
|
||||
|
||||
pub use procmacros::*;
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Helper macro for checking doctest code snippets
|
||||
#[macro_export]
|
||||
macro_rules! before_snippet {
|
||||
() => {
|
||||
r#"
|
||||
# #![no_std]
|
||||
# use esp_hal::prelude::*;
|
||||
# use procmacros::handler;
|
||||
# use esp_hal::interrupt;
|
||||
# #[panic_handler]
|
||||
# fn panic(_ : &core::panic::PanicInfo) -> ! {
|
||||
# loop {}
|
||||
# }
|
||||
# fn main() {
|
||||
# let mut peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
"#
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Shorthand to define enums with From implementations.
|
||||
#[macro_export]
|
||||
macro_rules! any_enum {
|
||||
($(#[$meta:meta])* $vis:vis enum $name:ident {
|
||||
$(
|
||||
$(#[$variant_meta:meta])*
|
||||
$variant:ident($inner:ty)
|
||||
),* $(,)?
|
||||
}) => {
|
||||
$(#[$meta])*
|
||||
$vis enum $name {
|
||||
$(
|
||||
$(#[$variant_meta])*
|
||||
$variant($inner),
|
||||
)*
|
||||
}
|
||||
|
||||
$(
|
||||
$(#[$variant_meta])*
|
||||
impl From<$inner> for $name {
|
||||
fn from(inner: $inner) -> Self {
|
||||
$name::$variant(inner)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Shorthand to define AnyPeripheral instances.
|
||||
#[macro_export]
|
||||
macro_rules! any_peripheral {
|
||||
($(#[$meta:meta])* $vis:vis peripheral $name:ident {
|
||||
$(
|
||||
$(#[cfg($variant_meta:meta)])*
|
||||
$variant:ident($inner:ty)
|
||||
),* $(,)?
|
||||
}) => {
|
||||
paste::paste! {
|
||||
$(#[$meta])*
|
||||
$vis struct $name([< $name Inner >]);
|
||||
impl $crate::private::Sealed for $name {}
|
||||
|
||||
impl $crate::dma::PeripheralMarker for $name {
|
||||
#[inline(always)]
|
||||
fn peripheral(&self) -> $crate::system::Peripheral {
|
||||
match &self.0 {
|
||||
$(
|
||||
$(#[cfg($variant_meta)])*
|
||||
[<$name Inner>]::$variant(inner) => inner.peripheral(),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::peripheral::Peripheral for $name {
|
||||
type P = $name;
|
||||
|
||||
unsafe fn clone_unchecked(&self) -> Self::P {
|
||||
match &self.0 {
|
||||
$(
|
||||
$(#[cfg($variant_meta)])*
|
||||
[<$name Inner>]::$variant(inner) => $name::from(inner.clone_unchecked()),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum [< $name Inner >] {
|
||||
$(
|
||||
$(#[cfg($variant_meta)])*
|
||||
$variant($inner),
|
||||
)*
|
||||
}
|
||||
|
||||
$(
|
||||
$(#[cfg($variant_meta)])*
|
||||
impl From<$inner> for $name {
|
||||
fn from(inner: $inner) -> Self {
|
||||
Self([< $name Inner >]::$variant(inner))
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
@ -207,16 +207,34 @@ impl<T: Peripheral> Peripheral for PeripheralRef<'_, T> {
|
||||
}
|
||||
|
||||
mod peripheral_macros {
|
||||
/// Creates a new `Peripherals` struct and its associated methods.
|
||||
///
|
||||
/// The macro has a few fields doing different things, in the form of
|
||||
/// `[first] second <= third (fourth)`.
|
||||
/// - The first field is the name of the `Peripherals` enum variant. This is
|
||||
/// optional and used to create `PeripheralMarker` implementations for
|
||||
/// DMA-eligible peripherals.
|
||||
/// - The second field is the name of the peripheral, as it appears in the
|
||||
/// `Peripherals` struct.
|
||||
/// - The third field is the name of the peripheral as it appears in the
|
||||
/// PAC. This may be `virtual` if the peripheral is not present in the
|
||||
/// PAC.
|
||||
/// - The fourth field is an optional list of interrupts that can be bound
|
||||
/// to the peripheral.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! peripherals {
|
||||
($($(#[$cfg:meta])? $name:ident <= $from_pac:tt $(($($interrupt:ident),*))? ),*$(,)?) => {
|
||||
(
|
||||
$(
|
||||
$([$enum_variant:ident])? $name:ident <= $from_pac:tt $(($($interrupt:ident),*))?
|
||||
), *$(,)?
|
||||
) => {
|
||||
|
||||
/// Contains the generated peripherals which implement [`Peripheral`]
|
||||
mod peripherals {
|
||||
pub use super::pac::*;
|
||||
$(
|
||||
$crate::create_peripheral!($(#[$cfg])? $name <= $from_pac);
|
||||
$crate::create_peripheral!($([$enum_variant])? $name <= $from_pac);
|
||||
)*
|
||||
}
|
||||
|
||||
@ -224,7 +242,6 @@ mod peripheral_macros {
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Peripherals {
|
||||
$(
|
||||
$(#[$cfg])?
|
||||
/// Each field represents a hardware peripheral.
|
||||
pub $name: peripherals::$name,
|
||||
)*
|
||||
@ -245,9 +262,7 @@ mod peripheral_macros {
|
||||
Self::steal()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Peripherals {
|
||||
/// Unsafely create an instance of this peripheral out of thin air.
|
||||
///
|
||||
/// # Safety
|
||||
@ -257,7 +272,6 @@ mod peripheral_macros {
|
||||
pub unsafe fn steal() -> Self {
|
||||
Self {
|
||||
$(
|
||||
$(#[$cfg])?
|
||||
$name: peripherals::$name::steal(),
|
||||
)*
|
||||
}
|
||||
@ -313,8 +327,7 @@ mod peripheral_macros {
|
||||
#[macro_export]
|
||||
/// Macro to create a peripheral structure.
|
||||
macro_rules! create_peripheral {
|
||||
($(#[$cfg:meta])? $name:ident <= virtual) => {
|
||||
$(#[$cfg])?
|
||||
($([$enum_variant:ident])? $name:ident <= virtual) => {
|
||||
#[derive(Debug)]
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Represents a virtual peripheral with no associated hardware.
|
||||
@ -323,7 +336,6 @@ mod peripheral_macros {
|
||||
/// is defined as virtual.
|
||||
pub struct $name { _inner: () }
|
||||
|
||||
$(#[$cfg])?
|
||||
impl $name {
|
||||
/// Unsafely create an instance of this peripheral out of thin air.
|
||||
///
|
||||
@ -346,29 +358,21 @@ mod peripheral_macros {
|
||||
}
|
||||
|
||||
impl $crate::private::Sealed for $name {}
|
||||
};
|
||||
($(#[$cfg:meta])? $name:ident <= $base:ident) => {
|
||||
$(#[$cfg])?
|
||||
#[derive(Debug)]
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Represents a concrete hardware peripheral.
|
||||
///
|
||||
/// This struct is generated by the `create_peripheral!` macro when the peripheral
|
||||
/// is tied to an actual hardware device.
|
||||
pub struct $name { _inner: () }
|
||||
|
||||
$(#[$cfg])?
|
||||
impl $name {
|
||||
/// Unsafely create an instance of this peripheral out of thin air.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that you're only using one instance of this type at a time.
|
||||
#[inline]
|
||||
pub unsafe fn steal() -> Self {
|
||||
Self { _inner: () }
|
||||
$(
|
||||
impl $crate::dma::PeripheralMarker for $crate::peripherals::$name {
|
||||
#[inline(always)]
|
||||
fn peripheral(&self) -> $crate::system::Peripheral {
|
||||
$crate::system::Peripheral::$enum_variant
|
||||
}
|
||||
}
|
||||
)?
|
||||
};
|
||||
|
||||
($([$enum_variant:ident])? $name:ident <= $base:ident) => {
|
||||
$crate::create_peripheral!($([$enum_variant])? $name <= virtual);
|
||||
|
||||
impl $name {
|
||||
#[doc = r"Pointer to the register block"]
|
||||
pub const PTR: *const <super::pac::$base as core::ops::Deref>::Target = super::pac::$base::PTR;
|
||||
|
||||
@ -388,22 +392,10 @@ mod peripheral_macros {
|
||||
}
|
||||
|
||||
impl core::ops::DerefMut for $name {
|
||||
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut *(Self::PTR as *mut _) }
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::peripheral::Peripheral for $name {
|
||||
type P = $name;
|
||||
|
||||
#[inline]
|
||||
unsafe fn clone_unchecked(&self) -> Self::P {
|
||||
Self::steal()
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::private::Sealed for $name {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ crate::peripherals! {
|
||||
HINF <= HINF,
|
||||
I2C0 <= I2C0,
|
||||
I2C1 <= I2C1,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
I2S1 <= I2S1 (I2S1),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
[I2s1] I2S1 <= I2S1 (I2S1),
|
||||
IO_MUX <= IO_MUX,
|
||||
LEDC <= LEDC,
|
||||
MCPWM0 <= MCPWM0,
|
||||
@ -60,8 +60,8 @@ crate::peripherals! {
|
||||
SLCHOST <= SLCHOST,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||
SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||
[Spi3] SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||
SYSTEM <= DPORT,
|
||||
SW_INTERRUPT <= virtual,
|
||||
TIMG0 <= TIMG0,
|
||||
|
@ -40,7 +40,7 @@ crate::peripherals! {
|
||||
SHA <= SHA,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||
SYSTEM <= SYSTEM,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
SW_INTERRUPT <= virtual,
|
||||
|
@ -34,7 +34,7 @@ crate::peripherals! {
|
||||
GPIO_SD <= GPIO_SD,
|
||||
HMAC <= HMAC,
|
||||
I2C0 <= I2C0,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
IO_MUX <= IO_MUX,
|
||||
LEDC <= LEDC,
|
||||
@ -47,7 +47,7 @@ crate::peripherals! {
|
||||
SHA <= SHA,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||
SYSTEM <= SYSTEM,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
SW_INTERRUPT <= virtual,
|
||||
|
@ -37,7 +37,7 @@ crate::peripherals! {
|
||||
HP_APM <= HP_APM,
|
||||
HP_SYS <= HP_SYS,
|
||||
I2C0 <= I2C0,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
IEEE802154 <= IEEE802154,
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
INTPRI <= INTPRI,
|
||||
@ -73,7 +73,7 @@ crate::peripherals! {
|
||||
SOC_ETM <= SOC_ETM,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||
SYSTEM <= PCR,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
SW_INTERRUPT <= virtual,
|
||||
|
@ -35,7 +35,7 @@ crate::peripherals! {
|
||||
HP_SYS <= HP_SYS,
|
||||
I2C0 <= I2C0,
|
||||
I2C1 <= I2C1,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
IEEE802154 <= IEEE802154,
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
INTPRI <= INTPRI,
|
||||
@ -65,7 +65,7 @@ crate::peripherals! {
|
||||
SOC_ETM <= SOC_ETM,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||
SYSTEM <= PCR,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
SW_INTERRUPT <= virtual,
|
||||
|
@ -35,7 +35,7 @@ crate::peripherals! {
|
||||
HMAC <= HMAC,
|
||||
I2C0 <= I2C0,
|
||||
I2C1 <= I2C1,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
IO_MUX <= IO_MUX,
|
||||
LEDC <= LEDC,
|
||||
@ -52,9 +52,8 @@ crate::peripherals! {
|
||||
SHA <= SHA,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||
SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||
SPI4 <= SPI4,
|
||||
[Spi2] SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||
[Spi3] SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||
SYSCON <= SYSCON,
|
||||
SYSTEM <= SYSTEM,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
|
@ -36,12 +36,12 @@ crate::peripherals! {
|
||||
HMAC <= HMAC,
|
||||
I2C0 <= I2C0,
|
||||
I2C1 <= I2C1,
|
||||
I2S0 <= I2S0 (I2S0),
|
||||
I2S1 <= I2S1 (I2S1),
|
||||
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||
[I2s1] I2S1 <= I2S1 (I2S1),
|
||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||
INTERRUPT_CORE1 <= INTERRUPT_CORE1,
|
||||
IO_MUX <= IO_MUX,
|
||||
LCD_CAM <= LCD_CAM,
|
||||
[LcdCam] LCD_CAM <= LCD_CAM,
|
||||
LEDC <= LEDC,
|
||||
LPWR <= RTC_CNTL,
|
||||
PCNT <= PCNT,
|
||||
@ -59,8 +59,8 @@ crate::peripherals! {
|
||||
SHA <= SHA,
|
||||
SPI0 <= SPI0,
|
||||
SPI1 <= SPI1,
|
||||
SPI2 <= SPI2 (SPI2),
|
||||
SPI3 <= SPI3 (SPI3),
|
||||
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||
[Spi3] SPI3 <= SPI3 (SPI3),
|
||||
SYSTEM <= SYSTEM,
|
||||
SYSTIMER <= SYSTIMER,
|
||||
SW_INTERRUPT <= virtual,
|
||||
|
@ -87,6 +87,7 @@ use crate::{
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
private,
|
||||
spi::AnySpi,
|
||||
system::PeripheralClockControl,
|
||||
Mode,
|
||||
};
|
||||
@ -452,15 +453,35 @@ pub trait HalfDuplexReadWrite {
|
||||
}
|
||||
|
||||
/// SPI peripheral driver
|
||||
pub struct Spi<'d, T, M> {
|
||||
pub struct Spi<'d, M, T = AnySpi> {
|
||||
spi: PeripheralRef<'d, T>,
|
||||
_mode: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<'d, T, M> Spi<'d, T, M>
|
||||
impl<'d, M, T> Spi<'d, M, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
fn new_internal(
|
||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, M, T> {
|
||||
crate::into_ref!(spi);
|
||||
|
||||
let mut spi = Spi {
|
||||
spi: spi.map_into(),
|
||||
_mode: PhantomData,
|
||||
};
|
||||
spi.spi.reset_peripheral();
|
||||
spi.spi.enable_peripheral();
|
||||
spi.spi.setup(frequency);
|
||||
spi.spi.init();
|
||||
spi.spi.set_data_mode(mode);
|
||||
|
||||
spi
|
||||
}
|
||||
|
||||
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
||||
@ -486,7 +507,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, M> Spi<'d, T, M>
|
||||
impl<'d, M, T> Spi<'d, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: DuplexMode,
|
||||
@ -499,7 +520,7 @@ where
|
||||
pub fn with_dma<CH, DmaMode>(
|
||||
self,
|
||||
channel: crate::dma::Channel<'d, CH, DmaMode>,
|
||||
) -> SpiDma<'d, T, M, DmaMode>
|
||||
) -> SpiDma<'d, M, DmaMode, T>
|
||||
where
|
||||
CH: DmaChannelConvert<T::Dma>,
|
||||
DmaMode: Mode,
|
||||
@ -508,7 +529,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -544,7 +565,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||
impl<'d> Spi<'d, FullDuplexMode> {
|
||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||
///
|
||||
/// All pins are optional. Setup these pins using
|
||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||
pub fn new(
|
||||
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, FullDuplexMode> {
|
||||
Self::new_typed(spi, frequency, mode)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -552,13 +587,15 @@ where
|
||||
///
|
||||
/// All pins are optional. Setup these pins using
|
||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||
pub fn new(
|
||||
spi: impl Peripheral<P = T> + 'd,
|
||||
pub fn new_typed(
|
||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
crate::into_ref!(spi);
|
||||
Self::new_internal(spi, frequency, mode)
|
||||
) -> Spi<'d, FullDuplexMode, T> {
|
||||
let spi = Spi::<FullDuplexMode, T>::new_internal(spi, frequency, mode);
|
||||
|
||||
// Disconnect any lingering connections
|
||||
spi.with_pins(NoPin, NoPin, NoPin, NoPin)
|
||||
}
|
||||
|
||||
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
|
||||
@ -614,26 +651,6 @@ where
|
||||
.with_cs(cs)
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(
|
||||
spi: PeripheralRef<'d, T>,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
spi.reset_peripheral();
|
||||
spi.enable_peripheral();
|
||||
|
||||
let mut spi = Spi {
|
||||
spi,
|
||||
_mode: PhantomData,
|
||||
};
|
||||
spi.spi.setup(frequency);
|
||||
spi.spi.init();
|
||||
spi.spi.set_data_mode(mode);
|
||||
|
||||
// Disconnect any lingering connections
|
||||
spi.with_pins(NoPin, NoPin, NoPin, NoPin)
|
||||
}
|
||||
|
||||
/// Change the bus frequency of the SPI instance.
|
||||
///
|
||||
/// This method allows user to update the bus frequency for the SPI
|
||||
@ -643,7 +660,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, T, HalfDuplexMode>
|
||||
impl<'d> Spi<'d, HalfDuplexMode> {
|
||||
/// Constructs an SPI instance in half-duplex mode.
|
||||
///
|
||||
/// All pins are optional. Setup these pins using
|
||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||
pub fn new_half_duplex(
|
||||
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, HalfDuplexMode> {
|
||||
Self::new_half_duplex_typed(spi, frequency, mode)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, HalfDuplexMode, T>
|
||||
where
|
||||
T: ExtendedInstance,
|
||||
{
|
||||
@ -651,13 +682,15 @@ where
|
||||
///
|
||||
/// All pins are optional. Setup these pins using
|
||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||
pub fn new_half_duplex(
|
||||
spi: impl Peripheral<P = T> + 'd,
|
||||
pub fn new_half_duplex_typed(
|
||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, HalfDuplexMode> {
|
||||
crate::into_ref!(spi);
|
||||
Self::new_internal(spi, frequency, mode)
|
||||
) -> Spi<'d, HalfDuplexMode, T> {
|
||||
let spi = Spi::<HalfDuplexMode, T>::new_internal(spi, frequency, mode);
|
||||
|
||||
// Disconnect any lingering connections
|
||||
spi.with_pins(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin)
|
||||
}
|
||||
|
||||
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance in
|
||||
@ -761,27 +794,6 @@ where
|
||||
.with_sio3(sio3)
|
||||
.with_cs(cs)
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(
|
||||
spi: PeripheralRef<'d, T>,
|
||||
frequency: HertzU32,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, HalfDuplexMode> {
|
||||
spi.reset_peripheral();
|
||||
spi.enable_peripheral();
|
||||
|
||||
let mut spi = Spi {
|
||||
spi,
|
||||
_mode: PhantomData::<HalfDuplexMode>,
|
||||
};
|
||||
spi.spi.setup(frequency);
|
||||
spi.spi.init();
|
||||
spi.spi.set_data_mode(mode);
|
||||
|
||||
// Disconnect any lingering connections
|
||||
spi.with_pins(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin)
|
||||
}
|
||||
|
||||
/// Change the bus frequency of the SPI instance in half-duplex mode.
|
||||
///
|
||||
/// This method allows you to update the bus frequency for the SPI
|
||||
@ -799,7 +811,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HalfDuplexReadWrite for Spi<'_, T, HalfDuplexMode>
|
||||
impl<T> HalfDuplexReadWrite for Spi<'_, HalfDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -890,7 +902,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> embedded_hal_02::spi::FullDuplex<u8> for Spi<'_, T, FullDuplexMode>
|
||||
impl<T> embedded_hal_02::spi::FullDuplex<u8> for Spi<'_, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -905,7 +917,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> embedded_hal_02::blocking::spi::Transfer<u8> for Spi<'_, T, FullDuplexMode>
|
||||
impl<T> embedded_hal_02::blocking::spi::Transfer<u8> for Spi<'_, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -916,7 +928,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> embedded_hal_02::blocking::spi::Write<u8> for Spi<'_, T, FullDuplexMode>
|
||||
impl<T> embedded_hal_02::blocking::spi::Write<u8> for Spi<'_, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -959,7 +971,7 @@ mod dma {
|
||||
/// [`SpiDmaBus`] via `with_buffers` to get access
|
||||
/// to a DMA capable SPI bus that implements the
|
||||
/// embedded-hal traits.
|
||||
pub struct SpiDma<'d, T, D, M>
|
||||
pub struct SpiDma<'d, D, M, T = AnySpi>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -975,7 +987,7 @@ mod dma {
|
||||
}
|
||||
|
||||
#[cfg(all(esp32, spi_address_workaround))]
|
||||
unsafe impl<'d, T, D, M> Send for SpiDma<'d, T, D, M>
|
||||
unsafe impl<'d, D, M, T> Send for SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -983,7 +995,7 @@ mod dma {
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> core::fmt::Debug for SpiDma<'d, T, D, M>
|
||||
impl<'d, D, M, T> core::fmt::Debug for SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -998,7 +1010,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> SpiDma<'d, T, D, M>
|
||||
impl<'d, D, M, T> SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1206,7 +1218,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> crate::private::Sealed for SpiDma<'d, T, D, M>
|
||||
impl<'d, D, M, T> crate::private::Sealed for SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1214,7 +1226,7 @@ mod dma {
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> InterruptConfigurable for SpiDma<'d, T, D, M>
|
||||
impl<'d, D, M, T> InterruptConfigurable for SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1226,7 +1238,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> SpiDma<'d, T, D, M>
|
||||
impl<'d, D, M, T> SpiDma<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1246,7 +1258,7 @@ mod dma {
|
||||
self,
|
||||
dma_rx_buf: DmaRxBuf,
|
||||
dma_tx_buf: DmaTxBuf,
|
||||
) -> SpiDmaBus<'d, T, D, M> {
|
||||
) -> SpiDmaBus<'d, D, M, T> {
|
||||
SpiDmaBus::new(self, dma_rx_buf, dma_tx_buf)
|
||||
}
|
||||
}
|
||||
@ -1255,23 +1267,23 @@ mod dma {
|
||||
///
|
||||
/// This structure holds references to the SPI instance, DMA buffers, and
|
||||
/// transfer status.
|
||||
pub struct SpiDmaTransfer<'d, T, D, M, Buf>
|
||||
pub struct SpiDmaTransfer<'d, D, M, Buf, T = AnySpi>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
M: Mode,
|
||||
{
|
||||
spi_dma: ManuallyDrop<SpiDma<'d, T, D, M>>,
|
||||
spi_dma: ManuallyDrop<SpiDma<'d, D, M, T>>,
|
||||
dma_buf: ManuallyDrop<Buf>,
|
||||
}
|
||||
|
||||
impl<'d, T, D, M, Buf> SpiDmaTransfer<'d, T, D, M, Buf>
|
||||
impl<'d, D, M, T, Buf> SpiDmaTransfer<'d, D, M, Buf, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
M: Mode,
|
||||
{
|
||||
fn new(spi_dma: SpiDma<'d, T, D, M>, dma_buf: Buf) -> Self {
|
||||
fn new(spi_dma: SpiDma<'d, D, M, T>, dma_buf: Buf) -> Self {
|
||||
Self {
|
||||
spi_dma: ManuallyDrop::new(spi_dma),
|
||||
dma_buf: ManuallyDrop::new(dma_buf),
|
||||
@ -1290,7 +1302,7 @@ mod dma {
|
||||
///
|
||||
/// This method blocks until the transfer is finished and returns the
|
||||
/// `SpiDma` instance and the associated buffer.
|
||||
pub fn wait(mut self) -> (SpiDma<'d, T, D, M>, Buf) {
|
||||
pub fn wait(mut self) -> (SpiDma<'d, D, M, T>, Buf) {
|
||||
self.spi_dma.wait_for_idle();
|
||||
let retval = unsafe {
|
||||
(
|
||||
@ -1310,7 +1322,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M, Buf> Drop for SpiDmaTransfer<'d, T, D, M, Buf>
|
||||
impl<'d, D, M, T, Buf> Drop for SpiDmaTransfer<'d, D, M, Buf, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1329,7 +1341,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, Buf> SpiDmaTransfer<'d, T, D, crate::Async, Buf>
|
||||
impl<'d, T, D, Buf> SpiDmaTransfer<'d, D, crate::Async, Buf, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1342,7 +1354,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, M> SpiDma<'d, T, FullDuplexMode, M>
|
||||
impl<'d, M, T> SpiDma<'d, FullDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -1377,7 +1389,7 @@ mod dma {
|
||||
pub fn dma_write<TX: DmaTxBuffer>(
|
||||
mut self,
|
||||
mut buffer: TX,
|
||||
) -> Result<SpiDmaTransfer<'d, T, FullDuplexMode, M, TX>, (Error, Self, TX)> {
|
||||
) -> Result<SpiDmaTransfer<'d, FullDuplexMode, M, TX, T>, (Error, Self, TX)> {
|
||||
self.wait_for_idle();
|
||||
|
||||
match unsafe { self.start_dma_write(&mut buffer) } {
|
||||
@ -1416,7 +1428,7 @@ mod dma {
|
||||
pub fn dma_read<RX: DmaRxBuffer>(
|
||||
mut self,
|
||||
mut buffer: RX,
|
||||
) -> Result<SpiDmaTransfer<'d, T, FullDuplexMode, M, RX>, (Error, Self, RX)> {
|
||||
) -> Result<SpiDmaTransfer<'d, FullDuplexMode, M, RX, T>, (Error, Self, RX)> {
|
||||
self.wait_for_idle();
|
||||
match unsafe { self.start_dma_read(&mut buffer) } {
|
||||
Ok(_) => Ok(SpiDmaTransfer::new(self, buffer)),
|
||||
@ -1455,7 +1467,7 @@ mod dma {
|
||||
mut self,
|
||||
mut rx_buffer: RX,
|
||||
mut tx_buffer: TX,
|
||||
) -> Result<SpiDmaTransfer<'d, T, FullDuplexMode, M, (RX, TX)>, (Error, Self, RX, TX)>
|
||||
) -> Result<SpiDmaTransfer<'d, FullDuplexMode, M, (RX, TX), T>, (Error, Self, RX, TX)>
|
||||
{
|
||||
self.wait_for_idle();
|
||||
match unsafe { self.start_dma_transfer(&mut rx_buffer, &mut tx_buffer) } {
|
||||
@ -1465,7 +1477,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, M> SpiDma<'d, T, HalfDuplexMode, M>
|
||||
impl<'d, M, T> SpiDma<'d, HalfDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -1517,7 +1529,7 @@ mod dma {
|
||||
address: Address,
|
||||
dummy: u8,
|
||||
mut buffer: RX,
|
||||
) -> Result<SpiDmaTransfer<'d, T, HalfDuplexMode, M, RX>, (Error, Self, RX)> {
|
||||
) -> Result<SpiDmaTransfer<'d, HalfDuplexMode, M, RX, T>, (Error, Self, RX)> {
|
||||
self.wait_for_idle();
|
||||
|
||||
match unsafe {
|
||||
@ -1584,7 +1596,7 @@ mod dma {
|
||||
address: Address,
|
||||
dummy: u8,
|
||||
mut buffer: TX,
|
||||
) -> Result<SpiDmaTransfer<'d, T, HalfDuplexMode, M, TX>, (Error, Self, TX)> {
|
||||
) -> Result<SpiDmaTransfer<'d, HalfDuplexMode, M, TX, T>, (Error, Self, TX)> {
|
||||
self.wait_for_idle();
|
||||
|
||||
match unsafe {
|
||||
@ -1600,18 +1612,18 @@ mod dma {
|
||||
///
|
||||
/// This structure is responsible for managing SPI transfers using DMA
|
||||
/// buffers.
|
||||
pub struct SpiDmaBus<'d, T, D, M>
|
||||
pub struct SpiDmaBus<'d, D, M, T = AnySpi>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
M: Mode,
|
||||
{
|
||||
spi_dma: SpiDma<'d, T, D, M>,
|
||||
spi_dma: SpiDma<'d, D, M, T>,
|
||||
rx_buf: DmaRxBuf,
|
||||
tx_buf: DmaTxBuf,
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> SpiDmaBus<'d, T, D, M>
|
||||
impl<'d, D, M, T> SpiDmaBus<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1619,7 +1631,7 @@ mod dma {
|
||||
{
|
||||
/// Creates a new `SpiDmaBus` with the specified SPI instance and DMA
|
||||
/// buffers.
|
||||
pub fn new(spi_dma: SpiDma<'d, T, D, M>, rx_buf: DmaRxBuf, tx_buf: DmaTxBuf) -> Self {
|
||||
pub fn new(spi_dma: SpiDma<'d, D, M, T>, rx_buf: DmaRxBuf, tx_buf: DmaTxBuf) -> Self {
|
||||
Self {
|
||||
spi_dma,
|
||||
rx_buf,
|
||||
@ -1668,7 +1680,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> InterruptConfigurable for SpiDmaBus<'d, T, D, M>
|
||||
impl<'d, D, M, T> InterruptConfigurable for SpiDmaBus<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1680,7 +1692,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, D, M> crate::private::Sealed for SpiDmaBus<'d, T, D, M>
|
||||
impl<'d, D, M, T> crate::private::Sealed for SpiDmaBus<'d, D, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
D: DuplexMode,
|
||||
@ -1688,7 +1700,7 @@ mod dma {
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, T, M> SpiDmaBus<'d, T, FullDuplexMode, M>
|
||||
impl<'d, M, T> SpiDmaBus<'d, FullDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -1788,7 +1800,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, M> HalfDuplexReadWrite for SpiDmaBus<'d, T, HalfDuplexMode, M>
|
||||
impl<'d, M, T> HalfDuplexReadWrite for SpiDmaBus<'d, HalfDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -1860,7 +1872,7 @@ mod dma {
|
||||
}
|
||||
|
||||
impl<'d, T> embedded_hal_02::blocking::spi::Transfer<u8>
|
||||
for SpiDmaBus<'d, T, FullDuplexMode, crate::Blocking>
|
||||
for SpiDmaBus<'d, FullDuplexMode, crate::Blocking, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
{
|
||||
@ -1873,7 +1885,7 @@ mod dma {
|
||||
}
|
||||
|
||||
impl<'d, T> embedded_hal_02::blocking::spi::Write<u8>
|
||||
for SpiDmaBus<'d, T, FullDuplexMode, crate::Blocking>
|
||||
for SpiDmaBus<'d, FullDuplexMode, crate::Blocking, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
{
|
||||
@ -1932,7 +1944,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> SpiDmaBus<'d, T, FullDuplexMode, crate::Async>
|
||||
impl<'d, T> SpiDmaBus<'d, FullDuplexMode, crate::Async, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
{
|
||||
@ -2046,7 +2058,7 @@ mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> embedded_hal_async::spi::SpiBus for SpiDmaBus<'d, T, FullDuplexMode, crate::Async>
|
||||
impl<'d, T> embedded_hal_async::spi::SpiBus for SpiDmaBus<'d, FullDuplexMode, crate::Async, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
{
|
||||
@ -2078,7 +2090,7 @@ mod dma {
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<'d, T, M> ErrorType for SpiDmaBus<'d, T, FullDuplexMode, M>
|
||||
impl<'d, M, T> ErrorType for SpiDmaBus<'d, FullDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -2086,7 +2098,7 @@ mod dma {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T, M> SpiBus for SpiDmaBus<'d, T, FullDuplexMode, M>
|
||||
impl<'d, M, T> SpiBus for SpiDmaBus<'d, FullDuplexMode, M, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
M: Mode,
|
||||
@ -2121,11 +2133,11 @@ mod ehal1 {
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<T, M> embedded_hal::spi::ErrorType for Spi<'_, T, M> {
|
||||
impl<T, M> embedded_hal::spi::ErrorType for Spi<'_, M, T> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<T> FullDuplex for Spi<'_, T, FullDuplexMode>
|
||||
impl<T> FullDuplex for Spi<'_, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -2138,7 +2150,7 @@ mod ehal1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SpiBus for Spi<'_, T, FullDuplexMode>
|
||||
impl<T> SpiBus for Spi<'_, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
@ -2680,24 +2692,21 @@ pub trait Instance: private::Sealed + PeripheralMarker {
|
||||
}
|
||||
|
||||
fn ch_bus_freq(&mut self, frequency: HertzU32) {
|
||||
// Disable clock source
|
||||
#[cfg(gdma)]
|
||||
self.register_block().clk_gate().modify(|_, w| {
|
||||
w.clk_en().clear_bit();
|
||||
w.mst_clk_active().clear_bit();
|
||||
w.mst_clk_sel().clear_bit()
|
||||
});
|
||||
fn enable_clocks(_reg_block: &RegisterBlock, _enable: bool) {
|
||||
#[cfg(gdma)]
|
||||
_reg_block.clk_gate().modify(|_, w| {
|
||||
w.clk_en().bit(_enable);
|
||||
w.mst_clk_active().bit(_enable);
|
||||
w.mst_clk_sel().bit(_enable)
|
||||
});
|
||||
}
|
||||
|
||||
enable_clocks(self.register_block(), false);
|
||||
|
||||
// Change clock frequency
|
||||
self.setup(frequency);
|
||||
|
||||
// Enable clock source
|
||||
#[cfg(gdma)]
|
||||
self.register_block().clk_gate().modify(|_, w| {
|
||||
w.clk_en().set_bit();
|
||||
w.mst_clk_active().set_bit();
|
||||
w.mst_clk_sel().set_bit()
|
||||
});
|
||||
enable_clocks(self.register_block(), true);
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32, esp32c3, esp32s2)))]
|
||||
@ -3296,3 +3305,115 @@ impl ExtendedInstance for crate::peripherals::SPI3 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for super::AnySpi {
|
||||
delegate::delegate! {
|
||||
to match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi,
|
||||
#[cfg(spi3)]
|
||||
super::AnySpiInner::Spi3(spi) => spi,
|
||||
} {
|
||||
fn register_block(&self) -> &RegisterBlock;
|
||||
fn spi_num(&self) -> u8;
|
||||
fn sclk_signal(&self) -> OutputSignal;
|
||||
fn mosi_signal(&self) -> OutputSignal;
|
||||
fn miso_signal(&self) -> InputSignal;
|
||||
fn cs_signal(&self) -> OutputSignal;
|
||||
}
|
||||
}
|
||||
delegate::delegate! {
|
||||
to match &mut self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi,
|
||||
#[cfg(spi3)]
|
||||
super::AnySpiInner::Spi3(spi) => spi,
|
||||
} {
|
||||
fn set_interrupt_handler(&mut self, handler: InterruptHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtendedInstance for super::AnySpi {
|
||||
fn sio0_input_signal(&self) -> InputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio0_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio0_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
|
||||
fn sio1_output_signal(&self) -> OutputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio1_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio1_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
|
||||
fn sio2_output_signal(&self) -> OutputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio2_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio2_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
|
||||
fn sio2_input_signal(&self) -> InputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio2_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio2_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
|
||||
fn sio3_output_signal(&self) -> OutputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio3_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio3_output_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
|
||||
fn sio3_input_signal(&self) -> InputSignal {
|
||||
match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi.sio3_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, any(esp32, esp32s3)))]
|
||||
super::AnySpiInner::Spi3(spi) => spi.sio3_input_signal(),
|
||||
|
||||
#[cfg(all(spi3, not(any(esp32, esp32s3))))]
|
||||
super::AnySpiInner::Spi3(_) => unimplemented!("SPI3 is does not support QSPI"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceDma for super::AnySpi {
|
||||
delegate::delegate! {
|
||||
to match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi,
|
||||
#[cfg(spi3)]
|
||||
super::AnySpiInner::Spi3(spi) => spi,
|
||||
} {
|
||||
fn clear_dma_interrupts(&self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
//! more information on these modes, please refer to the documentation in their
|
||||
//! respective modules.
|
||||
|
||||
use crate::dma::{DmaError, PeripheralMarker};
|
||||
use crate::dma::{DmaEligible, DmaError};
|
||||
|
||||
pub mod master;
|
||||
pub mod slave;
|
||||
@ -101,18 +101,28 @@ pub struct HalfDuplexMode {}
|
||||
impl DuplexMode for HalfDuplexMode {}
|
||||
impl crate::private::Sealed for HalfDuplexMode {}
|
||||
|
||||
#[cfg(spi2)]
|
||||
impl PeripheralMarker for crate::peripherals::SPI2 {
|
||||
#[inline(always)]
|
||||
fn peripheral(&self) -> crate::system::Peripheral {
|
||||
crate::system::Peripheral::Spi2
|
||||
crate::any_peripheral! {
|
||||
/// Any SPI peripheral.
|
||||
pub peripheral AnySpi {
|
||||
#[cfg(spi2)]
|
||||
Spi2(crate::peripherals::SPI2),
|
||||
#[cfg(spi3)]
|
||||
Spi3(crate::peripherals::SPI3),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(spi3)]
|
||||
impl PeripheralMarker for crate::peripherals::SPI3 {
|
||||
#[inline(always)]
|
||||
fn peripheral(&self) -> crate::system::Peripheral {
|
||||
crate::system::Peripheral::Spi3
|
||||
impl DmaEligible for AnySpi {
|
||||
#[cfg(gdma)]
|
||||
type Dma = crate::dma::AnyGdmaChannel;
|
||||
#[cfg(pdma)]
|
||||
type Dma = crate::dma::AnySpiDmaChannel;
|
||||
|
||||
fn dma_peripheral(&self) -> crate::dma::DmaPeripheral {
|
||||
match &self.0 {
|
||||
#[cfg(spi2)]
|
||||
AnySpiInner::Spi2(_) => crate::dma::DmaPeripheral::Spi2,
|
||||
#[cfg(spi3)]
|
||||
AnySpiInner::Spi3(_) => crate::dma::DmaPeripheral::Spi3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ use crate::{
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
private,
|
||||
spi::AnySpi,
|
||||
system::PeripheralClockControl,
|
||||
};
|
||||
|
||||
@ -86,17 +87,14 @@ const MAX_DMA_SIZE: usize = 32768 - 32;
|
||||
/// SPI peripheral driver.
|
||||
///
|
||||
/// See the [module-level documentation][self] for more details.
|
||||
pub struct Spi<'d, T, M> {
|
||||
pub struct Spi<'d, M, T = AnySpi> {
|
||||
spi: PeripheralRef<'d, T>,
|
||||
#[allow(dead_code)]
|
||||
data_mode: SpiMode,
|
||||
_mode: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
impl<'d> Spi<'d, FullDuplexMode> {
|
||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||
pub fn new<
|
||||
SCK: PeripheralInput,
|
||||
@ -104,42 +102,68 @@ where
|
||||
MISO: PeripheralOutput,
|
||||
CS: PeripheralInput,
|
||||
>(
|
||||
spi: impl Peripheral<P = T> + 'd,
|
||||
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
||||
sclk: impl Peripheral<P = SCK> + 'd,
|
||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||
miso: impl Peripheral<P = MISO> + 'd,
|
||||
cs: impl Peripheral<P = CS> + 'd,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
crate::into_ref!(spi, sclk, mosi, miso, cs);
|
||||
) -> Spi<'d, FullDuplexMode> {
|
||||
Self::new_typed(spi, sclk, mosi, miso, cs, mode)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||
pub fn new_typed<
|
||||
SCK: PeripheralInput,
|
||||
MOSI: PeripheralInput,
|
||||
MISO: PeripheralOutput,
|
||||
CS: PeripheralInput,
|
||||
>(
|
||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||
sclk: impl Peripheral<P = SCK> + 'd,
|
||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||
miso: impl Peripheral<P = MISO> + 'd,
|
||||
cs: impl Peripheral<P = CS> + 'd,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, FullDuplexMode, T> {
|
||||
crate::into_ref!(sclk, mosi, miso, cs);
|
||||
|
||||
let this = Self::new_internal(spi, mode);
|
||||
|
||||
// TODO: with_pins et. al.
|
||||
sclk.enable_input(true, private::Internal);
|
||||
sclk.connect_input_to_peripheral(spi.sclk_signal(), private::Internal);
|
||||
sclk.connect_input_to_peripheral(this.spi.sclk_signal(), private::Internal);
|
||||
|
||||
mosi.enable_input(true, private::Internal);
|
||||
mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal);
|
||||
mosi.connect_input_to_peripheral(this.spi.mosi_signal(), private::Internal);
|
||||
|
||||
miso.set_to_push_pull_output(private::Internal);
|
||||
miso.connect_peripheral_to_output(spi.miso_signal(), private::Internal);
|
||||
miso.connect_peripheral_to_output(this.spi.miso_signal(), private::Internal);
|
||||
|
||||
cs.enable_input(true, private::Internal);
|
||||
cs.connect_input_to_peripheral(spi.cs_signal(), private::Internal);
|
||||
cs.connect_input_to_peripheral(this.spi.cs_signal(), private::Internal);
|
||||
|
||||
Self::new_internal(spi, mode)
|
||||
this
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(
|
||||
spi: PeripheralRef<'d, T>,
|
||||
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
spi.reset_peripheral();
|
||||
spi.enable_peripheral();
|
||||
) -> Spi<'d, FullDuplexMode, T> {
|
||||
crate::into_ref!(spi);
|
||||
|
||||
let mut spi = Spi {
|
||||
spi,
|
||||
spi: spi.map_into(),
|
||||
data_mode: mode,
|
||||
_mode: PhantomData,
|
||||
};
|
||||
spi.spi.reset_peripheral();
|
||||
spi.spi.enable_peripheral();
|
||||
spi.spi.init();
|
||||
spi.spi.set_data_mode(mode, false);
|
||||
|
||||
@ -169,7 +193,7 @@ pub mod dma {
|
||||
Mode,
|
||||
};
|
||||
|
||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
{
|
||||
@ -181,7 +205,7 @@ pub mod dma {
|
||||
channel: Channel<'d, CH, DmaMode>,
|
||||
rx_descriptors: &'static mut [DmaDescriptor],
|
||||
tx_descriptors: &'static mut [DmaDescriptor],
|
||||
) -> SpiDma<'d, T, DmaMode>
|
||||
) -> SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
CH: DmaChannelConvert<T::Dma>,
|
||||
DmaMode: Mode,
|
||||
@ -192,7 +216,7 @@ pub mod dma {
|
||||
}
|
||||
|
||||
/// A DMA capable SPI instance.
|
||||
pub struct SpiDma<'d, T, DmaMode>
|
||||
pub struct SpiDma<'d, DmaMode, T = AnySpi>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -203,7 +227,7 @@ pub mod dma {
|
||||
tx_chain: DescriptorChain,
|
||||
}
|
||||
|
||||
impl<'d, T, DmaMode> core::fmt::Debug for SpiDma<'d, T, DmaMode>
|
||||
impl<'d, DmaMode, T> core::fmt::Debug for SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -213,7 +237,7 @@ pub mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, DmaMode> DmaSupport for SpiDma<'d, T, DmaMode>
|
||||
impl<'d, DmaMode, T> DmaSupport for SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -232,7 +256,7 @@ pub mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, DmaMode> DmaSupportTx for SpiDma<'d, T, DmaMode>
|
||||
impl<'d, DmaMode, T> DmaSupportTx for SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -248,7 +272,7 @@ pub mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, DmaMode> DmaSupportRx for SpiDma<'d, T, DmaMode>
|
||||
impl<'d, DmaMode, T> DmaSupportRx for SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -264,7 +288,7 @@ pub mod dma {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T, DmaMode> SpiDma<'d, T, DmaMode>
|
||||
impl<'d, DmaMode, T> SpiDma<'d, DmaMode, T>
|
||||
where
|
||||
T: InstanceDma,
|
||||
DmaMode: Mode,
|
||||
@ -566,8 +590,6 @@ pub trait Instance: private::Sealed + PeripheralMarker {
|
||||
PeripheralClockControl::enable(self.peripheral());
|
||||
}
|
||||
|
||||
fn spi_num(&self) -> u8;
|
||||
|
||||
#[cfg(esp32)]
|
||||
fn prepare_length_and_lines(&self, rx_len: usize, tx_len: usize) {
|
||||
let reg_block = self.register_block();
|
||||
@ -728,11 +750,6 @@ impl Instance for crate::peripherals::SPI2 {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn spi_num(&self) -> u8 {
|
||||
2
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sclk_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
@ -785,11 +802,6 @@ impl Instance for crate::peripherals::SPI3 {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn spi_num(&self) -> u8 {
|
||||
3
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sclk_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
@ -834,3 +846,21 @@ impl Instance for crate::peripherals::SPI3 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for super::AnySpi {
|
||||
delegate::delegate! {
|
||||
to match &self.0 {
|
||||
super::AnySpiInner::Spi2(spi) => spi,
|
||||
#[cfg(spi3)]
|
||||
super::AnySpiInner::Spi3(spi) => spi,
|
||||
} {
|
||||
fn register_block(&self) -> &RegisterBlock;
|
||||
fn sclk_signal(&self) -> InputSignal;
|
||||
fn mosi_signal(&self) -> InputSignal;
|
||||
fn miso_signal(&self) -> OutputSignal;
|
||||
fn cs_signal(&self) -> InputSignal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceDma for super::AnySpi {}
|
||||
|
@ -12,7 +12,6 @@ use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
interrupt::{software::SoftwareInterruptControl, Priority},
|
||||
peripherals::SPI3,
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Spi, SpiDma},
|
||||
@ -35,7 +34,7 @@ macro_rules! mk_static {
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn interrupt_driven_task(spi: SpiDma<'static, SPI3, FullDuplexMode, Async>) {
|
||||
async fn interrupt_driven_task(spi: SpiDma<'static, FullDuplexMode, Async>) {
|
||||
let mut ticker = Ticker::every(Duration::from_millis(1));
|
||||
|
||||
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(128);
|
||||
|
@ -38,7 +38,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
type SpiUnderTest = SpiDma<'static, esp_hal::peripherals::SPI2, HalfDuplexMode, Blocking>;
|
||||
type SpiUnderTest = SpiDma<'static, HalfDuplexMode, Blocking>;
|
||||
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
|
@ -15,7 +15,6 @@ use esp_hal::{
|
||||
dma::{Dma, DmaDescriptor, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{Io, Level, NoPin},
|
||||
peripherals::SPI2,
|
||||
prelude::*,
|
||||
spi::{master::Spi, FullDuplexMode, SpiMode},
|
||||
};
|
||||
@ -35,7 +34,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
struct Context {
|
||||
spi: Spi<'static, SPI2, FullDuplexMode>,
|
||||
spi: Spi<'static, FullDuplexMode>,
|
||||
dma_channel: DmaChannelCreator,
|
||||
// Reuse the really large buffer so we don't run out of DRAM with many tests
|
||||
rx_buffer: &'static mut [u8],
|
||||
|
@ -9,7 +9,6 @@ use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{Io, Level, Output},
|
||||
peripherals::SPI2,
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||
@ -22,7 +21,7 @@ use esp_hal::{
|
||||
use hil_test as _;
|
||||
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
||||
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||
miso_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@ use esp_hal::{
|
||||
dma_buffers,
|
||||
gpio::{interconnect::InputSignal, Io},
|
||||
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
||||
peripherals::SPI2,
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||
@ -23,7 +22,7 @@ use esp_hal::{
|
||||
use hil_test as _;
|
||||
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
||||
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
pcnt_source: InputSignal,
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ use esp_hal::{
|
||||
dma_descriptors_chunk_size,
|
||||
gpio::{interconnect::InputSignal, Io},
|
||||
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
||||
peripherals::SPI2,
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||
@ -40,7 +39,7 @@ macro_rules! dma_alloc_buffer {
|
||||
}
|
||||
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
||||
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
pcnt_source: InputSignal,
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ use esp_hal::{
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
gpio::{interconnect::InputSignal, Io, Level, Output, PeripheralInput},
|
||||
peripherals::SPI2,
|
||||
spi::{slave::Spi, FullDuplexMode, SpiMode},
|
||||
};
|
||||
use hil_test as _;
|
||||
@ -26,7 +25,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
struct Context {
|
||||
spi: Spi<'static, SPI2, FullDuplexMode>,
|
||||
spi: Spi<'static, FullDuplexMode>,
|
||||
dma_channel: DmaChannelCreator,
|
||||
bitbang_spi: BitbangSpi,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user