AnsweredAssumed Answered

Nucleo L476RG, ADC + DMA, Half vs Complete (HAL)

Question asked by kledtke.steve.002 on Sep 29, 2015

Hallo,

I'm trying to modify an example which uses ADC + DMA, which uses the ST-provided HAL, to my needs.

I want to use a buffer and be notified when each half is completed, so I can transfer the data in a double buffer scheme.
I implemented these functions, which both do get called:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

But - I added variables using HAL_GetTicks (1ms resolution)  to store for each function when it was called. With a samplerate of roughly 8000 Hz and a buffer of 128 samples, i.e. half buffer of 64 samples, the interval should be about 8 milliseconds. But according to my measurement, the half completed and completed callbacks get called in the same millisecond.
What could be wrong?

The sysclock is at 80 MHz.

ADC + DMA config:

    /* ADC Periph interface clock configuration */
    __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK)
  
    AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_ASYNC_DIV16;          /* Asynchronous clock mode, input ADC clock not divided */
    AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;             /* 12-bit resolution for converted data */
    AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
    AdcHandle.Init.ScanConvMode          = DISABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
    AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
    AdcHandle.Init.LowPowerAutoWait      = DISABLE;                       /* Auto-delayed conversion feature disabled */
    AdcHandle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
    AdcHandle.Init.NbrOfConversion       = 1;                             /* Parameter discarded because sequencer is disabled */
    AdcHandle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
    AdcHandle.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
    AdcHandle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
    AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
    AdcHandle.Init.DMAContinuousRequests = ENABLE;                        /* DMA circular mode selected */
    AdcHandle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
    AdcHandle.Init.OversamplingMode      = DISABLE;                       /* No oversampling */
    
//---------------------------------------------------------------------------
    /* ### - 3 - Channel configuration ######################################## */
    sConfig.Channel      = ADCx_CHANNEL;                /* Sampled channel number */
    sConfig.Rank         = ADC_REGULAR_RANK_1;          /* Rank of sampled channel number ADCx_CHANNEL */
    sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;    /* Sampling time (number of clock cycles unit) */
    sConfig.SingleDiff   = ADC_SINGLE_ENDED;            /* Single-ended input channel */
    sConfig.OffsetNumber = ADC_OFFSET_NONE;             /* No offset subtraction */
    sConfig.Offset = 0;
    
//---------------------------------------------------------------------------
  DmaHandle.Instance                 = DMA1_Channel1;
  DmaHandle.Init.Request             = DMA_REQUEST_0;
  DmaHandle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  DmaHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
  DmaHandle.Init.MemInc              = DMA_MINC_ENABLE;
  DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  DmaHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  DmaHandle.Init.Mode                = DMA_CIRCULAR;
  DmaHandle.Init.Priority            = DMA_PRIORITY_MEDIUM;

Outcomes