Skip to main content
Visitor II
September 12, 2025
Question

STM32h735g ADC3 Support in Zephyr

  • September 12, 2025
  • 6 replies
  • 875 views

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)

 

    This topic has been closed for replies.

    6 replies

    ST Employee
    September 15, 2025

    Hello @anthonyog

    I wanted to bring your attention to an important issue with ADC3 when switching channels, this is due to a hardware limitation described in the STM32H735G errata. ADC3 should only be used in continuous conversion mode on a single channel to avoid data corruption.

    Check STM32H72xx/73xx device errata - Errata sheet, section 2.10.7 

    anthonyogAuthor
    Visitor II
    September 16, 2025

    Can you clarify if ADC3 is only supports continuous mode, or is there some other mode that I can use to access multiple ADC3 channels?

    If there is another mode where I can access multiple ADC3 channels, are you familiar enough with Zephyr to know how I could set that up?

    Graduate II
    September 15, 2025

    @Sarra.S wait, what?

    I'm using ADC3 on a H733 (and H735-DK) with continuous conversion on several sequenced channels for 2 years now. And it's working.

    I have checked the errata sheet just now, never did concerning ADC3, but there's not much info.

    What are the exact limitations?

    ST Employee
    September 16, 2025

    Hello @LCE

    Thank you for sharing your experience, it's really important! 

    I have submitted an internal ticket with dedicated team to get further clarification on the ADC3 channel switching behavior and the related erratum (Internal ticket number: Ticket 217552 ) 

    We will keep you informed as soon as we receive feedback

     

     

    Graduate II
    September 16, 2025

    @Sarra.S thanks for taking care of that!

    I use ADC3 in continuous mode and sequencing at least 2 channels (Vref & temperature) with DMA (circular, overwriting, no interrupts) on the Nucleo-H723, the H735-Discovery-Kit, and a custom board with H733 (10 channels or so).

     

    ST Employee
    September 16, 2025

    Hi again @LCE

    This limitation is related only to product revision A, could you confirm your products revision? 

    Graduate II
    September 16, 2025

    STM32CubeProgrammer says it's revision Z.

    Relieved I am... :)

    Thanks!

    And sorry for hijacking this thread!

    ST Employee
    September 16, 2025

    Hello @anthonyog,

    I recommend trying Zephyr 3.7 (LTS) or later, as these versions include improvements for ADC3, ADC4, and ADC5.

    I hope my answer has helped you. When your question is answered, please select this topic as the solution that answered you, as it will help others find that answer faster.

    Thanks for your contribution.

    Dor_RH

    anthonyogAuthor
    Visitor II
    September 16, 2025

    I am currently using Zephyr 3.7.0. Is there a specific 3.7 version where this was improved?

    anthonyogAuthor
    Visitor II
    September 18, 2025

    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 

    ST Employee
    October 16, 2025

    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>;

     

    anthonyogAuthor
    Visitor II
    October 16, 2025

    @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";
    	};
    };

     

    ST Employee
    October 16, 2025

    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.