cancel
Showing results for 
Search instead for 
Did you mean: 

SPI with DMA: Add delay between bytes

JSmit.11
Associate II

Hi all,

I am working with a peripheral using SPI at 25MHz.

I would like to use DMA to send a continuous stream of data but the problem is that peripheral requires a 125ns delay between bytes.

Is there any way to achieve that with DMA?

I guess if i use DMA there will be no delays between bytes and thus it is not suitable for me.

Thanks

12 REPLIES 12
Uwe Bonnes
Principal II

Perhaps try to set up DMA, enable SPI and immediate disable it. With the RXNE interrupt set, reenable SPI in the interrupt after the delay has happended.

Which STM32?

Trigger the DMA from a timer, not from SPI itself.

JW

Hi, thanks for reply.

I am using two cpu's.

STM32L4S7ZIT6 and

STM32L462RET6

You mean that each byte transmission should be triggered by the timer? And and delay should be added between transmissions?

> You mean that each byte transmission should be triggered by the timer?

Yes.

> And and delay should be added between transmissions?

You set the timer so that timing of triggers of individual transfers is equal to duration of the SPI frame (byte) plus the required delay, plus some reserve for DMA jitter caused by conflicts within DMA and on buses, resynchronizations, etc. - this depends on the particularities of your aplication. Try.

JW

JSmit.11
Associate II

Hello,

After a long break i have returned to that issue.

I have some problems with DMAMUX overrun interrupt.

I decided to use LPTIM1 timer OUT event as a synchronization event. I have the following settings for DMAMUX:

NBREQ = 0 (1 spi transfer)

SE=1 (synchronization enable)

EGE=0 (event disable)

I see that DMA transfer occur. And I can regulate the intervals between SPI transfers changing the LPTIM1 counter value.

The problem is that i have DMAMUX overrun interrupt. That causes problems with detection of SPI completion. (HAL_SPI_TxCpltCallback is not called)

I see that overrun happens via SOFx register. I have read the manual which says that it can happen when synchronization. Here is the quote:

[FROM RM042]

If a new DMA request trigger event occurs before the DMAMUX request generator counter underrun (the internal counter programmed via the GNBREQ field of the DMAMUX_RGxCR register), and if the request generator channel x was enabled via GE, then the request trigger event overrun flag bit OFx is asserted by the hardware in the status DMAMUX_RGSR register

[FROM RM END]

So as I understand if a request from LPTIM will happen while there is DMA transaction the ovverun interrupt will happen.

But i my case the LPTIM overflow time is much larger than SPI transfer. I have checked that. So it might not an issue here.

Thre is another quote from RM0432:

[FROM RM042]

The request generator channel x must be disabled (DMAMUX_RGxCR.GE = 0) at the completion of the usage of the related channel of the DMA controller. Else, upon a new detected trigger event, there is a trigger overrun due to the absence of an acknowledge (that is, no served request) received from the DMA.

[FROM RM042 END]

So let say I send via SPI 5 bytes. After 5th byte is send if the channel is not disabled the next trigger from timer will cause overrun interrupt.

This is how i understand above note. I see that overrun happens only after all spi transfers complete.

Am i correct? Do i need to disable the channel manually.

I am using HAL. After I get a overrun interrupt, my breakpoint triggers. I see through peripherals view that channel is enabled..

Maybe there is a bug in a HAL library?

Thanks

> I see that overrun happens via SOFx register.

So it's a Synchronization overrun, yet you're quoiting from the Trigger overrun (indicated by OFx) subchapter.

0693W00000BbA88QAF.pngI don't use Cube.

JW

JSmit.11
Associate II

Sorry. I have mixed all up.

I have Synchronization overrun.

But in RM there is the same quote about it.

[QUOTE]

Synchronization overrun and interrupt If a new synchronization event occurs before the request counter underrun (the internal request counter programmed via the NBREQ field of the DMAMUX_CxCR register), the synchronization overrun flag bit SOFx is set in the DMAMUX_CSR status register. Note: The request multiplexer channel x synchronization must be disabled (DMAMUX_CxCR.SE = 0) at the completion of the use of the related channel of the DMA controller. Else, upon a new detected synchronization event, there is a synchronization overrun due to the absence of a DMA acknowledge (that is, no served request) received from the DMA controller.

[END]

So maybe i need to disable the channel after DMA transfer completed?

Or just ignore the interrupt (don't enable it).

JW

JSmit.11
Associate II

I will try.

But do i understand correctly that when DMA transfer is finished the next trigger from TIM will cause overrun event? Because transfer counter NBREQ  is over.

That is a bit strange design. Maybe it is done for purpose.