cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 Trigger DMA1 from TIM2 Update

daniel2
Associate II
Posted on July 15, 2015 at 00:09

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 😎 it transfers the data one time and then does not transfer any more data until I press the button again.


void EXTI15_10_IRQHandler(void)

{

if (EXTI_GetITStatus(USER_BUTTON_EXTI_LINE) == SET)

{

DMA_ClearITPendingBit(DMA1_IT_GL2);

DMA_SetCurrDataCounter(DMA1_Channel2, ARRAYSIZE);

//Enable DMA1 Channel transfer

DMA_Cmd(DMA1_Channel2, ENABLE);

TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);


/* TIM2 enable counter */

TIM_Cmd(TIM2, ENABLE);


EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);

}

}

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);
}

1 REPLY 1
daniel2
Associate II
Posted on July 15, 2015 at 15:16

Okay so I discovered that M2M mode does not support trigger off the timer. So with that disabled, when I start the timer a bit is shifted out on every rising edge of my timer update until it has shifted ''ARRAYSIZE'' number of bytes.