From 31a135c0f14e0896be6db3ed439ce2294c2ade69 Mon Sep 17 00:00:00 2001 From: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:19:16 +0100 Subject: [PATCH] Add SPI Half Duplex Write HIL test (#1801) Co-authored-by: Dominic Fischer --- hil-test/Cargo.toml | 4 + hil-test/tests/spi_half_duplex_write.rs | 114 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 hil-test/tests/spi_half_duplex_write.rs diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index 04bffe96114..2e1a042be80 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -64,6 +64,10 @@ harness = false name = "spi_half_duplex_read" harness = false +[[test]] +name = "spi_half_duplex_write" +harness = false + [[test]] name = "pcnt" harness = false diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs new file mode 100644 index 00000000000..421cf9ac865 --- /dev/null +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -0,0 +1,114 @@ +//! SPI Half Duplex Write Test +//! +//! Following pins are used: +//! SCLK GPIO0 +//! MOSI GPIO2 +//! +//! PCNT GPIO3 +//! +//! Connect MOSI (GPIO2) and PCNT (GPIO3) pins. + +//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3 + +#![no_std] +#![no_main] + +use defmt_rtt as _; +use esp_backtrace as _; + +#[cfg(test)] +#[embedded_test::tests] +mod tests { + use esp_hal::{ + clock::ClockControl, + dma::{Dma, DmaPriority}, + dma_buffers, + gpio::{Io, Pull}, + pcnt::{ + channel::{EdgeMode, PcntInputConfig, PcntSource}, + Pcnt, + }, + peripherals::Peripherals, + prelude::_fugit_RateExtU32, + spi::{ + master::{prelude::*, Address, Command, Spi}, + SpiDataMode, + SpiMode, + }, + system::SystemControl, + }; + + #[init] + fn init() {} + + #[test] + #[timeout(3)] + fn test_spi_writes_are_correctly_by_pcnt() { + 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 pcnt = Pcnt::new(peripherals.PCNT, None); + let dma = Dma::new(peripherals.DMA); + + let sclk = io.pins.gpio0; + let mosi = io.pins.gpio2; + let mosi_mirror = io.pins.gpio3; + + #[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_descriptors) = dma_buffers!(DMA_BUFFER_SIZE, 0); + + let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks) + .with_sck(sclk) + .with_mosi(mosi) + .with_dma( + dma_channel.configure(false, DmaPriority::Priority0), + tx_descriptors, + rx_descriptors, + ); + + 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 3 pos edges. + tx_buffer.fill(0b0110_1010); + + let transfer = spi + .write( + SpiDataMode::Single, + Command::None, + Address::None, + 0, + &tx_buffer, + ) + .unwrap(); + transfer.wait().unwrap(); + + assert_eq!(unit.get_value(), (3 * DMA_BUFFER_SIZE) as _); + + let transfer = spi + .write( + SpiDataMode::Single, + Command::None, + Address::None, + 0, + &tx_buffer, + ) + .unwrap(); + transfer.wait().unwrap(); + + assert_eq!(unit.get_value(), (6 * DMA_BUFFER_SIZE) as _); + } +}