aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/adc/f1.rs16
-rw-r--r--embassy-stm32/src/adc/f3.rs16
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs24
-rw-r--r--embassy-stm32/src/adc/g4.rs27
-rw-r--r--embassy-stm32/src/adc/mod.rs56
-rw-r--r--embassy-stm32/src/adc/v1.rs22
-rw-r--r--embassy-stm32/src/adc/v2.rs20
-rw-r--r--embassy-stm32/src/adc/v3.rs34
-rw-r--r--embassy-stm32/src/adc/v4.rs29
-rw-r--r--embassy-stm32/src/opamp.rs8
-rw-r--r--examples/stm32h7/src/bin/adc.rs2
11 files changed, 128 insertions, 126 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;
5use embassy_hal_internal::into_ref; 5use embassy_hal_internal::into_ref;
6 6
7use super::blocking_delay_us; 7use super::blocking_delay_us;
8use crate::adc::{Adc, AdcPin, Instance, SampleTime}; 8use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::time::Hertz; 9use crate::time::Hertz;
10use crate::{interrupt, Peripheral}; 10use crate::{interrupt, Peripheral};
11 11
@@ -32,16 +32,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
32} 32}
33 33
34pub struct Vref; 34pub struct Vref;
35impl<T: Instance> AdcPin<T> for Vref {} 35impl<T: Instance> AdcChannel<T> for Vref {}
36impl<T: Instance> super::SealedAdcPin<T> for Vref { 36impl<T: Instance> super::SealedAdcChannel<T> for Vref {
37 fn channel(&self) -> u8 { 37 fn channel(&self) -> u8 {
38 17 38 17
39 } 39 }
40} 40}
41 41
42pub struct Temperature; 42pub struct Temperature;
43impl<T: Instance> AdcPin<T> for Temperature {} 43impl<T: Instance> AdcChannel<T> for Temperature {}
44impl<T: Instance> super::SealedAdcPin<T> for Temperature { 44impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
45 fn channel(&self) -> u8 { 45 fn channel(&self) -> u8 {
46 16 46 16
47 } 47 }
@@ -135,8 +135,8 @@ impl<'d, T: Instance> Adc<'d, T> {
135 T::regs().dr().read().0 as u16 135 T::regs().dr().read().0 as u16
136 } 136 }
137 137
138 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 138 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
139 Self::set_channel_sample_time(pin.channel(), self.sample_time); 139 Self::set_channel_sample_time(channel.channel(), self.sample_time);
140 T::regs().cr1().modify(|reg| { 140 T::regs().cr1().modify(|reg| {
141 reg.set_scan(false); 141 reg.set_scan(false);
142 reg.set_discen(false); 142 reg.set_discen(false);
@@ -151,7 +151,7 @@ impl<'d, T: Instance> Adc<'d, T> {
151 }); 151 });
152 152
153 // Configure the channel to sample 153 // Configure the channel to sample
154 T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel())); 154 T::regs().sqr3().write(|reg| reg.set_sq(0, channel.channel()));
155 self.convert().await 155 self.convert().await
156 } 156 }
157 157
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;
5use embassy_hal_internal::into_ref; 5use embassy_hal_internal::into_ref;
6 6
7use super::blocking_delay_us; 7use super::blocking_delay_us;
8use crate::adc::{Adc, AdcPin, Instance, SampleTime}; 8use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
10use crate::time::Hertz; 10use crate::time::Hertz;
11use crate::{interrupt, Peripheral}; 11use crate::{interrupt, Peripheral};
@@ -32,8 +32,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
32} 32}
33 33
34pub struct Vref; 34pub struct Vref;
35impl<T: Instance> AdcPin<T> for Vref {} 35impl<T: Instance> AdcChannel<T> for Vref {}
36impl<T: Instance> super::SealedAdcPin<T> for Vref { 36impl<T: Instance> super::SealedAdcChannel<T> for Vref {
37 fn channel(&self) -> u8 { 37 fn channel(&self) -> u8 {
38 18 38 18
39 } 39 }
@@ -47,8 +47,8 @@ impl Vref {
47} 47}
48 48
49pub struct Temperature; 49pub struct Temperature;
50impl<T: Instance> AdcPin<T> for Temperature {} 50impl<T: Instance> AdcChannel<T> for Temperature {}
51impl<T: Instance> super::SealedAdcPin<T> for Temperature { 51impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
52 fn channel(&self) -> u8 { 52 fn channel(&self) -> u8 {
53 16 53 16
54 } 54 }
@@ -154,11 +154,11 @@ impl<'d, T: Instance> Adc<'d, T> {
154 T::regs().dr().read().rdata() 154 T::regs().dr().read().rdata()
155 } 155 }
156 156
157 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 157 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
158 Self::set_channel_sample_time(pin.channel(), self.sample_time); 158 Self::set_channel_sample_time(channel.channel(), self.sample_time);
159 159
160 // Configure the channel to sample 160 // Configure the channel to sample
161 T::regs().sqr1().write(|w| w.set_sq(0, pin.channel())); 161 T::regs().sqr1().write(|w| w.set_sq(0, channel.channel()));
162 self.convert().await 162 self.convert().await
163 } 163 }
164 164
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;
7use embassy_time::Instant; 7use embassy_time::Instant;
8 8
9use super::Resolution; 9use super::Resolution;
10use crate::adc::{Adc, AdcPin, Instance, SampleTime}; 10use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::time::Hertz; 12use crate::time::Hertz;
13use crate::{interrupt, Peripheral}; 13use crate::{interrupt, Peripheral};
@@ -64,8 +64,8 @@ fn update_vref<T: Instance>(op: i8) {
64} 64}
65 65
66pub struct Vref<T: Instance>(core::marker::PhantomData<T>); 66pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
67impl<T: Instance> AdcPin<T> for Vref<T> {} 67impl<T: Instance> AdcChannel<T> for Vref<T> {}
68impl<T: Instance> super::SealedAdcPin<T> for Vref<T> { 68impl<T: Instance> super::SealedAdcChannel<T> for Vref<T> {
69 fn channel(&self) -> u8 { 69 fn channel(&self) -> u8 {
70 17 70 17
71 } 71 }
@@ -123,8 +123,8 @@ impl<T: Instance> Drop for Vref<T> {
123} 123}
124 124
125pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); 125pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
126impl<T: Instance> AdcPin<T> for Temperature<T> {} 126impl<T: Instance> AdcChannel<T> for Temperature<T> {}
127impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> { 127impl<T: Instance> super::SealedAdcChannel<T> for Temperature<T> {
128 fn channel(&self) -> u8 { 128 fn channel(&self) -> u8 {
129 16 129 16
130 } 130 }
@@ -271,8 +271,8 @@ impl<'d, T: Instance> Adc<'d, T> {
271 } 271 }
272 } 272 }
273 273
274 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 274 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
275 self.set_sample_sequence(&[pin.channel()]).await; 275 self.set_sample_sequence(&[channel.channel()]).await;
276 self.convert().await 276 self.convert().await
277 } 277 }
278 278
@@ -283,18 +283,18 @@ impl<'d, T: Instance> Adc<'d, T> {
283 } 283 }
284 } 284 }
285 285
286 pub async fn set_sample_time(&mut self, pin: &mut impl AdcPin<T>, sample_time: SampleTime) { 286 pub async fn set_sample_time(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) {
287 if Self::get_channel_sample_time(pin.channel()) != sample_time { 287 if Self::get_channel_sample_time(channel.channel()) != sample_time {
288 self.stop_adc().await; 288 self.stop_adc().await;
289 unsafe { 289 unsafe {
290 Self::set_channel_sample_time(pin.channel(), sample_time); 290 Self::set_channel_sample_time(channel.channel(), sample_time);
291 } 291 }
292 self.start_adc().await; 292 self.start_adc().await;
293 } 293 }
294 } 294 }
295 295
296 pub fn get_sample_time(&self, pin: &impl AdcPin<T>) -> SampleTime { 296 pub fn get_sample_time(&self, channel: &impl AdcChannel<T>) -> SampleTime {
297 Self::get_channel_sample_time(pin.channel()) 297 Self::get_channel_sample_time(channel.channel())
298 } 298 }
299 299
300 /// Sets the channel sample time 300 /// 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 @@
2use pac::adc::vals::{Adcaldif, Difsel, Exten}; 2use pac::adc::vals::{Adcaldif, Difsel, Exten};
3use pac::adccommon::vals::Presc; 3use pac::adccommon::vals::Presc;
4 4
5use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; 5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::{pac, Peripheral}; 7use crate::{pac, Peripheral};
8 8
@@ -33,8 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
33// 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 33// 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
34/// Internal voltage reference channel. 34/// Internal voltage reference channel.
35pub struct VrefInt; 35pub struct VrefInt;
36impl<T: Instance> InternalChannel<T> for VrefInt {} 36impl<T: Instance> AdcChannel<T> for VrefInt {}
37impl<T: Instance> super::SealedInternalChannel<T> for VrefInt { 37impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
38 fn channel(&self) -> u8 { 38 fn channel(&self) -> u8 {
39 VREF_CHANNEL 39 VREF_CHANNEL
40 } 40 }
@@ -42,8 +42,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
42 42
43/// Internal temperature channel. 43/// Internal temperature channel.
44pub struct Temperature; 44pub struct Temperature;
45impl<T: Instance> InternalChannel<T> for Temperature {} 45impl<T: Instance> AdcChannel<T> for Temperature {}
46impl<T: Instance> super::SealedInternalChannel<T> for Temperature { 46impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
47 fn channel(&self) -> u8 { 47 fn channel(&self) -> u8 {
48 TEMP_CHANNEL 48 TEMP_CHANNEL
49 } 49 }
@@ -51,8 +51,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
51 51
52/// Internal battery voltage channel. 52/// Internal battery voltage channel.
53pub struct Vbat; 53pub struct Vbat;
54impl<T: Instance> InternalChannel<T> for Vbat {} 54impl<T: Instance> AdcChannel<T> for Vbat {}
55impl<T: Instance> super::SealedInternalChannel<T> for Vbat { 55impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
56 fn channel(&self) -> u8 { 56 fn channel(&self) -> u8 {
57 VBAT_CHANNEL 57 VBAT_CHANNEL
58 } 58 }
@@ -258,18 +258,9 @@ impl<'d, T: Instance> Adc<'d, T> {
258 } 258 }
259 259
260 /// Read an ADC pin. 260 /// Read an ADC pin.
261 pub fn read<P>(&mut self, pin: &mut P) -> u16 261 pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
262 where 262 channel.setup();
263 P: AdcPin<T>,
264 P: crate::gpio::Pin,
265 {
266 pin.set_as_analog();
267
268 self.read_channel(pin.channel())
269 }
270 263
271 /// Read an ADC internal channel.
272 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
273 self.read_channel(channel.channel()) 264 self.read_channel(channel.channel())
274 } 265 }
275 266
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index c753d046c..040ee9c53 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -15,6 +15,8 @@
15#[cfg_attr(adc_g4, path = "g4.rs")] 15#[cfg_attr(adc_g4, path = "g4.rs")]
16mod _version; 16mod _version;
17 17
18use core::marker::PhantomData;
19
18#[allow(unused)] 20#[allow(unused)]
19#[cfg(not(adc_f3_v2))] 21#[cfg(not(adc_f3_v2))]
20pub use _version::*; 22pub use _version::*;
@@ -58,15 +60,10 @@ trait SealedInstance {
58 fn state() -> &'static State; 60 fn state() -> &'static State;
59} 61}
60 62
61pub(crate) trait SealedAdcPin<T: Instance> { 63pub(crate) trait SealedAdcChannel<T> {
62 #[cfg(any(adc_v1, adc_l0, adc_v2))] 64 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
63 fn set_as_analog(&mut self) {} 65 fn setup(&mut self) {}
64
65 #[allow(unused)]
66 fn channel(&self) -> u8;
67}
68 66
69trait SealedInternalChannel<T> {
70 #[allow(unused)] 67 #[allow(unused)]
71 fn channel(&self) -> u8; 68 fn channel(&self) -> u8;
72} 69}
@@ -124,12 +121,36 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::R
124 type Interrupt: crate::interrupt::typelevel::Interrupt; 121 type Interrupt: crate::interrupt::typelevel::Interrupt;
125} 122}
126 123
127/// ADC pin. 124/// ADC channel.
128#[allow(private_bounds)]
129pub trait AdcPin<T: Instance>: SealedAdcPin<T> {}
130/// ADC internal channel.
131#[allow(private_bounds)] 125#[allow(private_bounds)]
132pub trait InternalChannel<T>: SealedInternalChannel<T> {} 126pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
127 #[allow(unused_mut)]
128 fn degrade_adc(mut self) -> AnyAdcChannel<T> {
129 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
130 self.setup();
131
132 AnyAdcChannel {
133 channel: self.channel(),
134 _phantom: PhantomData,
135 }
136 }
137}
138
139/// A type-erased channel for a given ADC instance.
140///
141/// This is useful in scenarios where you need the ADC channels to have the same type, such as
142/// storing them in an array.
143pub struct AnyAdcChannel<T> {
144 channel: u8,
145 _phantom: PhantomData<T>,
146}
147
148impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
149impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
150 fn channel(&self) -> u8 {
151 self.channel
152 }
153}
133 154
134foreach_adc!( 155foreach_adc!(
135 ($inst:ident, $common_inst:ident, $clock:ident) => { 156 ($inst:ident, $common_inst:ident, $clock:ident) => {
@@ -158,11 +179,10 @@ foreach_adc!(
158 179
159macro_rules! impl_adc_pin { 180macro_rules! impl_adc_pin {
160 ($inst:ident, $pin:ident, $ch:expr) => { 181 ($inst:ident, $pin:ident, $ch:expr) => {
161 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} 182 impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
162 183 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
163 impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin { 184 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4))]
164 #[cfg(any(adc_v1, adc_l0, adc_v2))] 185 fn setup(&mut self) {
165 fn set_as_analog(&mut self) {
166 <Self as crate::gpio::SealedPin>::set_as_analog(self); 186 <Self as crate::gpio::SealedPin>::set_as_analog(self);
167 } 187 }
168 188
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;
7use stm32_metapac::adc::vals::Ckmode; 7use stm32_metapac::adc::vals::Ckmode;
8 8
9use super::blocking_delay_us; 9use super::blocking_delay_us;
10use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 10use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::peripherals::ADC1; 12use crate::peripherals::ADC1;
13use crate::{interrupt, Peripheral}; 13use crate::{interrupt, Peripheral};
@@ -36,26 +36,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
36pub struct Vbat; 36pub struct Vbat;
37 37
38#[cfg(not(adc_l0))] 38#[cfg(not(adc_l0))]
39impl AdcPin<ADC1> for Vbat {} 39impl AdcChannel<ADC1> for Vbat {}
40 40
41#[cfg(not(adc_l0))] 41#[cfg(not(adc_l0))]
42impl super::SealedAdcPin<ADC1> for Vbat { 42impl super::SealedAdcChannel<ADC1> for Vbat {
43 fn channel(&self) -> u8 { 43 fn channel(&self) -> u8 {
44 18 44 18
45 } 45 }
46} 46}
47 47
48pub struct Vref; 48pub struct Vref;
49impl AdcPin<ADC1> for Vref {} 49impl AdcChannel<ADC1> for Vref {}
50impl super::SealedAdcPin<ADC1> for Vref { 50impl super::SealedAdcChannel<ADC1> for Vref {
51 fn channel(&self) -> u8 { 51 fn channel(&self) -> u8 {
52 17 52 17
53 } 53 }
54} 54}
55 55
56pub struct Temperature; 56pub struct Temperature;
57impl AdcPin<ADC1> for Temperature {} 57impl AdcChannel<ADC1> for Temperature {}
58impl super::SealedAdcPin<ADC1> for Temperature { 58impl super::SealedAdcChannel<ADC1> for Temperature {
59 fn channel(&self) -> u8 { 59 fn channel(&self) -> u8 {
60 16 60 16
61 } 61 }
@@ -155,12 +155,12 @@ impl<'d, T: Instance> Adc<'d, T> {
155 T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode)); 155 T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode));
156 } 156 }
157 157
158 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 158 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
159 let channel = pin.channel(); 159 let ch_num = channel.channel();
160 pin.set_as_analog(); 160 channel.setup();
161 161
162 // A.7.5 Single conversion sequence code example - Software trigger 162 // A.7.5 Single conversion sequence code example - Software trigger
163 T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true)); 163 T::regs().chselr().write(|reg| reg.set_chselx(ch_num as usize, true));
164 164
165 self.convert().await 165 self.convert().await
166 } 166 }
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 @@
1use embassy_hal_internal::into_ref; 1use embassy_hal_internal::into_ref;
2 2
3use super::blocking_delay_us; 3use super::blocking_delay_us;
4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
5use crate::peripherals::ADC1; 5use crate::peripherals::ADC1;
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::Peripheral; 7use crate::Peripheral;
@@ -12,8 +12,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
12pub const VREF_CALIB_MV: u32 = 3300; 12pub const VREF_CALIB_MV: u32 = 3300;
13 13
14pub struct VrefInt; 14pub struct VrefInt;
15impl AdcPin<ADC1> for VrefInt {} 15impl AdcChannel<ADC1> for VrefInt {}
16impl super::SealedAdcPin<ADC1> for VrefInt { 16impl super::SealedAdcChannel<ADC1> for VrefInt {
17 fn channel(&self) -> u8 { 17 fn channel(&self) -> u8 {
18 17 18 17
19 } 19 }
@@ -27,8 +27,8 @@ impl VrefInt {
27} 27}
28 28
29pub struct Temperature; 29pub struct Temperature;
30impl AdcPin<ADC1> for Temperature {} 30impl AdcChannel<ADC1> for Temperature {}
31impl super::SealedAdcPin<ADC1> for Temperature { 31impl super::SealedAdcChannel<ADC1> for Temperature {
32 fn channel(&self) -> u8 { 32 fn channel(&self) -> u8 {
33 cfg_if::cfg_if! { 33 cfg_if::cfg_if! {
34 if #[cfg(any(stm32f2, stm32f40, stm32f41))] { 34 if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
@@ -48,8 +48,8 @@ impl Temperature {
48} 48}
49 49
50pub struct Vbat; 50pub struct Vbat;
51impl AdcPin<ADC1> for Vbat {} 51impl AdcChannel<ADC1> for Vbat {}
52impl super::SealedAdcPin<ADC1> for Vbat { 52impl super::SealedAdcChannel<ADC1> for Vbat {
53 fn channel(&self) -> u8 { 53 fn channel(&self) -> u8 {
54 18 54 18
55 } 55 }
@@ -175,11 +175,11 @@ where
175 T::regs().dr().read().0 as u16 175 T::regs().dr().read().0 as u16
176 } 176 }
177 177
178 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 178 pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
179 pin.set_as_analog(); 179 channel.setup();
180 180
181 // Configure ADC 181 // Configure ADC
182 let channel = pin.channel(); 182 let channel = channel.channel();
183 183
184 // Select channel 184 // Select channel
185 T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); 185 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;
2use embassy_hal_internal::into_ref; 2use embassy_hal_internal::into_ref;
3 3
4use super::blocking_delay_us; 4use super::blocking_delay_us;
5use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 5use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::Peripheral; 6use crate::Peripheral;
7 7
8/// Default VREF voltage used for sample conversion to millivolts. 8/// Default VREF voltage used for sample conversion to millivolts.
@@ -11,8 +11,8 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
11pub const VREF_CALIB_MV: u32 = 3000; 11pub const VREF_CALIB_MV: u32 = 3000;
12 12
13pub struct VrefInt; 13pub struct VrefInt;
14impl<T: Instance> AdcPin<T> for VrefInt {} 14impl<T: Instance> AdcChannel<T> for VrefInt {}
15impl<T: Instance> super::SealedAdcPin<T> for VrefInt { 15impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
16 fn channel(&self) -> u8 { 16 fn channel(&self) -> u8 {
17 cfg_if! { 17 cfg_if! {
18 if #[cfg(adc_g0)] { 18 if #[cfg(adc_g0)] {
@@ -30,8 +30,8 @@ impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
30} 30}
31 31
32pub struct Temperature; 32pub struct Temperature;
33impl<T: Instance> AdcPin<T> for Temperature {} 33impl<T: Instance> AdcChannel<T> for Temperature {}
34impl<T: Instance> super::SealedAdcPin<T> for Temperature { 34impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
35 fn channel(&self) -> u8 { 35 fn channel(&self) -> u8 {
36 cfg_if! { 36 cfg_if! {
37 if #[cfg(adc_g0)] { 37 if #[cfg(adc_g0)] {
@@ -49,8 +49,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Temperature {
49} 49}
50 50
51pub struct Vbat; 51pub struct Vbat;
52impl<T: Instance> AdcPin<T> for Vbat {} 52impl<T: Instance> AdcChannel<T> for Vbat {}
53impl<T: Instance> super::SealedAdcPin<T> for Vbat { 53impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
54 fn channel(&self) -> u8 { 54 fn channel(&self) -> u8 {
55 cfg_if! { 55 cfg_if! {
56 if #[cfg(adc_g0)] { 56 if #[cfg(adc_g0)] {
@@ -70,8 +70,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Vbat {
70cfg_if! { 70cfg_if! {
71 if #[cfg(adc_h5)] { 71 if #[cfg(adc_h5)] {
72 pub struct VddCore; 72 pub struct VddCore;
73 impl<T: Instance> AdcPin<T> for VddCore {} 73 impl<T: Instance> AdcChannel<T> for VddCore {}
74 impl<T: Instance> super::SealedAdcPin<T> for VddCore { 74 impl<T: Instance> super::SealedAdcChannel<T> for VddCore {
75 fn channel(&self) -> u8 { 75 fn channel(&self) -> u8 {
76 6 76 6
77 } 77 }
@@ -82,8 +82,8 @@ cfg_if! {
82cfg_if! { 82cfg_if! {
83 if #[cfg(adc_u0)] { 83 if #[cfg(adc_u0)] {
84 pub struct DacOut; 84 pub struct DacOut;
85 impl<T: Instance> AdcPin<T> for DacOut {} 85 impl<T: Instance> AdcChannel<T> for DacOut {}
86 impl<T: Instance> super::SealedAdcPin<T> for DacOut { 86 impl<T: Instance> super::SealedAdcChannel<T> for DacOut {
87 fn channel(&self) -> u8 { 87 fn channel(&self) -> u8 {
88 19 88 19
89 } 89 }
@@ -220,7 +220,7 @@ impl<'d, T: Instance> Adc<'d, T> {
220 T::regs().dr().read().0 as u16 220 T::regs().dr().read().0 as u16
221 } 221 }
222 222
223 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 223 pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
224 // Make sure bits are off 224 // Make sure bits are off
225 while T::regs().cr().read().addis() { 225 while T::regs().cr().read().addis() {
226 // spin 226 // spin
@@ -241,18 +241,18 @@ impl<'d, T: Instance> Adc<'d, T> {
241 // RM0492, RM0481, etc. 241 // RM0492, RM0481, etc.
242 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." 242 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected."
243 #[cfg(adc_h5)] 243 #[cfg(adc_h5)]
244 if pin.channel() == 0 { 244 if channel.channel() == 0 {
245 T::regs().or().modify(|reg| reg.set_op0(true)); 245 T::regs().or().modify(|reg| reg.set_op0(true));
246 } 246 }
247 247
248 // Configure channel 248 // Configure channel
249 Self::set_channel_sample_time(pin.channel(), self.sample_time); 249 Self::set_channel_sample_time(channel.channel(), self.sample_time);
250 250
251 // Select channel 251 // Select channel
252 #[cfg(not(any(adc_g0, adc_u0)))] 252 #[cfg(not(any(adc_g0, adc_u0)))]
253 T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); 253 T::regs().sqr1().write(|reg| reg.set_sq(0, channel.channel()));
254 #[cfg(any(adc_g0, adc_u0))] 254 #[cfg(any(adc_g0, adc_u0))]
255 T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel())); 255 T::regs().chselr().write(|reg| reg.set_chsel(1 << channel.channel()));
256 256
257 // Some models are affected by an erratum: 257 // Some models are affected by an erratum:
258 // If we perform conversions slower than 1 kHz, the first read ADC value can be 258 // 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> {
270 // RM0492, RM0481, etc. 270 // RM0492, RM0481, etc.
271 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." 271 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected."
272 #[cfg(adc_h5)] 272 #[cfg(adc_h5)]
273 if pin.channel() == 0 { 273 if channel.channel() == 0 {
274 T::regs().or().modify(|reg| reg.set_op0(false)); 274 T::regs().or().modify(|reg| reg.set_op0(false));
275 } 275 }
276 276
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 @@
2use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; 2use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
3use pac::adccommon::vals::Presc; 3use pac::adccommon::vals::Presc;
4 4
5use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; 5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::{pac, Peripheral}; 7use crate::{pac, Peripheral};
8 8
@@ -33,8 +33,8 @@ const VBAT_CHANNEL: u8 = 17;
33// 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 33// 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
34/// Internal voltage reference channel. 34/// Internal voltage reference channel.
35pub struct VrefInt; 35pub struct VrefInt;
36impl<T: Instance> InternalChannel<T> for VrefInt {} 36impl<T: Instance> AdcChannel<T> for VrefInt {}
37impl<T: Instance> super::SealedInternalChannel<T> for VrefInt { 37impl<T: Instance> super::SealedAdcChannel<T> for VrefInt {
38 fn channel(&self) -> u8 { 38 fn channel(&self) -> u8 {
39 VREF_CHANNEL 39 VREF_CHANNEL
40 } 40 }
@@ -42,8 +42,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
42 42
43/// Internal temperature channel. 43/// Internal temperature channel.
44pub struct Temperature; 44pub struct Temperature;
45impl<T: Instance> InternalChannel<T> for Temperature {} 45impl<T: Instance> AdcChannel<T> for Temperature {}
46impl<T: Instance> super::SealedInternalChannel<T> for Temperature { 46impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
47 fn channel(&self) -> u8 { 47 fn channel(&self) -> u8 {
48 TEMP_CHANNEL 48 TEMP_CHANNEL
49 } 49 }
@@ -51,8 +51,8 @@ impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
51 51
52/// Internal battery voltage channel. 52/// Internal battery voltage channel.
53pub struct Vbat; 53pub struct Vbat;
54impl<T: Instance> InternalChannel<T> for Vbat {} 54impl<T: Instance> AdcChannel<T> for Vbat {}
55impl<T: Instance> super::SealedInternalChannel<T> for Vbat { 55impl<T: Instance> super::SealedAdcChannel<T> for Vbat {
56 fn channel(&self) -> u8 { 56 fn channel(&self) -> u8 {
57 VBAT_CHANNEL 57 VBAT_CHANNEL
58 } 58 }
@@ -271,19 +271,10 @@ impl<'d, T: Instance> Adc<'d, T> {
271 T::regs().dr().read().0 as u16 271 T::regs().dr().read().0 as u16
272 } 272 }
273 273
274 /// Read an ADC pin. 274 /// Read an ADC channel.
275 pub fn read<P>(&mut self, pin: &mut P) -> u16 275 pub fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
276 where 276 channel.setup();
277 P: AdcPin<T>,
278 P: crate::gpio::Pin,
279 {
280 pin.set_as_analog();
281 277
282 self.read_channel(pin.channel())
283 }
284
285 /// Read an ADC internal channel.
286 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
287 self.read_channel(channel.channel()) 278 self.read_channel(channel.channel())
288 } 279 }
289 280
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 {
198 ($inst:ident, $adc:ident, $ch:expr) => { 198 ($inst:ident, $adc:ident, $ch:expr) => {
199 foreach_adc!( 199 foreach_adc!(
200 ($adc, $common_inst:ident, $adc_clock:ident) => { 200 ($adc, $common_inst:ident, $adc_clock:ident) => {
201 impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> 201 impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc>
202 for OpAmpOutput<'d, crate::peripherals::$inst> 202 for OpAmpOutput<'d, crate::peripherals::$inst>
203 { 203 {
204 fn channel(&self) -> u8 { 204 fn channel(&self) -> u8 {
@@ -206,7 +206,7 @@ macro_rules! impl_opamp_external_output {
206 } 206 }
207 } 207 }
208 208
209 impl<'d> crate::adc::AdcPin<crate::peripherals::$adc> 209 impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc>
210 for OpAmpOutput<'d, crate::peripherals::$inst> 210 for OpAmpOutput<'d, crate::peripherals::$inst>
211 { 211 {
212 } 212 }
@@ -244,7 +244,7 @@ macro_rules! impl_opamp_internal_output {
244 ($inst:ident, $adc:ident, $ch:expr) => { 244 ($inst:ident, $adc:ident, $ch:expr) => {
245 foreach_adc!( 245 foreach_adc!(
246 ($adc, $common_inst:ident, $adc_clock:ident) => { 246 ($adc, $common_inst:ident, $adc_clock:ident) => {
247 impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> 247 impl<'d> crate::adc::SealedAdcChannel<crate::peripherals::$adc>
248 for OpAmpInternalOutput<'d, crate::peripherals::$inst> 248 for OpAmpInternalOutput<'d, crate::peripherals::$inst>
249 { 249 {
250 fn channel(&self) -> u8 { 250 fn channel(&self) -> u8 {
@@ -252,7 +252,7 @@ macro_rules! impl_opamp_internal_output {
252 } 252 }
253 } 253 }
254 254
255 impl<'d> crate::adc::AdcPin<crate::peripherals::$adc> 255 impl<'d> crate::adc::AdcChannel<crate::peripherals::$adc>
256 for OpAmpInternalOutput<'d, crate::peripherals::$inst> 256 for OpAmpInternalOutput<'d, crate::peripherals::$inst>
257 { 257 {
258 } 258 }
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) {
51 let mut vrefint_channel = adc.enable_vrefint(); 51 let mut vrefint_channel = adc.enable_vrefint();
52 52
53 loop { 53 loop {
54 let vrefint = adc.read_internal(&mut vrefint_channel); 54 let vrefint = adc.read(&mut vrefint_channel);
55 info!("vrefint: {}", vrefint); 55 info!("vrefint: {}", vrefint);
56 let measured = adc.read(&mut p.PC0); 56 let measured = adc.read(&mut p.PC0);
57 info!("measured: {}", measured); 57 info!("measured: {}", measured);