AnsweredAssumed Answered

DMA2 Not getting interrupt

Question asked by ali.babar on Feb 24, 2014
Latest reply on Jan 26, 2015 by gregory.glen
Hello members,
I have written a code for transfering data from DCMI (using DMA2) to internal RAM buffer. Then using a flag indication I need it to transfer data to SD/MMC (which is also using DMA2 and working perfectly).  I am getting DCMI interrupt from but not getting it from DMA2. I cannot figure out where configurations are getting wrong. My code is as follows. 
void NVIC_Config(void)
{
    /***********/
    /*** DMA2 **/
    /***********/
    NVIC_InitTypeDef NVIC_InitStructure;
     
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn; // DMA2 Stream 1 global Interrupt
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /***********/
    /*** SDIO **/
    /***********/
 
    //  Configure the NVIC Preemption Priority Bits
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn; // DMA2 Stream 3 global Interrupt
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
     
    /***********/
    /*** DCMI **/
    /***********/
     
    NVIC_InitStructure. NVIC_IRQChannel = DCMI_IRQn;
    NVIC_InitStructure. NVIC_IRQChannelPreemptionPriority = 1 ;
    NVIC_InitStructure. NVIC_IRQChannelSubPriority = 1 ;
    NVIC_InitStructure. NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init (&NVIC_InitStructure) ;
}
void DCMI_GPIO_Config(void)
{
// GPIO config done here
}
void INIT_DCMI(void)
{
// Hardware sync, data mode 8 bit, clock polarities setting
}
void Connfig_DCMI_DMA(void)
{
    DMA_DeInit(DMA2_Stream1);   // DMA2 Stream1 Configuration
     
    // Check if the DMA Stream is disabled before enabling it
    while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);
     
    /* DMA2 Stream1 configuration */
    DMA_InitStructure.DMA_Channel = DMA_Channel_1;
    // The next two lines needed to be handled carefully
    DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;  // Source Address
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) (& DCMI_Buffer_1); // Destination address
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //
    DMA_InitStructure.DMA_BufferSize = DMA_DCMI_FIFO_BUF_Size; // 1024 bytes buffer
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // increment is not enabled peripherals
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Enable memory increments
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     // circular mode need to be ping pong
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;   // ping pong mode selected
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream1, &DMA_InitStructure);     // DMA2 IRQ channel Configuration */
     
    // here double buffer is being used (read stmfxxx_dma.c file from line 661 to 716)
    DMA_DoubleBufferModeConfig( DMA2_Stream1, (uint32_t) (&DCMI_Buffer_2), (uint32_t) (&DCMI_Buffer_1) );
    DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE);
     
    DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE);  // Enable DMA Stream Transfer Complete interrupt
    DMA_ITConfig(DMA2_Stream1, DMA_IT_HT, ENABLE);  // Half tranfer
    DMA_ITConfig(DMA2_Stream1, DMA_IT_TE, ENABLE);
     
    DMA_Cmd(DMA2_Stream1, ENABLE);  // DMA Stream enable
    while (DMA_GetCmdStatus(DMA2_Stream1) != ENABLE); // Wait for DMA to start up
}
void DCMI_DMA_ProcessIRQSrc(void)
{
    /* Test on DMA channel 1 Transfer Complete interrupt */
    if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
    {
        DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
        USART_SendData_s(USART3,"DMA CH1 Full Transfer Complete \r\n");
         
        if (DMA_GetCurrentMemoryTarget(DMA2_Stream1))
        {
            //memory 0 used
            USART_SendData_s( USART3,"memory 0 used\r\n");
            DMA_MemoryTargetConfig(DMA2_Stream1, (uint32_t) (&DCMI_Buffer_2), (uint32_t) (&DCMI_Buffer_1));
            // buffordma = 0;
        }
        else
        {
            //memory 1 used
            USART_SendData_s( USART3,"memory 1 used\r\n");
            DMA_MemoryTargetConfig(DMA2_Stream1, (uint32_t) (&DCMI_Buffer_1), (uint32_t) (&DCMI_Buffer_2));
            // buffordma = 1;
        }      
    }
    /* Test on DMA channel 1 Half Transfer interrupt */
    if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_HTIF1))
    {
        DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_HTIF1);
        USART_SendData_s( USART3,"DMA ch 1 Half Transfer \r\n");               
    }
        if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_TEIF1))
    {
        DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TEIF1);
        USART_SendData_s( USART3,"DMA ch 1 Half Transfer \r\n");               
    }
     
}
 
void DCMI_ProcessIRQSrc(void)
{
    // Interrupt generated after receipt of full frame
    if ( DCMI_GetITStatus ( DCMI_IT_FRAME ) == SET ) {
        DCMI_ClearITPendingBit ( DCMI_IT_FRAME ) ;  
    }
    // Interrupt generated when changing the signal VSYNC
    // from active to inactive (VPOL = Low)
    if ( DCMI_GetITStatus ( DCMI_IT_VSYNC ) == SET ) {
        DCMI_ClearITPendingBit ( DCMI_IT_VSYNC ) ;
    // Wait until the DMA has finished transfer to RAM
    //  while ( DMA_GetFlagStatus ( DMA2_Stream1, DMA_FLAG_TCIF1 ) == RESET ) ;
    //  USART_SendData_s(USART3, "DCMI_IT_VSYNC\r\n");
    }
 
    // Interrupt generated when changing the signal HSYNC
    // from active to inactive (HPOL = Low)
    if ( DCMI_GetITStatus ( DCMI_IT_LINE ) == SET ) {
         
        DCMI_ClearITPendingBit ( DCMI_IT_LINE ) ;
        //USART_SendData_s(USART3, "DCMI_H\r\n");
   }
    // Interrupt generated when the old data (32-bit) in the registry DCMI_DR
    // not uploaded completely before the onset of the new data
    if ( DCMI_GetITStatus ( DCMI_IT_OVF ) == SET ) {
    //  USART_SendData_s(USART3, "DCMI_DR\r\n");
        DCMI_ClearITPendingBit ( DCMI_IT_OVF ) ;
    }
}
void Enable_Intp_DCMI(void)
{
    USART_SendData_s(USART3,"Enable_Intp_DCMI\r\n");
    DCMI_ITConfig(  DCMI_IT_VSYNC   , ENABLE    );  // Interrupt generated by passage VSYNC signal from active to inactive
    DCMI_ITConfig(  DCMI_IT_LINE    , ENABLE    );  // Interrupt generated after receiving one line of image data
    DCMI_ITConfig(  DCMI_IT_FRAME   , ENABLE    );  // Interrupt generated after receiving one frame of image
//  DCMI_ITConfig(  DCMI_IT_OVF     , ENABLE    );
//  DCMI_ITConfig(  DCMI_IT_ERR     , ENABLE    );
}

Outcomes