In order to get ADC working on the H7 used the Giga Overlay as the model. The following changes were made to the arduino_portenta_h7_m7.overlay:
&adc1 {
pinctrl-0 = <&adc1_inp12_pc2
&adc1_inp13_pc3
&adc1_inp18_pa4
&adc1_inp3_pa6
&adc1_inp0_pa0_c
&adc1_inp1_pa1_c>;
pinctrl-names = "default";
st,adc-clock-source = <SYNC>;
st,adc-prescaler = <4>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
channel@c {
reg = <12>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
channel@d {
reg = <13>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
channel@12 {
reg = <18>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
channel@3 {
reg = <3>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
/* PA0_C and PA1_C */
channel@0 {
reg = <0>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
channel@1 {
reg = <1>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
};
&adc3 {
pinctrl-0 = <&adc3_inp0_pc2_c
&adc3_inp1_pc3_c>;
pinctrl-names = "default";
st,adc-clock-source = <SYNC>;
st,adc-prescaler = <4>;
status = "okay";
#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_MAX>;
zephyr,resolution = <16>;
};
channel@1 {
reg = <1>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_MAX>;
zephyr,resolution = <16>;
};
};
.....
adc-pin-gpios = <&gpioz 0 0>, /* analog only */
<&gpioz 1 0>, /* analog only */
<&gpioz 2 0>, /* analog only */
<&gpioz 3 0>, /* analog only */
<&gpioc 2 0>,
<&gpioc 3 0>,
<&gpioa 4 0>,
<&gpioa 6 0>;
...
io-channels = <&adc1 0>,
<&adc1 1>,
<&adc3 0>,
<&adc3 1>,
<&adc1 12>,
<&adc1 13>,
<&adc1 18>,
<&adc1 3>;
};
In the conf file enabled CONFIG_ADC=y
Also added the pure_analog_pins,h and ,cpp files modified to use the H7 Analog Pins A0-A3.
Rung out the analog pins a0-a7 using a analog joystick from adafruit:
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
//pinMode(10, OUTPUT); // PC2
Serial.begin(115200);
while (!Serial && millis() < 4000) {}
}
void loop() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
//digitalWrite(10, !digitalRead(10));
Serial.print(analogRead(A0)); Serial.print("\t");
Serial.print(analogRead(A1)); Serial.print("\t");
Serial.print(analogRead(A2)); Serial.print("\t");
Serial.print(analogRead(A3)); Serial.print("\t");
Serial.print(analogRead(A4)); Serial.print("\t");
Serial.print(analogRead(A5)); Serial.print("\t");
Serial.print(analogRead(A6)); Serial.print("\t");
Serial.print(analogRead(A7)); Serial.println();
delay(250);
if (Serial.available() ) {
while (Serial.read() != -1) {}
//analogRead(A4);
}
}
While A0-A3 and A6/A7 worked as expected found A4 and A5 were non operational. We tried a few things but no luck.
@KurtE instrumented a simple test sketch to print out the pin configs
void print_gpio_regs(const char *name, GPIO_TypeDef *port) {
//printk("GPIO%s(%p) %08X %08X %08x\n", name, port, port->MODER, port->AFR[0], port->AFR[1]);
Serial.print("GPIO");
Serial.print(name);
Serial.print(" ");
Serial.print(port->MODER, HEX);
Serial.print(" ");
Serial.print(port->AFR[0], HEX);
Serial.print(" ");
Serial.println(port->AFR[1], HEX);
}
void show_all_gpio_regs() {
print_gpio_regs("A", (GPIO_TypeDef *)GPIOA_BASE);
print_gpio_regs("B", (GPIO_TypeDef *)GPIOB_BASE);
print_gpio_regs("C", (GPIO_TypeDef *)GPIOC_BASE);
print_gpio_regs("D", (GPIO_TypeDef *)GPIOD_BASE);
print_gpio_regs("E", (GPIO_TypeDef *)GPIOE_BASE);
print_gpio_regs("F", (GPIO_TypeDef *)GPIOF_BASE);
print_gpio_regs("G", (GPIO_TypeDef *)GPIOG_BASE);
print_gpio_regs("H", (GPIO_TypeDef *)GPIOH_BASE);
print_gpio_regs("I", (GPIO_TypeDef *)GPIOI_BASE);
print_gpio_regs("J", (GPIO_TypeDef *)GPIOJ_BASE);
print_gpio_regs("K", (GPIO_TypeDef *)GPIOK_BASE);
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
//pinMode(10, OUTPUT); // PC2
Serial.begin(115200);
while (!Serial && millis() < 4000) {}
show_all_gpio_regs();
}
void loop() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
//digitalWrite(10, !digitalRead(10));
Serial.print(analogRead(A0));
Serial.print("\t");
Serial.print(analogRead(A1));
Serial.print("\t");
Serial.print(analogRead(A2));
Serial.print("\t");
Serial.print(analogRead(A3));
Serial.print("\t");
Serial.print(analogRead(A4));
Serial.print("\t");
Serial.print(analogRead(A5));
Serial.print("\t");
Serial.print(analogRead(A6));
Serial.print("\t");
Serial.print(analogRead(A7));
Serial.println();
delay(250);
if (Serial.available()) {
show_all_gpio_regs();
while (Serial.read() != -1) {}
Serial.println("Paused");
while (Serial.read() == -1) {}
while (Serial.read() != -1) {}
//analogRead(A4);
}
}
and found that pins A4 and A5 modes were set to AF5 which according to the spec

identifed a4 and a5 as MISO and MOSI for SPI2.
@KurtE found there was an open issue [RFC] Add device init/de-init functionality in Zephyr related to this.
So besides some PWM pins being non-operational we now have some analog pins non-operational.
In order to get ADC working on the H7 used the Giga Overlay as the model. The following changes were made to the arduino_portenta_h7_m7.overlay:
In the conf file enabled
CONFIG_ADC=yAlso added the pure_analog_pins,h and ,cpp files modified to use the H7 Analog Pins A0-A3.
Rung out the analog pins a0-a7 using a analog joystick from adafruit:
While A0-A3 and A6/A7 worked as expected found A4 and A5 were non operational. We tried a few things but no luck.
@KurtE instrumented a simple test sketch to print out the pin configs
and found that pins A4 and A5 modes were set to AF5 which according to the spec
identifed a4 and a5 as MISO and MOSI for SPI2.
@KurtE found there was an open issue [RFC] Add device init/de-init functionality in Zephyr related to this.
So besides some PWM pins being non-operational we now have some analog pins non-operational.