cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with SPI DMA transfer on STM32H743

Curtis B.
Senior

Hello community,

I am facing massive problems using the SPI1 with DMA transfer on the STM32H743 Nucleo board. Using interrupt based transfer works, but when I try to use DMA I always receive zeros in the receive buffer and I get an overrun error from the SPI peripheral.

As the SPI is configured in full duplex master mode I use the HAL_SPI_TransmitReceive_DMA function to generate a clock signal on the bus when I want to receive data. I configured both TX and RX DMA channels for the SPI. HAL_SPI_TransmitReceive_DMA returns HAL_OK. DMA transfer is completed and SPI_DMATransmitReceiveCplt is called. However, HAL_SPI_TxRxCpltCallback is not called due to the overrun error of the SPI.

I know that there are several rules to obey when you want to use DMA with the STM32H743. The DMA channels can only access RAM in the D1 and D2 region. As I use TrueStudio with the gnuarm compiler I added following section to the linker file:

  .DMA_**** :
{
. = ABSOLUTE(0x30047000);
*(.DMA_*****);
} >RAM_D2

I initialized the buffers in the source code in the following way:

__attribute__((section(".DMA_****"))) RFM22_RX_BUFFER_t RFM22_RX_buffer;
__attribute__((section(".DMA_****"))) uint8_t dump[RX_READ_BYTES];
__attribute__((section(".DMA_****"))) uint8_t dump2[RX_READ_BYTES];

 I verified with the debugger, that the buffer variables are in the correct RAM section.

I also know that using the D-cache can lead to several problems. I configured the memory protection unit in a way that the Buffer section is not cacheable not shareable and not bufferable. I even tried it with cache complete deactivated. But I still get the same erroneous behaviour.

Does anyone have a hint whether I might have missed something important?

Best regards,

Daniel

12 REPLIES 12
wynandsp
Associate III

Hi Curtis,

I went stealth yesterday and the reason for that is that I decided to do a most basic project with just the SPI4 rx and tx.

Clock was set at 400MHz DMA channel selected randomly by CubeMX.

In my App I just created 2 buffers uint8_t RxBuffer[8] and TxBuffer[8]. Caches disabled.

With this setup I got the HAL_SPI_TransmitReceive_DMA working.

Then enabled both caches and immediately RxBuffer showed 0's. With this I added the maintenance functions and all worked well. After this I created a protected memory area at 0x30000000 of 64kB and moved my buffers inside this area. MPU enabled and removed the cache maintenance functions. Now for some odd reason it is working.

So there is a base to work from and by the way the above took me a whole day to accomplish. I messed around with the system clock settings and the MPU and this broke the whole thing. In the end I setup CubeMX to have all the settings as I require and regenerated the code. And then it worked.

Thank you for the comment on the MPU and the linker script it made me revisit what I thought was ok.

Now for the next step and that is to get my original app working, but at least I am convinced now that it is possible to have the SPI Tx and Rx working with DMA.

Cheers.!

Asantos
Senior

Are you using revision y chips?

You can't transmit and receive SPI using DMA for STM32H743 with y revision. There is an errata for that.

wynandsp
Associate III

Dear Asantos,

Thank you for the answer. Yes I am using rev Y.

My app however is working perfectly with TransmitReceive_DMA.

At this point I am trying to remember if I did a mcu package upgrade during the development. It is the only thing that I can think of at this point in time.