cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 - DMA Double Buffer Mode To/From GPIO

stcom9174
Associate II
Posted on November 15, 2017 at 02:02

Hello All,

I am trying to use double buffer mode on one of the GPIO ports - using the timer method; and I've enabled circular DMA mode and have enabled M0AR and M1AR; but when the first transfer takes place; I'm getting a program exception.

Does the DMA controller automatically make the switch between memory spaces or am I supposed to do that in the IRQ?

I thought once this was set up - the M0AR being Mem_0 and M1AR being Mem_1 did it.  I admit in the std perif lib the description of that being the 'current memory' is a little confusing - but I've tried implementing this several ways and the exception always occurs after the first transfer.

Right now - the DMA controller is copying to both buffers on every transfer - I see that in the debugger.

I am calling these command in my DMA init code:

DMA_DoubleBufferModeConfig(DMA2_Stream1, (uint32_t) &dbRxBuffer0[0], DMA_Memory_0);  // ? Current memory

DMA_DoubleBufferModeConfig(DMA2_Stream1, (uint32_t) &dbRxBuffer1[0], DMA_Memory_1);

DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE);

Thanks In Advance,

John W.

4 REPLIES 4
stcom9174
Associate II
Posted on November 15, 2017 at 02:08

I should add:

Since the DMA physical path in this case is shared - meaning I'm using TIM1_CH1 for both xmit and rcv; and that has to be turned on and off; will circular mode work?  

I do have to turn off the stream and redirect on every xmit (out of the GPIO port) and rcv (in from the GPIO port).

Thanks,

John W.

Posted on November 15, 2017 at 05:07

I recall the double buffer requires interrupts to refresh the DMA as double buffer mode. If single buffer cyclical mode, then no interrupt is needed. Dynamically changing stream seems acrobatic. If the goal is to scan fast GPIOs, use timers input captures (Input) or output compares (Output). Some STM32 families can DMA on the capture/compare register.

Posted on November 15, 2017 at 14:38

OK KE.

Thanks for the reply.

Another issue I just saw makes me think the TIM1_CH1 input clock is being divided by 2 - but I don't know how that could be happening right now.  It looks like every other byte is being received - maybe something thinks it is in 16 bit mode vs. 8 bits and the high byte is getting lost?  Sure looks something like that right now.

I noticed in the docs when you access IDR and ODR that the registers are always in 16 bit mode - so makes me think the register xfers going on are 16 bits and could explain why I'm seeing every other byte transferred in the RCV buffers.

Thanks,

John W.

Posted on November 15, 2017 at 14:52

Make sure the DMA is transferring 16 bit modes. Long time ago, a 16 bit timer register is 'latched' when read in 8 bit mode: The LSB (or MSB) was latched when the MSB (or LSB) is read in 8 bit mode, which could explain the foreseen behaviour.