mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
Refactor SPI tests & re-enable S3 and some S2 (#1990)
* Deduplicate spi_full_duplex_dma_async * Refactor SPI tests * Separate out PCNT tests * Re-enable test on S3 * Re-enable some S2 tests
This commit is contained in:
parent
d0f98b6c1f
commit
e1697310f6
@ -79,6 +79,10 @@ harness = false
|
|||||||
name = "spi_full_duplex_dma_async"
|
name = "spi_full_duplex_dma_async"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "spi_full_duplex_dma_pcnt"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "spi_half_duplex_read"
|
name = "spi_half_duplex_read"
|
||||||
harness = false
|
harness = false
|
||||||
|
@ -28,8 +28,15 @@ struct Context {
|
|||||||
spi: Spi<'static, esp_hal::peripherals::SPI2, FullDuplexMode>,
|
spi: Spi<'static, esp_hal::peripherals::SPI2, FullDuplexMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
#[cfg(test)]
|
||||||
pub fn init() -> Self {
|
#[embedded_test::tests]
|
||||||
|
mod tests {
|
||||||
|
use defmt::assert_eq;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init() -> Context {
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
@ -49,19 +56,6 @@ impl Context {
|
|||||||
|
|
||||||
Context { spi }
|
Context { spi }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[embedded_test::tests]
|
|
||||||
mod tests {
|
|
||||||
use defmt::assert_eq;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[init]
|
|
||||||
fn init() -> Context {
|
|
||||||
Context::init()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
|
@ -6,349 +6,145 @@
|
|||||||
//! MOSI GPIO3
|
//! MOSI GPIO3
|
||||||
//! CS GPIO8
|
//! CS GPIO8
|
||||||
//!
|
//!
|
||||||
//! Only for test_dma_read_dma_write_pcnt and test_dma_read_dma_transfer_pcnt
|
|
||||||
//! tests:
|
|
||||||
//! PCNT GPIO2
|
|
||||||
//! OUTPUT GPIO5 (helper to keep MISO LOW)
|
|
||||||
//!
|
|
||||||
//! The idea of using PCNT (input) here is to connect MOSI to it and count the
|
|
||||||
//! edges of whatever SPI writes (in this test case 3 pos edges).
|
|
||||||
//!
|
|
||||||
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
|
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::Io,
|
gpio::Io,
|
||||||
peripherals::Peripherals,
|
peripherals::{Peripherals, SPI2},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{master::Spi, SpiMode},
|
spi::{
|
||||||
|
master::{dma::SpiDma, Spi},
|
||||||
|
FullDuplexMode,
|
||||||
|
SpiMode,
|
||||||
|
},
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
|
Blocking,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(
|
||||||
|
feature = "esp32",
|
||||||
|
feature = "esp32s2",
|
||||||
|
))] {
|
||||||
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||||
|
} else {
|
||||||
|
use esp_hal::dma::DmaChannel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[embedded_test::tests]
|
#[embedded_test::tests]
|
||||||
mod tests {
|
mod tests {
|
||||||
use defmt::assert_eq;
|
use defmt::assert_eq;
|
||||||
use esp_hal::{
|
|
||||||
dma::{DmaRxBuf, DmaTxBuf},
|
|
||||||
spi::master::dma::SpiDmaBus,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[init]
|
||||||
#[timeout(3)]
|
fn init() -> Context {
|
||||||
fn test_symmetric_dma_transfer() {
|
|
||||||
const DMA_BUFFER_SIZE: usize = 4;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let sclk = io.pins.gpio0;
|
let sclk = io.pins.gpio0;
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
let mosi = io.pins.gpio3;
|
||||||
|
let miso = io.pins.gpio2;
|
||||||
let cs = io.pins.gpio8;
|
let cs = io.pins.gpio8;
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
|
||||||
let dma_channel = dma.spi2channel;
|
let dma_channel = dma.spi2channel;
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
} else {
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
|
}
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
}
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
|
||||||
|
|
||||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||||
|
|
||||||
|
Context { spi }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
fn test_symmetric_dma_transfer(ctx: Context) {
|
||||||
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4);
|
||||||
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
||||||
|
|
||||||
let transfer = spi
|
let transfer = ctx
|
||||||
|
.spi
|
||||||
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
let (_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
||||||
assert_eq!(dma_tx_buf.as_slice(), dma_rx_buf.as_slice());
|
assert_eq!(dma_tx_buf.as_slice(), dma_rx_buf.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
// S3 is disabled due to https://github.com/esp-rs/esp-hal/issues/1524#issuecomment-2255306292
|
fn test_asymmetric_dma_transfer(ctx: Context) {
|
||||||
#[cfg(not(feature = "esp32s3"))]
|
|
||||||
fn test_asymmetric_dma_transfer() {
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4, 2);
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4, 2);
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
||||||
|
|
||||||
let transfer = spi
|
let transfer = ctx
|
||||||
|
.spi
|
||||||
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
let (_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
||||||
assert_eq!(dma_tx_buf.as_slice()[0..1], dma_rx_buf.as_slice()[0..1]);
|
assert_eq!(dma_tx_buf.as_slice()[0..1], dma_rx_buf.as_slice()[0..1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
fn test_symmetric_dma_transfer_huge_buffer() {
|
fn test_symmetric_dma_transfer_huge_buffer(ctx: Context) {
|
||||||
const DMA_BUFFER_SIZE: usize = 4096;
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4096);
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
for (i, d) in dma_tx_buf.as_mut_slice().iter_mut().enumerate() {
|
for (i, d) in dma_tx_buf.as_mut_slice().iter_mut().enumerate() {
|
||||||
*d = i as _;
|
*d = i as _;
|
||||||
}
|
}
|
||||||
|
|
||||||
let transfer = spi
|
let transfer = ctx
|
||||||
|
.spi
|
||||||
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
let (_, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
||||||
assert_eq!(dma_tx_buf.as_slice(), dma_rx_buf.as_slice());
|
assert_eq!(dma_tx_buf.as_slice(), dma_rx_buf.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
#[cfg(any(
|
fn test_dma_bus_symmetric_transfer(ctx: Context) {
|
||||||
feature = "esp32",
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4);
|
||||||
feature = "esp32c6",
|
|
||||||
feature = "esp32h2",
|
|
||||||
feature = "esp32s3"
|
|
||||||
))]
|
|
||||||
fn test_dma_read_dma_write_pcnt() {
|
|
||||||
use esp_hal::{
|
|
||||||
gpio::{Level, Output, Pull},
|
|
||||||
pcnt::{
|
|
||||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
|
||||||
Pcnt,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const DMA_BUFFER_SIZE: usize = 5;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let mosi_mirror = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let miso = io.pins.gpio6;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let mut out_pin = Output::new(io.pins.gpio5, Level::High);
|
|
||||||
out_pin.set_low();
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
let unit = pcnt.unit0;
|
|
||||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
|
||||||
mosi_mirror,
|
|
||||||
PcntInputConfig { pull: Pull::Down },
|
|
||||||
));
|
|
||||||
unit.channel0
|
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
|
||||||
|
|
||||||
// Fill the buffer where each byte has 3 pos edges.
|
|
||||||
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
|
||||||
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
for i in 1..4 {
|
|
||||||
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
|
||||||
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
|
||||||
(spi, dma_rx_buf) = transfer.wait();
|
|
||||||
assert_eq!(dma_rx_buf.as_slice(), &[0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
let transfer = spi.dma_write(dma_tx_buf).map_err(|e| e.0).unwrap();
|
|
||||||
(spi, dma_tx_buf) = transfer.wait();
|
|
||||||
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[timeout(3)]
|
|
||||||
#[cfg(any(
|
|
||||||
feature = "esp32",
|
|
||||||
feature = "esp32c6",
|
|
||||||
feature = "esp32h2",
|
|
||||||
feature = "esp32s3"
|
|
||||||
))]
|
|
||||||
fn test_dma_read_dma_transfer_pcnt() {
|
|
||||||
use esp_hal::{
|
|
||||||
gpio::{Level, Output, Pull},
|
|
||||||
pcnt::{
|
|
||||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
|
||||||
Pcnt,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const DMA_BUFFER_SIZE: usize = 5;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let mosi_mirror = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let miso = io.pins.gpio6;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let mut out_pin = Output::new(io.pins.gpio5, Level::High);
|
|
||||||
out_pin.set_low();
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
let unit = pcnt.unit0;
|
|
||||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
|
||||||
mosi_mirror,
|
|
||||||
PcntInputConfig { pull: Pull::Down },
|
|
||||||
));
|
|
||||||
unit.channel0
|
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
|
||||||
|
|
||||||
// Fill the buffer where each byte has 3 pos edges.
|
|
||||||
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
|
||||||
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
for i in 1..4 {
|
|
||||||
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
|
||||||
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
|
||||||
(spi, dma_rx_buf) = transfer.wait();
|
|
||||||
assert_eq!(dma_rx_buf.as_slice(), &[0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
let transfer = spi
|
|
||||||
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
|
||||||
.map_err(|e| e.0)
|
|
||||||
.unwrap();
|
|
||||||
(spi, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
|
||||||
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[timeout(3)]
|
|
||||||
fn test_dma_bus_symmetric_transfer() {
|
|
||||||
const DMA_BUFFER_SIZE: usize = 4;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
|
||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
let mut spi = ctx.spi.with_buffers(dma_tx_buf, dma_rx_buf);
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0))
|
|
||||||
.with_buffers(dma_tx_buf, dma_rx_buf);
|
|
||||||
|
|
||||||
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
||||||
let mut rx_buf = [0; 4];
|
let mut rx_buf = [0; 4];
|
||||||
@ -360,32 +156,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
fn test_dma_bus_asymmetric_transfer() {
|
fn test_dma_bus_asymmetric_transfer(ctx: Context) {
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4);
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4);
|
||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
let mut spi = ctx.spi.with_buffers(dma_tx_buf, dma_rx_buf);
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0))
|
|
||||||
.with_buffers(dma_tx_buf, dma_rx_buf);
|
|
||||||
|
|
||||||
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
||||||
let mut rx_buf = [0; 4];
|
let mut rx_buf = [0; 4];
|
||||||
@ -397,34 +173,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
fn test_dma_bus_symmetric_transfer_huge_buffer() {
|
fn test_dma_bus_symmetric_transfer_huge_buffer(ctx: Context) {
|
||||||
const DMA_BUFFER_SIZE: usize = 4096;
|
const DMA_BUFFER_SIZE: usize = 4096;
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let miso = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(40);
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(40);
|
||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
let mut spi = ctx.spi.with_buffers(dma_tx_buf, dma_rx_buf);
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0))
|
|
||||||
.with_buffers(dma_tx_buf, dma_rx_buf);
|
|
||||||
|
|
||||||
let tx_buf = core::array::from_fn(|i| i as _);
|
let tx_buf = core::array::from_fn(|i| i as _);
|
||||||
let mut rx_buf = [0; DMA_BUFFER_SIZE];
|
let mut rx_buf = [0; DMA_BUFFER_SIZE];
|
||||||
|
@ -23,33 +23,53 @@
|
|||||||
use embedded_hal_async::spi::SpiBus;
|
use embedded_hal_async::spi::SpiBus;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Io, Level, Output, Pull},
|
gpio::{GpioPin, Io, Level, Output, Pull},
|
||||||
pcnt::{
|
pcnt::{
|
||||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||||
|
unit::Unit,
|
||||||
Pcnt,
|
Pcnt,
|
||||||
},
|
},
|
||||||
peripherals::Peripherals,
|
peripherals::{Peripherals, SPI2},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{master::Spi, SpiMode},
|
spi::{
|
||||||
|
master::{dma::asynch::SpiDmaAsyncBus, Spi},
|
||||||
|
SpiMode,
|
||||||
|
},
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(
|
||||||
|
feature = "esp32",
|
||||||
|
feature = "esp32s2",
|
||||||
|
))] {
|
||||||
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||||
|
} else {
|
||||||
|
use esp_hal::dma::DmaChannel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DMA_BUFFER_SIZE: usize = 5;
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
spi: SpiDmaAsyncBus<'static, SPI2, DmaChannel0>,
|
||||||
|
pcnt_unit: Unit<'static, 0>,
|
||||||
|
out_pin: Output<'static, GpioPin<5>>,
|
||||||
|
mosi_mirror: GpioPin<2>,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
|
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
|
||||||
mod tests {
|
mod tests {
|
||||||
use defmt::assert_eq;
|
use defmt::assert_eq;
|
||||||
use esp_hal::dma::{DmaRxBuf, DmaTxBuf};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[init]
|
||||||
#[timeout(3)]
|
fn init() -> Context {
|
||||||
async fn test_async_dma_read_dma_write_pcnt() {
|
|
||||||
const DMA_BUFFER_SIZE: usize = 5;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
@ -68,88 +88,40 @@ mod tests {
|
|||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
|
||||||
let dma_channel = dma.spi2channel;
|
let dma_channel = dma.spi2channel;
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
} else {
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
||||||
.with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0))
|
.with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0))
|
||||||
.with_buffers(dma_tx_buf, dma_rx_buf);
|
.with_buffers(dma_tx_buf, dma_rx_buf);
|
||||||
|
|
||||||
let unit = pcnt.unit0;
|
Context {
|
||||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
spi,
|
||||||
|
pcnt_unit: pcnt.unit0,
|
||||||
|
out_pin,
|
||||||
mosi_mirror,
|
mosi_mirror,
|
||||||
PcntInputConfig { pull: Pull::Down },
|
|
||||||
));
|
|
||||||
unit.channel0
|
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
|
||||||
|
|
||||||
let mut receive = [0; DMA_BUFFER_SIZE];
|
|
||||||
|
|
||||||
// Fill the buffer where each byte has 3 pos edges.
|
|
||||||
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
|
||||||
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
for i in 1..4 {
|
|
||||||
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
|
||||||
SpiBus::read(&mut spi, &mut receive).await.unwrap();
|
|
||||||
assert_eq!(receive, [0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
SpiBus::write(&mut spi, &transmit).await.unwrap();
|
|
||||||
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
async fn test_async_dma_read_dma_transfer_pcnt() {
|
async fn test_async_dma_read_dma_write_pcnt(mut ctx: Context) {
|
||||||
const DMA_BUFFER_SIZE: usize = 5;
|
ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||||
|
ctx.mosi_mirror,
|
||||||
let peripherals = Peripherals::take();
|
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
|
||||||
let sclk = io.pins.gpio0;
|
|
||||||
let mosi_mirror = io.pins.gpio2;
|
|
||||||
let mosi = io.pins.gpio3;
|
|
||||||
let miso = io.pins.gpio6;
|
|
||||||
let cs = io.pins.gpio8;
|
|
||||||
|
|
||||||
let mut out_pin = Output::new(io.pins.gpio5, Level::High);
|
|
||||||
out_pin.set_low();
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
|
||||||
let dma_channel = dma.spi2channel;
|
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
|
||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
|
||||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
|
||||||
|
|
||||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
|
||||||
.with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0))
|
|
||||||
.with_buffers(dma_tx_buf, dma_rx_buf);
|
|
||||||
|
|
||||||
let unit = pcnt.unit0;
|
|
||||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
|
||||||
mosi_mirror,
|
|
||||||
PcntInputConfig { pull: Pull::Down },
|
PcntInputConfig { pull: Pull::Down },
|
||||||
));
|
));
|
||||||
unit.channel0
|
ctx.pcnt_unit
|
||||||
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
let mut receive = [0; DMA_BUFFER_SIZE];
|
let mut receive = [0; DMA_BUFFER_SIZE];
|
||||||
@ -157,17 +129,45 @@ mod tests {
|
|||||||
// Fill the buffer where each byte has 3 pos edges.
|
// Fill the buffer where each byte has 3 pos edges.
|
||||||
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
||||||
|
|
||||||
assert_eq!(out_pin.is_set_low(), true);
|
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||||
|
|
||||||
for i in 1..4 {
|
for i in 1..4 {
|
||||||
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||||
SpiBus::read(&mut spi, &mut receive).await.unwrap();
|
SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap();
|
||||||
assert_eq!(receive, [0, 0, 0, 0, 0]);
|
assert_eq!(receive, [0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
SpiBus::transfer(&mut spi, &mut receive, &transmit)
|
SpiBus::write(&mut ctx.spi, &transmit).await.unwrap();
|
||||||
|
assert_eq!(ctx.pcnt_unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
async fn test_async_dma_read_dma_transfer_pcnt(mut ctx: Context) {
|
||||||
|
ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||||
|
ctx.mosi_mirror,
|
||||||
|
PcntInputConfig { pull: Pull::Down },
|
||||||
|
));
|
||||||
|
ctx.pcnt_unit
|
||||||
|
.channel0
|
||||||
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
|
let mut receive = [0; DMA_BUFFER_SIZE];
|
||||||
|
|
||||||
|
// Fill the buffer where each byte has 3 pos edges.
|
||||||
|
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
||||||
|
|
||||||
|
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||||
|
|
||||||
|
for i in 1..4 {
|
||||||
|
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||||
|
SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap();
|
||||||
|
assert_eq!(receive, [0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
|
SpiBus::transfer(&mut ctx.spi, &mut receive, &transmit)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
assert_eq!(ctx.pcnt_unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
180
hil-test/tests/spi_full_duplex_dma_pcnt.rs
Normal file
180
hil-test/tests/spi_full_duplex_dma_pcnt.rs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
//! SPI Full Duplex DMA ASYNC Test with PCNT readback.
|
||||||
|
//!
|
||||||
|
//! Folowing pins are used:
|
||||||
|
//! SCLK GPIO0
|
||||||
|
//! MOSI GPIO3
|
||||||
|
//! CS GPIO8
|
||||||
|
//! PCNT GPIO2
|
||||||
|
//! OUTPUT GPIO5 (helper to keep MISO LOW)
|
||||||
|
//!
|
||||||
|
//! The idea of using PCNT (input) here is to connect MOSI to it and count the
|
||||||
|
//! edges of whatever SPI writes (in this test case 3 pos edges).
|
||||||
|
//!
|
||||||
|
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
|
||||||
|
|
||||||
|
//% CHIPS: esp32 esp32c6 esp32h2 esp32s3
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use esp_hal::{
|
||||||
|
clock::ClockControl,
|
||||||
|
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||||
|
dma_buffers,
|
||||||
|
gpio::{GpioPin, Io, Level, Output, Pull},
|
||||||
|
pcnt::{
|
||||||
|
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||||
|
unit::Unit,
|
||||||
|
Pcnt,
|
||||||
|
},
|
||||||
|
peripherals::{Peripherals, SPI2},
|
||||||
|
prelude::*,
|
||||||
|
spi::{
|
||||||
|
master::{dma::SpiDma, Spi},
|
||||||
|
FullDuplexMode,
|
||||||
|
SpiMode,
|
||||||
|
},
|
||||||
|
system::SystemControl,
|
||||||
|
Blocking,
|
||||||
|
};
|
||||||
|
use hil_test as _;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(
|
||||||
|
feature = "esp32",
|
||||||
|
feature = "esp32s2",
|
||||||
|
))] {
|
||||||
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||||
|
} else {
|
||||||
|
use esp_hal::dma::DmaChannel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>,
|
||||||
|
pcnt_unit: Unit<'static, 0>,
|
||||||
|
out_pin: Output<'static, GpioPin<5>>,
|
||||||
|
mosi_mirror: GpioPin<2>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[embedded_test::tests]
|
||||||
|
mod tests {
|
||||||
|
use defmt::assert_eq;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init() -> Context {
|
||||||
|
let peripherals = Peripherals::take();
|
||||||
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
let sclk = io.pins.gpio0;
|
||||||
|
let mosi = io.pins.gpio3;
|
||||||
|
let miso = io.pins.gpio6;
|
||||||
|
let cs = io.pins.gpio8;
|
||||||
|
|
||||||
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
|
||||||
|
let dma_channel = dma.spi2channel;
|
||||||
|
} else {
|
||||||
|
let dma_channel = dma.channel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||||
|
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
||||||
|
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||||
|
|
||||||
|
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||||
|
|
||||||
|
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
|
||||||
|
out_pin.set_low();
|
||||||
|
assert_eq!(out_pin.is_set_low(), true);
|
||||||
|
let mosi_mirror = io.pins.gpio2;
|
||||||
|
|
||||||
|
Context {
|
||||||
|
spi,
|
||||||
|
pcnt_unit: pcnt.unit0,
|
||||||
|
out_pin,
|
||||||
|
mosi_mirror,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
fn test_dma_read_dma_write_pcnt(ctx: Context) {
|
||||||
|
const DMA_BUFFER_SIZE: usize = 5;
|
||||||
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
|
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
|
let unit = ctx.pcnt_unit;
|
||||||
|
let mut spi = ctx.spi;
|
||||||
|
|
||||||
|
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||||
|
ctx.mosi_mirror,
|
||||||
|
PcntInputConfig { pull: Pull::Down },
|
||||||
|
));
|
||||||
|
unit.channel0
|
||||||
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
|
// Fill the buffer where each byte has 3 pos edges.
|
||||||
|
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
||||||
|
|
||||||
|
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||||
|
|
||||||
|
for i in 1..4 {
|
||||||
|
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||||
|
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
||||||
|
(spi, dma_rx_buf) = transfer.wait();
|
||||||
|
assert_eq!(dma_rx_buf.as_slice(), &[0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
|
let transfer = spi.dma_write(dma_tx_buf).map_err(|e| e.0).unwrap();
|
||||||
|
(spi, dma_tx_buf) = transfer.wait();
|
||||||
|
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
fn test_dma_read_dma_transfer_pcnt(ctx: Context) {
|
||||||
|
const DMA_BUFFER_SIZE: usize = 5;
|
||||||
|
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
|
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
|
|
||||||
|
let unit = ctx.pcnt_unit;
|
||||||
|
let mut spi = ctx.spi;
|
||||||
|
|
||||||
|
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||||
|
ctx.mosi_mirror,
|
||||||
|
PcntInputConfig { pull: Pull::Down },
|
||||||
|
));
|
||||||
|
unit.channel0
|
||||||
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
|
// Fill the buffer where each byte has 3 pos edges.
|
||||||
|
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
||||||
|
|
||||||
|
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||||
|
|
||||||
|
for i in 1..4 {
|
||||||
|
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||||
|
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
||||||
|
(spi, dma_rx_buf) = transfer.wait();
|
||||||
|
assert_eq!(dma_rx_buf.as_slice(), &[0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
|
let transfer = spi
|
||||||
|
.dma_transfer(dma_tx_buf, dma_rx_buf)
|
||||||
|
.map_err(|e| e.0)
|
||||||
|
.unwrap();
|
||||||
|
(spi, (dma_tx_buf, dma_rx_buf)) = transfer.wait();
|
||||||
|
assert_eq!(unit.get_value(), (i * 3 * DMA_BUFFER_SIZE) as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,39 +8,54 @@
|
|||||||
//!
|
//!
|
||||||
//! Connect MISO (GPIO2) and GPIO (GPIO3) pins.
|
//! Connect MISO (GPIO2) and GPIO (GPIO3) pins.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use hil_test as _;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[embedded_test::tests]
|
|
||||||
mod tests {
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf},
|
dma::{Dma, DmaPriority, DmaRxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Io, Level, Output},
|
gpio::{GpioPin, Io, Level, Output},
|
||||||
peripherals::Peripherals,
|
peripherals::{Peripherals, SPI2},
|
||||||
prelude::_fugit_RateExtU32,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Address, Command, Spi},
|
master::{dma::SpiDma, Address, Command, Spi},
|
||||||
|
HalfDuplexMode,
|
||||||
SpiDataMode,
|
SpiDataMode,
|
||||||
SpiMode,
|
SpiMode,
|
||||||
},
|
},
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
|
Blocking,
|
||||||
};
|
};
|
||||||
|
use hil_test as _;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(
|
||||||
|
feature = "esp32",
|
||||||
|
feature = "esp32s2",
|
||||||
|
))] {
|
||||||
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||||
|
} else {
|
||||||
|
use esp_hal::dma::DmaChannel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||||
|
miso_mirror: Output<'static, GpioPin<3>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[embedded_test::tests]
|
||||||
|
mod tests {
|
||||||
|
use defmt::assert_eq;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init() {}
|
fn init() -> Context {
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[timeout(3)]
|
|
||||||
fn test_spi_reads_correctly_from_gpio_pin() {
|
|
||||||
const DMA_BUFFER_SIZE: usize = 4;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
@ -49,25 +64,38 @@ mod tests {
|
|||||||
let sclk = io.pins.gpio0;
|
let sclk = io.pins.gpio0;
|
||||||
let miso = io.pins.gpio2;
|
let miso = io.pins.gpio2;
|
||||||
|
|
||||||
let mut miso_mirror = Output::new(io.pins.gpio3, Level::High);
|
let miso_mirror = Output::new(io.pins.gpio3, Level::High);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
|
||||||
let dma_channel = dma.spi2channel;
|
let dma_channel = dma.spi2channel;
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
} else {
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (buffer, descriptors, _, _) = dma_buffers!(DMA_BUFFER_SIZE, 0);
|
let spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(descriptors, buffer).unwrap();
|
|
||||||
|
|
||||||
let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_miso(miso)
|
.with_miso(miso)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||||
|
|
||||||
|
Context { spi, miso_mirror }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
fn test_spi_reads_correctly_from_gpio_pin(mut ctx: Context) {
|
||||||
|
const DMA_BUFFER_SIZE: usize = 4;
|
||||||
|
|
||||||
|
let (buffer, descriptors, _, _) = dma_buffers!(DMA_BUFFER_SIZE, 0);
|
||||||
|
let mut dma_rx_buf = DmaRxBuf::new(descriptors, buffer).unwrap();
|
||||||
|
|
||||||
// SPI should read '0's from the MISO pin
|
// SPI should read '0's from the MISO pin
|
||||||
miso_mirror.set_low();
|
ctx.miso_mirror.set_low();
|
||||||
|
|
||||||
|
let mut spi = ctx.spi;
|
||||||
|
|
||||||
let transfer = spi
|
let transfer = spi
|
||||||
.read(
|
.read(
|
||||||
@ -84,7 +112,7 @@ mod tests {
|
|||||||
assert_eq!(dma_rx_buf.as_slice(), &[0x00; DMA_BUFFER_SIZE]);
|
assert_eq!(dma_rx_buf.as_slice(), &[0x00; DMA_BUFFER_SIZE]);
|
||||||
|
|
||||||
// SPI should read '1's from the MISO pin
|
// SPI should read '1's from the MISO pin
|
||||||
miso_mirror.set_high();
|
ctx.miso_mirror.set_high();
|
||||||
|
|
||||||
let transfer = spi
|
let transfer = spi
|
||||||
.read(
|
.read(
|
||||||
|
@ -8,71 +8,105 @@
|
|||||||
//!
|
//!
|
||||||
//! Connect MOSI (GPIO2) and PCNT (GPIO3) pins.
|
//! Connect MOSI (GPIO2) and PCNT (GPIO3) pins.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c6 esp32h2 esp32s3
|
//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use hil_test as _;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[embedded_test::tests]
|
|
||||||
mod tests {
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaPriority, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Io, Pull},
|
gpio::{GpioPin, Io, Pull},
|
||||||
pcnt::{
|
pcnt::{
|
||||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||||
|
unit::Unit,
|
||||||
Pcnt,
|
Pcnt,
|
||||||
},
|
},
|
||||||
peripherals::Peripherals,
|
peripherals::{Peripherals, SPI2},
|
||||||
prelude::_fugit_RateExtU32,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
master::{Address, Command, Spi},
|
master::{dma::SpiDma, Address, Command, Spi},
|
||||||
|
HalfDuplexMode,
|
||||||
SpiDataMode,
|
SpiDataMode,
|
||||||
SpiMode,
|
SpiMode,
|
||||||
},
|
},
|
||||||
system::SystemControl,
|
system::SystemControl,
|
||||||
|
Blocking,
|
||||||
};
|
};
|
||||||
|
use hil_test as _;
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(
|
||||||
|
feature = "esp32",
|
||||||
|
feature = "esp32s2",
|
||||||
|
))] {
|
||||||
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||||
|
} else {
|
||||||
|
use esp_hal::dma::DmaChannel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||||
|
pcnt_unit: Unit<'static, 0>,
|
||||||
|
mosi_mirror: GpioPin<3>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[embedded_test::tests]
|
||||||
|
mod tests {
|
||||||
|
use defmt::assert_eq;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init() {}
|
fn init() -> Context {
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[timeout(3)]
|
|
||||||
fn test_spi_writes_are_correctly_by_pcnt() {
|
|
||||||
const DMA_BUFFER_SIZE: usize = 4;
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let system = SystemControl::new(peripherals.SYSTEM);
|
let system = SystemControl::new(peripherals.SYSTEM);
|
||||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
|
||||||
|
|
||||||
let sclk = io.pins.gpio0;
|
let sclk = io.pins.gpio0;
|
||||||
let mosi = io.pins.gpio2;
|
let mosi = io.pins.gpio2;
|
||||||
let mosi_mirror = io.pins.gpio3;
|
let mosi_mirror = io.pins.gpio3;
|
||||||
|
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2"))]
|
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||||
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
|
||||||
let dma_channel = dma.spi2channel;
|
let dma_channel = dma.spi2channel;
|
||||||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
|
} else {
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (buffer, descriptors, _, _) = dma_buffers!(DMA_BUFFER_SIZE, 0);
|
let spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(descriptors, buffer).unwrap();
|
|
||||||
|
|
||||||
let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||||
|
|
||||||
let unit = pcnt.unit0;
|
Context {
|
||||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
spi,
|
||||||
mosi_mirror,
|
mosi_mirror,
|
||||||
|
pcnt_unit: pcnt.unit0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[timeout(3)]
|
||||||
|
fn test_spi_writes_are_correctly_by_pcnt(ctx: Context) {
|
||||||
|
const DMA_BUFFER_SIZE: usize = 4;
|
||||||
|
|
||||||
|
let (buffer, descriptors, _, _) = dma_buffers!(DMA_BUFFER_SIZE, 0);
|
||||||
|
let mut dma_tx_buf = DmaTxBuf::new(descriptors, buffer).unwrap();
|
||||||
|
|
||||||
|
let unit = ctx.pcnt_unit;
|
||||||
|
let mut spi = ctx.spi;
|
||||||
|
|
||||||
|
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||||
|
ctx.mosi_mirror,
|
||||||
PcntInputConfig { pull: Pull::Down },
|
PcntInputConfig { pull: Pull::Down },
|
||||||
));
|
));
|
||||||
unit.channel0
|
unit.channel0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user