Question
Extra Data Transferred by DMA
Posted on July 21, 2015 at 21:27
Hi All,
I'm configuring my DMA to transfer 48 bytes of data, and am triggering the DMA interrupt both on TC and HT events. Currently if I disable the DMA after the first interrupt, so I would expect to see 24 bytes of data but in reality I see 25-26 bytes. If I disable the DMA after the TC only, I see anywhere from 2-5 extra bytes of data. The data is the correct data in the consecutive bytes of my source so it seems like the DMA isn't being disabled fast enough. Also, if I slow my TIM2 down, the problem disappears. Is there a better way to do this than what I have below:/* Button press to initiate DMA transfer */
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(USER_BUTTON_EXTI_LINE) == SET)
{
EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);
// Clear all flags for DMA
DMA_ClearFlag(DMA1_FLAG_TC2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2 | DMA1_FLAG_TE2);
DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_HT5 | DMA1_FLAG_GL5 | DMA1_FLAG_TE5);
DMA_ClearFlag(DMA1_FLAG_HT7 | DMA1_FLAG_GL7 | DMA1_FLAG_TE7);
// Configure number of bytes to transfer
DMA_SetCurrDataCounter(DMA1_Channel2, ARRAYSIZE); // ARRAYSIZE = 48
DMA_SetCurrDataCounter(DMA1_Channel5, ARRAYSIZE);
DMA_SetCurrDataCounter(DMA1_Channel7, ARRAYSIZE);
// Enable DMA1 Channel2
DMA_Cmd(DMA1_Channel2, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
DMA_Cmd(DMA1_Channel7, ENABLE);
// Enable TIM2 Update trigger for DMA
TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
TIM_DMACmd(TIM2, TIM_DMA_CC1, ENABLE);
TIM_DMACmd(TIM2, TIM_DMA_CC2, ENABLE);
/* TIM Interrupts enable */
//TIM_ITConfig(TIM2, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
//TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* Enable Timer 2 with counter preloaded */
TIM_SetCounter(TIM2, TIMER_PERIOD);
TIM_Cmd(TIM2, ENABLE);
}
}
/* DMA1 Channel7 Interrupt Handler */
void DMA1_Channel7_IRQHandler(void)
//Clear DMA1 Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits
DMA_ClearITPendingBit(DMA1_IT_GL7 | DMA1_IT_TC7 | DMA1_IT_HT7);
/* TIM Interrupts Disable */
TIM_ITConfig(TIM2, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2, DISABLE);
/* Disable Timer 2 */
TIM_Cmd(TIM2, DISABLE);
// disable the DMA channels
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA_Cmd(DMA1_Channel7, DISABLE);
TIM_DMACmd(TIM2, TIM_DMA_CC1, DISABLE);
TIM_DMACmd(TIM2, TIM_DMA_CC2, DISABLE);
TIM_DMACmd(TIM2, TIM_DMA_Update, DISABLE);
STM_EVAL_LEDToggle(LED2);
}