AnsweredAssumed Answered

STM32F3 Trigger DMA1 from TIM2 Update

Question asked by bujak.dan on Jul 15, 2015
Latest reply on Jul 15, 2015 by bujak.dan
I configure my DMA, and am trying to trigger it to move data from an array to a GPIO-> BSRR each time TIM2 update interrupt triggers. I have assigned a push button to enable the peripherals as per below. However, as soon as I enable the DMA (line 8) it transfers the data one time and then does not transfer any more data until I press the button again.

01.void EXTI15_10_IRQHandler(void)
02.{
03.    if (EXTI_GetITStatus(USER_BUTTON_EXTI_LINE) == SET)
04.    {
05.        DMA_ClearITPendingBit(DMA1_IT_GL2);
06.        DMA_SetCurrDataCounter(DMA1_Channel2, ARRAYSIZE);
07.        //Enable DMA1 Channel transfer
08.        DMA_Cmd(DMA1_Channel2, ENABLE);
09.        TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
10.         
11.        /* TIM2 enable counter */
12.        TIM_Cmd(TIM2, ENABLE);
13.         
14.        EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);
15.    }
16.}


1. DMA_Cmd(DMA1_Channel2, ENABLE);
2. TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
3. TIM_Cmd(TIM2, ENABLE);

I toggle an LED in the TIM2 ISR so I know the interrupt is occurring. What do I need to do in order to  have the DMA perform the same array data move each time?

void WS2812_Basic_DMA_Init2(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
    //enable DMA1 clock
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
    //reset DMA1 channe1 to default values;
    DMA_DeInit(DMA1_Channel2);
    //channel will be used for memory to memory transfer
    DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
    //setting normal mode (non circular)
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    //medium priority
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    //source and destination data size word=32bit
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    //automatic memory increment enable. Destination and source
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    //Location assigned to peripheral register will be source
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    //chunk of data to be transfered
    DMA_InitStructure.DMA_BufferSize = 0;
    //source and destination start addresses
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOC->BSRR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&source;
    //send values to DMA registers
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);
 
 
 
    //Enable DMA1 channel IRQ Channel */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    // Enable DMA1 Channel Transfer Complete interrupt
    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
}


Outcomes