Skip to content

SAMD21: Wrong voltage reference set by enum adc_referenceΒ #45443

@lucasssvaz

Description

@lucasssvaz

Hello there!

While working with the SAMD21G18A MCU I noticed a weird behavior on the voltage reference selection for the ADC and haven't found any comment, issue or google result regarding this. After a some troubleshooting I decided to post this here to let anyone who's facing the same problem know.

Describe the bug

In short:

  • ADC_VREF_VDD_1_2 actually uses the 1/1.48 VDDANA reference voltage instead of 1/2 VDDANA
  • ADC_VREF_VDD_1 uses the 1/2 VDDANA reference voltage, instead of being unsupported (as per the MCU datasheet).

This was tested using only the SAMD21G18A MCU, it might work as intended in other sam0 MCUs.
For more information, please see below.

To Reproduce

After getting some weird readings with the SAMD21 ADC, I decided to do some basic tests to find out why this was occurring. The test are based on the internal tests used by twister. These are the basic configurations I used during the test (other than the ADC reference):

#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#define ADC_CHANNEL_ID 0
#define ADC_1ST_CHANNEL_INPUT ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val

The chosen input is the internal pin SCALEDIOVCC, which is the ANAVCC divided by 4 (In our case: 3.3/4 = 0.825V). Five readings were made, using ADC_VREF_INTERNAL, ADC_VREF_VDD_1, ADC_VREF_VDD_1_2, ADC_VREF_VDD_1_3 and ADC_VREF_VDD_1_4 each.

Expected behavior

These are the results, remember that all valid readings should convert to approximately 0.825V:

  • ADC_VREF_INTERNAL (1V theoretically)
    Raw: 3378, converting to volts: 0.830V (Ok)

  • ADC_VREF_VDD_1 (Theoretically not supported the MCU)
    Raw: 2078, converting to volts: 1.670V (WRONG)

  • ADC_VREF_VDD_1_2 (1.65V theoretically)
    Raw: 1540, converting to volts: 0.620V (WRONG)

  • ADC_VREF_VDD_1_3 (Theoretically not supported the MCU)
    Error: unsupported reference. (Ok)

  • ADC_VREF_VDD_1_4 (Theoretically not supported the MCU)
    Error: unsupported reference. (Ok)

Impact

As there is no note about the use of macros defined by enum adc_reference
with the SAMD21 processor and they don't define the voltages as the documentation suggests (see below in Additional context), it's very easy to be stuck in ADC reading problems without delving deep into the Zephyr source to find out why.

New users could easily spend a lot of time troubleshooting this problem when this is only a matter of mislabeling.

Environment:

  • OS: Linux
  • Toolchain: Zephyr SDK
  • Version: zephyr-v3.0.0-1614-g6d7d41420415

Additional context

After following a trail of #include's, I found out that the macros needed, used by adc_sam0_channel_setup() to control the reference voltage, are defined in adc_fixup_sam0.h:

#ifndef ADC_REFCTRL_REFSEL_INTERNAL
#  ifdef ADC_REFCTRL_REFSEL_INTREF
#    define ADC_REFCTRL_REFSEL_INTERNAL ADC_REFCTRL_REFSEL_INTREF
#  else
#    define ADC_REFCTRL_REFSEL_INTERNAL ADC_REFCTRL_REFSEL_INT1V
#  endif
#endif

#ifndef ADC_REFCTRL_REFSEL_VDD_1_2
#  ifdef ADC_REFCTRL_REFSEL_INTVCC0
#    define ADC_REFCTRL_REFSEL_VDD_1_2 ADC_REFCTRL_REFSEL_INTVCC0
#  else
#    define ADC_REFCTRL_REFSEL_VDD_1_2 ADC_REFCTRL_REFSEL_INTVCC1
#  endif
#endif

#ifndef ADC_REFCTRL_REFSEL_VDD_1
#  ifdef ADC_REFCTRL_REFSEL_INTVCC1
#    define ADC_REFCTRL_REFSEL_VDD_1 ADC_REFCTRL_REFSEL_INTVCC1
#  endif
#endif

Following the definitions through the files and consulting the MCU datasheet, the final definitions for each macro is:

  • ADC_REFCTRL_REFSEL_INTERNAL = ADC_REFCTRL_REFSEL_INT1V = 1V (Ok)
  • ADC_REFCTRL_REFSEL_VDD_1_2 = ADC_REFCTRL_REFSEL_INTVCC0 = 1/1.48 VDDANA (WRONG, should be ADC_REFCTRL_REFSEL_INTVCC1)
  • ADC_REFCTRL_REFSEL_VDD_1 = ADC_REFCTRL_REFSEL_INTVCC1 = 1/2 VDDANA (WRONG, should be invalid for the SAMD21).

Also, there is no way (that I'm aware) besides manually changing the register to use the 1/1.48 VDDANA reference voltage using the current enum adc_reference layout.


That's it everyone!
Thanks for the patience and have a nice week!
Lucas Vaz

Metadata

Metadata

Assignees

Labels

area: ADCAnalog-to-Digital Converter (ADC)bugThe issue is a bug, or the PR is fixing a bugplatform: Microchip SAMMicrochip SAM Platform (formerly Atmel SAM)priority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions