Extended ADC driver for sync start by EXTTRIG

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
joewa
Posts: 22
Joined: Tue May 13, 2014 10:40 pm

Extended ADC driver for sync start by EXTTRIG

Post by joewa »

Hello Giovanni,

Finally, I succeeded implementing what I wanted: Starting the ADC in continuous circular mode by a timer. Doing so, all ADC values which are read now, are EXACTLY matching the timer values of the timer which triggered the ADC conversion. I.e. the timer becomes the absolute time reference for the ADC values.

To achieve that I had to modify the function adc_lld_start_conversion (in my case in hal/ports/STM32/STM32F1xx/adc_lld.c)

Code: Select all

void adc_lld_start_conversion(ADCDriver *adcp) {
  uint32_t mode, cr2;
  const ADCConversionGroup *grpp = adcp->grpp;

  /* DMA setup.*/
  mode = adcp->dmamode;
  if (grpp->circular) {
    mode |= STM32_DMA_CR_CIRC;
    if (adcp->depth > 1) {
      /* If circular buffer depth > 1, then the half transfer interrupt
         is enabled in order to allow streaming processing.*/
      mode |= STM32_DMA_CR_HTIE;
    }
  }
  dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
  dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
                                            (uint32_t)adcp->depth);
  dmaStreamSetMode(adcp->dmastp, mode);
  dmaStreamEnable(adcp->dmastp);

  /* ADC setup.*/
  adcp->adc->CR1   = grpp->cr1 | ADC_CR1_SCAN;
  cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
  if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG)) == 0) // activate continuous mode if EXTRIG is NOT selected
    cr2 |= ADC_CR2_CONT;
  adcp->adc->CR2   = grpp->cr2 | cr2;
  adcp->adc->SMPR1 = grpp->smpr1;
  adcp->adc->SMPR2 = grpp->smpr2;
  adcp->adc->SQR1  = grpp->sqr1;
  adcp->adc->SQR2  = grpp->sqr2;
  adcp->adc->SQR3  = grpp->sqr3;

  /* ADC start by writing ADC_CR2_ADON a second time - if EXTTRIG and CONT is NOT selected */
  if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG | ADC_CR2_CONT)) == 0) adcp->adc->CR2   = cr2;
}

The only thing I added is the condition in the last line. This prevents ADON being set the second time because this would immediately start the conversion although the EXTRIG flag is set.

Here is the ADC configuration:

Code: Select all

static const ADCConversionGroup adc_commutate_group = {
      TRUE, // circular mode
      ADC_COMMUTATE_NUM_CHANNELS,
      adc_commutate_cb,
      adc_commutate_err_cb,
      0, // ADC_CR1
      ADC_CR2_EXTTRIG | ADC_CR2_CONT, // ADC_CR2: use ext event | select TIM1_CC1 event | Cont-mode (start once, always run)
      0, // ADC_SMPR1
      ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5), // ADC_SMPR2
      ADC_SQR1_NUM_CH(ADC_COMMUTATE_NUM_CHANNELS), // ADC_SQR1
      0, // ADC_SQR2
      // ADC regular sequence register 3 (ADC_SQR3): U_VOLTAGE (see schematic)
      ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)// ADC_SQR3
};

So, we have to set ADC_CR2 to ADC_CR2_EXTTRIG | ADC_CR2_CONT plus the respective trigger source...

Do you think you could integrate this in all the ADC drivers?

It would be definately helpful, demonstrating the new feature in an example program then.

Cheers
Jörg
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Extended ADC driver for sync start by EXTTRIG

Post by Giovanni »

Hi,

Sure, it would be interesting to create a small application using the GPT driver for timings and the ADC driver for acquisitions.

Giovanni
Post Reply