From 7cdbae2a5d5693a63ce55c08f39a69f2b4f0689c Mon Sep 17 00:00:00 2001
From: Univa <41708691+Univa@users.noreply.github.com>
Date: Mon, 20 May 2024 21:29:20 -0400
Subject: [PATCH 1/4] add AnyAdcChannel

---
 embassy-stm32/src/adc/f1.rs      | 16 +++++-----
 embassy-stm32/src/adc/f3.rs      | 16 +++++-----
 embassy-stm32/src/adc/f3_v1_1.rs | 24 +++++++-------
 embassy-stm32/src/adc/g4.rs      | 27 ++++++----------
 embassy-stm32/src/adc/mod.rs     | 54 ++++++++++++++++++++++++--------
 embassy-stm32/src/adc/v1.rs      | 22 ++++++-------
 embassy-stm32/src/adc/v2.rs      | 20 ++++++------
 embassy-stm32/src/adc/v3.rs      | 34 ++++++++++----------
 embassy-stm32/src/adc/v4.rs      | 29 ++++++-----------
 embassy-stm32/src/opamp.rs       |  8 ++---
 examples/stm32h7/src/bin/adc.rs  |  2 +-
 11 files changed, 131 insertions(+), 121 deletions(-)

diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 80eaecc14..3822d5032 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
 use embassy_hal_internal::into_ref;
 
 use super::blocking_delay_us;
-use crate::adc::{Adc, AdcPin, Instance, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
 
@@ -32,16 +32,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
-impl<T: Instance> AdcPin<T> for Vref {}
-impl<T: Instance> super::SealedAdcPin<T> for Vref {
+impl<T: Instance> AdcChannel<T> for Vref {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
         17
     }
 }
 
 pub struct Temperature;
-impl<T: Instance> AdcPin<T> for Temperature {}
-impl<T: Instance> super::SealedAdcPin<T> for Temperature {
+impl<T: Instance> AdcChannel<T> for Temperature {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
         16
     }
@@ -135,8 +135,8 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().dr().read().0 as u16
     }
 
-    pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
-        Self::set_channel_sample_time(pin.channel(), self.sample_time);
+    pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        Self::set_channel_sample_time(channel.channel(), self.sample_time);
         T::regs().cr1().modify(|reg| {
             reg.set_scan(false);
             reg.set_discen(false);
@@ -151,7 +151,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         });
 
         // Configure the channel to sample
-        T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel()));
+        T::regs().sqr3().write(|reg| reg.set_sq(0, channel.channel()));
         self.convert().await
     }
 
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index c22a3fe4a..3f076d64b 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
 use embassy_hal_internal::into_ref;
 
 use super::blocking_delay_us;
-use crate::adc::{Adc, AdcPin, Instance, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
@@ -32,8 +32,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
-impl<T: Instance> AdcPin<T> for Vref {}
-impl<T: Instance> super::SealedAdcPin<T> for Vref {
+impl<T: Instance> AdcChannel<T> for Vref {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
         18
     }
@@ -47,8 +47,8 @@ impl Vref {
 }
 
 pub struct Temperature;
-impl<T: Instance> AdcPin<T> for Temperature {}
-impl<T: Instance> super::SealedAdcPin<T> for Temperature {
+impl<T: Instance> AdcChannel<T> for Temperature {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
         16
     }
@@ -154,11 +154,11 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().dr().read().rdata()
     }
 
-    pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
-        Self::set_channel_sample_time(pin.channel(), self.sample_time);
+    pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        Self::set_channel_sample_time(channel.channel(), self.sample_time);
 
         // Configure the channel to sample
-        T::regs().sqr1().write(|w| w.set_sq(0, pin.channel()));
+        T::regs().sqr1().write(|w| w.set_sq(0, channel.channel()));
         self.convert().await
     }
 
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index 672ace04f..106956989 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -7,7 +7,7 @@ use embassy_hal_internal::into_ref;
 use embassy_time::Instant;
 
 use super::Resolution;
-use crate::adc::{Adc, AdcPin, Instance, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
@@ -64,8 +64,8 @@ fn update_vref<T: Instance>(op: i8) {
 }
 
 pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
-impl<T: Instance> AdcPin<T> for Vref<T> {}
-impl<T: Instance> super::SealedAdcPin<T> for Vref<T> {
+impl<T: Instance> AdcChannel<T> for Vref<T> {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vref<T> {
     fn channel(&self) -> u8 {
         17
     }
@@ -123,8 +123,8 @@ impl<T: Instance> Drop for Vref<T> {
 }
 
 pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
-impl<T: Instance> AdcPin<T> for Temperature<T> {}
-impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> {
+impl<T: Instance> AdcChannel<T> for Temperature<T> {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature<T> {
     fn channel(&self) -> u8 {
         16
     }
@@ -271,8 +271,8 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
     }
 
-    pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
-        self.set_sample_sequence(&[pin.channel()]).await;
+    pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        self.set_sample_sequence(&[channel.channel()]).await;
         self.convert().await
     }
 
@@ -283,18 +283,18 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
     }
 
-    pub async fn set_sample_time(&mut self, pin: &mut impl AdcPin<T>, sample_time: SampleTime) {
-        if Self::get_channel_sample_time(pin.channel()) != sample_time {
+    pub async fn set_sample_time(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) {
+        if Self::get_channel_sample_time(channel.channel()) != sample_time {
             self.stop_adc().await;
             unsafe {
-                Self::set_channel_sample_time(pin.channel(), sample_time);
+                Self::set_channel_sample_time(channel.channel(), sample_time);
             }
             self.start_adc().await;
         }
     }
 
-    pub fn get_sample_time(&self, pin: &impl AdcPin<T>) -> SampleTime {
-        Self::get_channel_sample_time(pin.channel())
+    pub fn get_sample_time(&self, channel: &impl AdcChannel<T>) -> SampleTime {
+        Self::get_channel_sample_time(channel.channel())
     }
 
     /// Sets the channel sample time
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 221cc2a40..ce7f5db70 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Difsel, Exten};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,8 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
-impl<T: Instance> InternalChannel<T> for VrefInt {}
-impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
+impl<T: Instance> AdcChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
         VREF_CHANNEL
     }
@@ -42,8 +42,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
+impl<T: Instance> AdcChannel<T> for Temperature {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
         TEMP_CHANNEL
     }
@@ -51,8 +51,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
-impl<T: Instance> InternalChannel<T> for Vbat {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
+impl<T: Instance> AdcChannel<T> for Vbat {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
         VBAT_CHANNEL
     }
@@ -258,18 +258,9 @@ impl<'d, T: Instance> Adc<'d, T> {
     }
 
     /// Read an ADC pin.
-    pub fn read<P>(&mut self, pin: &mut P) -> u16
-    where
-        P: AdcPin<T>,
-        P: crate::gpio::Pin,
-    {
-        pin.set_as_analog();
+    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        channel.setup();
 
-        self.read_channel(pin.channel())
-    }
-
-    /// Read an ADC internal channel.
-    pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
         self.read_channel(channel.channel())
     }
 
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index c753d046c..6a3d0f44c 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -15,6 +15,8 @@
 #[cfg_attr(adc_g4, path = "g4.rs")]
 mod _version;
 
+use core::marker::PhantomData;
+
 #[allow(unused)]
 #[cfg(not(adc_f3_v2))]
 pub use _version::*;
@@ -58,15 +60,12 @@ trait SealedInstance {
     fn state() -> &'static State;
 }
 
-pub(crate) trait SealedAdcPin<T: Instance> {
-    #[cfg(any(adc_v1, adc_l0, adc_v2))]
-    fn set_as_analog(&mut self) {}
+pub(crate) trait SealedAdcPin<T: Instance> {}
 
-    #[allow(unused)]
-    fn channel(&self) -> u8;
-}
+pub(crate) trait SealedAdcChannel<T> {
+    #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
+    fn setup(&mut self) {}
 
-trait SealedInternalChannel<T> {
     #[allow(unused)]
     fn channel(&self) -> u8;
 }
@@ -126,10 +125,37 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::R
 
 /// ADC pin.
 #[allow(private_bounds)]
-pub trait AdcPin<T: Instance>: SealedAdcPin<T> {}
-/// ADC internal channel.
+pub trait AdcPin<T: Instance>: AdcChannel<T> + SealedAdcPin<T> {}
+/// ADC channel.
 #[allow(private_bounds)]
-pub trait InternalChannel<T>: SealedInternalChannel<T> {}
+pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
+    #[allow(unused_mut)]
+    fn degrade_adc(mut self) -> AnyAdcChannel<T> {
+        #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
+        self.setup();
+
+        AnyAdcChannel {
+            channel: self.channel(),
+            _phantom: PhantomData,
+        }
+    }
+}
+
+/// A type-erased channel for a given ADC instance.
+///
+/// This is useful in scenarios where you need the ADC channels to have the same type, such as
+/// storing them in an array.
+pub struct AnyAdcChannel<T> {
+    channel: u8,
+    _phantom: PhantomData<T>,
+}
+
+impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
+impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
+    fn channel(&self) -> u8 {
+        self.channel
+    }
+}
 
 foreach_adc!(
     ($inst:ident, $common_inst:ident, $clock:ident) => {
@@ -159,10 +185,12 @@ foreach_adc!(
 macro_rules! impl_adc_pin {
     ($inst:ident, $pin:ident, $ch:expr) => {
         impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
+        impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {}
 
-        impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {
-            #[cfg(any(adc_v1, adc_l0, adc_v2))]
-            fn set_as_analog(&mut self) {
+        impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
+        impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
+            #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
+            fn setup(&mut self) {
                 <Self as crate::gpio::SealedPin>::set_as_analog(self);
             }
 
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index f17522076..090790c39 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -7,7 +7,7 @@ use embassy_hal_internal::into_ref;
 use stm32_metapac::adc::vals::Ckmode;
 
 use super::blocking_delay_us;
-use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::peripherals::ADC1;
 use crate::{interrupt, Peripheral};
@@ -36,26 +36,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 pub struct Vbat;
 
 #[cfg(not(adc_l0))]
-impl AdcPin<ADC1> for Vbat {}
+impl AdcChannel<ADC1> for Vbat {}
 
 #[cfg(not(adc_l0))]
-impl super::SealedAdcPin<ADC1> for Vbat {
+impl super::SealedAdcChannel<ADC1> for Vbat {
     fn channel(&self) -> u8 {
         18
     }
 }
 
 pub struct Vref;
-impl AdcPin<ADC1> for Vref {}
-impl super::SealedAdcPin<ADC1> for Vref {
+impl AdcChannel<ADC1> for Vref {}
+impl super::SealedAdcChannel<ADC1> for Vref {
     fn channel(&self) -> u8 {
         17
     }
 }
 
 pub struct Temperature;
-impl AdcPin<ADC1> for Temperature {}
-impl super::SealedAdcPin<ADC1> for Temperature {
+impl AdcChannel<ADC1> for Temperature {}
+impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
         16
     }
@@ -155,12 +155,12 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode));
     }
 
-    pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
-        let channel = pin.channel();
-        pin.set_as_analog();
+    pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        let ch_num = channel.channel();
+        channel.setup();
 
         // A.7.5 Single conversion sequence code example - Software trigger
-        T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
+        T::regs().chselr().write(|reg| reg.set_chselx(ch_num as usize, true));
 
         self.convert().await
     }
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 7771cf768..033108195 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,7 +1,7 @@
 use embassy_hal_internal::into_ref;
 
 use super::blocking_delay_us;
-use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::peripherals::ADC1;
 use crate::time::Hertz;
 use crate::Peripheral;
@@ -12,8 +12,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3300;
 
 pub struct VrefInt;
-impl AdcPin<ADC1> for VrefInt {}
-impl super::SealedAdcPin<ADC1> for VrefInt {
+impl AdcChannel<ADC1> for VrefInt {}
+impl super::SealedAdcChannel<ADC1> for VrefInt {
     fn channel(&self) -> u8 {
         17
     }
@@ -27,8 +27,8 @@ impl VrefInt {
 }
 
 pub struct Temperature;
-impl AdcPin<ADC1> for Temperature {}
-impl super::SealedAdcPin<ADC1> for Temperature {
+impl AdcChannel<ADC1> for Temperature {}
+impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
         cfg_if::cfg_if! {
             if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
@@ -48,8 +48,8 @@ impl Temperature {
 }
 
 pub struct Vbat;
-impl AdcPin<ADC1> for Vbat {}
-impl super::SealedAdcPin<ADC1> for Vbat {
+impl AdcChannel<ADC1> for Vbat {}
+impl super::SealedAdcChannel<ADC1> for Vbat {
     fn channel(&self) -> u8 {
         18
     }
@@ -175,11 +175,11 @@ where
         T::regs().dr().read().0 as u16
     }
 
-    pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
-        pin.set_as_analog();
+    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        channel.setup();
 
         // Configure ADC
-        let channel = pin.channel();
+        let channel = channel.channel();
 
         // Select channel
         T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index dc418297e..be857f4dd 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -2,7 +2,7 @@ use cfg_if::cfg_if;
 use embassy_hal_internal::into_ref;
 
 use super::blocking_delay_us;
-use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
+use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::Peripheral;
 
 /// Default VREF voltage used for sample conversion to millivolts.
@@ -11,8 +11,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3000;
 
 pub struct VrefInt;
-impl<T: Instance> AdcPin<T> for VrefInt {}
-impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
+impl<T: Instance> AdcChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
         cfg_if! {
             if #[cfg(adc_g0)] {
@@ -30,8 +30,8 @@ impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
 }
 
 pub struct Temperature;
-impl<T: Instance> AdcPin<T> for Temperature {}
-impl<T: Instance> super::SealedAdcPin<T> for Temperature {
+impl<T: Instance> AdcChannel<T> for Temperature {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
         cfg_if! {
             if #[cfg(adc_g0)] {
@@ -49,8 +49,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Temperature {
 }
 
 pub struct Vbat;
-impl<T: Instance> AdcPin<T> for Vbat {}
-impl<T: Instance> super::SealedAdcPin<T> for Vbat {
+impl<T: Instance> AdcChannel<T> for Vbat {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
         cfg_if! {
             if #[cfg(adc_g0)] {
@@ -70,8 +70,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Vbat {
 cfg_if! {
     if #[cfg(adc_h5)] {
         pub struct VddCore;
-        impl<T: Instance> AdcPin<T> for VddCore {}
-        impl<T: Instance> super::SealedAdcPin<T> for VddCore {
+        impl<T: Instance> AdcChannel<T> for VddCore {}
+        impl<T: Instance> super::SealedAdcChannel<T> for VddCore {
             fn channel(&self) -> u8 {
                 6
             }
@@ -82,8 +82,8 @@ cfg_if! {
 cfg_if! {
     if #[cfg(adc_u0)] {
         pub struct DacOut;
-        impl<T: Instance> AdcPin<T> for DacOut {}
-        impl<T: Instance> super::SealedAdcPin<T> for DacOut {
+        impl<T: Instance> AdcChannel<T> for DacOut {}
+        impl<T: Instance> super::SealedAdcChannel<T> for DacOut {
             fn channel(&self) -> u8 {
                 19
             }
@@ -220,7 +220,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().dr().read().0 as u16
     }
 
-    pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
+    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
         // Make sure bits are off
         while T::regs().cr().read().addis() {
             // spin
@@ -241,18 +241,18 @@ impl<'d, T: Instance> Adc<'d, T> {
         // RM0492, RM0481, etc.
         // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected."
         #[cfg(adc_h5)]
-        if pin.channel() == 0 {
+        if channel.channel() == 0 {
             T::regs().or().modify(|reg| reg.set_op0(true));
         }
 
         // Configure channel
-        Self::set_channel_sample_time(pin.channel(), self.sample_time);
+        Self::set_channel_sample_time(channel.channel(), self.sample_time);
 
         // Select channel
         #[cfg(not(any(adc_g0, adc_u0)))]
-        T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
+        T::regs().sqr1().write(|reg| reg.set_sq(0, channel.channel()));
         #[cfg(any(adc_g0, adc_u0))]
-        T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel()));
+        T::regs().chselr().write(|reg| reg.set_chsel(1 << channel.channel()));
 
         // Some models are affected by an erratum:
         // If we perform conversions slower than 1 kHz, the first read ADC value can be
@@ -270,7 +270,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         // RM0492, RM0481, etc.
         // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected."
         #[cfg(adc_h5)]
-        if pin.channel() == 0 {
+        if channel.channel() == 0 {
             T::regs().or().modify(|reg| reg.set_op0(false));
         }
 
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index ca87b41ee..f564114c2 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,8 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
-impl<T: Instance> InternalChannel<T> for VrefInt {}
-impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
+impl<T: Instance> AdcChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
         VREF_CHANNEL
     }
@@ -42,8 +42,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
+impl<T: Instance> AdcChannel<T> for Temperature {}
+impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
         TEMP_CHANNEL
     }
@@ -51,8 +51,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
-impl<T: Instance> InternalChannel<T> for Vbat {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
+impl<T: Instance> AdcChannel<T> for Vbat {}
+impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
         VBAT_CHANNEL
     }
@@ -271,19 +271,10 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().dr().read().0 as u16
     }
 
-    /// Read an ADC pin.
-    pub fn read<P>(&mut self, pin: &mut P) -> u16
-    where
-        P: AdcPin<T>,
-        P: crate::gpio::Pin,
-    {
-        pin.set_as_analog();
+    /// Read an ADC channel.
+    pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
+        channel.setup();
 
-        self.read_channel(pin.channel())
-    }
-
-    /// Read an ADC internal channel.
-    pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
         self.read_channel(channel.channel())
     }
 
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index a3b4352c0..487902959 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -198,7 +198,7 @@ macro_rules! impl_opamp_external_output {
     ($inst:ident, $adc:ident, $ch:expr) => {
         foreach_adc!(
             ($adc, $common_inst:ident, $adc_clock:ident) => {
-                impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
+                impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc>
                     for OpAmpOutput<'d, crate::peripherals::$inst>
                 {
                     fn channel(&self) -> u8 {
@@ -206,7 +206,7 @@ macro_rules! impl_opamp_external_output {
                     }
                 }
 
-                impl<'d> crate::adc::AdcPin<crate::peripherals::$adc>
+                impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc>
                     for OpAmpOutput<'d, crate::peripherals::$inst>
                 {
                 }
@@ -244,7 +244,7 @@ macro_rules! impl_opamp_internal_output {
     ($inst:ident, $adc:ident, $ch:expr) => {
         foreach_adc!(
             ($adc, $common_inst:ident, $adc_clock:ident) => {
-                impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
+                impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc>
                     for OpAmpInternalOutput<'d, crate::peripherals::$inst>
                 {
                     fn channel(&self) -> u8 {
@@ -252,7 +252,7 @@ macro_rules! impl_opamp_internal_output {
                     }
                 }
 
-                impl<'d> crate::adc::AdcPin<crate::peripherals::$adc>
+                impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc>
                     for OpAmpInternalOutput<'d, crate::peripherals::$inst>
                 {
                 }
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index 0009103d1..e9a857a74 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -51,7 +51,7 @@ async fn main(_spawner: Spawner) {
     let mut vrefint_channel = adc.enable_vrefint();
 
     loop {
-        let vrefint = adc.read_internal(&mut vrefint_channel);
+        let vrefint = adc.read(&mut vrefint_channel);
         info!("vrefint: {}", vrefint);
         let measured = adc.read(&mut p.PC0);
         info!("measured: {}", measured);

From ddbb6c8c31a558b82f8e2a13ddb364e371ec5776 Mon Sep 17 00:00:00 2001
From: Univa <41708691+Univa@users.noreply.github.com>
Date: Tue, 21 May 2024 19:03:14 -0400
Subject: [PATCH 2/4] add back InternalChannel and implement it where its
 missing

---
 embassy-stm32/src/adc/f1.rs      |  6 +++++-
 embassy-stm32/src/adc/f3.rs      |  6 +++++-
 embassy-stm32/src/adc/f3_v1_1.rs |  6 +++++-
 embassy-stm32/src/adc/g4.rs      |  8 +++++++-
 embassy-stm32/src/adc/mod.rs     |  5 ++++-
 embassy-stm32/src/adc/v1.rs      | 12 +++++++++++-
 embassy-stm32/src/adc/v2.rs      |  8 +++++++-
 embassy-stm32/src/adc/v3.rs      | 12 +++++++++++-
 embassy-stm32/src/adc/v4.rs      |  8 +++++++-
 9 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 3822d5032..cc7ffdea8 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
-use super::blocking_delay_us;
+use super::{blocking_delay_us, InternalChannel};
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
@@ -32,6 +32,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
+impl<T: Instance> InternalChannel<T> for Vref {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vref {}
 impl<T: Instance> AdcChannel<T> for Vref {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
@@ -40,6 +42,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for Vref {
 }
 
 pub struct Temperature;
+impl<T: Instance> InternalChannel<T> for Temperature {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 3f076d64b..363ddbe3a 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
-use super::blocking_delay_us;
+use super::{blocking_delay_us, InternalChannel};
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
@@ -32,6 +32,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
+impl<T: Instance> InternalChannel<T> for Vref {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vref {}
 impl<T: Instance> AdcChannel<T> for Vref {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
@@ -47,6 +49,8 @@ impl Vref {
 }
 
 pub struct Temperature;
+impl<T: Instance> InternalChannel<T> for Temperature {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index 106956989..73bfe4876 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -6,7 +6,7 @@ use embassy_futures::yield_now;
 use embassy_hal_internal::into_ref;
 use embassy_time::Instant;
 
-use super::Resolution;
+use super::{InternalChannel, Resolution};
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
@@ -64,6 +64,8 @@ fn update_vref<T: Instance>(op: i8) {
 }
 
 pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
+impl<T: Instance> InternalChannel<T> for Vref<T> {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vref<T> {}
 impl<T: Instance> AdcChannel<T> for Vref<T> {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref<T> {
     fn channel(&self) -> u8 {
@@ -123,6 +125,8 @@ impl<T: Instance> Drop for Vref<T> {
 }
 
 pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
+impl<T: Instance> InternalChannel<T> for Temperature<T> {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature<T> {}
 impl<T: Instance> AdcChannel<T> for Temperature<T> {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature<T> {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index ce7f5db70..f9751bd92 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Difsel, Exten};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, InternalChannel, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,6 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
+impl<T: Instance> InternalChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -42,6 +44,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
+impl<T: Instance> InternalChannel<T> for Temperature {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -51,6 +55,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
+impl<T: Instance> InternalChannel<T> for Vbat {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 6a3d0f44c..3e62b6f3b 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -61,7 +61,7 @@ trait SealedInstance {
 }
 
 pub(crate) trait SealedAdcPin<T: Instance> {}
-
+pub(crate) trait SealedInternalChannel<T> {}
 pub(crate) trait SealedAdcChannel<T> {
     #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
     fn setup(&mut self) {}
@@ -126,6 +126,9 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::R
 /// ADC pin.
 #[allow(private_bounds)]
 pub trait AdcPin<T: Instance>: AdcChannel<T> + SealedAdcPin<T> {}
+/// ADC internal channel.
+#[allow(private_bounds)]
+pub trait InternalChannel<T>: SealedInternalChannel<T> {}
 /// ADC channel.
 #[allow(private_bounds)]
 pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 090790c39..abd58952d 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -6,7 +6,7 @@ use embassy_hal_internal::into_ref;
 #[cfg(adc_l0)]
 use stm32_metapac::adc::vals::Ckmode;
 
-use super::blocking_delay_us;
+use super::{blocking_delay_us, InternalChannel};
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::peripherals::ADC1;
@@ -35,6 +35,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 #[cfg(not(adc_l0))]
 pub struct Vbat;
 
+#[cfg(not(adc_l0))]
+impl InternalChannel<ADC1> for Vbat {}
+
+#[cfg(not(adc_l0))]
+impl super::SealedInternalChannel<ADC1> for Vbat {}
+
 #[cfg(not(adc_l0))]
 impl AdcChannel<ADC1> for Vbat {}
 
@@ -46,6 +52,8 @@ impl super::SealedAdcChannel<ADC1> for Vbat {
 }
 
 pub struct Vref;
+impl InternalChannel<ADC1> for Vref {}
+impl super::SealedInternalChannel<ADC1> for Vref {}
 impl AdcChannel<ADC1> for Vref {}
 impl super::SealedAdcChannel<ADC1> for Vref {
     fn channel(&self) -> u8 {
@@ -54,6 +62,8 @@ impl super::SealedAdcChannel<ADC1> for Vref {
 }
 
 pub struct Temperature;
+impl InternalChannel<ADC1> for Temperature {}
+impl super::SealedInternalChannel<ADC1> for Temperature {}
 impl AdcChannel<ADC1> for Temperature {}
 impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 033108195..f7b791903 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,6 +1,6 @@
 use embassy_hal_internal::into_ref;
 
-use super::blocking_delay_us;
+use super::{blocking_delay_us, InternalChannel};
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::peripherals::ADC1;
 use crate::time::Hertz;
@@ -12,6 +12,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3300;
 
 pub struct VrefInt;
+impl InternalChannel<ADC1> for VrefInt {}
+impl super::SealedInternalChannel<ADC1> for VrefInt {}
 impl AdcChannel<ADC1> for VrefInt {}
 impl super::SealedAdcChannel<ADC1> for VrefInt {
     fn channel(&self) -> u8 {
@@ -27,6 +29,8 @@ impl VrefInt {
 }
 
 pub struct Temperature;
+impl InternalChannel<ADC1> for Temperature {}
+impl super::SealedInternalChannel<ADC1> for Temperature {}
 impl AdcChannel<ADC1> for Temperature {}
 impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
@@ -48,6 +52,8 @@ impl Temperature {
 }
 
 pub struct Vbat;
+impl InternalChannel<ADC1> for Vbat {}
+impl super::SealedInternalChannel<ADC1> for Vbat {}
 impl AdcChannel<ADC1> for Vbat {}
 impl super::SealedAdcChannel<ADC1> for Vbat {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index be857f4dd..36e0e3df3 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,7 +1,7 @@
 use cfg_if::cfg_if;
 use embassy_hal_internal::into_ref;
 
-use super::blocking_delay_us;
+use super::{blocking_delay_us, InternalChannel};
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::Peripheral;
 
@@ -11,6 +11,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3000;
 
 pub struct VrefInt;
+impl<T: Instance> InternalChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -30,6 +32,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 }
 
 pub struct Temperature;
+impl<T: Instance> InternalChannel<T> for Temperature {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -49,6 +53,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 }
 
 pub struct Vbat;
+impl<T: Instance> InternalChannel<T> for Vbat {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
@@ -70,6 +76,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
 cfg_if! {
     if #[cfg(adc_h5)] {
         pub struct VddCore;
+        impl<T: Instance> InternalChannel<T> for VddCore {}
+        impl<T: Instance> super::SealedInternalChannel<T> for VddCore {}
         impl<T: Instance> AdcChannel<T> for VddCore {}
         impl<T: Instance> super::SealedAdcChannel<T> for VddCore {
             fn channel(&self) -> u8 {
@@ -82,6 +90,8 @@ cfg_if! {
 cfg_if! {
     if #[cfg(adc_u0)] {
         pub struct DacOut;
+        impl<T: Instance> InternalChannel<T> for DacOut {}
+        impl<T: Instance> super::SealedInternalChannel<T> for DacOut {}
         impl<T: Instance> AdcChannel<T> for DacOut {}
         impl<T: Instance> super::SealedAdcChannel<T> for DacOut {
             fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index f564114c2..bf3a55797 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, InternalChannel, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,6 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
+impl<T: Instance> InternalChannel<T> for VrefInt {}
+impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -42,6 +44,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
+impl<T: Instance> InternalChannel<T> for Temperature {}
+impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -51,6 +55,8 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
+impl<T: Instance> InternalChannel<T> for Vbat {}
+impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {

From 41e11d86b9d2014c2d2b66dd55522a7dc77ac3d8 Mon Sep 17 00:00:00 2001
From: Univa <41708691+Univa@users.noreply.github.com>
Date: Tue, 21 May 2024 19:08:01 -0400
Subject: [PATCH 3/4] make AdcChannel required for InternalChannel

---
 embassy-stm32/src/adc/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 3e62b6f3b..9a15b4434 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -128,7 +128,7 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::R
 pub trait AdcPin<T: Instance>: AdcChannel<T> + SealedAdcPin<T> {}
 /// ADC internal channel.
 #[allow(private_bounds)]
-pub trait InternalChannel<T>: SealedInternalChannel<T> {}
+pub trait InternalChannel<T>: AdcChannel<T> + SealedInternalChannel<T> {}
 /// ADC channel.
 #[allow(private_bounds)]
 pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {

From 4e9206efb8fa49ad2ea0b5420db1d0e4cc22b6cc Mon Sep 17 00:00:00 2001
From: Univa <41708691+Univa@users.noreply.github.com>
Date: Wed, 22 May 2024 19:00:48 -0400
Subject: [PATCH 4/4] remove InternalChannel and AdcPin

---
 embassy-stm32/src/adc/f1.rs      |  6 +-----
 embassy-stm32/src/adc/f3.rs      |  6 +-----
 embassy-stm32/src/adc/f3_v1_1.rs |  6 +-----
 embassy-stm32/src/adc/g4.rs      |  8 +-------
 embassy-stm32/src/adc/mod.rs     | 11 -----------
 embassy-stm32/src/adc/v1.rs      | 12 +-----------
 embassy-stm32/src/adc/v2.rs      |  8 +-------
 embassy-stm32/src/adc/v3.rs      | 12 +-----------
 embassy-stm32/src/adc/v4.rs      |  8 +-------
 9 files changed, 8 insertions(+), 69 deletions(-)

diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index cc7ffdea8..3822d5032 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
-use super::{blocking_delay_us, InternalChannel};
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
@@ -32,8 +32,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
-impl<T: Instance> InternalChannel<T> for Vref {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vref {}
 impl<T: Instance> AdcChannel<T> for Vref {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
@@ -42,8 +40,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for Vref {
 }
 
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 363ddbe3a..3f076d64b 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
-use super::{blocking_delay_us, InternalChannel};
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
@@ -32,8 +32,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 }
 
 pub struct Vref;
-impl<T: Instance> InternalChannel<T> for Vref {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vref {}
 impl<T: Instance> AdcChannel<T> for Vref {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref {
     fn channel(&self) -> u8 {
@@ -49,8 +47,6 @@ impl Vref {
 }
 
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index 73bfe4876..106956989 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -6,7 +6,7 @@ use embassy_futures::yield_now;
 use embassy_hal_internal::into_ref;
 use embassy_time::Instant;
 
-use super::{InternalChannel, Resolution};
+use super::Resolution;
 use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
@@ -64,8 +64,6 @@ fn update_vref<T: Instance>(op: i8) {
 }
 
 pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
-impl<T: Instance> InternalChannel<T> for Vref<T> {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vref<T> {}
 impl<T: Instance> AdcChannel<T> for Vref<T> {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vref<T> {
     fn channel(&self) -> u8 {
@@ -125,8 +123,6 @@ impl<T: Instance> Drop for Vref<T> {
 }
 
 pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
-impl<T: Instance> InternalChannel<T> for Temperature<T> {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature<T> {}
 impl<T: Instance> AdcChannel<T> for Temperature<T> {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature<T> {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index f9751bd92..ce7f5db70 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Difsel, Exten};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcChannel, Instance, InternalChannel, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,8 +33,6 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
-impl<T: Instance> InternalChannel<T> for VrefInt {}
-impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -44,8 +42,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -55,8 +51,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
-impl<T: Instance> InternalChannel<T> for Vbat {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 9a15b4434..040ee9c53 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -60,8 +60,6 @@ trait SealedInstance {
     fn state() -> &'static State;
 }
 
-pub(crate) trait SealedAdcPin<T: Instance> {}
-pub(crate) trait SealedInternalChannel<T> {}
 pub(crate) trait SealedAdcChannel<T> {
     #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
     fn setup(&mut self) {}
@@ -123,12 +121,6 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::R
     type Interrupt: crate::interrupt::typelevel::Interrupt;
 }
 
-/// ADC pin.
-#[allow(private_bounds)]
-pub trait AdcPin<T: Instance>: AdcChannel<T> + SealedAdcPin<T> {}
-/// ADC internal channel.
-#[allow(private_bounds)]
-pub trait InternalChannel<T>: AdcChannel<T> + SealedInternalChannel<T> {}
 /// ADC channel.
 #[allow(private_bounds)]
 pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
@@ -187,9 +179,6 @@ foreach_adc!(
 
 macro_rules! impl_adc_pin {
     ($inst:ident, $pin:ident, $ch:expr) => {
-        impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
-        impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {}
-
         impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
         impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
             #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index abd58952d..090790c39 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -6,7 +6,7 @@ use embassy_hal_internal::into_ref;
 #[cfg(adc_l0)]
 use stm32_metapac::adc::vals::Ckmode;
 
-use super::{blocking_delay_us, InternalChannel};
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::peripherals::ADC1;
@@ -35,12 +35,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
 #[cfg(not(adc_l0))]
 pub struct Vbat;
 
-#[cfg(not(adc_l0))]
-impl InternalChannel<ADC1> for Vbat {}
-
-#[cfg(not(adc_l0))]
-impl super::SealedInternalChannel<ADC1> for Vbat {}
-
 #[cfg(not(adc_l0))]
 impl AdcChannel<ADC1> for Vbat {}
 
@@ -52,8 +46,6 @@ impl super::SealedAdcChannel<ADC1> for Vbat {
 }
 
 pub struct Vref;
-impl InternalChannel<ADC1> for Vref {}
-impl super::SealedInternalChannel<ADC1> for Vref {}
 impl AdcChannel<ADC1> for Vref {}
 impl super::SealedAdcChannel<ADC1> for Vref {
     fn channel(&self) -> u8 {
@@ -62,8 +54,6 @@ impl super::SealedAdcChannel<ADC1> for Vref {
 }
 
 pub struct Temperature;
-impl InternalChannel<ADC1> for Temperature {}
-impl super::SealedInternalChannel<ADC1> for Temperature {}
 impl AdcChannel<ADC1> for Temperature {}
 impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index f7b791903..033108195 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,6 +1,6 @@
 use embassy_hal_internal::into_ref;
 
-use super::{blocking_delay_us, InternalChannel};
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::peripherals::ADC1;
 use crate::time::Hertz;
@@ -12,8 +12,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3300;
 
 pub struct VrefInt;
-impl InternalChannel<ADC1> for VrefInt {}
-impl super::SealedInternalChannel<ADC1> for VrefInt {}
 impl AdcChannel<ADC1> for VrefInt {}
 impl super::SealedAdcChannel<ADC1> for VrefInt {
     fn channel(&self) -> u8 {
@@ -29,8 +27,6 @@ impl VrefInt {
 }
 
 pub struct Temperature;
-impl InternalChannel<ADC1> for Temperature {}
-impl super::SealedInternalChannel<ADC1> for Temperature {}
 impl AdcChannel<ADC1> for Temperature {}
 impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
@@ -52,8 +48,6 @@ impl Temperature {
 }
 
 pub struct Vbat;
-impl InternalChannel<ADC1> for Vbat {}
-impl super::SealedInternalChannel<ADC1> for Vbat {}
 impl AdcChannel<ADC1> for Vbat {}
 impl super::SealedAdcChannel<ADC1> for Vbat {
     fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 36e0e3df3..be857f4dd 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,7 +1,7 @@
 use cfg_if::cfg_if;
 use embassy_hal_internal::into_ref;
 
-use super::{blocking_delay_us, InternalChannel};
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::Peripheral;
 
@@ -11,8 +11,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 pub const VREF_CALIB_MV: u32 = 3000;
 
 pub struct VrefInt;
-impl<T: Instance> InternalChannel<T> for VrefInt {}
-impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -32,8 +30,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 }
 
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -53,8 +49,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 }
 
 pub struct Vbat;
-impl<T: Instance> InternalChannel<T> for Vbat {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {
@@ -76,8 +70,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
 cfg_if! {
     if #[cfg(adc_h5)] {
         pub struct VddCore;
-        impl<T: Instance> InternalChannel<T> for VddCore {}
-        impl<T: Instance> super::SealedInternalChannel<T> for VddCore {}
         impl<T: Instance> AdcChannel<T> for VddCore {}
         impl<T: Instance> super::SealedAdcChannel<T> for VddCore {
             fn channel(&self) -> u8 {
@@ -90,8 +82,6 @@ cfg_if! {
 cfg_if! {
     if #[cfg(adc_u0)] {
         pub struct DacOut;
-        impl<T: Instance> InternalChannel<T> for DacOut {}
-        impl<T: Instance> super::SealedInternalChannel<T> for DacOut {}
         impl<T: Instance> AdcChannel<T> for DacOut {}
         impl<T: Instance> super::SealedAdcChannel<T> for DacOut {
             fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index bf3a55797..f564114c2 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
 use pac::adccommon::vals::Presc;
 
-use super::{blocking_delay_us, Adc, AdcChannel, Instance, InternalChannel, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -33,8 +33,6 @@ const VBAT_CHANNEL: u8 = 17;
 // NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
 /// Internal voltage reference channel.
 pub struct VrefInt;
-impl<T: Instance> InternalChannel<T> for VrefInt {}
-impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {}
 impl<T: Instance> AdcChannel<T> for VrefInt {}
 impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
     fn channel(&self) -> u8 {
@@ -44,8 +42,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
 
 /// Internal temperature channel.
 pub struct Temperature;
-impl<T: Instance> InternalChannel<T> for Temperature {}
-impl<T: Instance> super::SealedInternalChannel<T> for Temperature {}
 impl<T: Instance> AdcChannel<T> for Temperature {}
 impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
     fn channel(&self) -> u8 {
@@ -55,8 +51,6 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
 
 /// Internal battery voltage channel.
 pub struct Vbat;
-impl<T: Instance> InternalChannel<T> for Vbat {}
-impl<T: Instance> super::SealedInternalChannel<T> for Vbat {}
 impl<T: Instance> AdcChannel<T> for Vbat {}
 impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
     fn channel(&self) -> u8 {