Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADC Voltage Reference issue with STM32U5 MCU #50895

Closed
vibhor-meshram opened this issue Oct 3, 2022 · 13 comments
Closed

ADC Voltage Reference issue with STM32U5 MCU #50895

vibhor-meshram opened this issue Oct 3, 2022 · 13 comments
Assignees
Labels
area: ADC Analog-to-Digital Converter (ADC) bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: low Low impact/importance bug

Comments

@vibhor-meshram
Copy link

Bug Description:-

I am using nucleo_u575zi_q board and wanted to implement ADC on it. my overlay file looks as follows:-

/ {
zephyr,user {
/* adjust channel number according to pinmux in board.dts */
io-channels = <&adc1 1>;
};
};

&adc1 {
#address-cells = <1>;
#size-cells = <0>;

channel@1 {
    reg = <1>;
    zephyr,gain = "ADC_GAIN_1";
    zephyr,reference = "ADC_REF_INTERNAL";
    zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
    zephyr,resolution = <14>;
};

};

I am trying to test the ADC code with different ADC reference voltages (like VDD, VDD/2, External etc), when I change the reference voltage, it doesn't have any effect on output ADC value. Also while debugging, I found that in adc_stm32.c file the following piece of code that allows only ADC_INTERNAL reference to set.

if (channel_cfg->reference != ADC_REF_INTERNAL) {
LOG_ERR("Invalid channel reference");
return -EINVAL;
}

Expected Behaviour:-
The ADC raw values should saturate when input voltage provided to ADC channel is equal to Vref set in the overlay file. For example if Vref is set to VDD/2, the ADC values should saturate if 1.65 volts is provided to ADC input channel.

Platform:-
Windows 10
Zephyr Version 3.1.0

@vibhor-meshram vibhor-meshram added the bug The issue is a bug, or the PR is fixing a bug label Oct 3, 2022
@erwango erwango added area: ADC Analog-to-Digital Converter (ADC) platform: STM32 ST Micro STM32 priority: low Low impact/importance bug labels Oct 3, 2022
@erwango
Copy link
Member

erwango commented Oct 3, 2022

@vibhor-meshram There were somesignificant changes on ADC during last release. Did you check status on V3.2 ?

@vibhor-meshram
Copy link
Author

@erwango I tried to compile adc example using zephyr 3.2.0 version for nucleo_u575zi_q board. I set the reference to "ADC_REF_VDD_1_2". On compilation I got following error:-
C:/Users/zephyrproject/zephyr/drivers/gpio/gpio_stm32.c:714: undefined reference to LL_PWR_EnableVddIO2'`

I fixed this error by making changes to gpio_stm32.c code. After successful compilation, the serial terminal output was as follows:-

*** Booting Zephyr OS build v3.2.0-rc3-219-g2946a1c0786c *** Could not setup channel #0 (-22) *** Booting Zephyr OS build v3.2.0-rc3-219-g2946a1c0786c *** Could not setup channel #0 (-22)

I tried the above using reference as "ADC_REF_EXTERNAL0" as well and got the same results.

@FRASTM
Copy link
Collaborator

FRASTM commented Oct 4, 2022

With the nucleo_u575zi_q, the samples/drivers/adc gives:

  • adc@42028000, channel 1: 0 = 0 mV when pin A5 on GND
  • adc@42028000, channel 1: 16383 = 3299 mV when pin A5 on 3V3 or 5V
  • adc@42028000, channel 1: 9087 = 1830 mV when pin A5 on 1V8

@erwango
Copy link
Member

erwango commented Oct 4, 2022

@erwango I tried to compile adc example using zephyr 3.2.0 version for nucleo_u575zi_q board. I set the reference to "ADC_REF_VDD_1_2". On compilation I got following error:-

Please run "west update".

@FRASTM
Copy link
Collaborator

FRASTM commented Oct 4, 2022

The error "Could not setup channel #0 (-22)" comes from the adc_stm32.c driver that only accepts the ADC_REF_INTERNAL as reference.
This channel_cfg->reference is an enum value that should be converted to a nb of mv if this has to be compared to the DT_INST_PROP(0, vref_mv) ( expressed in mV).

In that case, the channel must define its vref :

	channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_VDD_1";
		zephyr,vref-mv = <3300>;
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <14>;
	};

@vibhor-meshram
Copy link
Author

@FRASTM Thanks for your resolution. Upon trying the the above solution my observation are as follows:-

  1. After setting reference voltage as "ADC_REF_VDD_1" and adding vref-mv, I still get the adc error - Could not setup channel #0 (-22) . I had to comment the following line of code from adc_stm32.c

if (channel_cfg->reference != ADC_REF_INTERNAL) { LOG_ERR("Invalid channel reference"); return -EINVAL; }

  1. I set reference to "ADC_REF_VDD_1_2" and vref-mv to "1650". It had no effect on the raw values of ADC. The output is as follows when supplied 1.8 V to adc input channel ( 5 ).
    `ADC reading:
  • adc@42028000, channel 1: 9004 = 906 mV
    ADC reading:
  • adc@42028000, channel 1: 8942 = 900 mV
    ADC reading:
  • adc@42028000, channel 1: 8901 = 896 mV
    ADC reading:
  • adc@42028000, channel 1: 8844 = 890 mV`
    Here I see no effect of reference voltage on ADC raw values. Ideally it should have shown 16383 as I am supplying more than reference voltage to the ADC input channel.

@FRASTM
Copy link
Collaborator

FRASTM commented Oct 5, 2022

Yes, the stm32 adc driver is limited to the ADC_REF_INTERNAL mainly, I guess, due to the hw design where the input pin VREF+ is VDDA = 3.3V
When input pin channel 1 is 1.8 V this is ~half the physical Vref voltage (on the hw) raw value is 1/2 ADC full range and calculation gives 1/2 given voltage reference ADC_REF_VDD_1_2.

@vibhor-meshram
Copy link
Author

I removed solder points that connects VDDA to Vref+ and now I am able to use external vref IC to provide reference voltage to my board. This worked without making any changes in the code ( Keeping the reference as ADC_REF_INTERNAL ). I am not sure about the enum provided for voltage reference. Is it only used for calculation purpose (convert raw data to mv) or it does some register configuration to use internal reference?

@FRASTM
Copy link
Collaborator

FRASTM commented Oct 6, 2022

The ADC_REF_INTERNAL is for calculation (giving the voltage for the Full range of ADC)

@vibhor-meshram
Copy link
Author

Is there any way I could configure internal VREFBUF register to use as reference for ADC?

@FRASTM
Copy link
Collaborator

FRASTM commented Oct 6, 2022

There is an internal channel (0) in the ADC1 to measure the V Ref.
It works more or less like Vbat (drivers/sensor/stm32_vbat/stm32_vbat.c) or temp sensor (drivers/sensor/stm32_temp/stm32_temp.c) but is not implemented
Then I guess the measured value should be used as a variable instead of ADC_REF_INTERNAL constant

@vibhor-meshram
Copy link
Author

Thanks @FRASTM for your help. I am closing the issue now.

@GilDev
Copy link

GilDev commented Jul 18, 2024

Any news on this? The driver still does not support using VDD as reference…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ADC Analog-to-Digital Converter (ADC) bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests

4 participants