2020-07-15 05:24 AM
I'm trying to implement a SPI Slave using a circular DMA on the STM32H7.
I'm able to correctly receive the bytes sent from a master.
I have enabled an interrupt on the rising edge of the chip select to read out the sent bytes at the end of a transmission as I don't know the master transmission length before hand.
Here I can correctly read out the bytes sent by the master.
On the next transmission I want to respond with the 1st byte from the previous transmission so i fill the transmit DMA buffer with this one byte as a test.
Here I get the issue that the byte sent back is 10 transmissions behind.
(The buffersize used is 50 bytes)
So when I receive the nr 12, the slave sends out the nr 2, even though in the transmit buffer we've written the nr 12.
At first glance I would think that it would be a cache issue but I've read through https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices.
It doesn't seem like that's the issue as the SPI transmits and receives.
I've used the various suggestions to see if it would work correctly but it doesn't.
The current fix now is to use HAL_SPI_Abort and HAL_SPI_TransmitReceive_DMA in the interrupt routine which works as intended (but is quite slow).
Am I not understanding something here or could someone explain why this is not working as intended ?
2020-07-15 06:17 AM
The peripheral is going to pre-load a few bytes before they're actually transmitted. Disable the FIFO to reduce this number, but it will never be 0. You can send a few dummy bytes in order to flush these from the system.
You've already outlined the options--abort and restart the transfer if you need to change the next byte that will be sent. If you can't live with HAL overhead, you can implement these at the register level.
2020-07-15 07:15 AM
thanks for the fast answer!
The FIFO is already disabled, so the 10 bytes will probably be the amount that's pre-loaded.
Sending the dummy bytes would indeed be a solution,
but as the slave can't decide when to send bytes I don't exactly know how to do this ?
The HAL_SPI_Abort and HAL_SPI_TransmitReceive_DMA seems very harsh (and time consuming).
I've looked into the datasheet of the SPI but can't seem to find anything about clearing the SPI peripheral.
I've found some info online that suggests resetting the SPI with the RCC and re-configuring it entirely? This also seams pretty harsh.
2020-07-15 12:54 PM
Single or double core?
Try it with the m4, no cache issuses.
The mdma is a good way to get data back and forth between the m7 tcram and d2 sram. I haven't tried it, but there is a way to link the mdma to a dma channel.
2020-07-15 02:07 PM
SPI for H7 is a new animal. On L4, the issue was dma keeps filling slave tx fifo. when nss goes high, how to flush it? in l4, a rcc/sys spi reset is needed as spi disable won t
2020-07-15 02:10 PM
no control of sck means no way to flush. still using the fifo worth it for performance.
2020-07-15 03:09 PM
You say it's not a cache issue, but did you read the part about the dmas not being able to access the m7 tcram? Use the m4, that's what it's there for or use the mdma to copy data from d2 ram dma buffer to m7 tcram.
2020-07-15 03:48 PM
> but as the slave can't decide when to send bytes I don't exactly know how to do this ?
This would be something you'd have to do on the master side. It's not that rare for SPI communication to include 1-2 dummy bytes after the master sends something where the master sends a byte and ignores the result to give the slave some time to come up with the proper response. 10 bytes is a bit much, but it's the same principle.