Skip to main content
AraceliGuerrero
Associate II
September 29, 2026
Question

STM32H755 SPI3 + DMA: first transaction works, subsequent transaction fails

  • September 29, 2026
  • 4 replies
  • 65 views

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.

4 replies

ST Technical Moderator
October 1, 2026

Hello ​@AraceliGuerrero 

Are you using SPI for the handshake? 

At the end of the first transaction please check whether HAL returned to HAL_SPI_STATE_READY or if an error flag is set in the handle. 

In addition to the handshake add a small delay before calling HAL_SPI_TransmitReceive_DMA() on master side. This gives the time to slave to be prepared before the master start the transaction 

Mybe you can try to use breakpoint instead of handshake for debug. 

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Saket_Om
TDK
October 1, 2026

The slave DMA reception is prepared before the master starts the transaction.

I would recheck this assumption as this would fully explain the symptoms. How do you know it’s ready?

There are working DMA SPI master/slave examples you can pull from.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate II
October 2, 2026

Suggest you check what you are doing with TSIZE in SPI control register 2 (SPI_CR2).  If TSIZE is greater than 1 (TSIZE = 0) a transaction will run for TSIZE and then stall. 

“Bit 12 TXC: TxFIFO transmission complete
The flag behavior depends on TSIZE setting.
When TSIZE = 0, the TXC is changed by hardware exclusively and it raises each time the
TxFIFO becomes empty and there is no activity on the bus.
If TSIZE ≠ 0 there is no specific reason to monitor TXC as it just copies the EOT flag value
including its software clearing. The TXC generates an interrupt when EOTIE is set.
This flag is set when SPI is reset or disabled.
0: current data transfer is still ongoing, data is available in TxFIFO or last frame transmission
is on going.
1: last TxFIFO frame transmission complete”

DMA depends upon TXP: Tx-packet space available and maybe TXC ?  

There is a lot to be said for setting TSIZE = 0 that way transaction never stalls.  Hope that helps.

Associate II
October 2, 2026

Suggest you also have a look at this related thread that was just solved this morning:-

 

      SPI Only sending 2 bytes and then TXTF flag goes high