2019-10-11 12:55 AM
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
2019-10-11 01:32 AM
Generally, you need to:
I don't Cube.
JW
2019-10-14 01:34 AM
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
2019-10-14 01:51 AM
JW