AnsweredAssumed Answered

Extra Data Transferred by DMA

Question asked by bujak.dan on Jul 21, 2015
Latest reply on Jul 21, 2015 by bujak.dan
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);
}

Outcomes