AnsweredAssumed Answered

Checking for finished SPI / DMA transfer - missing data?

Question asked by nohaj.miroslav on Feb 18, 2014
Latest reply on Jun 16, 2015 by elliott.grant
Hello all,

I've run through couple of SPI DMA threads here, but I didn't find what I was looking for... On my STM32F103 I'm sending data to host over SPI:
- my STM32 acts as SPI slave
- SPI transfer is done using DMA
- data is transferred in blocks of ~520 bytes (260 words (word = 16 bits)), each block is a separate DMA transfer

Everything works mostly fine, but from time to time I loose the first word of the block, so I guess I'm not waiting correctly for SPI DMA transfer to finish before starting a new one.

I set a flag at the end of DMA transfer in interrupt, so I have DMA1_Channel2_IRQHandler and DMA1_Channel3_IRQHandler. When both transfer interrupts arrive, I assume that the SPI DMA finished and I start a new SPI DMA transfer. I guess that in the problematic case the DMA has finished, but the SPI is still transferring the last WORD, so I added a check / loop like this after the received interrupts:

void waitForSPIidle(void)
    while((SPI1->SR & 2) == 0);  // wait while TXE flag is 0 (TX is not empty)
    while((SPI1->SR & (1 << 7)) != 0);  // wait while BSY flag is 1 (SPI is busy)

The lost WORD is missing (or maybe arrived instead of the last word in the previous block) on the host part, so checking the TXE and then BSY flag should be enough to see if nothing more is transmitted. The thing is that this doesn't help. What am I missing? I don't want to add mostly unnecessary delay before starting each DMA SPI transfer, I would rather check some flags...