Skip to main content
Explorer
June 4, 2025
Solved

SPI communication using DMA on the STM32H743.

  • June 4, 2025
  • 3 replies
  • 566 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

    Explorer
    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	
    TDKAnswer
    Super User
    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?

    Explorer II
    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