From 14a36737b5a767170ff955c7ff32443be0d90652 Mon Sep 17 00:00:00 2001 From: molqzone Date: Wed, 9 Sep 2026 16:25:56 +0800 Subject: [PATCH 1/2] fix(spi): arm the SPI slave peripheral after its DMA channels start --- esp-hal/src/spi/slave.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 34e065a42cc..67cfde29193 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -172,6 +172,9 @@ pub mod dma { spi::Error, }; + #[cfg(not(spi_slave_dma_engine = "SPI_DMA"))] + use crate::RegisterToggle; + const MAX_DMA_SIZE: usize = 32768 - 32; impl<'d> Spi<'d, Blocking> { @@ -490,8 +493,6 @@ pub mod dma { self.info .prepare_length_and_lines(read_buffer_len, write_buffer_len); - self.reset_dma_before_usr_cmd(); - #[cfg(not(esp32))] self.regs() .dma_conf() @@ -499,26 +500,36 @@ pub mod dma { self.clear_dma_interrupts(); self.info.setup_for_flush(); - self.regs().cmd().modify(|_, w| w.usr().set_bit()); if read_buffer_len > 0 { + self.reset_dma_rx_fifo(); channel.rx.start_transfer()?; } if write_buffer_len > 0 { + self.reset_dma_tx_fifo(); channel.tx.start_transfer()?; } + // The SPI master owns SCLK and CS. Arm the peripheral only after + // both GDMA directions can service the first edge. + self.regs().cmd().modify(|_, w| w.usr().set_bit()); + Ok(()) } - fn reset_dma_before_usr_cmd(&self) { + fn reset_dma_rx_fifo(&self) { #[cfg(not(spi_slave_dma_engine = "SPI_DMA"))] - self.regs().dma_conf().modify(|_, w| { - w.rx_afifo_rst().set_bit(); - w.buf_afifo_rst().set_bit(); - w.dma_afifo_rst().set_bit() - }); + self.regs() + .dma_conf() + .toggle(|w, bit| w.rx_afifo_rst().bit(bit)); + } + + fn reset_dma_tx_fifo(&self) { + #[cfg(not(spi_slave_dma_engine = "SPI_DMA"))] + self.regs() + .dma_conf() + .toggle(|w, bit| w.dma_afifo_rst().bit(bit)); } fn enable_dma(&self) { From 4b9536fe3fa29da52e9fbfaad9f28548a47a502c Mon Sep 17 00:00:00 2001 From: molqzone Date: Wed, 16 Sep 2026 09:57:19 +0800 Subject: [PATCH 2/2] style: format SPI slave imports --- esp-hal/src/spi/slave.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 67cfde29193..2c64e4b11a1 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -165,6 +165,8 @@ pub mod dma { use enumset::enum_set; use super::*; + #[cfg(not(spi_slave_dma_engine = "SPI_DMA"))] + use crate::RegisterToggle; use crate::{ DriverMode, dma::{Channel, DmaRxBuffer, DmaRxInterrupt, DmaTxBuffer, EmptyBuf}, @@ -172,9 +174,6 @@ pub mod dma { spi::Error, }; - #[cfg(not(spi_slave_dma_engine = "SPI_DMA"))] - use crate::RegisterToggle; - const MAX_DMA_SIZE: usize = 32768 - 32; impl<'d> Spi<'d, Blocking> {