cancel
Showing results for 
Search instead for 
Did you mean: 

DMA won't get enabled

joecarlhr
Associate II
Posted on March 29, 2014 at 17:53

Hello stmGuys. I'm having a problem configuring my DMA. I've tried everything I can imagine and it still doesn't work. I want the DMA to transfer data from a memory array to the GPIOD->ODR register. Here is my DMA_Init function:

void

Init_DMA()

{

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

DMA_InitTypeDef DMA_InitStructure;

TIM_TimeBaseInitTypeDef timerInitStructure;

timerInitStructure.TIM_Prescaler = 0;

timerInitStructure.TIM_CounterMode = TIM_CounterMode_Down;

timerInitStructure.TIM_Period = 1;

timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

timerInitStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2, &timerInitStructure);

TIM_DMACmd(TIM2,TIM_DMA_Update,ENABLE);

//This is connected to DMA1_Stream1 Channel_3

TIM_Cmd(TIM2, ENABLE);

DMA_DeInit(DMA1_Stream1);

while

(DMA_GetCmdStatus(DMA1_Stream1));

//Wait until its ready to be configured

DMA_InitStructure.DMA_Channel = DMA_Channel_3;

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &GPIOD->ODR;

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &v_memory[0];

DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;

DMA_InitStructure.DMA_BufferSize = 160;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //Tried all possible combinations sizes

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //

DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

//

DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOStatus_HalfFull;

//

DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

//I've tried all possible combinations with these params

DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single ;

//

DMA_Init(DMA1_Stream1, &DMA_InitStructure);

DMA_Cmd(DMA1_Stream1, ENABLE);

}

v_memory is defined as: uint8_t v_memory[160];

The GPIOD is well configured as output.

In my main loop I'm continously checking DMA1_Stream1 status and I've discovered its always disabled. Even if I enable it just before checking. If I don't configure Timer2 as the DMA Request then the DMA keeps enabled but it doesent transfer any data... I want this transfer to be done every time the timer reaches 0 value. I'm refilling this timer in other function so it's not the problem. I really can't see what I'm missing. Anyone there able to bring light here?

Thanks in advance.

6 REPLIES 6
joecarlhr
Associate II
Posted on March 29, 2014 at 18:17

Thanks for your answer clive1. I already tried DMA2 with TIM1. Sorry for not mentioning it. It didn't work either, actually DMA2's clock is AHB1 too.

Is there anything else I could have missed?

Posted on March 29, 2014 at 18:35

Both DMA1 and DMA2 are on AHB, however DMA1 works with APB1 peripherals, and DMA2 works with APB2 peripherals.

The Period of One is a bit on the low side, not sure how that's remotely sustainable. Does the DMA flags some error or under/overflow condition?

I'm only going to touch complete exemplars.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
joecarlhr
Associate II
Posted on March 29, 2014 at 19:25

Well you are right. I reconfigured it again to use DMA2_Stream5 Channel_6 with TIM1 now it  keeps enabled and all error flags are set to 0. I changed Timer period to 10. But It's still transfering nothing to GPIOD->ODR.

Is this normal? Isn't there any extra configuration I'm missing?

EDIT: Sorry, all I said in this last post was not ture, I just forgot to enable TIM1 clock and thats why the DMA was keeping enabled.  I enabled TIM1's clock and the DMA gets disabled again and actually the FIFO error flag is set. Even with FIFO mode disabled....

Posted on March 29, 2014 at 19:46

Ok, this is the example I was looking for earlier, where I output via the GPIO using an internal clock. I don't have a scope or bench set up to test things right now, but this was tested with a scope to prove GPIO output.

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/DMA%20MemoryToMemory%20using%20Timer%20for%20delivery%20rate&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD065...

Observe how the example is formed and presented as a stand-alone demonstration.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
joecarlhr
Associate II
Posted on March 30, 2014 at 12:39

Thanks so much clive1 I got some output on GPIOD->ODR now. It's a bit complicated to understand the way this DMA works...