2014-03-29 09:53 AM
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.2014-03-29 09:57 AM
The AHB is not on APB1, I think you need to use DMA2 for such transactions.
2014-03-29 10:17 AM
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?2014-03-29 10:35 AM
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.2014-03-29 11:25 AM
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....2014-03-29 11:46 AM
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.
Observe how the example is formed and presented as a stand-alone demonstration.2014-03-30 03:39 AM
Thanks so much clive1 I got some output on GPIOD->ODR now. It's a bit complicated to understand the way this DMA works...