Confused by differing delcarations of ADCConversionGroup

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
Lithimlin
Posts: 2
Joined: Sat Sep 07, 2019 4:24 pm

Confused by differing delcarations of ADCConversionGroup

Postby Lithimlin » Sat Sep 07, 2019 4:50 pm

I have an STM32F030C and have three analog signals I want to read with the ADC. They are on ADC_IN4, ADC_IN5 and ADC_IN5 (or PA4 to PA6). I don't need any callbacks, want to use a resolution of 12 bit and only need one sample per channel per conversion with no need for a circular buffer.

I looked at the documentation of the hal ADC Driver and some examples online and in the code examples and am confused by how to use the ADCConversionGroup.

In the hal_adc_lld.h it says there are 4 parameters in the struct:

Code: Select all

  105  /**
  106  * @brief   Conversion group configuration structure.
  107  * @details This implementation-dependent structure describes a conversion
  108  *          operation.
  109  * @note    The use of this configuration structure requires knowledge of
  110  *          PLATFORM ADC cell registers interface, please refer to the PLATFORM
  111  *          reference manual for details.
  112  */
  113 typedef struct {
  114   /**
  115    * @brief   Enables the circular buffer mode for the group.
  116    */
  117   bool                      circular;
  118   /**
  119    * @brief   Number of the analog channels belonging to the conversion group.
  120    */
  121   adc_channels_num_t        num_channels;
  122   /**
  123    * @brief   Callback function associated to the group or @p NULL.
  124    */
  125   adccallback_t             end_cb;
  126   /**
  127    * @brief   Error callback or @p NULL.
  128    */
  129   adcerrorcallback_t        error_cb;
  130   /* End of the mandatory fields.*/
  131 } ADCConversionGroup;

In the example for the STM32F0xx ADC, there are 8 parameters in a struct:

Code: Select all

/*
 * ADC conversion group.
 * Mode:        Linear buffer, 8 samples of 1 channel, SW triggered.
 * Channels:    IN10.
 */
static const ADCConversionGroup adcgrpcfg1 = {
  FALSE,
  ADC_GRP1_NUM_CHANNELS,
  NULL,
  adcerrorcallback,
  ADC_CFGR1_CONT | ADC_CFGR1_RES_12BIT,             /* CFGR1 */
  ADC_TR(0, 0),                                     /* TR */
  ADC_SMPR_SMP_1P5,                                 /* SMPR */
  ADC_CHSELR_CHSEL10                                /* CHSELR */
};

/*
 * ADC conversion group.
 * Mode:        Continuous, 16 samples of 8 channels, SW triggered.
 * Channels:    IN10, IN11, Sensor, VRef.
 */
static const ADCConversionGroup adcgrpcfg2 = {
  TRUE,
  ADC_GRP2_NUM_CHANNELS,
  adccallback,
  adcerrorcallback,
  ADC_CFGR1_CONT | ADC_CFGR1_RES_12BIT,             /* CFGR1 */
  ADC_TR(0, 0),                                     /* TR */
  ADC_SMPR_SMP_28P5,                                /* SMPR */
  ADC_CHSELR_CHSEL10 | ADC_CHSELR_CHSEL11 |
  ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17           /* CHSELR */
};

In some forum posts here and guides on the internet I found them used with 11 parameters as well though; for example here:

Code: Select all

static const ADCConversionGroup adcgrpcfg1 = {
   FALSE, // circular buffer mode
   IR_ADC_GRP1_NUM_CHANNELS, // number of the analog channels
   NULL, // callback function
   NULL, // error callback
   0, // CR1
   ADC_CR2_SWSTART, // CR2
   ADC_SMPR1_SMP_AN11(ADC_SAMPLE_3) | ADC_SMPR1_SMP_AN14(ADC_SAMPLE_3) | ADC_SMPR1_SMP_AN15(ADC_SAMPLE_3),// sample times for channel 10-18
   0,// sample times for channel 0-9
   ADC_SQR1_NUM_CH(IR_ADC_GRP1_NUM_CHANNELS),// ADC SQR1 Conversion group sequence 13-16 + sequence length.
   0, // ADC SQR2 Conversion group sequence 7-12
   ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN14) | ADC_SQR3_SQ3_N(ADC_CHANNEL_IN15) // ADC SQR3 Conversion group sequence 1-6
};

Another thing to add here is that it uses a completely different way to address the channels and set the sample rates, etc.

My question now is the following: Which of these is the "correct"/best usage of the ADCConversionGroup and why are there so many differences between the code examples, the documentation and code you find online?
Which is the preferred way of passing the channels, sample rates, etc?
And last but not least: For the above mentioned scenario, what would be the correct ADCConversionGroup?

User avatar
Giovanni
Site Admin
Posts: 12098
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 549 times
Been thanked: 469 times
Contact:

Re: Confused by differing delcarations of ADCConversionGroup

Postby Giovanni » Sat Sep 07, 2019 5:25 pm

Hi,

The STM32 has 4 different types of ADCs (and growing), probably you saw examples for other types. If you don't need callbacks then set those to NULL and use adcConvert() rather than adcStartConversion().

The ADCConversionGroup structure has a variable number of parameters, what you posted is the first group, the standard parameters. For each ADC type there is a second group of fields which depend on the ADC type and are named after ADC registers, the number can change.

The meaning of the (register named) fields changes depending on the ADC type, you should look at the STM32 Reference Manual for the meaning of bits inside. The demo usually include a couple of configuration examples, simple cases.

Conversion structures are not compatible among different ADC types.

Giovanni

Lithimlin
Posts: 2
Joined: Sat Sep 07, 2019 4:24 pm

Re: Confused by differing delcarations of ADCConversionGroup

Postby Lithimlin » Sun Sep 08, 2019 11:08 am

Thanks a lot for the reply. That really cleared up the confusion.


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 1 guest