cancel
Showing results for 
Search instead for 
Did you mean: 

How to activate FIFO and BURST on DMA Memory to Timer transaction (STM32F7)

alexandre23
Associate III

Hello,

I try to activate fifo + burst in dma transaction, without success (goal is a DSHOT driver* for drone)

My setup (stm32f767):

memory to timer TIM3 in pwm mode, writing several CCR registers in timer using DPAR+DBA+DBL (DBA set to access CCR registers, DBL set for length=2)

transaction is triggered by TIM3_UP stream

psize = msize = half word

inc peripheral = false, inc memory = true

circular = false

number of beat is 40

if I don’t use fifo, (neither burst), it works when the dma controller is not busy with other transfer, but when there is lot of spi, i²c and SDIO using DMA at the same time, I have up to 7% of malformed dshot frames : the TIM CCR registers are not updated in time due to latency on the DMA controller, and the timer use the previous CCR value to generate pulse.

I want to activate fifo (DMDIS=1) and burst in an attempt to mitigate this latency problem :

I tried this setups :

fifo theshold 4/4

mburst = 4

pburst = 4

Does not work at all : the timer is not updated, and I get FEIF (fifo error) bit set when DMA ISR is called. Most of the time the ISR is called, the fifo status is FIFO FULL.

I follow RM0410 recommendations :

beat number (40) is multiple of burst size * data size (8)

buffer memory address and DPAR address are aligned(8)

buffer memory is in a non Dcached memory area

I probably miss an obvious thing, but I am on this since few days now, so any help is welcome !

Alexandre

* https://github.com/alex31/chibios_enac_various_common/blob/fix_dma_fifo/esc_dshot.c

9 REPLIES 9

What is DSHOT? What is dshot frame and how is it malformed? Show pictures.

How exactly do you set up DMA? Read out and show registers content, not code. How do you trigger DMA? And how is the timer set up (again registers content)?

> beat number (40) is multiple of burst size * data size (8)

What exactly do you mean by "beat number"?

JW

alexandre23
Associate III

DSHOT is a serial protocol to communicate 16 bits value to an electronic speed controler. It is meant to replace a duty based PWM which can be seen as an analog value, by a numeric value with 16 bits, a bit is 0 or 1 depending on pulse width. using a timer with 4 channels, i can generate frame for up to 4 engine in //

When there is a latency problem, the timer use the previous CCR value instead of the one that should be given by DMA, and i get a 17 bits frame instead of 16 bits with a bit duplicated.

By the way, i just found a workaround, since the duplicated bits are always the first or second position, i have add 2 zero CCR values in the dma buffer,

but my initial question remain, why it is not working if i activate fifo ?

DMA transaction is triggered by software setting the EN bit of DMA_SxCR each time i transmit a frame, i am not using circular mode

beat number is the number of half word that are transmitted in a DMA transaction (beat is the word used in the RM410 reference manual)

for the values of the registers in the DMA stream just before enabling the EN bit (without fifo, when it works) :

(gdb) p/x *dmap->dmastream->stream
$5 = {CR = 0xa032c50, NDTR = 0x28, PAR = 0x4000044c, M0AR = 0x2007c000, M1AR = 0x0, FCR = 0x21}
 
 

DMA stream just before enabling the EN bit (with fifo, does not work) :

(gdb) p/x *dmap->dmastream->stream
$3 = {CR = 0xaa32c50, NDTR = 0x28, PAR = 0x4000044c, M0AR = 0x2007c000, M1AR = 0x0, FCR = 0xa7}

In the two case (with or without FIFO), the configuration of TIM3 is the same :

(gdb) p/x *TIM3
$6 = {CR1 = 0x85, CR2 = 0x8, SMCR = 0x0, DIER = 0x100, SR = 0x1f, EGR = 0x0, CCMR1 = 0x6868, CCMR2 = 0x6868, 
  CCER = 0x11, CNT = 0x14f, PSC = 0x0, ARR = 0x167, RCR = 0x0, CCR1 = 0x0, CCR2 = 0x0, CCR3 = 0x0, 
  CCR4 = 0x0, BDTR = 0x0, DCR = 0x10d, DMAR = 0x0, OR = 0x0, CCMR3 = 0x0, CCR5 = 0x0, CCR6 = 0x0, AF1 = 0x0, 
  AF2 = 0x0}

I will find a logic analyser to show the signal.

Forget about bursts, just enable FIFO and set the memory-size transfer to word (DMA_SxCR.MSIZE=0b10).

JW

alexandre23
Associate III

thanks for your help.

Setting the memory-size transfer to word is OK, but when i activate fifo (without burst) , the timer is no more updated.

I have tried to use only one timer channel, using CCR[0] as peripheral address instead DMAR, but it's the same : works without fifo, not with fifo.

To detect bad frame in my test bench, i use another timer in input capture mode, in DMA, to compare and compute percentage of bad frame and in that direction (peripheral to memory) fifo activation works even with memory burst.

I must confess that i have not a complete understanding of the burst part of the dma, why there is separate peripheral burst size and memory burst size, how to set theses size, does it depend on the direction of the transaction ?

A.

> Setting the memory-size transfer to word is OK, but when i activate fifo (without burst) , the timer is no more updated.

Show DMA registers (including status) after enabling.

JW

alexandre23
Associate III

Hello, i have found my bug : i was setting fifo register after allocating the dma stream instead of before.

Thanks for the help, it now works with fifo and even with burst.

I still have a question : how to choose burst size. I think i understand the memory burst size idea, but i have more difficulties with peripheral burst size, and why they can be different.

A.

> i was setting fifo register after allocating the dma stream

What do you mean by "allocating" - enabling, i.e. setting DMA_SxCR.EN?

I don't think it's a good idea to use bursts on the peripheral side, especially not with the TIM DMAR facility.

JW

alexandre23
Associate III

In fact dmaAllocate is a function API of the HAL (ChibiOS) that I use and basically what it does is :

clearing DMA CR register then setting CR_RESET and FCR_RESET bit then associating NVIC vector.

correct order of operation is :

dmaAllocate

dma register settings (all registers including FCR)

dma EN bit setting

what i was doing was

setting FCR

dmaAllocate

dma register settings (all registers but FCR)

dma EN bit setting

so it was an order of operation error.

I will follow your advice and just enabling fifo and not burst.

Anyway, activating burst involve strong constraints on buffer alignment and size :

from RM410:

The address pointers (DMA_SxPAR or DMA_SxM0AR registers) must be chosen so as to

ensure that all transfers within a burst block are aligned on the address boundary equal to

the size of the transfer.

What is the expected size of the transfert here ? :

a/ burst_size [4,8,16]

b/ burst size [4,8,16] * msize (or psize) [1,2,4] ?

A.

b

JW