cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 SPI with DMA using memory to start transfer

ARess
Associate

Dear all,

I'm starting to use STM32H7 for a real-time project and my first task is to optimize the SPI communication.

The final implementation will be a library that elaborates data from SPI and send the elaborated data in another SPI (like a pass-through). The library I have to use needs #2 memory locations for data in and data out, my idea is to use DMA (memory to pheripheral) to manage the data sending automatucally without any code interacion in the main loop.

The path will be:

1 - source sends data on SPI2

2 - DMA gets data on SPI2_DR register and copies in the SPI_DataIn_Buffer

2 - the library gets data from SPI_DataIn_Buffer, elaborates it and copies in SPI_DataOut_Buffer

3 - DMA gets data on SPI_DataOut_Buffer and copies in the SPI2_DR

6 - STM32H7 sends data to destination

Im my implementation I configured the DMA (send only) like

    hdma_tx.Instance                 = SPIx_TX_DMA_STREAM;
    hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
    hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
    hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
    hdma_tx.Init.Request             = SPIx_TX_DMA_REQUEST;
    hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma_tx.Init.Mode                = DMA_NORMAL;
    hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
 
HAL_DMA_Init(&hdma_tx);
__HAL_LINKDMA(hspi, hdmatx, hdma_tx);
 
    HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1);
    HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn);

and I also tried to add directly register configuration to add source and destination

DMA1_Stream3->PAR   	= 	(uint32_t)&(SPI1->TXDR);	//	DMA stream x peripheral address register
DMA1_Stream3->M0AR 	=	(uint32_t)&(SPI1RxBuf[0]);	//	DMA stream 3 memory 0 address register
DMA1_Stream3->NDTR	=	0x07;						//	DMA stream x number of data register [7 HALF-WORDS, 14 Bytes]
DMA1_Stream3->CR    	= 	(DMA1_Stream3->CR & 0xFE100000) | 0x00022855;

I checked in the example provivded with STM32Cube_FW_H7_V1.5.0 package but all these examples use functions like HAL_SPI_TransmitReceive_DMA but, in my understanding, this means use functions in the main loop and I would like to avoid this (if possible).

Thanks for your support and Best regards

3 REPLIES 3

Generally, you need to:

  • enable DMA request generation in SPI (TXDMAEN/RXDMAEN, see Communication using DMA (direct memory addressing) subchapter of SPI chapter in RM)
  • 'H7 uses DMAMUX so you have to configure that too
  • and then as you've said, configure DMA itself; don't forget to clear the status flags before enabling the given stream

I don't Cube.

JW

ARess
Associate

Dear JW,

thanks a lot for your reply. Following your suggestion, I read the chapter in the reference manual (RM0433) related the DMA for SPI, including chapter 16 (DMAMUX). Checking examples on the "STM32Cube_FW_H7_V1.5.0" package (in details, DMAMUX_RequestGen project) I tried to modify it for SPI using but I still have some doubt about the DMAMUX

In the example I found this code

dmamux_ReqGenParams.SignalID  = HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT; /* External request signal is LPTIM2 signal */
dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_RISING;      /* External request signal edge is Rising  */
dmamux_ReqGenParams.RequestNumber = 1;                          /* 1 requests on each edge of the external request signal  */
 
HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams);

where the first instruction should be related to the external request (in this case LPTIM2 signal). I serached something for SPI but no label in this case.

Do you know where is possible to find detailed procedure about DMAMUX setting?

The Cube doesn't help.

Thanks and best regards

0690X00000AqJ8DQAV.pngJW