Skip to main content
Associate III
June 4, 2025
Solved

SPI communication using DMA on the STM32H743.

  • June 4, 2025
  • 3 replies
  • 624 views

SPI communication using DMA on the STM32H743.

We have created a program for SPI communication using DMA, The first send/receive with HAL_SPI_TransmitReceive_DMA is successful.
However, when the exact same process is executed afterwards, all received values are 0.
The second send/receive with HAL_SPI_TransmitReceive_DMA is not successful.

Does anyone know why this is happening?

 

This topic has been closed for replies.
Best answer by TDK

What are you talking to?

Can you verify on a logic analyzer that the data coming in is non-zero?

Are you managing cache appropriately or is it turned off?

What specifically makes you think all received values are zero?

How are you observing them?

Does HAL_SPI_TransmitReceive_DMA return HAL_OK and does the transfer complete callback get called?

3 replies

Associate III
June 4, 2025

We are not sure if this is relevant, but I will post the SPI handle Structure values.

 

first dma_spi
hspi1	SPI_HandleTypeDef	{...}	
	Instance	SPI_TypeDef *	0x40013000	
		CR1	volatile uint32_t	0x1001	
		CR2	volatile uint32_t	0x0	
		CFG1	volatile uint32_t	0x70007	
		CFG2	volatile uint32_t	0x47400000	
		IER	volatile uint32_t	0x0	
		SR	volatile uint32_t	0x1002	
		IFCR	volatile uint32_t	0x0	
		RESERVED0	uint32_t	0x0	
		TXDR	volatile uint32_t	0x0	
		RESERVED1	uint32_t [3]	0x40013024	
			RESERVED1[0]	uint32_t	0x0	
			RESERVED1[1]	uint32_t	0x0	
			RESERVED1[2]	uint32_t	0x0	
		RXDR	volatile uint32_t	0x0	
		RESERVED2	uint32_t [3]	0x40013034	
			RESERVED2[0]	uint32_t	0x0	
			RESERVED2[1]	uint32_t	0x0	
			RESERVED2[2]	uint32_t	0x0	
		CRCPOLY	volatile uint32_t	0x107	
		TXCRC	volatile uint32_t	0x0	
		RXCRC	volatile uint32_t	0x0	
		UDRDR	volatile uint32_t	0x0	
		I2SCFGR	volatile uint32_t	0x0	
	Init	SPI_InitTypeDef	{...}	
		Mode	uint32_t	0x400000	
		Direction	uint32_t	0x0	
		DataSize	uint32_t	0x7	
		CLKPolarity	uint32_t	0x2000000	
		CLKPhase	uint32_t	0x1000000	
		NSS	uint32_t	0x4000000	
		BaudRatePrescaler	uint32_t	0x0	
		FirstBit	uint32_t	0x0	
		TIMode	uint32_t	0x0	
		CRCCalculation	uint32_t	0x0	
		CRCPolynomial	uint32_t	0x0	
		CRCLength	uint32_t	0x0	
		NSSPMode	uint32_t	0x40000000	
		NSSPolarity	uint32_t	0x0	
		FifoThreshold	uint32_t	0x0	
		TxCRCInitializationPattern	uint32_t	0x0	
		RxCRCInitializationPattern	uint32_t	0x0	
		MasterSSIdleness	uint32_t	0x0	
		MasterInterDataIdleness	uint32_t	0x0	
		MasterReceiverAutoSusp	uint32_t	0x0	
		MasterKeepIOState	uint32_t	0x0	
		IOSwap	uint32_t	0x0	
	pTxBuffPtr	const uint8_t *	0x0	
		*pTxBuffPtr	const uint8_t	0x40	
	TxXferSize	uint16_t	0x0	
	TxXferCount	volatile uint16_t	0x0	
	pRxBuffPtr	uint8_t *	0x0	
		*pRxBuffPtr	uint8_t	0x40	
	RxXferSize	uint16_t	0x0	
	RxXferCount	volatile uint16_t	0x0	
	CRCSize	uint32_t	0x0	
	RxISR	void (*)(struct __SPI_HandleTypeDef *)	0x0	
	TxISR	void (*)(struct __SPI_HandleTypeDef *)	0x0	
	hdmatx	DMA_HandleTypeDef *	0x240714a8	
		Instance	void *	0x40020058	
		Init	DMA_InitTypeDef	{...}	
			Request	uint32_t	0x26	
			Direction	uint32_t	0x40	
			PeriphInc	uint32_t	0x0	
			MemInc	uint32_t	0x400	
			PeriphDataAlignment	uint32_t	0x0	
			MemDataAlignment	uint32_t	0x0	
			Mode	uint32_t	0x0	
			Priority	uint32_t	0x10000	
			FIFOMode	uint32_t	0x0	
			FIFOThreshold	uint32_t	0x0	
			MemBurst	uint32_t	0x0	
			PeriphBurst	uint32_t	0x0	
		Lock	HAL_LockTypeDef	0x0	
		State	volatile HAL_DMA_StateTypeDef	0x1	
		Parent	void *	0x24071100	
		XferCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferHalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1CpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1HalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferErrorCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferAbortCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		ErrorCode	volatile uint32_t	0x0	
		StreamBaseAddress	uint32_t	0x40020000	
		StreamIndex	uint32_t	0x16	
		DMAmuxChannel	DMAMUX_Channel_TypeDef *	0x4002080c	
			CCR	volatile uint32_t	0x26	
		DMAmuxChannelStatus	DMAMUX_ChannelStatus_TypeDef *	0x40020880	
			CSR	volatile uint32_t	0x0	
			CFR	volatile uint32_t	0x0	
		DMAmuxChannelStatusMask	uint32_t	0x8	
		DMAmuxRequestGen	DMAMUX_RequestGen_TypeDef *	0x0	
			RGCR	volatile uint32_t	0x47868640	
		DMAmuxRequestGenStatus	DMAMUX_RequestGenStatus_TypeDef *	0x0	
			RGSR	volatile uint32_t	0x47868640	
			RGCFR	volatile uint32_t	0x25d3796f	
		DMAmuxRequestGenStatusMask	uint32_t	0x0	
	hdmarx	DMA_HandleTypeDef *	0x24071430	
		Instance	void *	0x40020040	
		Init	DMA_InitTypeDef	{...}	
			Request	uint32_t	0x25	
			Direction	uint32_t	0x0	
			PeriphInc	uint32_t	0x0	
			MemInc	uint32_t	0x400	
			PeriphDataAlignment	uint32_t	0x0	
			MemDataAlignment	uint32_t	0x0	
			Mode	uint32_t	0x0	
			Priority	uint32_t	0x10000	
			FIFOMode	uint32_t	0x0	
			FIFOThreshold	uint32_t	0x0	
			MemBurst	uint32_t	0x0	
			PeriphBurst	uint32_t	0x0	
		Lock	HAL_LockTypeDef	0x0	
		State	volatile HAL_DMA_StateTypeDef	0x1	
		Parent	void *	0x24071100	
		XferCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferHalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1CpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1HalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferErrorCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferAbortCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		ErrorCode	volatile uint32_t	0x0	
		StreamBaseAddress	uint32_t	0x40020000	
		StreamIndex	uint32_t	0x10	
		DMAmuxChannel	DMAMUX_Channel_TypeDef *	0x40020808	
			CCR	volatile uint32_t	0x25	
		DMAmuxChannelStatus	DMAMUX_ChannelStatus_TypeDef *	0x40020880	
			CSR	volatile uint32_t	0x0	
			CFR	volatile uint32_t	0x0	
		DMAmuxChannelStatusMask	uint32_t	0x4	
		DMAmuxRequestGen	DMAMUX_RequestGen_TypeDef *	0x0	
			RGCR	volatile uint32_t	0x47868640	
		DMAmuxRequestGenStatus	DMAMUX_RequestGenStatus_TypeDef *	0x0	
			RGSR	volatile uint32_t	0x47868640	
			RGCFR	volatile uint32_t	0x25d3796f	
		DMAmuxRequestGenStatusMask	uint32_t	0x0	
	Lock	HAL_LockTypeDef	0x0	
	State	volatile HAL_SPI_StateTypeDef	0x1	
	ErrorCode	volatile uint32_t	0x0	
txdata[0]	uint8_t	0x80	
txdata[1]	uint8_t	0x0	
txdata[2]	uint8_t	0x0	
txdata[3]	uint8_t	0x0	
txdata[4]	uint8_t	0x0	
txdata[5]	uint8_t	0x0	
second dma_spi
hspi1	SPI_HandleTypeDef	{...}	
	Instance	SPI_TypeDef *	0x40013000	
		CR1	volatile uint32_t	0x1000	
		CR2	volatile uint32_t	0x5	
		CFG1	volatile uint32_t	0x70007	
		CFG2	volatile uint32_t	0x47400000	
		IER	volatile uint32_t	0x0	
		SR	volatile uint32_t	0xe007	
		IFCR	volatile uint32_t	0x0	
		RESERVED0	uint32_t	0x0	
		TXDR	volatile uint32_t	0x0	
		RESERVED1	uint32_t [3]	0x40013024	
			RESERVED1[0]	uint32_t	0x0	
			RESERVED1[1]	uint32_t	0x0	
			RESERVED1[2]	uint32_t	0x0	
		RXDR	volatile uint32_t	0x0	
		RESERVED2	uint32_t [3]	0x40013034	
			RESERVED2[0]	uint32_t	0x0	
			RESERVED2[1]	uint32_t	0x0	
			RESERVED2[2]	uint32_t	0x0	
		CRCPOLY	volatile uint32_t	0x107	
		TXCRC	volatile uint32_t	0x0	
		RXCRC	volatile uint32_t	0x0	
		UDRDR	volatile uint32_t	0x0	
		I2SCFGR	volatile uint32_t	0x0	
	Init	SPI_InitTypeDef	{...}	
		Mode	uint32_t	0x400000	
		Direction	uint32_t	0x0	
		DataSize	uint32_t	0x7	
		CLKPolarity	uint32_t	0x2000000	
		CLKPhase	uint32_t	0x1000000	
		NSS	uint32_t	0x4000000	
		BaudRatePrescaler	uint32_t	0x0	
		FirstBit	uint32_t	0x0	
		TIMode	uint32_t	0x0	
		CRCCalculation	uint32_t	0x0	
		CRCPolynomial	uint32_t	0x0	
		CRCLength	uint32_t	0x0	
		NSSPMode	uint32_t	0x40000000	
		NSSPolarity	uint32_t	0x0	
		FifoThreshold	uint32_t	0x0	
		TxCRCInitializationPattern	uint32_t	0x0	
		RxCRCInitializationPattern	uint32_t	0x0	
		MasterSSIdleness	uint32_t	0x0	
		MasterInterDataIdleness	uint32_t	0x0	
		MasterReceiverAutoSusp	uint32_t	0x0	
		MasterKeepIOState	uint32_t	0x0	
		IOSwap	uint32_t	0x0	
	pTxBuffPtr	const uint8_t *	0x30000260	
		*pTxBuffPtr	const uint8_t	0x80	
	TxXferSize	uint16_t	0x5	
	TxXferCount	volatile uint16_t	0x0	
	pRxBuffPtr	uint8_t *	0x30000040	
		*pRxBuffPtr	uint8_t	0x0	
	RxXferSize	uint16_t	0x5	
	RxXferCount	volatile uint16_t	0x0	
	CRCSize	uint32_t	0x0	
	RxISR	void (*)(struct __SPI_HandleTypeDef *)	0x0	
	TxISR	void (*)(struct __SPI_HandleTypeDef *)	0x0	
	hdmatx	DMA_HandleTypeDef *	0x240714a8	
		Instance	void *	0x40020058	
		Init	DMA_InitTypeDef	{...}	
		Lock	HAL_LockTypeDef	0x0	
		State	volatile HAL_DMA_StateTypeDef	0x1	
		Parent	void *	0x24071100	
		XferCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferHalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1CpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1HalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferErrorCallback	void (*)(struct __DMA_HandleTypeDef *)	0x800fe6f	
		XferAbortCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		ErrorCode	volatile uint32_t	0x0	
		StreamBaseAddress	uint32_t	0x40020000	
		StreamIndex	uint32_t	0x16	
		DMAmuxChannel	DMAMUX_Channel_TypeDef *	0x4002080c	
		DMAmuxChannelStatus	DMAMUX_ChannelStatus_TypeDef *	0x40020880	
		DMAmuxChannelStatusMask	uint32_t	0x8	
		DMAmuxRequestGen	DMAMUX_RequestGen_TypeDef *	0x0	
		DMAmuxRequestGenStatus	DMAMUX_RequestGenStatus_TypeDef *	0x0	
		DMAmuxRequestGenStatusMask	uint32_t	0x0	
	hdmarx	DMA_HandleTypeDef *	0x24071430	
		Instance	void *	0x40020040	
		Init	DMA_InitTypeDef	{...}	
			Request	uint32_t	0x25	
			Direction	uint32_t	0x0	
			PeriphInc	uint32_t	0x0	
			MemInc	uint32_t	0x400	
			PeriphDataAlignment	uint32_t	0x0	
			MemDataAlignment	uint32_t	0x0	
			Mode	uint32_t	0x0	
			Priority	uint32_t	0x10000	
			FIFOMode	uint32_t	0x0	
			FIFOThreshold	uint32_t	0x0	
			MemBurst	uint32_t	0x0	
			PeriphBurst	uint32_t	0x0	
		Lock	HAL_LockTypeDef	0x0	
		State	volatile HAL_DMA_StateTypeDef	0x1	
		Parent	void *	0x24071100	
		XferCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x800fe0d	
		XferHalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x800fe53	
		XferM1CpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferM1HalfCpltCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		XferErrorCallback	void (*)(struct __DMA_HandleTypeDef *)	0x800fe6f	
		XferAbortCallback	void (*)(struct __DMA_HandleTypeDef *)	0x0	
		ErrorCode	volatile uint32_t	0x0	
		StreamBaseAddress	uint32_t	0x40020000	
		StreamIndex	uint32_t	0x10	
		DMAmuxChannel	DMAMUX_Channel_TypeDef *	0x40020808	
			CCR	volatile uint32_t	0x25	
		DMAmuxChannelStatus	DMAMUX_ChannelStatus_TypeDef *	0x40020880	
			CSR	volatile uint32_t	0x0	
			CFR	volatile uint32_t	0x0	
		DMAmuxChannelStatusMask	uint32_t	0x4	
		DMAmuxRequestGen	DMAMUX_RequestGen_TypeDef *	0x0	
			RGCR	volatile uint32_t	0x47868640	
		DMAmuxRequestGenStatus	DMAMUX_RequestGenStatus_TypeDef *	0x0	
			RGSR	volatile uint32_t	0x47868640	
			RGCFR	volatile uint32_t	0x25d3796f	
		DMAmuxRequestGenStatusMask	uint32_t	0x0	
	Lock	HAL_LockTypeDef	0x0	
	State	volatile HAL_SPI_StateTypeDef	0x1	
	ErrorCode	volatile uint32_t	0x0	
txdata[0]	uint8_t	0x80	
txdata[1]	uint8_t	0x0	
txdata[2]	uint8_t	0x0	
txdata[3]	uint8_t	0x0	
txdata[4]	uint8_t	0x0	
txdata[5]	uint8_t	0x0	
TDK
TDKBest answer
June 4, 2025

What are you talking to?

Can you verify on a logic analyzer that the data coming in is non-zero?

Are you managing cache appropriately or is it turned off?

What specifically makes you think all received values are zero?

How are you observing them?

Does HAL_SPI_TransmitReceive_DMA return HAL_OK and does the transfer complete callback get called?

"If you feel a post has answered your question, please click ""Accept as Solution""."
JBias
Associate III
June 5, 2025

I was seeing something similar on the STM32H7S3L8 except for me I was not getting the next callbacks unless I did a HAL_SPI_INIT as well as a HAL_DMA_INIT in between. Later I was able to reduce the time by optimizing out what was not needed. Of course, I would check the data stream coming in to verify that there is non-zero data as suggested by TDK

 

// HAL_SPI_Init(hspi);																//1. Verify SPI Initialization <-- works but too long
	SPI3->IER |= SPI_IER_RXPIE | SPI_IER_EOTIE; 									// Enable RX Packet Interrupt, End of Transfer Interrupt <--works instead of full HAL_SPI_Init(hspi)
// 	HAL_DMA_Init(&handle_HPDMA1_Channel15);										//2. Confirm DMA Configuration <-- works but too long
	if ((HPDMA1_Channel14->CFCR != 0 )|(handle_HPDMA1_Channel14.Lock != HAL_UNLOCKED)|(handle_HPDMA1_Channel14.State != HAL_DMA_STATE_READY)) {
		__HAL_DMA_DISABLE(&handle_HPDMA1_Channel14); 								//Disable DMA to allow register changes
		__HAL_DMA_RESET_HANDLE_STATE(&handle_HPDMA1_Channel14);						//Put into reset state to allow LOCK change todo needed ?
		__HAL_DMA_CLEAR_FLAG(&handle_HPDMA1_Channel14, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
									DMA_FLAG_TO));									//Clear all flags todo needed ?
		handle_HPDMA1_Channel14.Lock = HAL_UNLOCKED;								//Unlock
		handle_HPDMA1_Channel14.State = HAL_DMA_STATE_READY; 						//Ready State
		HPDMA1_Channel14->CCR |= DMA_CCR_EN; 										//Restart DMA
	}
	// Restart DMA for continuous reception
	volatile uint8_t *vBuffer = &gS2_RxData[0];										//8-bit buffer
	HAL_SPI_Receive_DMA(hspi, (uint8_t *)vBuffer, gS2_RxSize);						//DMA/SPI Start - Ready to receive