cancel
Showing results for 
Search instead for 
Did you mean: 

STM32h735g ADC3 Support in Zephyr

anthonyog
Associate II

I am trying to use pins on ADC3 of an STM32h735g in Zephyr, but I am getting a "Could not read (-22)" error, despite not having issues with ADC1. Is ADC3 supported? If so, can you help me with how to configure it?

This is based on the Zephyr samples/drivers/adc/adc_dt and I am using the stm32h735g Discovery Kit to test this.

I modified boards/stm32h735g_disco.overlay to

/* Copyright (c) 2021 STMicroelectronics
   SPDX-License-Identifier: Apache-2.0 */

 / {
	zephyr,user {
		/* Adding adc3 1 to the existing definition of io-channels */
		io-channels = <&adc1 0>, <&adc3 1>;
	};
};

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

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

/* The following I defined for adc3 */
&adc3 {
	#address-cells = <1>;
	#size-cells = <0>;
        /* Compiler requiess definition for the following on adc3*/
	pinctrl-0 = <&adc3_inp0_pc2_c>;
	pinctrl-names = "default";
	st,adc-clock-source = <SYNC>;
	st,adc-prescaler = <4>;
	status = "okay";

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

However the output is

ADC reading[0]: 
- adc@40022000, channel 0: 2278 = 114 mV
- adc@58026000, channel 1: Could not read (-22)

 

13 REPLIES 13
anthonyog
Associate II

Using a revision Z chip and changing the resolution to "<8>", I am able to read voltage on adc3 channel 0, but I get 0 for any other channel. The channels of interest for me are 1, 2, 0xF, and 0xE. Should those pins be available for the ADC in rev Z?

I am using Zephyr 3.7.0 

gautierg-st
ST Employee

Hello @anthonyog 

Your pinctrl and your channels do not match. If you want to read from adc3_inp0_pc2_c, your channel should be defined like this:

	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <16>;
		status = "okay";
	};

Likewise here:

 / {
	zephyr,user {
		/* Adding adc3 0 to the existing definition of io-channels */
		io-channels = <&adc1 0>, <&adc3 0>;
	};
};

The idea is that in inpX, X is your channel number. Just remember that `channel@` expects an hexadecimal value so for an inp15 for example, you would have

	channel@f {
		reg = <15>;

 

@gautierg-st can you point me to some documentation that agrees with what you are saying?

On ADC1, I always set the pinctrl-0 to the first (0) channel (adc1_inp0_pa0_c) even if I only define/read other (non-zero) channels.

I am interested in reading ADC3 channel 1, however it won't compile if I change pinctrl-0 to adc1_inp1_pc2_c.
The following results in "devicetree error: /soc/adc@58026000: undefined node label 'adc3_inp1_pc2_c'"

&adc3 {
	#address-cells = <1>;
	#size-cells = <0>;
	st,adc-clock-source = <SYNC>;
	st,adc-prescaler = <4>;
	vref-mv = <3300>;
	pinctrl-0 = <&adc3_inp1_pc2_c>;
	pinctrl-names = "default";
	status = "okay";

	channel: channel@1 {
		reg = <0x1>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <16>;
		zephyr,oversampling = <8>;
		status = "okay";
	};
};

 

Unfortunately, there isn't much documentation about it. I can invite you to look at different overlay examples in samples and tests folders.

I confirm that it works without correctly specifying the pinctrl, but that is by chance: pins are by default configured in analog mode, so if untouched otherwise, they are already correctly configured. It is not very clean, but it works.

It is also perfectly normal that your application doesn't compile with adc3_inp1_pc2_c since it doesn't exist. For channel 1 of ADC3 it should be adc3_inp1_pc3_c. Refer to the pinctrl file of your board for the pin definitions.

 

I finally figured out what was wrong in your configuration. You configured a resolution of 16 for ADC3, but for H735, the max resolution of ADC3 is 12. I've tested it on a Nucleo H723ZG and made it work.