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

stm32h7: adc: sequence of more than 8 channels does not work #79909

Closed
nono313 opened this issue Oct 16, 2024 · 4 comments · Fixed by #82955
Closed

stm32h7: adc: sequence of more than 8 channels does not work #79909

nono313 opened this issue Oct 16, 2024 · 4 comments · Fixed by #82955
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

@nono313
Copy link
Contributor

nono313 commented Oct 16, 2024

Describe the bug
Starting an adc scan sequence of more than 8 channels does not work on STM32H7

Tested on nucleo_h723zg with adc_sequence sample

To Reproduce

  1. create an overlay for the stm32h723 in the board folder of the adc_sequence sample (see below)
  2. update the prj.conf to add logs and reduce extra samples with
CONFIG_LOG=y
CONFIG_ADC_LOG_LEVEL_DBG=y
CONFIG_SEQUENCE_SAMPLES=1
  1. go to samples/drivers/adc/adc_sequence and build the project with west build -b nucleo_h723zg . -p
  2. flash to nucleo board with west flash

Example of overlay I used:


/ {
	zephyr,user {
	};

	aliases {
		adc0 = &adc1;
	};
};

&gpiod {
    status = "okay";
};

&gpioc {
    status = "okay";
};

&gpiob {
    status = "okay";
};

&clk_lsi {
	status = "okay";
};

&clk_hsi48 {
	status = "okay";
};

&clk_hsi {
	status = "okay";
	hsi-div = <1>;
};

&clk_hse {
	clock-frequency = <DT_FREQ_M(25)>;
	status = "disabled";
};

&pll {
	div-m = <4>;
	mul-n = <34>;
	div-p = <1>;
	div-q = <68>;	/* DIVQ at 68 to get 8MHz FDCAN clock */
	div-r = <2>;
	clocks = <&clk_hsi>;
	status = "okay";
};

&pll2 {
	status = "okay";
	clocks = <&clk_hsi>;
	div-m = <4>;
	mul-n = <12>;
	div-p = <4>;
	div-q = <2>;
	div-r = <2>;
};

&rcc {
	clock-frequency = <DT_FREQ_M(544)>;
	clocks = <&pll>;
	d1cpre = <1>;
	hpre = <2>;    /* HCLK: 272   MHz */
	d1ppre = <2>;  /* APB1: 136 MHz */
	d2ppre1 = <2>; /* APB2: 136 MHz */
	d2ppre2 = <2>; /* APB3: 136 MHz */
	d3ppre = <2>;  /* APB4: 136 MHz */
};


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

	pinctrl-0 = <&adc1_inp11_pc1 &adc1_inp10_pc0 &adc1_inp17_pa1 &adc1_inp16_pa0
		&adc1_inp15_pa3 &adc1_inp14_pa2 &adc1_inp19_pa5 &adc1_inp18_pa4 
		&adc1_inp7_pa7 &adc1_inp3_pa6 &adc1_inp8_pc5 &adc1_inp4_pc4
		&adc1_inp5_pb1 &adc1_inp9_pb0 &adc1_inp6_pf12 &adc1_inp2_pf11>;
	pinctrl-names = "default";
	st,adc-clock-source = <ASYNC>;	/* PLL2_P @48MHz */
	st,adc-prescaler = <1>;
	st,adc-sequencer = <FULLY_CONFIGURABLE>;
	vref-mv = <2000>;

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

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

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

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

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

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

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

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

	channel@a {
	 	reg = <10>;
	 	zephyr,gain = "ADC_GAIN_1";
	 	zephyr,reference = "ADC_REF_INTERNAL";
	 	zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
	 	zephyr,vref-mv = <2000>;
	 	zephyr,resolution = <16>;
	 };
};

Expected behavior
Sequence should start and complete in a loop and analog values should be displayed

Impact
Sequence need to be split to be at most 8 channels long

Logs and console output
Here is the log I have with 9 channels:

[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_start_conversion: Starting conversion
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.

When I only set 8 channels (commenting out one channel), I get this logs: in a loop:

[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
[00:00:00.000,000] <dbg> adc_stm32: adc_stm32_channel_setup: Channel setup succeeded!
- adc@40022000, channel 2, 1 sequence samples:
- - 1015 = 0mV
- adc@40022000, channel 3, 1 sequence samples:
- - 751 = 0mV
- adc@40022000, channel 4, 1 sequence samples:
- - 8 = 0mV
- adc@40022000, channel 5, 1 sequence samples:
- - 480 = 0mV
- adc@40022000, channel 6, 1 sequence samples:
- - 1002 = 0mV
- adc@40022000, channel 7, 1 sequence samples:
- - 9 = 0mV
- adc@40022000, channel 8, 1 sequence samples:
- - 13 = 0mV
- adc@40022000, channel 9, 1 sequence samples:
- - 10 = 0mV
ADC sequence reading [1]:
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_start_conversion: Starting conversion
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
[00:00:01.002,000] <dbg> adc_stm32: adc_stm32_isr: adc@40022000 ISR triggered.
- adc@40022000, channel 2, 1 sequence samples:
- - 656 = 0mV
- adc@40022000, channel 3, 1 sequence samples:
- - 436 = 0mV
- adc@40022000, channel 4, 1 sequence samples:
- - 11 = 0mV
- adc@40022000, channel 5, 1 sequence samples:
- - 350 = 0mV
- adc@40022000, channel 6, 1 sequence samples:
- - 534 = 0mV
- adc@40022000, channel 7, 1 sequence samples:
- - 14 = 0mV
- adc@40022000, channel 8, 1 sequence samples:
- - 9 = 0mV
- adc@40022000, channel 9, 1 sequence samples:
- - 11 = 0mV

Environment (please complete the following information):

  • OS: Linux (Ubuntu 24.04)
  • Toolchain: Zephyr sdk 0.16.5
  • Release 3.7.0

Additional context

@nono313 nono313 added the bug The issue is a bug, or the PR is fixing a bug label Oct 16, 2024
@nordicjm nordicjm added the platform: STM32 ST Micro STM32 label Oct 16, 2024
@nordicjm nordicjm added the area: ADC Analog-to-Digital Converter (ADC) label Oct 16, 2024
@erwango erwango assigned gautierg-st and unassigned erwango Oct 16, 2024
@erwango erwango added the priority: low Low impact/importance bug label Oct 16, 2024
@gautierg-st
Copy link
Contributor

Hello,
I think you could have an overrun error (this can be checked in the ADC status register). Could you try increasing the st,adc-prescaler and/or the zephyr,acquisition-time?

@nono313
Copy link
Contributor Author

nono313 commented Oct 16, 2024

Hello, I think you could have an overrun error (this can be checked in the ADC status register). Could you try increasing the st,adc-prescaler and/or the zephyr,acquisition-time?

That was it, thanks. I do indeed see OVR flag set. As the OVR flag is not handled in the interrupt there is no information for the user that an overrun occurred. Should I close this issue and should OVR be handled in the driver anyway ?

@gautierg-st
Copy link
Contributor

OVR is very tricky to handle, if it happens, more likely than not it will happen again, since timings will probably be the same the next time a measurement is made. The best way to treat OVR is to not have it happen at all by configuring the timings accordingly (mainly clock source, prescaler and sampling time).
But maybe a log stating that an overrun occurred and that timings need to be adjusted would be in order.

@erwango
Copy link
Member

erwango commented Nov 6, 2024

@gautierg-st Could you open a PR to provide a message when OVR is seen ?

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

Successfully merging a pull request may close this issue.

4 participants