cancel
Showing results for 
Search instead for 
Did you mean: 

How to handle left-aligned ADC data?

callsignhermit
Associate II

The STM32Cube API provides several helper macros for working with ADC data, including:

  • __HAL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)
  • __HAL_ADC_CONVERT_DATA_RESOLUTION(__DATA__, __ADC_RESOLUTION_CURRENT__, __ADC_RESOLUTION_TARGET__)
  • __HAL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__, __ADC_DATA__, __ADC_RESOLUTION__)
  • __HAL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__, __ADC_RESOLUTION__)

These accept ADC resolution as input, so I guess I don’t have to convert data to a specific resolution (in the case of the third and the fourth macros)

I’m curious if they also account for ADC data alignment, or should the data from the ADC DR be normalized and right-aligned before given to them? (Except perhaps for the first one, since the number of ADC bins is independent of alignment.)

4 REPLIES 4
Ozone
Principal III

I would say, look at the actual implementation of those macros.
Those might differ for separate platforms and ADC implementations.

By the way, I don't use Cube/HAL, nor do I think macros are a good idea in general.

TDK
Super User

Since alignment is not passed to the macro, they have no way to account for it. Adjust for alignment prior to calling these macros.

If you feel a post has answered your question, please click "Accept as Solution".

Checked the implementation—they are simply wrappers to their respecitve counterpart in the LL API. So here is the code in LL.

#define __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)                             \
  (0xFFFUL >> ((__ADC_RESOLUTION__) >> (ADC_CFGR_RES_BITOFFSET_POS - 1UL)))

#define __LL_ADC_CONVERT_DATA_RESOLUTION(__DATA__,\
                                         __ADC_RESOLUTION_CURRENT__,\
                                         __ADC_RESOLUTION_TARGET__)          \
(((__DATA__)                                                                 \
  << ((__ADC_RESOLUTION_CURRENT__) >> (ADC_CFGR_RES_BITOFFSET_POS - 1UL)))   \
 >> ((__ADC_RESOLUTION_TARGET__) >> (ADC_CFGR_RES_BITOFFSET_POS - 1UL))      \
)

#define __LL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\
                                      __ADC_DATA__,\
                                      __ADC_RESOLUTION__)                    \
((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__)                                   \
 / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)                                \
)

#define __LL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__,\
                                         __ADC_RESOLUTION__)                 \
(((uint32_t)(*VREFINT_CAL_ADDR) * VREFINT_CAL_VREF)                          \
 / __LL_ADC_CONVERT_DATA_RESOLUTION((__VREFINT_ADC_DATA__),                  \
                                    (__ADC_RESOLUTION__),                    \
                                    LL_ADC_RESOLUTION_12B)                   \
)

They assume right alignment, though I have trouble understanding how (resolution >> resolution bit offset - 1) translates to shift amount. The description of HAL and LL drivers don’t seem to mention this. However, I’m looking at the STM32G4 edition (UM2570) so it might be different for others.

Hello @callsignhermit 

All helper macro are data default format, without post-processing:

- Default data alignment (right aligned : LSB at position 0).

- No offset

- No gain

If ADC conversion data is post-processed, these helper macro can be used with parameters computation performed by application.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om