AnsweredAssumed Answered

HAL based ADC-DMA makes only one transaction

Question asked by baranov.aleksandr on Jan 26, 2016
Latest reply on Jan 28, 2016 by Amel N
Hello. I try to make a simple non-continuous ADC-DMA transaction of 10 measurements. I get only one sample in my array. I don't  use interrupts, just wait for DMA completion. Could you tell, what I am doing wrong?
Here are my functions (I am sorry if there exist some codebox tag and I did not notice it):

UINT16 Adc1ShortReadBuf[10];

void Get10Samples(void)
{
     DMA_HandleTypeDef     DmaHandle1;

     DmaHandle1.Init.Channel = DMA_CHANNEL_0;
     DmaHandle1.Instance = DMA2_Stream4;
     HAL_DMA_DeInit(&DmaHandle1);
     DmaHandle1.Init.Direction = DMA_PERIPH_TO_MEMORY;
     DmaHandle1.Init.PeriphInc = DMA_PINC_DISABLE;
     DmaHandle1.Init.MemInc = DMA_MINC_ENABLE; 
     DmaHandle1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; 
     DmaHandle1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
     DmaHandle1.Init.Mode = DMA_NORMAL; 
     DmaHandle1.Init.Priority = DMA_PRIORITY_HIGH;
     DmaHandle1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;   
     DmaHandle1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; 
     DmaHandle1.Init.MemBurst = DMA_MBURST_SINGLE;
     DmaHandle1.Init.PeriphBurst = DMA_PBURST_SINGLE;
     HAL_DMA_Init(&DmaHandle1);

     ADC_ChannelConfTypeDef sConfig;
     sConfig.SamplingTime = ADC_SAMPLETIME_112CYCLES;
     sConfig.Rank = 1;
     sConfig.Offset = 0;
     ADC_HandleTypeDef AdcHandle1;
     ADC_MultiModeTypeDef multimode;     
     AdcHandle1.Instance = ADC1;     

     HAL_ADC_DeInit(&AdcHandle1);
     AdcHandle1.Init.ClockPrescaler             = ADC_CLOCKPRESCALER_PCLK_DIV8 ;
     AdcHandle1.Init.Resolution                 = ADC_RESOLUTION12b;
     AdcHandle1.Init.ScanConvMode               = DISABLE;
     AdcHandle1.Init.ContinuousConvMode         = DISABLE; 
     AdcHandle1.Init.DiscontinuousConvMode     = DISABLE;
     AdcHandle1.Init.ExternalTrigConvEdge       = ADC_EXTERNALTRIGCONVEDGE_NONE; 
     AdcHandle1.Init.ExternalTrigConv           = ADC_SOFTWARE_START;
     AdcHandle1.Init.DataAlign                  = ADC_DATAALIGN_RIGHT;
     AdcHandle2.Init.NbrOfDiscConversion        = 0;
     AdcHandle1.Init.NbrOfConversion            = 1;
     AdcHandle1.Init.DMAContinuousRequests      = DISABLE;
     AdcHandle1.Init.EOCSelection               = DISABLE;
     HAL_ADC_Init(&AdcHandle1);

     multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;     
     multimode.Mode = ADC_MODE_INDEPENDENT;
     multimode.DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;
      HAL_ADCEx_MultiModeConfigChannel(&AdcHandle1, &multimode);
     DMA_ClearTCFlag(&DmaHandle1);        

      sConfig.Channel = ADC_CHANNEL_0;
     HAL_ADC_ConfigChannel(&AdcHandle1, &sConfig);
     __HAL_LINKDMA(&AdcHandle1, DMA_Handle, DmaHandle1);     
     ADC_DMA_start(&AdcHandle1, (uint32_t*)Adc1ShortReadBuf, 10);
}

HAL_StatusTypeDef ADC_DMA_start(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
{
 __IO uint32_t counter = 0;
  
   /* Enable ADC DMA mode */
  hadc->Instance->CR2 |= ADC_CR2_DMA;
    /* Set  src and dst addresses and length*/
  HAL_DMA_Start(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
  
    /* Check if ADC peripheral is disabled in order to enable it and wait during 
     Tstab time the ADC's stabilization */
  if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
  {  
    /* Enable the Peripheral */
    __HAL_ADC_ENABLE(hadc);
    
    /* Delay for ADC stabilization time */
    /* Compute number of CPU cycles to wait for */
    counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
    while(counter != 0)
    {
      counter--;
    }
  }
    hadc->Instance->CR2 |= ADC_CR2_SWSTART;
  
  /* Return function status */
  return HAL_OK;
}

Solved it. Conversion has to be continuous. Actually, the post can be deleted.
AB

Outcomes