AnsweredAssumed Answered

STM32F205: DMA2 operation with ADC1 problem

Question asked by geamblu.clement.001 on Jul 29, 2013
Latest reply on Jul 30, 2013 by geamblu.clement.001
Hello, 

I have a problem to work the DMA2 with ADC1 on STM32F205 chip. Problem is the interrupt routine DMA2_Stream0_IRQHandler is never executed despite of configuration is performed. The flag TCIF0 is however raised. I worked 2 days on this problem without to find where is the problem.

Thanks for your help.

Configuration is the following:
void DV_ADC_Init(void)
{
   T_U8    Rank;
   ADC_InitTypeDef       ADC_InitStructure;
   ADC_CommonInitTypeDef ADC_CommonInitStructure;
   NVIC_InitTypeDef      NVIC_InitStructure;
    
   /* Enable ADC1, GPIOA/B/C and DMA2 clocks **********************************/
  RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
    
  /* ADC Common Init **********************************************************/
  ADC_CommonInitStructure.ADC_Mode             = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler        = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);
    
  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution           = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode         = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode   = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv     = 0;
  ADC_InitStructure.ADC_DataAlign            = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion      = NUMBER_OF_ADC_CHANNEL;
  ADC_Init(ADC1, &ADC_InitStructure);
    
   /* Enable ADC interrupt in NVIC ********************************************/
   NVIC_InitStructure.NVIC_IRQChannel                   = ADC_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
   NVIC_Init(&NVIC_InitStructure);  
 
   /* Set regular channel config **********************************************/
   for(Rank=0; Rank<(NUMBER_OF_ADC_CHANNEL); Rank++)
   {
      if(REGULAR == LS_DV_ADC_ChannelMap[Rank].Cfg.u8ChannelType)
      {
        /* Regular channel configuration */
        ADC_RegularChannelConfig(ADC1,
                                 (T_U32)LS_DV_ADC_ChannelMap[Rank].Cfg.u8ChannelId,
                                 Rank + 1,
                                 (T_U32)LS_DV_ADC_ChannelMap[Rank].Cfg.u8SampleTime);
      }
      else
      {
        /* Injected channel configuration */
      }
   }
    
   /* Enable DMA request after last transfer (Single-ADC mode) */
   ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
    
   /* Power on the ADC module / Shall be the last operation because rewrite this
     register will cause a start of conversion ********************************/
   ADC_Cmd(ADC1, ENABLE);
      
   /* Activates DMA transfert *************************************************/
   ADC_DMACmd(ADC1, ENABLE);
    
   /* Configure the DMA2 Stream0 *********************************************/
   DMA_Config();
  
}
 
void DMA_Config(void)
{
  DMA_InitTypeDef  DMA_InitStructure;
  __IO uint32_t    Timeout = TIMEOUT_MAX;
  T_U32   Llu_u32SizeOfTransfer = (T_U32)NUMBER_OF_ADC_CHANNEL;
   
  /* Reset DMA Stream registers (for debug purpose) */
  DMA_DeInit(DMA2_Stream0);
 
  /* Check if the DMA Stream is disabled before enabling it.
     Note that this step is useful when the same Stream is used multiple times:
     enabled, then disabled then re-enabled... In this case, the DMA Stream disable
     will be effective only at the end of the ongoing data transfer and it will
     not be possible to re-configure it before making sure that the Enable bit
     has been cleared by hardware. If the Stream is used only once, this step might
     be bypassed. */
  while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE)
  {
  }
   
  /* Configure DMA Stream */
  DMA_InitStructure.DMA_Channel            = DMA_Channel_0; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)&Gua_DMA_RawValue;
  DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize         = (uint32_t)Llu_u32SizeOfTransfer;
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;        
  DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
     
  /* Enable DMA Stream Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
 
  /* DMA Stream enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);
 
  /* Check if the DMA Stream has been effectively enabled.
     The DMA Stream Enable bit is cleared immediately by hardware if there is an
     error in the configuration parameters and the transfer is no started (ie. when
     wrong FIFO threshold is configured ...) */
  Timeout = TIMEOUT_MAX;
  while ((DMA_GetCmdStatus(DMA2_Stream0) != ENABLE) && (Timeout-- > 0))
  {
  }
    
  /* Check if a timeout condition occurred */
  if (Timeout == 0)
  {
    /* Manage the error: to simplify the code enter an infinite loop */
    while (1)
    {
    }
  }   
}
 
void DMA2_Stream0_IRQHandler(void)
{
  if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0))
  {
   DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
   DV_ADC_DMA_EndOfTransfer();    //--> Perform the data treatment of ADC result.
  }
}
 
int main(void)
{
  DV_ADC_Init();
  while(1);
  //Other tasks is performed but not presented.
}

Outcomes