mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +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)
|
- 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)
|
- Add burst transfer support to DMA buffers (#2336)
|
||||||
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
|
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
|
||||||
|
- Added `AnySpi` and `AnySpiDmaChannel`. (#2334)
|
||||||
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
|
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Peripheral type erasure for SPI (#2334)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Removed
|
### 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>] {}
|
impl $crate::private::Sealed for [<Spi $num DmaChannel>] {}
|
||||||
|
|
||||||
#[doc = concat!("Creates a channel for SPI", $num)]
|
#[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 {
|
impl RegBlock for I2S0 {
|
||||||
fn register_block(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
unsafe { &*I2S0::PTR.cast::<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)]
|
#[cfg(i2s1)]
|
||||||
impl RegBlock for I2S1 {
|
impl RegBlock for I2S1 {
|
||||||
fn register_block(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
|
@ -136,13 +136,7 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
use crate::{dma::PeripheralMarker, peripherals::LCD_CAM};
|
use crate::peripherals::LCD_CAM;
|
||||||
|
|
||||||
impl PeripheralMarker for LCD_CAM {
|
|
||||||
fn peripheral(&self) -> crate::system::Peripheral {
|
|
||||||
crate::system::Peripheral::LcdCam
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct Instance;
|
pub(crate) struct Instance;
|
||||||
|
|
||||||
|
@ -142,7 +142,6 @@ mod fmt;
|
|||||||
|
|
||||||
#[cfg(riscv)]
|
#[cfg(riscv)]
|
||||||
pub use esp_riscv_rt::{self, entry, riscv};
|
pub use esp_riscv_rt::{self, entry, riscv};
|
||||||
pub use procmacros as macros;
|
|
||||||
#[cfg(xtensa)]
|
#[cfg(xtensa)]
|
||||||
pub use xtensa_lx;
|
pub use xtensa_lx;
|
||||||
#[cfg(xtensa)]
|
#[cfg(xtensa)]
|
||||||
@ -241,6 +240,8 @@ pub mod debugger;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
|
||||||
|
pub mod macros;
|
||||||
|
|
||||||
/// State of the CPU saved when entering exception or interrupt
|
/// State of the CPU saved when entering exception or interrupt
|
||||||
pub mod trapframe {
|
pub mod trapframe {
|
||||||
#[cfg(riscv)]
|
#[cfg(riscv)]
|
||||||
@ -449,26 +450,6 @@ unsafe extern "C" fn stack_chk_fail() {
|
|||||||
panic!("Stack corruption detected");
|
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::{
|
use crate::{
|
||||||
clock::{Clocks, CpuClock},
|
clock::{Clocks, CpuClock},
|
||||||
config::{WatchdogConfig, WatchdogStatus},
|
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 {
|
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)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! peripherals {
|
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`]
|
/// Contains the generated peripherals which implement [`Peripheral`]
|
||||||
mod peripherals {
|
mod peripherals {
|
||||||
pub use super::pac::*;
|
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)]
|
#[allow(non_snake_case)]
|
||||||
pub struct Peripherals {
|
pub struct Peripherals {
|
||||||
$(
|
$(
|
||||||
$(#[$cfg])?
|
|
||||||
/// Each field represents a hardware peripheral.
|
/// Each field represents a hardware peripheral.
|
||||||
pub $name: peripherals::$name,
|
pub $name: peripherals::$name,
|
||||||
)*
|
)*
|
||||||
@ -245,9 +262,7 @@ mod peripheral_macros {
|
|||||||
Self::steal()
|
Self::steal()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Peripherals {
|
|
||||||
/// Unsafely create an instance of this peripheral out of thin air.
|
/// Unsafely create an instance of this peripheral out of thin air.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -257,7 +272,6 @@ mod peripheral_macros {
|
|||||||
pub unsafe fn steal() -> Self {
|
pub unsafe fn steal() -> Self {
|
||||||
Self {
|
Self {
|
||||||
$(
|
$(
|
||||||
$(#[$cfg])?
|
|
||||||
$name: peripherals::$name::steal(),
|
$name: peripherals::$name::steal(),
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
@ -313,8 +327,7 @@ mod peripheral_macros {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
/// Macro to create a peripheral structure.
|
/// Macro to create a peripheral structure.
|
||||||
macro_rules! create_peripheral {
|
macro_rules! create_peripheral {
|
||||||
($(#[$cfg:meta])? $name:ident <= virtual) => {
|
($([$enum_variant:ident])? $name:ident <= virtual) => {
|
||||||
$(#[$cfg])?
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
/// Represents a virtual peripheral with no associated hardware.
|
/// Represents a virtual peripheral with no associated hardware.
|
||||||
@ -323,7 +336,6 @@ mod peripheral_macros {
|
|||||||
/// is defined as virtual.
|
/// is defined as virtual.
|
||||||
pub struct $name { _inner: () }
|
pub struct $name { _inner: () }
|
||||||
|
|
||||||
$(#[$cfg])?
|
|
||||||
impl $name {
|
impl $name {
|
||||||
/// Unsafely create an instance of this peripheral out of thin air.
|
/// Unsafely create an instance of this peripheral out of thin air.
|
||||||
///
|
///
|
||||||
@ -346,29 +358,21 @@ mod peripheral_macros {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::private::Sealed for $name {}
|
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 {
|
impl $crate::dma::PeripheralMarker for $crate::peripherals::$name {
|
||||||
/// Unsafely create an instance of this peripheral out of thin air.
|
#[inline(always)]
|
||||||
///
|
fn peripheral(&self) -> $crate::system::Peripheral {
|
||||||
/// # Safety
|
$crate::system::Peripheral::$enum_variant
|
||||||
///
|
}
|
||||||
/// You must ensure that you're only using one instance of this type at a time.
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn steal() -> Self {
|
|
||||||
Self { _inner: () }
|
|
||||||
}
|
}
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
($([$enum_variant:ident])? $name:ident <= $base:ident) => {
|
||||||
|
$crate::create_peripheral!($([$enum_variant])? $name <= virtual);
|
||||||
|
|
||||||
|
impl $name {
|
||||||
#[doc = r"Pointer to the register block"]
|
#[doc = r"Pointer to the register block"]
|
||||||
pub const PTR: *const <super::pac::$base as core::ops::Deref>::Target = super::pac::$base::PTR;
|
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 {
|
impl core::ops::DerefMut for $name {
|
||||||
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *(Self::PTR as *mut _) }
|
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,
|
HINF <= HINF,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2C1 <= I2C1,
|
I2C1 <= I2C1,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
I2S1 <= I2S1 (I2S1),
|
[I2s1] I2S1 <= I2S1 (I2S1),
|
||||||
IO_MUX <= IO_MUX,
|
IO_MUX <= IO_MUX,
|
||||||
LEDC <= LEDC,
|
LEDC <= LEDC,
|
||||||
MCPWM0 <= MCPWM0,
|
MCPWM0 <= MCPWM0,
|
||||||
@ -60,8 +60,8 @@ crate::peripherals! {
|
|||||||
SLCHOST <= SLCHOST,
|
SLCHOST <= SLCHOST,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||||
SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
[Spi3] SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||||
SYSTEM <= DPORT,
|
SYSTEM <= DPORT,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
TIMG0 <= TIMG0,
|
TIMG0 <= TIMG0,
|
||||||
|
@ -40,7 +40,7 @@ crate::peripherals! {
|
|||||||
SHA <= SHA,
|
SHA <= SHA,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||||
SYSTEM <= SYSTEM,
|
SYSTEM <= SYSTEM,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
|
@ -34,7 +34,7 @@ crate::peripherals! {
|
|||||||
GPIO_SD <= GPIO_SD,
|
GPIO_SD <= GPIO_SD,
|
||||||
HMAC <= HMAC,
|
HMAC <= HMAC,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||||
IO_MUX <= IO_MUX,
|
IO_MUX <= IO_MUX,
|
||||||
LEDC <= LEDC,
|
LEDC <= LEDC,
|
||||||
@ -47,7 +47,7 @@ crate::peripherals! {
|
|||||||
SHA <= SHA,
|
SHA <= SHA,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||||
SYSTEM <= SYSTEM,
|
SYSTEM <= SYSTEM,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
|
@ -37,7 +37,7 @@ crate::peripherals! {
|
|||||||
HP_APM <= HP_APM,
|
HP_APM <= HP_APM,
|
||||||
HP_SYS <= HP_SYS,
|
HP_SYS <= HP_SYS,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
IEEE802154 <= IEEE802154,
|
IEEE802154 <= IEEE802154,
|
||||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||||
INTPRI <= INTPRI,
|
INTPRI <= INTPRI,
|
||||||
@ -73,7 +73,7 @@ crate::peripherals! {
|
|||||||
SOC_ETM <= SOC_ETM,
|
SOC_ETM <= SOC_ETM,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||||
SYSTEM <= PCR,
|
SYSTEM <= PCR,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
|
@ -35,7 +35,7 @@ crate::peripherals! {
|
|||||||
HP_SYS <= HP_SYS,
|
HP_SYS <= HP_SYS,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2C1 <= I2C1,
|
I2C1 <= I2C1,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
IEEE802154 <= IEEE802154,
|
IEEE802154 <= IEEE802154,
|
||||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||||
INTPRI <= INTPRI,
|
INTPRI <= INTPRI,
|
||||||
@ -65,7 +65,7 @@ crate::peripherals! {
|
|||||||
SOC_ETM <= SOC_ETM,
|
SOC_ETM <= SOC_ETM,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||||
SYSTEM <= PCR,
|
SYSTEM <= PCR,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
|
@ -35,7 +35,7 @@ crate::peripherals! {
|
|||||||
HMAC <= HMAC,
|
HMAC <= HMAC,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2C1 <= I2C1,
|
I2C1 <= I2C1,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||||
IO_MUX <= IO_MUX,
|
IO_MUX <= IO_MUX,
|
||||||
LEDC <= LEDC,
|
LEDC <= LEDC,
|
||||||
@ -52,9 +52,8 @@ crate::peripherals! {
|
|||||||
SHA <= SHA,
|
SHA <= SHA,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2_DMA, SPI2),
|
||||||
SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
[Spi3] SPI3 <= SPI3 (SPI3_DMA, SPI3),
|
||||||
SPI4 <= SPI4,
|
|
||||||
SYSCON <= SYSCON,
|
SYSCON <= SYSCON,
|
||||||
SYSTEM <= SYSTEM,
|
SYSTEM <= SYSTEM,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
|
@ -36,12 +36,12 @@ crate::peripherals! {
|
|||||||
HMAC <= HMAC,
|
HMAC <= HMAC,
|
||||||
I2C0 <= I2C0,
|
I2C0 <= I2C0,
|
||||||
I2C1 <= I2C1,
|
I2C1 <= I2C1,
|
||||||
I2S0 <= I2S0 (I2S0),
|
[I2s0] I2S0 <= I2S0 (I2S0),
|
||||||
I2S1 <= I2S1 (I2S1),
|
[I2s1] I2S1 <= I2S1 (I2S1),
|
||||||
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
|
||||||
INTERRUPT_CORE1 <= INTERRUPT_CORE1,
|
INTERRUPT_CORE1 <= INTERRUPT_CORE1,
|
||||||
IO_MUX <= IO_MUX,
|
IO_MUX <= IO_MUX,
|
||||||
LCD_CAM <= LCD_CAM,
|
[LcdCam] LCD_CAM <= LCD_CAM,
|
||||||
LEDC <= LEDC,
|
LEDC <= LEDC,
|
||||||
LPWR <= RTC_CNTL,
|
LPWR <= RTC_CNTL,
|
||||||
PCNT <= PCNT,
|
PCNT <= PCNT,
|
||||||
@ -59,8 +59,8 @@ crate::peripherals! {
|
|||||||
SHA <= SHA,
|
SHA <= SHA,
|
||||||
SPI0 <= SPI0,
|
SPI0 <= SPI0,
|
||||||
SPI1 <= SPI1,
|
SPI1 <= SPI1,
|
||||||
SPI2 <= SPI2 (SPI2),
|
[Spi2] SPI2 <= SPI2 (SPI2),
|
||||||
SPI3 <= SPI3 (SPI3),
|
[Spi3] SPI3 <= SPI3 (SPI3),
|
||||||
SYSTEM <= SYSTEM,
|
SYSTEM <= SYSTEM,
|
||||||
SYSTIMER <= SYSTIMER,
|
SYSTIMER <= SYSTIMER,
|
||||||
SW_INTERRUPT <= virtual,
|
SW_INTERRUPT <= virtual,
|
||||||
|
@ -87,6 +87,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
private,
|
private,
|
||||||
|
spi::AnySpi,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralClockControl,
|
||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
@ -452,15 +453,35 @@ pub trait HalfDuplexReadWrite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// SPI peripheral driver
|
/// SPI peripheral driver
|
||||||
pub struct Spi<'d, T, M> {
|
pub struct Spi<'d, M, T = AnySpi> {
|
||||||
spi: PeripheralRef<'d, T>,
|
spi: PeripheralRef<'d, T>,
|
||||||
_mode: PhantomData<M>,
|
_mode: PhantomData<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, M> Spi<'d, T, M>
|
impl<'d, M, T> Spi<'d, M, T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
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.
|
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||||
///
|
///
|
||||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
/// 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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: DuplexMode,
|
M: DuplexMode,
|
||||||
@ -499,7 +520,7 @@ where
|
|||||||
pub fn with_dma<CH, DmaMode>(
|
pub fn with_dma<CH, DmaMode>(
|
||||||
self,
|
self,
|
||||||
channel: crate::dma::Channel<'d, CH, DmaMode>,
|
channel: crate::dma::Channel<'d, CH, DmaMode>,
|
||||||
) -> SpiDma<'d, T, M, DmaMode>
|
) -> SpiDma<'d, M, DmaMode, T>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<T::Dma>,
|
CH: DmaChannelConvert<T::Dma>,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -508,7 +529,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
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
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
@ -552,13 +587,15 @@ where
|
|||||||
///
|
///
|
||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new(
|
pub fn new_typed(
|
||||||
spi: impl Peripheral<P = T> + 'd,
|
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, T, FullDuplexMode> {
|
) -> Spi<'d, FullDuplexMode, T> {
|
||||||
crate::into_ref!(spi);
|
let spi = Spi::<FullDuplexMode, T>::new_internal(spi, frequency, mode);
|
||||||
Self::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.
|
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
|
||||||
@ -614,26 +651,6 @@ where
|
|||||||
.with_cs(cs)
|
.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.
|
/// Change the bus frequency of the SPI instance.
|
||||||
///
|
///
|
||||||
/// This method allows user to update the bus frequency for the SPI
|
/// 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
|
where
|
||||||
T: ExtendedInstance,
|
T: ExtendedInstance,
|
||||||
{
|
{
|
||||||
@ -651,13 +682,15 @@ where
|
|||||||
///
|
///
|
||||||
/// All pins are optional. Setup these pins using
|
/// All pins are optional. Setup these pins using
|
||||||
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
/// [with_pins](Self::with_pins) or individual methods for each pin.
|
||||||
pub fn new_half_duplex(
|
pub fn new_half_duplex_typed(
|
||||||
spi: impl Peripheral<P = T> + 'd,
|
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, T, HalfDuplexMode> {
|
) -> Spi<'d, HalfDuplexMode, T> {
|
||||||
crate::into_ref!(spi);
|
let spi = Spi::<HalfDuplexMode, T>::new_internal(spi, frequency, mode);
|
||||||
Self::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
|
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance in
|
||||||
@ -761,27 +794,6 @@ where
|
|||||||
.with_sio3(sio3)
|
.with_sio3(sio3)
|
||||||
.with_cs(cs)
|
.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.
|
/// Change the bus frequency of the SPI instance in half-duplex mode.
|
||||||
///
|
///
|
||||||
/// This method allows you to update the bus frequency for the SPI
|
/// 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
|
where
|
||||||
T: Instance,
|
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
|
where
|
||||||
T: Instance,
|
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
|
where
|
||||||
T: Instance,
|
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
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
@ -959,7 +971,7 @@ mod dma {
|
|||||||
/// [`SpiDmaBus`] via `with_buffers` to get access
|
/// [`SpiDmaBus`] via `with_buffers` to get access
|
||||||
/// to a DMA capable SPI bus that implements the
|
/// to a DMA capable SPI bus that implements the
|
||||||
/// embedded-hal traits.
|
/// embedded-hal traits.
|
||||||
pub struct SpiDma<'d, T, D, M>
|
pub struct SpiDma<'d, D, M, T = AnySpi>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
@ -975,7 +987,7 @@ mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(esp32, spi_address_workaround))]
|
#[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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
@ -1246,7 +1258,7 @@ mod dma {
|
|||||||
self,
|
self,
|
||||||
dma_rx_buf: DmaRxBuf,
|
dma_rx_buf: DmaRxBuf,
|
||||||
dma_tx_buf: DmaTxBuf,
|
dma_tx_buf: DmaTxBuf,
|
||||||
) -> SpiDmaBus<'d, T, D, M> {
|
) -> SpiDmaBus<'d, D, M, T> {
|
||||||
SpiDmaBus::new(self, dma_rx_buf, dma_tx_buf)
|
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
|
/// This structure holds references to the SPI instance, DMA buffers, and
|
||||||
/// transfer status.
|
/// transfer status.
|
||||||
pub struct SpiDmaTransfer<'d, T, D, M, Buf>
|
pub struct SpiDmaTransfer<'d, D, M, Buf, T = AnySpi>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
spi_dma: ManuallyDrop<SpiDma<'d, T, D, M>>,
|
spi_dma: ManuallyDrop<SpiDma<'d, D, M, T>>,
|
||||||
dma_buf: ManuallyDrop<Buf>,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
M: Mode,
|
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 {
|
Self {
|
||||||
spi_dma: ManuallyDrop::new(spi_dma),
|
spi_dma: ManuallyDrop::new(spi_dma),
|
||||||
dma_buf: ManuallyDrop::new(dma_buf),
|
dma_buf: ManuallyDrop::new(dma_buf),
|
||||||
@ -1290,7 +1302,7 @@ mod dma {
|
|||||||
///
|
///
|
||||||
/// This method blocks until the transfer is finished and returns the
|
/// This method blocks until the transfer is finished and returns the
|
||||||
/// `SpiDma` instance and the associated buffer.
|
/// `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();
|
self.spi_dma.wait_for_idle();
|
||||||
let retval = unsafe {
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
@ -1377,7 +1389,7 @@ mod dma {
|
|||||||
pub fn dma_write<TX: DmaTxBuffer>(
|
pub fn dma_write<TX: DmaTxBuffer>(
|
||||||
mut self,
|
mut self,
|
||||||
mut buffer: TX,
|
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();
|
self.wait_for_idle();
|
||||||
|
|
||||||
match unsafe { self.start_dma_write(&mut buffer) } {
|
match unsafe { self.start_dma_write(&mut buffer) } {
|
||||||
@ -1416,7 +1428,7 @@ mod dma {
|
|||||||
pub fn dma_read<RX: DmaRxBuffer>(
|
pub fn dma_read<RX: DmaRxBuffer>(
|
||||||
mut self,
|
mut self,
|
||||||
mut buffer: RX,
|
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();
|
self.wait_for_idle();
|
||||||
match unsafe { self.start_dma_read(&mut buffer) } {
|
match unsafe { self.start_dma_read(&mut buffer) } {
|
||||||
Ok(_) => Ok(SpiDmaTransfer::new(self, buffer)),
|
Ok(_) => Ok(SpiDmaTransfer::new(self, buffer)),
|
||||||
@ -1455,7 +1467,7 @@ mod dma {
|
|||||||
mut self,
|
mut self,
|
||||||
mut rx_buffer: RX,
|
mut rx_buffer: RX,
|
||||||
mut tx_buffer: TX,
|
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();
|
self.wait_for_idle();
|
||||||
match unsafe { self.start_dma_transfer(&mut rx_buffer, &mut tx_buffer) } {
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
@ -1517,7 +1529,7 @@ mod dma {
|
|||||||
address: Address,
|
address: Address,
|
||||||
dummy: u8,
|
dummy: u8,
|
||||||
mut buffer: RX,
|
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();
|
self.wait_for_idle();
|
||||||
|
|
||||||
match unsafe {
|
match unsafe {
|
||||||
@ -1584,7 +1596,7 @@ mod dma {
|
|||||||
address: Address,
|
address: Address,
|
||||||
dummy: u8,
|
dummy: u8,
|
||||||
mut buffer: TX,
|
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();
|
self.wait_for_idle();
|
||||||
|
|
||||||
match unsafe {
|
match unsafe {
|
||||||
@ -1600,18 +1612,18 @@ mod dma {
|
|||||||
///
|
///
|
||||||
/// This structure is responsible for managing SPI transfers using DMA
|
/// This structure is responsible for managing SPI transfers using DMA
|
||||||
/// buffers.
|
/// buffers.
|
||||||
pub struct SpiDmaBus<'d, T, D, M>
|
pub struct SpiDmaBus<'d, D, M, T = AnySpi>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
spi_dma: SpiDma<'d, T, D, M>,
|
spi_dma: SpiDma<'d, D, M, T>,
|
||||||
rx_buf: DmaRxBuf,
|
rx_buf: DmaRxBuf,
|
||||||
tx_buf: DmaTxBuf,
|
tx_buf: DmaTxBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T, D, M> SpiDmaBus<'d, T, D, M>
|
impl<'d, D, M, T> SpiDmaBus<'d, D, M, T>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
D: DuplexMode,
|
||||||
@ -1619,7 +1631,7 @@ mod dma {
|
|||||||
{
|
{
|
||||||
/// Creates a new `SpiDmaBus` with the specified SPI instance and DMA
|
/// Creates a new `SpiDmaBus` with the specified SPI instance and DMA
|
||||||
/// buffers.
|
/// 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 {
|
Self {
|
||||||
spi_dma,
|
spi_dma,
|
||||||
rx_buf,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
D: DuplexMode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
@ -1860,7 +1872,7 @@ mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> embedded_hal_02::blocking::spi::Transfer<u8>
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
{
|
{
|
||||||
@ -1873,7 +1885,7 @@ mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> embedded_hal_02::blocking::spi::Write<u8>
|
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
|
where
|
||||||
T: InstanceDma,
|
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
|
where
|
||||||
T: InstanceDma,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
{
|
{
|
||||||
@ -2078,7 +2090,7 @@ mod dma {
|
|||||||
|
|
||||||
use super::*;
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
@ -2086,7 +2098,7 @@ mod dma {
|
|||||||
type Error = Error;
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
@ -2121,11 +2133,11 @@ mod ehal1 {
|
|||||||
|
|
||||||
use super::*;
|
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;
|
type Error = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> FullDuplex for Spi<'_, T, FullDuplexMode>
|
impl<T> FullDuplex for Spi<'_, FullDuplexMode, T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
@ -2138,7 +2150,7 @@ mod ehal1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SpiBus for Spi<'_, T, FullDuplexMode>
|
impl<T> SpiBus for Spi<'_, FullDuplexMode, T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
@ -2680,24 +2692,21 @@ pub trait Instance: private::Sealed + PeripheralMarker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ch_bus_freq(&mut self, frequency: HertzU32) {
|
fn ch_bus_freq(&mut self, frequency: HertzU32) {
|
||||||
// Disable clock source
|
fn enable_clocks(_reg_block: &RegisterBlock, _enable: bool) {
|
||||||
#[cfg(gdma)]
|
#[cfg(gdma)]
|
||||||
self.register_block().clk_gate().modify(|_, w| {
|
_reg_block.clk_gate().modify(|_, w| {
|
||||||
w.clk_en().clear_bit();
|
w.clk_en().bit(_enable);
|
||||||
w.mst_clk_active().clear_bit();
|
w.mst_clk_active().bit(_enable);
|
||||||
w.mst_clk_sel().clear_bit()
|
w.mst_clk_sel().bit(_enable)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_clocks(self.register_block(), false);
|
||||||
|
|
||||||
// Change clock frequency
|
// Change clock frequency
|
||||||
self.setup(frequency);
|
self.setup(frequency);
|
||||||
|
|
||||||
// Enable clock source
|
enable_clocks(self.register_block(), true);
|
||||||
#[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()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(esp32, esp32c3, esp32s2)))]
|
#[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
|
//! more information on these modes, please refer to the documentation in their
|
||||||
//! respective modules.
|
//! respective modules.
|
||||||
|
|
||||||
use crate::dma::{DmaError, PeripheralMarker};
|
use crate::dma::{DmaEligible, DmaError};
|
||||||
|
|
||||||
pub mod master;
|
pub mod master;
|
||||||
pub mod slave;
|
pub mod slave;
|
||||||
@ -101,18 +101,28 @@ pub struct HalfDuplexMode {}
|
|||||||
impl DuplexMode for HalfDuplexMode {}
|
impl DuplexMode for HalfDuplexMode {}
|
||||||
impl crate::private::Sealed for HalfDuplexMode {}
|
impl crate::private::Sealed for HalfDuplexMode {}
|
||||||
|
|
||||||
#[cfg(spi2)]
|
crate::any_peripheral! {
|
||||||
impl PeripheralMarker for crate::peripherals::SPI2 {
|
/// Any SPI peripheral.
|
||||||
#[inline(always)]
|
pub peripheral AnySpi {
|
||||||
fn peripheral(&self) -> crate::system::Peripheral {
|
#[cfg(spi2)]
|
||||||
crate::system::Peripheral::Spi2
|
Spi2(crate::peripherals::SPI2),
|
||||||
|
#[cfg(spi3)]
|
||||||
|
Spi3(crate::peripherals::SPI3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(spi3)]
|
impl DmaEligible for AnySpi {
|
||||||
impl PeripheralMarker for crate::peripherals::SPI3 {
|
#[cfg(gdma)]
|
||||||
#[inline(always)]
|
type Dma = crate::dma::AnyGdmaChannel;
|
||||||
fn peripheral(&self) -> crate::system::Peripheral {
|
#[cfg(pdma)]
|
||||||
crate::system::Peripheral::Spi3
|
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},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
private,
|
private,
|
||||||
|
spi::AnySpi,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralClockControl,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,17 +87,14 @@ const MAX_DMA_SIZE: usize = 32768 - 32;
|
|||||||
/// SPI peripheral driver.
|
/// SPI peripheral driver.
|
||||||
///
|
///
|
||||||
/// See the [module-level documentation][self] for more details.
|
/// 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>,
|
spi: PeripheralRef<'d, T>,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
data_mode: SpiMode,
|
data_mode: SpiMode,
|
||||||
_mode: PhantomData<M>,
|
_mode: PhantomData<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
impl<'d> Spi<'d, FullDuplexMode> {
|
||||||
where
|
|
||||||
T: Instance,
|
|
||||||
{
|
|
||||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||||
pub fn new<
|
pub fn new<
|
||||||
SCK: PeripheralInput,
|
SCK: PeripheralInput,
|
||||||
@ -104,42 +102,68 @@ where
|
|||||||
MISO: PeripheralOutput,
|
MISO: PeripheralOutput,
|
||||||
CS: PeripheralInput,
|
CS: PeripheralInput,
|
||||||
>(
|
>(
|
||||||
spi: impl Peripheral<P = T> + 'd,
|
spi: impl Peripheral<P = impl Into<AnySpi> + 'd> + 'd,
|
||||||
sclk: impl Peripheral<P = SCK> + 'd,
|
sclk: impl Peripheral<P = SCK> + 'd,
|
||||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||||
miso: impl Peripheral<P = MISO> + 'd,
|
miso: impl Peripheral<P = MISO> + 'd,
|
||||||
cs: impl Peripheral<P = CS> + 'd,
|
cs: impl Peripheral<P = CS> + 'd,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, T, FullDuplexMode> {
|
) -> Spi<'d, FullDuplexMode> {
|
||||||
crate::into_ref!(spi, sclk, mosi, miso, cs);
|
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.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.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.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.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(
|
pub(crate) fn new_internal(
|
||||||
spi: PeripheralRef<'d, T>,
|
spi: impl Peripheral<P = impl Into<T> + 'd> + 'd,
|
||||||
mode: SpiMode,
|
mode: SpiMode,
|
||||||
) -> Spi<'d, T, FullDuplexMode> {
|
) -> Spi<'d, FullDuplexMode, T> {
|
||||||
spi.reset_peripheral();
|
crate::into_ref!(spi);
|
||||||
spi.enable_peripheral();
|
|
||||||
|
|
||||||
let mut spi = Spi {
|
let mut spi = Spi {
|
||||||
spi,
|
spi: spi.map_into(),
|
||||||
data_mode: mode,
|
data_mode: mode,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
};
|
};
|
||||||
|
spi.spi.reset_peripheral();
|
||||||
|
spi.spi.enable_peripheral();
|
||||||
spi.spi.init();
|
spi.spi.init();
|
||||||
spi.spi.set_data_mode(mode, false);
|
spi.spi.set_data_mode(mode, false);
|
||||||
|
|
||||||
@ -169,7 +193,7 @@ pub mod dma {
|
|||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
impl<'d, T> Spi<'d, FullDuplexMode, T>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
{
|
{
|
||||||
@ -181,7 +205,7 @@ pub mod dma {
|
|||||||
channel: Channel<'d, CH, DmaMode>,
|
channel: Channel<'d, CH, DmaMode>,
|
||||||
rx_descriptors: &'static mut [DmaDescriptor],
|
rx_descriptors: &'static mut [DmaDescriptor],
|
||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> SpiDma<'d, T, DmaMode>
|
) -> SpiDma<'d, DmaMode, T>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<T::Dma>,
|
CH: DmaChannelConvert<T::Dma>,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -192,7 +216,7 @@ pub mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A DMA capable SPI instance.
|
/// A DMA capable SPI instance.
|
||||||
pub struct SpiDma<'d, T, DmaMode>
|
pub struct SpiDma<'d, DmaMode, T = AnySpi>
|
||||||
where
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -203,7 +227,7 @@ pub mod dma {
|
|||||||
tx_chain: DescriptorChain,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
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
|
where
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
@ -566,8 +590,6 @@ pub trait Instance: private::Sealed + PeripheralMarker {
|
|||||||
PeripheralClockControl::enable(self.peripheral());
|
PeripheralClockControl::enable(self.peripheral());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spi_num(&self) -> u8;
|
|
||||||
|
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
fn prepare_length_and_lines(&self, rx_len: usize, tx_len: usize) {
|
fn prepare_length_and_lines(&self, rx_len: usize, tx_len: usize) {
|
||||||
let reg_block = self.register_block();
|
let reg_block = self.register_block();
|
||||||
@ -728,11 +750,6 @@ impl Instance for crate::peripherals::SPI2 {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn spi_num(&self) -> u8 {
|
|
||||||
2
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn sclk_signal(&self) -> InputSignal {
|
fn sclk_signal(&self) -> InputSignal {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
@ -785,11 +802,6 @@ impl Instance for crate::peripherals::SPI3 {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn spi_num(&self) -> u8 {
|
|
||||||
3
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn sclk_signal(&self) -> InputSignal {
|
fn sclk_signal(&self) -> InputSignal {
|
||||||
cfg_if::cfg_if! {
|
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::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
interrupt::{software::SoftwareInterruptControl, Priority},
|
interrupt::{software::SoftwareInterruptControl, Priority},
|
||||||
peripherals::SPI3,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Spi, SpiDma},
|
master::{Spi, SpiDma},
|
||||||
@ -35,7 +34,7 @@ macro_rules! mk_static {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[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 mut ticker = Ticker::every(Duration::from_millis(1));
|
||||||
|
|
||||||
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(128);
|
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 {
|
struct Context {
|
||||||
spi: esp_hal::peripherals::SPI2,
|
spi: esp_hal::peripherals::SPI2,
|
||||||
|
@ -15,7 +15,6 @@ use esp_hal::{
|
|||||||
dma::{Dma, DmaDescriptor, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaDescriptor, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Io, Level, NoPin},
|
gpio::{Io, Level, NoPin},
|
||||||
peripherals::SPI2,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{master::Spi, FullDuplexMode, SpiMode},
|
spi::{master::Spi, FullDuplexMode, SpiMode},
|
||||||
};
|
};
|
||||||
@ -35,7 +34,7 @@ cfg_if::cfg_if! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: Spi<'static, SPI2, FullDuplexMode>,
|
spi: Spi<'static, FullDuplexMode>,
|
||||||
dma_channel: DmaChannelCreator,
|
dma_channel: DmaChannelCreator,
|
||||||
// Reuse the really large buffer so we don't run out of DRAM with many tests
|
// Reuse the really large buffer so we don't run out of DRAM with many tests
|
||||||
rx_buffer: &'static mut [u8],
|
rx_buffer: &'static mut [u8],
|
||||||
|
@ -9,7 +9,6 @@ use esp_hal::{
|
|||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Io, Level, Output},
|
gpio::{Io, Level, Output},
|
||||||
peripherals::SPI2,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||||
@ -22,7 +21,7 @@ use esp_hal::{
|
|||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||||
miso_mirror: Output<'static>,
|
miso_mirror: Output<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ use esp_hal::{
|
|||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{interconnect::InputSignal, Io},
|
gpio::{interconnect::InputSignal, Io},
|
||||||
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
||||||
peripherals::SPI2,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||||
@ -23,7 +22,7 @@ use esp_hal::{
|
|||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||||
pcnt_unit: Unit<'static, 0>,
|
pcnt_unit: Unit<'static, 0>,
|
||||||
pcnt_source: InputSignal,
|
pcnt_source: InputSignal,
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use esp_hal::{
|
|||||||
dma_descriptors_chunk_size,
|
dma_descriptors_chunk_size,
|
||||||
gpio::{interconnect::InputSignal, Io},
|
gpio::{interconnect::InputSignal, Io},
|
||||||
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
||||||
peripherals::SPI2,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
master::{Address, Command, HalfDuplexReadWrite, Spi, SpiDma},
|
||||||
@ -40,7 +39,7 @@ macro_rules! dma_alloc_buffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: SpiDma<'static, SPI2, HalfDuplexMode, Blocking>,
|
spi: SpiDma<'static, HalfDuplexMode, Blocking>,
|
||||||
pcnt_unit: Unit<'static, 0>,
|
pcnt_unit: Unit<'static, 0>,
|
||||||
pcnt_source: InputSignal,
|
pcnt_source: InputSignal,
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use esp_hal::{
|
|||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{interconnect::InputSignal, Io, Level, Output, PeripheralInput},
|
gpio::{interconnect::InputSignal, Io, Level, Output, PeripheralInput},
|
||||||
peripherals::SPI2,
|
|
||||||
spi::{slave::Spi, FullDuplexMode, SpiMode},
|
spi::{slave::Spi, FullDuplexMode, SpiMode},
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
@ -26,7 +25,7 @@ cfg_if::cfg_if! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: Spi<'static, SPI2, FullDuplexMode>,
|
spi: Spi<'static, FullDuplexMode>,
|
||||||
dma_channel: DmaChannelCreator,
|
dma_channel: DmaChannelCreator,
|
||||||
bitbang_spi: BitbangSpi,
|
bitbang_spi: BitbangSpi,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user