SPI master and DMA, tested ?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I am using BCM943362WCD4, which uses STM32xxx MCU and SDK 3.1.1

I am trying to enable DMA for SPI master and it just does not work. Transfer times out trying to send out first byte. Has DMA even been tested ? Line 394, I can read:


dma_init.DMA_PeripheralBaseAddr = ( uint32_t )spi->port->DR;

This is obviously wrong, passing port DR register content instead of DR register address, I replaced by

dma_init.DMA_PeripheralBaseAddr = ( uint32_t )&(spi->port->DR);


But that does not change anything, timeout again.


I'll keep reviewing the code, but it would be nice to have some help on that topic, has anybody enabled DMA for SPI master ?



Thanks.


9 Replies
Anonymous
Not applicable

One more typo, line 451/452

    /* Init and activate RX DMA channel */

    DMA_Init( spi->tx_dma.stream, &dma_init );

Should obviously be

    /* Init and activate RX DMA channel */

    DMA_Init( spi->rx_dma.stream, &dma_init );

That still does not fix my issue...

0 Likes
Anonymous
Not applicable

Hi,
do you try with SDK 2.4.1? It doesn't seem to have those typing errors

Thanks and Regards,
Sooraj

0 Likes
Anonymous
Not applicable

Hi, I actually don't. I checked 3.0.1, same problem.

I actually got it to work late last night, I'll post details here later today.

Thanks.

0 Likes
Anonymous
Not applicable

Alright, so a few things are wrong, additionally to the issues I reported earlier, the routine spi_dma_transfer() in platform_spi.c uses DMA_GetFlagStatus() to check for DMA completion. The flag that is passed to this function is defined as DMA_HISR_TCIF5 in platform.c.

DMA_GetFlagStatus() only accepts flags defined in stm32f4xx_dma.h, as DMA_FLAG_TCIFx. The reason is that DMA_GetFlagStatus() uses a reserved bit (bit 29) to identify if the register to be checked is located in LOW or HIGH ISR register. Since spi_dma_transfer() passes the DMA_HISR_TCIF5 without bit 29 set, DMA_GetFlagStatus() checks LISR while DMA_HISR_TCIF5 is located in HISR.

The bit is never seen as set and transfer is never seen as completed, spi_dma_transfer() always times out.

Two things, either the "FLAG" version of the mask should be set in platform.c or spi_dma_transfer() should NOT use DMA_GetFlagStatus().

One more thing, spi_dma_transfer() deactivate SPI chip select after transfer (success, or failure) which is WRONG, in case of a multi-segment transfer, chip select should NOT be deactivate at the end of the first segment.

CS management is already done in platform_spi_transfer(), there is NO need to touch  CS from DMA routine.

Anonymous
Not applicable

Thanks a lot.

I have been facing the same problem.

You saved me a lot of time in debugging. SPI Master with DMA works now.

Next round: Getting SPI slave to work with DMA. Have you tried it?

0 Likes
Anonymous
Not applicable

Hi, I haven't tried SPI slave since I have no need for it on my product.

0 Likes

Is this still an issue?  Can you create a new discussion if there are questions based on the latest SDK?

0 Likes
Anonymous
Not applicable

This is still an issue with released SDK, that can be address with the fix I described. I doubt duplicating post in the forum is the best way to address this, it might confuse people.

Thanks.

0 Likes
Anonymous
Not applicable

gangi

Requeset you to fix this bug in the coming releases of SDK version , as this is present in SDK from the version  3.0.1 to 3.1.2 .

0 Likes