2015-07-14 03:09 PM
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.
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);
}
2015-07-15 06:16 AM
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.