cancel
Showing results for 
Search instead for 
Did you mean: 

SPI slave with DMA transmits invalid data

masooli
Visitor

I am working with the STM32H743ZITx MCU and have configured SPI3 as a slave to transmit 16-bit items using DMA1. The DMA settings were configured through STM32Cube, utilizing a circular DMA with half-word data and peripheral memory alignments.

During transmission of 5 half-words, I observe that all values are correct initially. However, when I increment these values by one in the transmission complete callback, the subsequent transmission of 5 half-words sends the same values as before.

This issue persists through the 2nd and 3rd transmissions. In the fourth transmission, items 1, 2, 3, and 4 remain unchanged, while the 5th item is incremented by one. The expected increment for this item should be by 4. The behavior is inconsistent, with some items being incremented by one while others remain the same.

I want to emphasize that I increment the items by one each time a transmission is completed and the corresponding callback is triggered. I have also experimented with placing the TX buffer in SRAM1, SRAM2, and SRAM3, but the results were unchanged.

Initially, I suspected that cache might be invalidating the values, but I do not use cache. To address this, I defined a non-cacheable region in SRAM1 using the MPU and started the transmission again, yet the results remained the same.

Additionally, I attempted to use BDMA with SPI6, as the pins for SPI3 and SPI6 are shared, but encountered the same issue.

Is it possible to use DMA in SPI slave mode and ensure that the transmitted values accurately reflect those in RAM on the STM32H7 MCUs? Any insights or suggestions would be greatly appreciated.

3 REPLIES 3
TDK
Super User

Things are sent to the SPI TXFIFO as soon as possible. Since the SPI is in circular mode, the FIFO fills up with the initial data and gets sent out as clocks come in. Once it's in the TXFIFO, there's no way to change it.

Re-initialize the SPI on the rising or falling edge of the CS signal if you need to change the data.

 

Cache can also be getting in the way here if it is not managed properly. I recommend turning off DCACHE until things are working correctly.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for your response.

From what I understand, you are indicating that the data transmission from RAM to the SPI TX FIFO via DMA occurs asynchronously and immediately. However, I recall from the reference manual that the SPI signals the DMA when the TXC flag (or something like that indicating the end of transmission) is set. This suggests that the transmission may not be as immediate as you imply. If I modify the values before this flag is set, I could observe those changes reflected in the SPI TX data register. I may have misunderstood your use of the phrase "as soon as possible."

The core issue lies in the transmission of data from RAM to the FIFO. Why do I lack control over this transmission unless I disable and re-enable the EN bit of the SPI? My intention in using circular mode was to configure everything once and allow the system to operate autonomously without concerns about data validity.

As I mentioned earlier, I have disabled the cache, yet the results remain unchanged. I also considered the possibility of an alignment issue with the TX buffer, but I ensured 32-bit alignment, and the output was still the same.

I want to be able to transmit data to the master while it keeps the NSS bit active for 1, 2, 10, or any number of transmissions it requires. I mean when master says that it wants data from me, it should be able to keep the NSS active all the time!

> However, I recall from the reference manual that the SPI signals the DMA when the TXC flag (or something like that indicating the end of transmission) is set.

Where are you reading this? The RM describes how it works. End of transmission and TXC are not relevant here.

If you feel a post has answered your question, please click "Accept as Solution".