Skip to main content
joecarlhr
Associate II
March 29, 2014
Question

DMA won't get enabled

  • March 29, 2014
  • 6 replies
  • 1779 views
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.

    This topic has been closed for replies.

    6 replies

    joecarlhr
    joecarlhrAuthor
    Associate II
    March 29, 2014
    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?

    Tesla DeLorean
    Guru
    March 29, 2014
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    joecarlhr
    joecarlhrAuthor
    Associate II
    March 29, 2014
    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....

    Tesla DeLorean
    Guru
    March 29, 2014
    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=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=102

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

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    joecarlhr
    joecarlhrAuthor
    Associate II
    March 30, 2014
    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...