STM32H755 SPI3 + DMA: first transaction works, subsequent transaction fails
Hello,
I am debugging SPI3 communication between two STM32H755 boards:
-
UC1 = SPI master
-
UC2 = SPI slave
-
SPI3, full-duplex
-
DMA used for TX/RX
-
FreeRTOS
-
STM32H755
The problem is that the first SPI transaction can be completed correctly, but the following transaction does not behave as expected.
Before starting the SPI data exchange, I also perform a handshake/synchronization sequence between the two boards to ensure that both sides are ready. The handshake itself is implemented before the SPI test, but adding this synchronization does not resolve the issue.
The intended sequence is:
UC1 (Master) UC2 (Slave)
SYNC ----------------> receive SYNC
<---------------- OK
PING ----------------> receive PING
<---------------- PONG
PING ----------------> receive PING
<---------------- PONG
In the actual test, the first exchange can be received correctly, but the slave does not continue responding correctly on the next transaction. UC1 consequently remains waiting for the expected response.
I am using DMA for the SPI transfers and re-arming the slave reception for each transaction.
I have already checked/implemented the following:
-
SPI buffers are located in a dedicated linker section:
.spi_buffer -
Buffers are 32-byte aligned.
-
DMA buffers are located in RAM accessible by the selected DMA.
-
I'm working on the M4, so I don't need cache instructions.
-
DMA/SPI transfer state is explicitly handled between transactions.
-
CS is controlled externally by GPIO. For SPI3, CS is:
GPIOG PIN 10 -
The slave DMA reception is prepared before the master starts the transaction.
-
SPI configuration (CPOL/CPHA, data size, bit order, etc.) is matched between both boards.
-
I am checking the received buffer and adding debug information around the DMA callbacks.
I am currently using the STM32 HAL SPI DMA API and the transfer is essentially handled as:
CS_LOW();
HAL_SPI_TransmitReceive_DMA(&hspi3,
txBuffer,
rxBuffer,
TRANSFER_SIZE);
/* wait for completion */
CS_HIGH();
The slave is re-armed for the next transaction after processing the received data.
What I would like to verify
Is there any STM32H7-specific requirement that I may be missing when repeatedly using SPI + DMA, particularly on the slave side?
The fact that the first transaction works but the next one fails makes me suspect that some SPI, DMA or FIFO state is not being properly cleared/re-armed.
What registers or flags would you recommend checking immediately after the first successful transaction and before starting the second one?
Thanks.
