2025-06-03 9:30 PM
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?
Solved! Go to Solution.
2025-06-04 5:42 AM
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?
2025-06-03 9:34 PM
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
2025-06-04 5:42 AM
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?
2025-06-05 4:46 PM
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