aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-10 20:02:20 +0000
committerGitHub <[email protected]>2025-11-10 20:02:20 +0000
commitf6fe96841160e33bf2550907993c7e22ec0f63ad (patch)
tree13134e86ee251755dea9aae08536ab18b2dae02c
parent1da05747c416c989a128aabbbde4b46df7bba9b9 (diff)
parentb806d7a98d7bd01a8038573748fbc03c587ba62b (diff)
Merge pull request #4860 from xoviat/adc
cleanup adc
-rw-r--r--embassy-stm32/CHANGELOG.md1
-rw-r--r--embassy-stm32/src/adc/adc4.rs18
-rw-r--r--embassy-stm32/src/adc/c0.rs47
-rw-r--r--embassy-stm32/src/adc/f1.rs37
-rw-r--r--embassy-stm32/src/adc/f3.rs44
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs5
-rw-r--r--embassy-stm32/src/adc/g4.rs232
-rw-r--r--embassy-stm32/src/adc/injected.rs2
-rw-r--r--embassy-stm32/src/adc/mod.rs51
-rw-r--r--embassy-stm32/src/adc/ringbuffered.rs2
-rw-r--r--embassy-stm32/src/adc/v1.rs53
-rw-r--r--embassy-stm32/src/adc/v2.rs222
-rw-r--r--embassy-stm32/src/adc/v3.rs139
-rw-r--r--embassy-stm32/src/adc/v4.rs84
-rw-r--r--embassy-stm32/src/adc/watchdog_v1.rs6
-rw-r--r--examples/stm32c0/src/bin/adc.rs8
-rw-r--r--examples/stm32f0/src/bin/adc-watchdog.rs6
-rw-r--r--examples/stm32f0/src/bin/adc.rs5
-rw-r--r--examples/stm32f1/src/bin/adc.rs6
-rw-r--r--examples/stm32f334/src/bin/adc.rs12
-rw-r--r--examples/stm32f334/src/bin/opamp.rs12
-rw-r--r--examples/stm32f4/src/bin/adc.rs10
-rw-r--r--examples/stm32f4/src/bin/adc_dma.rs8
-rw-r--r--examples/stm32f7/src/bin/adc.rs6
-rw-r--r--examples/stm32g0/src/bin/adc.rs5
-rw-r--r--examples/stm32g0/src/bin/adc_oversampling.rs3
-rw-r--r--examples/stm32g4/src/bin/adc.rs3
-rw-r--r--examples/stm32g4/src/bin/adc_differential.rs3
-rw-r--r--examples/stm32g4/src/bin/adc_oversampling.rs3
-rw-r--r--examples/stm32h5/src/bin/adc.rs6
-rw-r--r--examples/stm32h7/src/bin/adc.rs6
-rw-r--r--examples/stm32l0/src/bin/adc.rs5
-rw-r--r--examples/stm32l4/src/bin/adc.rs4
-rw-r--r--examples/stm32l4/src/bin/adc_dma.rs10
-rw-r--r--examples/stm32u0/src/bin/adc.rs4
-rw-r--r--examples/stm32u5/src/bin/adc.rs18
-rw-r--r--examples/stm32wba/src/bin/adc.rs6
-rw-r--r--examples/stm32wba6/src/bin/adc.rs5
-rw-r--r--examples/stm32wl/src/bin/adc.rs6
-rw-r--r--examples/stm32wle5/src/bin/adc.rs5
-rw-r--r--tests/stm32/src/bin/dac.rs9
-rw-r--r--tests/stm32/src/bin/dac_l1.rs11
42 files changed, 475 insertions, 653 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
index 595778748..8a53c9f03 100644
--- a/embassy-stm32/CHANGELOG.md
+++ b/embassy-stm32/CHANGELOG.md
@@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
52- feat: stm32/dsi support zero parameter commands in `write_cmd` ([#4847](https://github.com/embassy-rs/embassy/pull/4847)) 52- feat: stm32/dsi support zero parameter commands in `write_cmd` ([#4847](https://github.com/embassy-rs/embassy/pull/4847))
53- feat: stm32/spi: added support for slave mode ([#4388](https://github.com/embassy-rs/embassy/pull/4388)) 53- feat: stm32/spi: added support for slave mode ([#4388](https://github.com/embassy-rs/embassy/pull/4388))
54- chore: Updated stm32-metapac and stm32-data dependencies 54- chore: Updated stm32-metapac and stm32-data dependencies
55- adc: reogranize and cleanup somewhat. require sample_time to be passed on conversion
55 56
56## 0.4.0 - 2025-08-26 57## 0.4.0 - 2025-08-26
57 58
diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs
index 2608160a3..befa8ed4a 100644
--- a/embassy-stm32/src/adc/adc4.rs
+++ b/embassy-stm32/src/adc/adc4.rs
@@ -327,18 +327,6 @@ impl<'d, T: Instance> Adc4<'d, T> {
327 Dac {} 327 Dac {}
328 } 328 }
329 329
330 /// Set the ADC sample time.
331 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
332 T::regs().smpr().modify(|w| {
333 w.set_smp(0, sample_time);
334 });
335 }
336
337 /// Get the ADC sample time.
338 pub fn sample_time(&self) -> SampleTime {
339 T::regs().smpr().read().smp(0)
340 }
341
342 /// Set the ADC resolution. 330 /// Set the ADC resolution.
343 pub fn set_resolution(&mut self, resolution: Resolution) { 331 pub fn set_resolution(&mut self, resolution: Resolution) {
344 T::regs().cfgr1().modify(|w| w.set_res(resolution.into())); 332 T::regs().cfgr1().modify(|w| w.set_res(resolution.into()));
@@ -387,7 +375,11 @@ impl<'d, T: Instance> Adc4<'d, T> {
387 } 375 }
388 376
389 /// Read an ADC channel. 377 /// Read an ADC channel.
390 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 378 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
379 T::regs().smpr().modify(|w| {
380 w.set_smp(0, sample_time);
381 });
382
391 channel.setup(); 383 channel.setup();
392 384
393 // Select channel 385 // Select channel
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index fc28df346..1869993a5 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -19,33 +19,17 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(25);
19 19
20const TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US: u32 = 20; 20const TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US: u32 = 20;
21 21
22const TEMP_CHANNEL: u8 = 9;
23const VREF_CHANNEL: u8 = 10;
24
25const NUM_HW_CHANNELS: u8 = 22; 22const NUM_HW_CHANNELS: u8 = 22;
26const CHSELR_SQ_SIZE: usize = 8; 23const CHSELR_SQ_SIZE: usize = 8;
27const CHSELR_SQ_MAX_CHANNEL: u8 = 14; 24const CHSELR_SQ_MAX_CHANNEL: u8 = 14;
28const CHSELR_SQ_SEQUENCE_END_MARKER: u8 = 0b1111; 25const CHSELR_SQ_SEQUENCE_END_MARKER: u8 = 0b1111;
29 26
30// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, 27impl<T: Instance> super::VrefConverter for T {
31// this currently cannot be modeled with stm32-data, 28 const CHANNEL: u8 = 10;
32// so these are available from the software on all ADCs.
33/// Internal voltage reference channel.
34pub struct VrefInt;
35impl<T: Instance> AdcChannel<T> for VrefInt {}
36impl<T: Instance> SealedAdcChannel<T> for VrefInt {
37 fn channel(&self) -> u8 {
38 VREF_CHANNEL
39 }
40} 29}
41 30
42/// Internal temperature channel. 31impl<T: Instance> super::TemperatureConverter for T {
43pub struct Temperature; 32 const CHANNEL: u8 = 9;
44impl<T: Instance> AdcChannel<T> for Temperature {}
45impl<T: Instance> SealedAdcChannel<T> for Temperature {
46 fn channel(&self) -> u8 {
47 TEMP_CHANNEL
48 }
49} 33}
50 34
51#[derive(Copy, Clone, Debug)] 35#[derive(Copy, Clone, Debug)]
@@ -156,7 +140,7 @@ pub enum Averaging {
156 140
157impl<'d, T: Instance> Adc<'d, T> { 141impl<'d, T: Instance> Adc<'d, T> {
158 /// Create a new ADC driver. 142 /// Create a new ADC driver.
159 pub fn new(adc: Peri<'d, T>, sample_time: SampleTime, resolution: Resolution) -> Self { 143 pub fn new(adc: Peri<'d, T>, resolution: Resolution) -> Self {
160 rcc::enable_and_reset::<T>(); 144 rcc::enable_and_reset::<T>();
161 145
162 T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK)); 146 T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK));
@@ -174,10 +158,7 @@ impl<'d, T: Instance> Adc<'d, T> {
174 ); 158 );
175 } 159 }
176 160
177 let mut s = Self { 161 let mut s = Self { adc };
178 adc,
179 sample_time: SampleTime::from_bits(0),
180 };
181 162
182 s.power_up(); 163 s.power_up();
183 164
@@ -189,8 +170,6 @@ impl<'d, T: Instance> Adc<'d, T> {
189 170
190 s.configure_default(); 171 s.configure_default();
191 172
192 s.set_sample_time_all_channels(sample_time);
193
194 s 173 s
195 } 174 }
196 175
@@ -237,29 +216,27 @@ impl<'d, T: Instance> Adc<'d, T> {
237 } 216 }
238 217
239 /// Enable reading the voltage reference internal channel. 218 /// Enable reading the voltage reference internal channel.
240 pub fn enable_vrefint(&self) -> VrefInt { 219 pub fn enable_vrefint(&self) -> super::VrefInt {
241 T::common_regs().ccr().modify(|reg| { 220 T::common_regs().ccr().modify(|reg| {
242 reg.set_vrefen(true); 221 reg.set_vrefen(true);
243 }); 222 });
244 223
245 VrefInt {} 224 super::VrefInt {}
246 } 225 }
247 226
248 /// Enable reading the temperature internal channel. 227 /// Enable reading the temperature internal channel.
249 pub fn enable_temperature(&self) -> Temperature { 228 pub fn enable_temperature(&self) -> super::Temperature {
250 debug!("Ensure that sample time is set to more than temperature sensor T_start from the datasheet!"); 229 debug!("Ensure that sample time is set to more than temperature sensor T_start from the datasheet!");
251 T::common_regs().ccr().modify(|reg| { 230 T::common_regs().ccr().modify(|reg| {
252 reg.set_tsen(true); 231 reg.set_tsen(true);
253 }); 232 });
254 233
255 Temperature {} 234 super::Temperature {}
256 } 235 }
257 236
258 /// Set the ADC sample time. 237 /// Set the ADC sample time.
259 /// Shall only be called when ADC is not converting. 238 /// Shall only be called when ADC is not converting.
260 pub fn set_sample_time_all_channels(&mut self, sample_time: SampleTime) { 239 pub fn set_sample_time_all_channels(&mut self, sample_time: SampleTime) {
261 self.sample_time = sample_time;
262
263 // Set all channels to use SMP1 field as source. 240 // Set all channels to use SMP1 field as source.
264 T::regs().smpr().modify(|w| { 241 T::regs().smpr().modify(|w| {
265 w.smpsel(0); 242 w.smpsel(0);
@@ -288,7 +265,9 @@ impl<'d, T: Instance> Adc<'d, T> {
288 T::regs().dr().read().data() as u16 265 T::regs().dr().read().data() as u16
289 } 266 }
290 267
291 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 268 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
269 self.set_sample_time_all_channels(sample_time);
270
292 Self::configure_channel(channel); 271 Self::configure_channel(channel);
293 T::regs().cfgr1().write(|reg| { 272 T::regs().cfgr1().write(|reg| {
294 reg.set_chselrmod(false); 273 reg.set_chselrmod(false);
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index f9c23d72b..835cc8c63 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -28,20 +28,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
28 } 28 }
29} 29}
30 30
31pub struct Vref; 31impl<T: Instance> super::VrefConverter for T {
32impl<T: Instance> AdcChannel<T> for Vref {} 32 const CHANNEL: u8 = 17;
33impl<T: Instance> super::SealedAdcChannel<T> for Vref {
34 fn channel(&self) -> u8 {
35 17
36 }
37} 33}
38 34
39pub struct Temperature; 35impl<T: Instance> super::TemperatureConverter for T {
40impl<T: Instance> AdcChannel<T> for Temperature {} 36 const CHANNEL: u8 = 16;
41impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
42 fn channel(&self) -> u8 {
43 16
44 }
45} 37}
46 38
47impl<'d, T: Instance> Adc<'d, T> { 39impl<'d, T: Instance> Adc<'d, T> {
@@ -71,10 +63,7 @@ impl<'d, T: Instance> Adc<'d, T> {
71 T::Interrupt::unpend(); 63 T::Interrupt::unpend();
72 unsafe { T::Interrupt::enable() }; 64 unsafe { T::Interrupt::enable() };
73 65
74 Self { 66 Self { adc }
75 adc,
76 sample_time: SampleTime::from_bits(0),
77 }
78 } 67 }
79 68
80 fn freq() -> Hertz { 69 fn freq() -> Hertz {
@@ -94,22 +83,18 @@ impl<'d, T: Instance> Adc<'d, T> {
94 } 83 }
95 } 84 }
96 85
97 pub fn enable_vref(&self) -> Vref { 86 pub fn enable_vref(&self) -> super::VrefInt {
98 T::regs().cr2().modify(|reg| { 87 T::regs().cr2().modify(|reg| {
99 reg.set_tsvrefe(true); 88 reg.set_tsvrefe(true);
100 }); 89 });
101 Vref {} 90 super::VrefInt {}
102 } 91 }
103 92
104 pub fn enable_temperature(&self) -> Temperature { 93 pub fn enable_temperature(&self) -> super::Temperature {
105 T::regs().cr2().modify(|reg| { 94 T::regs().cr2().modify(|reg| {
106 reg.set_tsvrefe(true); 95 reg.set_tsvrefe(true);
107 }); 96 });
108 Temperature {} 97 super::Temperature {}
109 }
110
111 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
112 self.sample_time = sample_time;
113 } 98 }
114 99
115 /// Perform a single conversion. 100 /// Perform a single conversion.
@@ -134,8 +119,8 @@ impl<'d, T: Instance> Adc<'d, T> {
134 T::regs().dr().read().0 as u16 119 T::regs().dr().read().0 as u16
135 } 120 }
136 121
137 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 122 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
138 Self::set_channel_sample_time(channel.channel(), self.sample_time); 123 Self::set_channel_sample_time(channel.channel(), sample_time);
139 T::regs().cr1().modify(|reg| { 124 T::regs().cr1().modify(|reg| {
140 reg.set_scan(false); 125 reg.set_scan(false);
141 reg.set_discen(false); 126 reg.set_discen(false);
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 73ceb087a..f6a4e1209 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -29,27 +29,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
29 } 29 }
30} 30}
31 31
32pub struct Vref; 32impl<T: Instance> super::VrefConverter for T {
33impl<T: Instance> AdcChannel<T> for Vref {} 33 const CHANNEL: u8 = 18;
34impl<T: Instance> super::SealedAdcChannel<T> for Vref {
35 fn channel(&self) -> u8 {
36 18
37 }
38}
39
40impl Vref {
41 /// The value that vref would be if vdda was at 3300mv
42 pub fn value(&self) -> u16 {
43 crate::pac::VREFINTCAL.data().read()
44 }
45} 34}
46 35
47pub struct Temperature; 36impl<T: Instance> super::TemperatureConverter for T {
48impl<T: Instance> AdcChannel<T> for Temperature {} 37 const CHANNEL: u8 = 16;
49impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
50 fn channel(&self) -> u8 {
51 16
52 }
53} 38}
54 39
55impl<'d, T: Instance> Adc<'d, T> { 40impl<'d, T: Instance> Adc<'d, T> {
@@ -90,10 +75,7 @@ impl<'d, T: Instance> Adc<'d, T> {
90 T::Interrupt::enable(); 75 T::Interrupt::enable();
91 } 76 }
92 77
93 Self { 78 Self { adc }
94 adc,
95 sample_time: SampleTime::from_bits(0),
96 }
97 } 79 }
98 80
99 fn freq() -> Hertz { 81 fn freq() -> Hertz {
@@ -112,20 +94,16 @@ impl<'d, T: Instance> Adc<'d, T> {
112 } 94 }
113 } 95 }
114 96
115 pub fn enable_vref(&self) -> Vref { 97 pub fn enable_vref(&self) -> super::VrefInt {
116 T::common_regs().ccr().modify(|w| w.set_vrefen(true)); 98 T::common_regs().ccr().modify(|w| w.set_vrefen(true));
117 99
118 Vref {} 100 super::VrefInt {}
119 } 101 }
120 102
121 pub fn enable_temperature(&self) -> Temperature { 103 pub fn enable_temperature(&self) -> super::Temperature {
122 T::common_regs().ccr().modify(|w| w.set_tsen(true)); 104 T::common_regs().ccr().modify(|w| w.set_tsen(true));
123 105
124 Temperature {} 106 super::Temperature {}
125 }
126
127 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
128 self.sample_time = sample_time;
129 } 107 }
130 108
131 /// Perform a single conversion. 109 /// Perform a single conversion.
@@ -150,8 +128,8 @@ impl<'d, T: Instance> Adc<'d, T> {
150 T::regs().dr().read().rdata() 128 T::regs().dr().read().rdata()
151 } 129 }
152 130
153 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 131 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
154 Self::set_channel_sample_time(channel.channel(), self.sample_time); 132 Self::set_channel_sample_time(channel.channel(), sample_time);
155 133
156 // Configure the channel to sample 134 // Configure the channel to sample
157 T::regs().sqr1().write(|w| w.set_sq(0, channel.channel())); 135 T::regs().sqr1().write(|w| w.set_sq(0, channel.channel()));
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index cd5de54f5..919ac3cc0 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -79,7 +79,7 @@ impl<T: Instance> Vref<T> {
79 } 79 }
80 80
81 pub async fn calibrate(&mut self, adc: &mut Adc<'_, T>) -> Calibration { 81 pub async fn calibrate(&mut self, adc: &mut Adc<'_, T>) -> Calibration {
82 let vref_val = adc.read(self).await; 82 let vref_val = adc.read(self, SampleTime::from(0)).await;
83 Calibration { 83 Calibration {
84 vref_cal: self.calibrated_value(), 84 vref_cal: self.calibrated_value(),
85 vref_val, 85 vref_val,
@@ -270,7 +270,8 @@ impl<'d, T: Instance> Adc<'d, T> {
270 } 270 }
271 } 271 }
272 272
273 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 273 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
274 self.set_sample_time(channel, sample_time).await;
274 self.set_sample_sequence(&[channel.channel()]).await; 275 self.set_sample_sequence(&[channel.channel()]).await;
275 self.convert().await 276 self.convert().await
276 } 277 }
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 3767820cf..5d9c6ff74 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -35,34 +35,6 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60);
35#[cfg(stm32h7)] 35#[cfg(stm32h7)]
36const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); 36const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
37 37
38// 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
39/// Internal voltage reference channel.
40pub struct VrefInt;
41impl<T: Instance + VrefChannel> AdcChannel<T> for VrefInt {}
42impl<T: Instance + VrefChannel> super::SealedAdcChannel<T> for VrefInt {
43 fn channel(&self) -> u8 {
44 T::CHANNEL
45 }
46}
47
48/// Internal temperature channel.
49pub struct Temperature;
50impl<T: Instance + TemperatureChannel> AdcChannel<T> for Temperature {}
51impl<T: Instance + TemperatureChannel> super::SealedAdcChannel<T> for Temperature {
52 fn channel(&self) -> u8 {
53 T::CHANNEL
54 }
55}
56
57/// Internal battery voltage channel.
58pub struct Vbat;
59impl<T: Instance + VBatChannel> AdcChannel<T> for Vbat {}
60impl<T: Instance + VBatChannel> super::SealedAdcChannel<T> for Vbat {
61 fn channel(&self) -> u8 {
62 T::CHANNEL
63 }
64}
65
66// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 38// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
67// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. 39// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
68#[allow(unused)] 40#[allow(unused)]
@@ -168,17 +140,14 @@ impl<'d, T: Instance> Adc<'d, T> {
168 ); 140 );
169 } 141 }
170 142
171 let mut s = Self { 143 let mut s = Self { adc };
172 adc,
173 sample_time: SampleTime::from_bits(0),
174 };
175 s.power_up(); 144 s.power_up();
176 s.configure_differential_inputs(); 145 s.configure_differential_inputs();
177 146
178 s.calibrate(); 147 s.calibrate();
179 blocking_delay_us(1); 148 blocking_delay_us(1);
180 149
181 s.enable(); 150 Self::enable();
182 s.configure(); 151 s.configure();
183 152
184 s 153 s
@@ -223,7 +192,7 @@ impl<'d, T: Instance> Adc<'d, T> {
223 blocking_delay_us(20); 192 blocking_delay_us(20);
224 } 193 }
225 194
226 fn enable(&mut self) { 195 fn enable() {
227 // Make sure bits are off 196 // Make sure bits are off
228 while T::regs().cr().read().addis() { 197 while T::regs().cr().read().addis() {
229 // spin 198 // spin
@@ -253,39 +222,39 @@ impl<'d, T: Instance> Adc<'d, T> {
253 } 222 }
254 223
255 /// Enable reading the voltage reference internal channel. 224 /// Enable reading the voltage reference internal channel.
256 pub fn enable_vrefint(&self) -> VrefInt 225 pub fn enable_vrefint(&self) -> super::VrefInt
257 where 226 where
258 T: VrefChannel, 227 T: super::VrefConverter,
259 { 228 {
260 T::common_regs().ccr().modify(|reg| { 229 T::common_regs().ccr().modify(|reg| {
261 reg.set_vrefen(true); 230 reg.set_vrefen(true);
262 }); 231 });
263 232
264 VrefInt {} 233 super::VrefInt {}
265 } 234 }
266 235
267 /// Enable reading the temperature internal channel. 236 /// Enable reading the temperature internal channel.
268 pub fn enable_temperature(&self) -> Temperature 237 pub fn enable_temperature(&self) -> super::Temperature
269 where 238 where
270 T: TemperatureChannel, 239 T: super::TemperatureConverter,
271 { 240 {
272 T::common_regs().ccr().modify(|reg| { 241 T::common_regs().ccr().modify(|reg| {
273 reg.set_vsenseen(true); 242 reg.set_vsenseen(true);
274 }); 243 });
275 244
276 Temperature {} 245 super::Temperature {}
277 } 246 }
278 247
279 /// Enable reading the vbat internal channel. 248 /// Enable reading the vbat internal channel.
280 pub fn enable_vbat(&self) -> Vbat 249 pub fn enable_vbat(&self) -> super::Vbat
281 where 250 where
282 T: VBatChannel, 251 T: super::VBatConverter,
283 { 252 {
284 T::common_regs().ccr().modify(|reg| { 253 T::common_regs().ccr().modify(|reg| {
285 reg.set_vbaten(true); 254 reg.set_vbaten(true);
286 }); 255 });
287 256
288 Vbat {} 257 super::Vbat {}
289 } 258 }
290 259
291 /// Enable differential channel. 260 /// Enable differential channel.
@@ -297,7 +266,7 @@ impl<'d, T: Instance> Adc<'d, T> {
297 /// channel on the other ADC unusable. The only exception is when ADC master and the slave 266 /// channel on the other ADC unusable. The only exception is when ADC master and the slave
298 /// operate in interleaved mode. 267 /// operate in interleaved mode.
299 #[cfg(stm32g4)] 268 #[cfg(stm32g4)]
300 pub fn set_differential_channel(&mut self, ch: usize, enable: bool) { 269 fn set_differential_channel(&mut self, ch: usize, enable: bool) {
301 T::regs().cr().modify(|w| w.set_aden(false)); // disable adc 270 T::regs().cr().modify(|w| w.set_aden(false)); // disable adc
302 T::regs().difsel().modify(|w| { 271 T::regs().difsel().modify(|w| {
303 w.set_difsel( 272 w.set_difsel(
@@ -350,11 +319,6 @@ impl<'d, T: Instance> Adc<'d, T> {
350 // T::regs().cfgr2().modify(|reg| reg.set_jovse(enable)); 319 // T::regs().cfgr2().modify(|reg| reg.set_jovse(enable));
351 // } 320 // }
352 321
353 /// Set the ADC sample time.
354 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
355 self.sample_time = sample_time;
356 }
357
358 /// Set the ADC resolution. 322 /// Set the ADC resolution.
359 pub fn set_resolution(&mut self, resolution: Resolution) { 323 pub fn set_resolution(&mut self, resolution: Resolution) {
360 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); 324 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
@@ -380,10 +344,10 @@ impl<'d, T: Instance> Adc<'d, T> {
380 } 344 }
381 345
382 /// Read an ADC pin. 346 /// Read an ADC pin.
383 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 347 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
384 channel.setup(); 348 channel.setup();
385 349
386 self.read_channel(channel) 350 self.read_channel(channel, sample_time)
387 } 351 }
388 352
389 /// Start regular adc conversion 353 /// Start regular adc conversion
@@ -399,7 +363,7 @@ impl<'d, T: Instance> Adc<'d, T> {
399 } 363 }
400 364
401 /// Teardown method for stopping regular ADC conversions 365 /// Teardown method for stopping regular ADC conversions
402 pub(super) fn teardown_adc() { 366 pub(super) fn teardown_dma() {
403 Self::stop_regular_conversions(); 367 Self::stop_regular_conversions();
404 368
405 // Disable dma control 369 // Disable dma control
@@ -454,39 +418,13 @@ impl<'d, T: Instance> Adc<'d, T> {
454 418
455 // Ensure no conversions are ongoing and ADC is enabled. 419 // Ensure no conversions are ongoing and ADC is enabled.
456 Self::stop_regular_conversions(); 420 Self::stop_regular_conversions();
457 self.enable(); 421 Self::enable();
458 422
459 // Set sequence length 423 Self::configure_sequence(sequence.map(|(channel, sample_time)| {
460 T::regs().sqr1().modify(|w| { 424 channel.setup();
461 w.set_l(sequence.len() as u8 - 1); 425
462 }); 426 (channel.channel, sample_time)
463 // Configure channels and ranks 427 }));
464 for (_i, (channel, sample_time)) in sequence.enumerate() {
465 Self::configure_channel(channel, sample_time);
466 match _i {
467 0..=3 => {
468 T::regs().sqr1().modify(|w| {
469 w.set_sq(_i, channel.channel());
470 });
471 }
472 4..=8 => {
473 T::regs().sqr2().modify(|w| {
474 w.set_sq(_i - 4, channel.channel());
475 });
476 }
477 9..=13 => {
478 T::regs().sqr3().modify(|w| {
479 w.set_sq(_i - 9, channel.channel());
480 });
481 }
482 14..=15 => {
483 T::regs().sqr4().modify(|w| {
484 w.set_sq(_i - 14, channel.channel());
485 });
486 }
487 _ => unreachable!(),
488 }
489 }
490 428
491 // Set continuous mode with oneshot dma. 429 // Set continuous mode with oneshot dma.
492 // Clear overrun flag before starting transfer. 430 // Clear overrun flag before starting transfer.
@@ -529,6 +467,47 @@ impl<'d, T: Instance> Adc<'d, T> {
529 }); 467 });
530 } 468 }
531 469
470 pub(super) fn configure_sequence(sequence: impl ExactSizeIterator<Item = (u8, SampleTime)>) {
471 // Set sequence length
472 T::regs().sqr1().modify(|w| {
473 w.set_l(sequence.len() as u8 - 1);
474 });
475
476 // Configure channels and ranks
477 for (_i, (ch, sample_time)) in sequence.enumerate() {
478 let sample_time = sample_time.into();
479 if ch <= 9 {
480 T::regs().smpr().modify(|reg| reg.set_smp(ch as _, sample_time));
481 } else {
482 T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
483 }
484
485 match _i {
486 0..=3 => {
487 T::regs().sqr1().modify(|w| {
488 w.set_sq(_i, ch);
489 });
490 }
491 4..=8 => {
492 T::regs().sqr2().modify(|w| {
493 w.set_sq(_i - 4, ch);
494 });
495 }
496 9..=13 => {
497 T::regs().sqr3().modify(|w| {
498 w.set_sq(_i - 9, ch);
499 });
500 }
501 14..=15 => {
502 T::regs().sqr4().modify(|w| {
503 w.set_sq(_i - 14, ch);
504 });
505 }
506 _ => unreachable!(),
507 }
508 }
509 }
510
532 /// Set external trigger for regular conversion sequence 511 /// Set external trigger for regular conversion sequence
533 fn set_regular_conversion_trigger(&mut self, trigger: ConversionTrigger) { 512 fn set_regular_conversion_trigger(&mut self, trigger: ConversionTrigger) {
534 T::regs().cfgr().modify(|r| { 513 T::regs().cfgr().modify(|r| {
@@ -582,43 +561,15 @@ impl<'d, T: Instance> Adc<'d, T> {
582 ); 561 );
583 // reset conversions and enable the adc 562 // reset conversions and enable the adc
584 Self::stop_regular_conversions(); 563 Self::stop_regular_conversions();
585 self.enable(); 564 Self::enable();
586 565
587 //adc side setup 566 //adc side setup
588 567
589 // Set sequence length 568 Self::configure_sequence(sequence.map(|(mut channel, sample_time)| {
590 T::regs().sqr1().modify(|w| { 569 channel.setup();
591 w.set_l(sequence.len() as u8 - 1);
592 });
593 570
594 // Configure channels and ranks 571 (channel.channel, sample_time)
595 for (_i, (mut channel, sample_time)) in sequence.enumerate() { 572 }));
596 Self::configure_channel(&mut channel, sample_time);
597
598 match _i {
599 0..=3 => {
600 T::regs().sqr1().modify(|w| {
601 w.set_sq(_i, channel.channel());
602 });
603 }
604 4..=8 => {
605 T::regs().sqr2().modify(|w| {
606 w.set_sq(_i - 4, channel.channel());
607 });
608 }
609 9..=13 => {
610 T::regs().sqr3().modify(|w| {
611 w.set_sq(_i - 9, channel.channel());
612 });
613 }
614 14..=15 => {
615 T::regs().sqr4().modify(|w| {
616 w.set_sq(_i - 14, channel.channel());
617 });
618 }
619 _ => unreachable!(),
620 }
621 }
622 573
623 // Clear overrun flag before starting transfer. 574 // Clear overrun flag before starting transfer.
624 T::regs().isr().modify(|reg| { 575 T::regs().isr().modify(|reg| {
@@ -691,7 +642,7 @@ impl<'d, T: Instance> Adc<'d, T> {
691 ); 642 );
692 643
693 Self::stop_regular_conversions(); 644 Self::stop_regular_conversions();
694 self.enable(); 645 Self::enable();
695 646
696 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1)); 647 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1));
697 648
@@ -755,12 +706,10 @@ impl<'d, T: Instance> Adc<'d, T> {
755 ( 706 (
756 Self { 707 Self {
757 adc: self.adc.clone_unchecked(), 708 adc: self.adc.clone_unchecked(),
758 sample_time: self.sample_time,
759 } 709 }
760 .into_ring_buffered(dma, dma_buf, regular_sequence, regular_conversion_mode), 710 .into_ring_buffered(dma, dma_buf, regular_sequence, regular_conversion_mode),
761 Self { 711 Self {
762 adc: self.adc.clone_unchecked(), 712 adc: self.adc.clone_unchecked(),
763 sample_time: self.sample_time,
764 } 713 }
765 .setup_injected_conversions(injected_sequence, injected_trigger, injected_interrupt), 714 .setup_injected_conversions(injected_sequence, injected_trigger, injected_interrupt),
766 ) 715 )
@@ -805,8 +754,8 @@ impl<'d, T: Instance> Adc<'d, T> {
805 Self::set_channel_sample_time(channel.channel(), sample_time); 754 Self::set_channel_sample_time(channel.channel(), sample_time);
806 } 755 }
807 756
808 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 757 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
809 Self::configure_channel(channel, self.sample_time); 758 Self::configure_channel(channel, sample_time);
810 #[cfg(stm32h7)] 759 #[cfg(stm32h7)]
811 { 760 {
812 T::regs().cfgr2().modify(|w| w.set_lshift(0)); 761 T::regs().cfgr2().modify(|w| w.set_lshift(0));
@@ -860,62 +809,49 @@ impl<T: Instance, const N: usize> InjectedAdc<T, N> {
860 } 809 }
861} 810}
862 811
863/// Implemented for ADCs that have a Temperature channel
864pub trait TemperatureChannel {
865 const CHANNEL: u8;
866}
867/// Implemented for ADCs that have a Vref channel
868pub trait VrefChannel {
869 const CHANNEL: u8;
870}
871/// Implemented for ADCs that have a VBat channel
872pub trait VBatChannel {
873 const CHANNEL: u8;
874}
875
876#[cfg(stm32g4)] 812#[cfg(stm32g4)]
877mod g4 { 813mod g4 {
878 pub use super::*; 814 use crate::adc::{TemperatureConverter, VBatConverter, VrefConverter};
879 815
880 impl TemperatureChannel for crate::peripherals::ADC1 { 816 impl TemperatureConverter for crate::peripherals::ADC1 {
881 const CHANNEL: u8 = 16; 817 const CHANNEL: u8 = 16;
882 } 818 }
883 819
884 impl VrefChannel for crate::peripherals::ADC1 { 820 impl VrefConverter for crate::peripherals::ADC1 {
885 const CHANNEL: u8 = 18; 821 const CHANNEL: u8 = 18;
886 } 822 }
887 823
888 impl VBatChannel for crate::peripherals::ADC1 { 824 impl VBatConverter for crate::peripherals::ADC1 {
889 const CHANNEL: u8 = 17; 825 const CHANNEL: u8 = 17;
890 } 826 }
891 827
892 #[cfg(peri_adc3_common)] 828 #[cfg(peri_adc3_common)]
893 impl VrefChannel for crate::peripherals::ADC3 { 829 impl VrefConverter for crate::peripherals::ADC3 {
894 const CHANNEL: u8 = 18; 830 const CHANNEL: u8 = 18;
895 } 831 }
896 832
897 #[cfg(peri_adc3_common)] 833 #[cfg(peri_adc3_common)]
898 impl VBatChannel for crate::peripherals::ADC3 { 834 impl VBatConverter for crate::peripherals::ADC3 {
899 const CHANNEL: u8 = 17; 835 const CHANNEL: u8 = 17;
900 } 836 }
901 837
902 #[cfg(not(stm32g4x1))] 838 #[cfg(not(stm32g4x1))]
903 impl VrefChannel for crate::peripherals::ADC4 { 839 impl VrefConverter for crate::peripherals::ADC4 {
904 const CHANNEL: u8 = 18; 840 const CHANNEL: u8 = 18;
905 } 841 }
906 842
907 #[cfg(not(stm32g4x1))] 843 #[cfg(not(stm32g4x1))]
908 impl TemperatureChannel for crate::peripherals::ADC5 { 844 impl TemperatureConverter for crate::peripherals::ADC5 {
909 const CHANNEL: u8 = 4; 845 const CHANNEL: u8 = 4;
910 } 846 }
911 847
912 #[cfg(not(stm32g4x1))] 848 #[cfg(not(stm32g4x1))]
913 impl VrefChannel for crate::peripherals::ADC5 { 849 impl VrefConverter for crate::peripherals::ADC5 {
914 const CHANNEL: u8 = 18; 850 const CHANNEL: u8 = 18;
915 } 851 }
916 852
917 #[cfg(not(stm32g4x1))] 853 #[cfg(not(stm32g4x1))]
918 impl VBatChannel for crate::peripherals::ADC5 { 854 impl VBatConverter for crate::peripherals::ADC5 {
919 const CHANNEL: u8 = 17; 855 const CHANNEL: u8 = 17;
920 } 856 }
921} 857}
@@ -923,13 +859,13 @@ mod g4 {
923// TODO this should look at each ADC individually and impl the correct channels 859// TODO this should look at each ADC individually and impl the correct channels
924#[cfg(stm32h7)] 860#[cfg(stm32h7)]
925mod h7 { 861mod h7 {
926 impl<T: Instance> TemperatureChannel for T { 862 impl<T: Instance> TemperatureConverter for T {
927 const CHANNEL: u8 = 18; 863 const CHANNEL: u8 = 18;
928 } 864 }
929 impl<T: Instance> VrefChannel for T { 865 impl<T: Instance> VrefConverter for T {
930 const CHANNEL: u8 = 19; 866 const CHANNEL: u8 = 19;
931 } 867 }
932 impl<T: Instance> VBatChannel for T { 868 impl<T: Instance> VBatConverter for T {
933 // TODO this should be 14 for H7a/b/35 869 // TODO this should be 14 for H7a/b/35
934 const CHANNEL: u8 = 17; 870 const CHANNEL: u8 = 17;
935 } 871 }
diff --git a/embassy-stm32/src/adc/injected.rs b/embassy-stm32/src/adc/injected.rs
index 0e4fe5847..f9f1bba2a 100644
--- a/embassy-stm32/src/adc/injected.rs
+++ b/embassy-stm32/src/adc/injected.rs
@@ -38,7 +38,7 @@ impl<T: Instance, const N: usize> InjectedAdc<T, N> {
38 38
39impl<T: Instance, const N: usize> Drop for InjectedAdc<T, N> { 39impl<T: Instance, const N: usize> Drop for InjectedAdc<T, N> {
40 fn drop(&mut self) { 40 fn drop(&mut self) {
41 Adc::<T>::teardown_adc(); 41 Adc::<T>::teardown_dma();
42 compiler_fence(Ordering::SeqCst); 42 compiler_fence(Ordering::SeqCst);
43 } 43 }
44} 44}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index ea7341f75..3bf893a35 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -47,8 +47,6 @@ dma_trait!(RxDma4, adc4::Instance);
47pub struct Adc<'d, T: Instance> { 47pub struct Adc<'d, T: Instance> {
48 #[allow(unused)] 48 #[allow(unused)]
49 adc: crate::Peri<'d, T>, 49 adc: crate::Peri<'d, T>,
50 #[cfg(not(any(adc_f3v3, adc_f3v2, adc_wba)))]
51 sample_time: SampleTime,
52} 50}
53 51
54#[cfg(any(adc_f1, adc_f3v1, adc_v1, adc_l0, adc_f3v2))] 52#[cfg(any(adc_f1, adc_f3v1, adc_v1, adc_l0, adc_f3v2))]
@@ -102,6 +100,55 @@ pub(crate) fn blocking_delay_us(us: u32) {
102 } 100 }
103} 101}
104 102
103/// Implemented for ADCs that have a Temperature channel
104pub trait TemperatureConverter {
105 const CHANNEL: u8;
106}
107/// Implemented for ADCs that have a Vref channel
108pub trait VrefConverter {
109 const CHANNEL: u8;
110}
111/// Implemented for ADCs that have a VBat channel
112pub trait VBatConverter {
113 const CHANNEL: u8;
114}
115
116// 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
117/// Internal voltage reference channel.
118pub struct VrefInt;
119impl<T: Instance + VrefConverter> AdcChannel<T> for VrefInt {}
120impl<T: Instance + VrefConverter> SealedAdcChannel<T> for VrefInt {
121 fn channel(&self) -> u8 {
122 T::CHANNEL
123 }
124}
125
126impl VrefInt {
127 #[cfg(any(adc_f3v1, adc_f3v2))]
128 /// The value that vref would be if vdda was at 3300mv
129 pub fn calibrated_value(&self) -> u16 {
130 crate::pac::VREFINTCAL.data().read()
131 }
132}
133
134/// Internal temperature channel.
135pub struct Temperature;
136impl<T: Instance + TemperatureConverter> AdcChannel<T> for Temperature {}
137impl<T: Instance + TemperatureConverter> SealedAdcChannel<T> for Temperature {
138 fn channel(&self) -> u8 {
139 T::CHANNEL
140 }
141}
142
143/// Internal battery voltage channel.
144pub struct Vbat;
145impl<T: Instance + VBatConverter> AdcChannel<T> for Vbat {}
146impl<T: Instance + VBatConverter> SealedAdcChannel<T> for Vbat {
147 fn channel(&self) -> u8 {
148 T::CHANNEL
149 }
150}
151
105/// ADC instance. 152/// ADC instance.
106#[cfg(not(any( 153#[cfg(not(any(
107 adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_g4, adc_f3v1, adc_f3v2, adc_g0, adc_u0, adc_h5, adc_h7rs, 154 adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_g4, adc_f3v1, adc_f3v2, adc_g0, adc_u0, adc_h5, adc_h7rs,
diff --git a/embassy-stm32/src/adc/ringbuffered.rs b/embassy-stm32/src/adc/ringbuffered.rs
index 971c8195c..024c6acdc 100644
--- a/embassy-stm32/src/adc/ringbuffered.rs
+++ b/embassy-stm32/src/adc/ringbuffered.rs
@@ -172,7 +172,7 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
172 172
173impl<T: Instance> Drop for RingBufferedAdc<'_, T> { 173impl<T: Instance> Drop for RingBufferedAdc<'_, T> {
174 fn drop(&mut self) { 174 fn drop(&mut self) {
175 Adc::<T>::teardown_adc(); 175 Adc::<T>::teardown_dma();
176 176
177 compiler_fence(Ordering::SeqCst); 177 compiler_fence(Ordering::SeqCst);
178 178
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index a5869d110..97557ee8a 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -5,10 +5,11 @@ use core::task::Poll;
5#[cfg(adc_l0)] 5#[cfg(adc_l0)]
6use stm32_metapac::adc::vals::Ckmode; 6use stm32_metapac::adc::vals::Ckmode;
7 7
8use super::blocking_delay_us; 8#[cfg(not(adc_l0))]
9use super::Vbat;
10use super::{Temperature, VrefInt, blocking_delay_us};
9use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 11use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
10use crate::interrupt::typelevel::Interrupt; 12use crate::interrupt::typelevel::Interrupt;
11use crate::peripherals::ADC1;
12use crate::{Peri, interrupt, rcc}; 13use crate::{Peri, interrupt, rcc};
13 14
14mod watchdog_v1; 15mod watchdog_v1;
@@ -42,32 +43,23 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
42} 43}
43 44
44#[cfg(not(adc_l0))] 45#[cfg(not(adc_l0))]
45pub struct Vbat; 46impl super::VBatConverter for crate::peripherals::ADC1 {
46 47 const CHANNEL: u8 = 18;
47#[cfg(not(adc_l0))] 48}
48impl AdcChannel<ADC1> for Vbat {}
49 49
50#[cfg(not(adc_l0))] 50#[cfg(not(adc_l0))]
51impl super::SealedAdcChannel<ADC1> for Vbat { 51impl super::VrefConverter for crate::peripherals::ADC1 {
52 fn channel(&self) -> u8 { 52 const CHANNEL: u8 = 17;
53 18
54 }
55} 53}
56 54
57pub struct Vref; 55#[cfg(adc_l0)]
58impl AdcChannel<ADC1> for Vref {} 56impl super::VrefConverter for crate::peripherals::ADC1 {
59impl super::SealedAdcChannel<ADC1> for Vref { 57 const CHANNEL: u8 = 18;
60 fn channel(&self) -> u8 {
61 17
62 }
63} 58}
64 59
65pub struct Temperature; 60#[cfg(not(adc_l0))]
66impl AdcChannel<ADC1> for Temperature {} 61impl super::TemperatureConverter for crate::peripherals::ADC1 {
67impl super::SealedAdcChannel<ADC1> for Temperature { 62 const CHANNEL: u8 = 16;
68 fn channel(&self) -> u8 {
69 if cfg!(adc_l0) { 18 } else { 16 }
70 }
71} 63}
72 64
73impl<'d, T: Instance> Adc<'d, T> { 65impl<'d, T: Instance> Adc<'d, T> {
@@ -114,10 +106,7 @@ impl<'d, T: Instance> Adc<'d, T> {
114 T::Interrupt::enable(); 106 T::Interrupt::enable();
115 } 107 }
116 108
117 Self { 109 Self { adc }
118 adc,
119 sample_time: SampleTime::from_bits(0),
120 }
121 } 110 }
122 111
123 #[cfg(not(adc_l0))] 112 #[cfg(not(adc_l0))]
@@ -130,12 +119,12 @@ impl<'d, T: Instance> Adc<'d, T> {
130 Vbat 119 Vbat
131 } 120 }
132 121
133 pub fn enable_vref(&self) -> Vref { 122 pub fn enable_vref(&self) -> VrefInt {
134 // Table 28. Embedded internal reference voltage 123 // Table 28. Embedded internal reference voltage
135 // tstart = 10μs 124 // tstart = 10μs
136 T::regs().ccr().modify(|reg| reg.set_vrefen(true)); 125 T::regs().ccr().modify(|reg| reg.set_vrefen(true));
137 blocking_delay_us(10); 126 blocking_delay_us(10);
138 Vref 127 VrefInt
139 } 128 }
140 129
141 pub fn enable_temperature(&self) -> Temperature { 130 pub fn enable_temperature(&self) -> Temperature {
@@ -149,10 +138,6 @@ impl<'d, T: Instance> Adc<'d, T> {
149 Temperature 138 Temperature
150 } 139 }
151 140
152 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
153 self.sample_time = sample_time;
154 }
155
156 pub fn set_resolution(&mut self, resolution: Resolution) { 141 pub fn set_resolution(&mut self, resolution: Resolution) {
157 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); 142 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
158 } 143 }
@@ -163,12 +148,13 @@ impl<'d, T: Instance> Adc<'d, T> {
163 T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode)); 148 T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode));
164 } 149 }
165 150
166 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 151 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
167 let ch_num = channel.channel(); 152 let ch_num = channel.channel();
168 channel.setup(); 153 channel.setup();
169 154
170 // A.7.5 Single conversion sequence code example - Software trigger 155 // A.7.5 Single conversion sequence code example - Software trigger
171 T::regs().chselr().write(|reg| reg.set_chsel_x(ch_num as usize, true)); 156 T::regs().chselr().write(|reg| reg.set_chsel_x(ch_num as usize, true));
157 T::regs().smpr().modify(|reg| reg.set_smp(sample_time.into()));
172 158
173 self.convert().await 159 self.convert().await
174 } 160 }
@@ -179,7 +165,6 @@ impl<'d, T: Instance> Adc<'d, T> {
179 reg.set_eosmp(true); 165 reg.set_eosmp(true);
180 }); 166 });
181 167
182 T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.into()));
183 T::regs().ier().modify(|w| w.set_eocie(true)); 168 T::regs().ier().modify(|w| w.set_eocie(true));
184 T::regs().cr().modify(|reg| reg.set_adstart(true)); 169 T::regs().cr().modify(|reg| reg.set_adstart(true));
185 170
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 90c6294d2..88a8b96ed 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,10 +1,9 @@
1use core::mem; 1use core::mem;
2use core::sync::atomic::{Ordering, compiler_fence}; 2use core::sync::atomic::{Ordering, compiler_fence};
3 3
4use super::blocking_delay_us; 4use super::{Temperature, Vbat, VrefInt, blocking_delay_us};
5use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel}; 5use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel};
6use crate::pac::adc::vals; 6use crate::pac::adc::vals;
7use crate::peripherals::ADC1;
8use crate::time::Hertz; 7use crate::time::Hertz;
9use crate::{Peri, rcc}; 8use crate::{Peri, rcc};
10 9
@@ -23,12 +22,22 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
23/// VREF voltage used for factory calibration of VREFINTCAL register. 22/// VREF voltage used for factory calibration of VREFINTCAL register.
24pub const VREF_CALIB_MV: u32 = 3300; 23pub const VREF_CALIB_MV: u32 = 3300;
25 24
26pub struct VrefInt; 25impl super::VrefConverter for crate::peripherals::ADC1 {
27impl AdcChannel<ADC1> for VrefInt {} 26 const CHANNEL: u8 = 17;
28impl super::SealedAdcChannel<ADC1> for VrefInt { 27}
29 fn channel(&self) -> u8 { 28
30 17 29#[cfg(any(stm32f2, stm32f40x, stm32f41x))]
31 } 30impl super::TemperatureConverter for crate::peripherals::ADC1 {
31 const CHANNEL: u8 = 16;
32}
33
34#[cfg(not(any(stm32f2, stm32f40x, stm32f41x)))]
35impl super::TemperatureConverter for crate::peripherals::ADC1 {
36 const CHANNEL: u8 = 18;
37}
38
39impl super::VBatConverter for crate::peripherals::ADC1 {
40 const CHANNEL: u8 = 18;
32} 41}
33 42
34impl VrefInt { 43impl VrefInt {
@@ -38,20 +47,6 @@ impl VrefInt {
38 } 47 }
39} 48}
40 49
41pub struct Temperature;
42impl AdcChannel<ADC1> for Temperature {}
43impl super::SealedAdcChannel<ADC1> for Temperature {
44 fn channel(&self) -> u8 {
45 cfg_if::cfg_if! {
46 if #[cfg(any(stm32f2, stm32f40x, stm32f41x))] {
47 16
48 } else {
49 18
50 }
51 }
52 }
53}
54
55impl Temperature { 50impl Temperature {
56 /// Time needed for temperature sensor readings to stabilize 51 /// Time needed for temperature sensor readings to stabilize
57 pub fn start_time_us() -> u32 { 52 pub fn start_time_us() -> u32 {
@@ -59,14 +54,6 @@ impl Temperature {
59 } 54 }
60} 55}
61 56
62pub struct Vbat;
63impl AdcChannel<ADC1> for Vbat {}
64impl super::SealedAdcChannel<ADC1> for Vbat {
65 fn channel(&self) -> u8 {
66 18
67 }
68}
69
70enum Prescaler { 57enum Prescaler {
71 Div2, 58 Div2,
72 Div4, 59 Div4,
@@ -117,10 +104,7 @@ where
117 104
118 blocking_delay_us(3); 105 blocking_delay_us(3);
119 106
120 Self { 107 Self { adc }
121 adc,
122 sample_time: SampleTime::from_bits(0),
123 }
124 } 108 }
125 109
126 /// Configures the ADC to use a DMA ring buffer for continuous data acquisition. 110 /// Configures the ADC to use a DMA ring buffer for continuous data acquisition.
@@ -137,61 +121,18 @@ where
137 self, 121 self,
138 dma: Peri<'d, impl RxDma<T>>, 122 dma: Peri<'d, impl RxDma<T>>,
139 dma_buf: &'d mut [u16], 123 dma_buf: &'d mut [u16],
140 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, 124 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, SampleTime)>,
141 ) -> RingBufferedAdc<'d, T> { 125 ) -> RingBufferedAdc<'d, T> {
142 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 126 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
143 127
144 T::regs().cr2().modify(|reg| { 128 Self::configure_sequence(sequence.map(|(mut channel, sample_time)| {
145 reg.set_adon(true);
146 });
147
148 // Check the sequence is long enough
149 T::regs().sqr1().modify(|r| {
150 r.set_l((sequence.len() - 1).try_into().unwrap());
151 });
152
153 for (i, (channel, sample_time)) in sequence.enumerate() {
154 // Set this GPIO as an analog input.
155 channel.setup(); 129 channel.setup();
156 130
157 // Set the channel in the right sequence field. 131 (channel.channel, sample_time)
158 T::regs().sqr3().modify(|w| w.set_sq(i, channel.channel())); 132 }));
159
160 Self::set_channel_sample_time(channel.channel(), sample_time);
161 }
162
163 compiler_fence(Ordering::SeqCst); 133 compiler_fence(Ordering::SeqCst);
164 134
165 let r = T::regs(); 135 Self::setup_dma();
166
167 // Clear all interrupts
168 r.sr().modify(|regs| {
169 regs.set_eoc(false);
170 regs.set_ovr(false);
171 regs.set_strt(false);
172 });
173
174 r.cr1().modify(|w| {
175 // Enable interrupt for end of conversion
176 w.set_eocie(true);
177 // Enable interrupt for overrun
178 w.set_ovrie(true);
179 // Scanning converisons of multiple channels
180 w.set_scan(true);
181 // Continuous conversion mode
182 w.set_discen(false);
183 });
184
185 r.cr2().modify(|w| {
186 // Enable DMA mode
187 w.set_dma(true);
188 // Enable continuous conversions
189 w.set_cont(true);
190 // DMA requests are issues as long as DMA=1 and data are converted.
191 w.set_dds(vals::Dds::CONTINUOUS);
192 // EOC flag is set at the end of each conversion.
193 w.set_eocs(vals::Eocs::EACH_CONVERSION);
194 });
195 136
196 // Don't disable the clock 137 // Don't disable the clock
197 mem::forget(self); 138 mem::forget(self);
@@ -199,28 +140,14 @@ where
199 RingBufferedAdc::new(dma, dma_buf) 140 RingBufferedAdc::new(dma, dma_buf)
200 } 141 }
201 142
202 pub(super) fn start() { 143 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
203 // Begin ADC conversions 144 channel.setup();
204 T::regs().cr2().modify(|reg| {
205 reg.set_adon(true);
206 reg.set_swstart(true);
207 });
208 }
209
210 pub(super) fn stop() {
211 // Stop ADC
212 T::regs().cr2().modify(|reg| {
213 // Stop ADC
214 reg.set_swstart(false);
215 });
216 }
217 145
218 pub fn set_sample_time(&mut self, sample_time: SampleTime) { 146 // Configure ADC
219 self.sample_time = sample_time; 147 let channel = channel.channel();
220 }
221 148
222 pub fn set_resolution(&mut self, resolution: Resolution) { 149 Self::configure_sequence([(channel, sample_time)].into_iter());
223 T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); 150 Self::blocking_convert()
224 } 151 }
225 152
226 /// Enables internal voltage reference and returns [VrefInt], which can be used in 153 /// Enables internal voltage reference and returns [VrefInt], which can be used in
@@ -256,8 +183,27 @@ where
256 Vbat {} 183 Vbat {}
257 } 184 }
258 185
259 /// Perform a single conversion. 186 pub(super) fn start() {
260 fn convert(&mut self) -> u16 { 187 // Begin ADC conversions
188 T::regs().cr2().modify(|reg| {
189 reg.set_adon(true);
190 reg.set_swstart(true);
191 });
192 }
193
194 pub(super) fn stop() {
195 // Stop ADC
196 T::regs().cr2().modify(|reg| {
197 // Stop ADC
198 reg.set_swstart(false);
199 });
200 }
201
202 pub fn set_resolution(&mut self, resolution: Resolution) {
203 T::regs().cr1().modify(|reg| reg.set_res(resolution.into()));
204 }
205
206 pub(super) fn blocking_convert() -> u16 {
261 // clear end of conversion flag 207 // clear end of conversion flag
262 T::regs().sr().modify(|reg| { 208 T::regs().sr().modify(|reg| {
263 reg.set_eoc(false); 209 reg.set_eoc(false);
@@ -278,31 +224,63 @@ where
278 T::regs().dr().read().0 as u16 224 T::regs().dr().read().0 as u16
279 } 225 }
280 226
281 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 227 pub(super) fn configure_sequence(sequence: impl ExactSizeIterator<Item = (u8, SampleTime)>) {
282 channel.setup(); 228 T::regs().cr2().modify(|reg| {
283 229 reg.set_adon(true);
284 // Configure ADC 230 });
285 let channel = channel.channel();
286 231
287 // Select channel 232 // Check the sequence is long enough
288 T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); 233 T::regs().sqr1().modify(|r| {
234 r.set_l((sequence.len() - 1).try_into().unwrap());
235 });
289 236
290 // Configure channel 237 for (i, (ch, sample_time)) in sequence.enumerate() {
291 Self::set_channel_sample_time(channel, self.sample_time); 238 // Set the channel in the right sequence field.
239 T::regs().sqr3().modify(|w| w.set_sq(i, ch));
292 240
293 self.convert() 241 let sample_time = sample_time.into();
242 if ch <= 9 {
243 T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time));
244 } else {
245 T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
246 }
247 }
294 } 248 }
295 249
296 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 250 pub(super) fn setup_dma() {
297 let sample_time = sample_time.into(); 251 let r = T::regs();
298 if ch <= 9 { 252
299 T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); 253 // Clear all interrupts
300 } else { 254 r.sr().modify(|regs| {
301 T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); 255 regs.set_eoc(false);
302 } 256 regs.set_ovr(false);
257 regs.set_strt(false);
258 });
259
260 r.cr1().modify(|w| {
261 // Enable interrupt for end of conversion
262 w.set_eocie(true);
263 // Enable interrupt for overrun
264 w.set_ovrie(true);
265 // Scanning converisons of multiple channels
266 w.set_scan(true);
267 // Continuous conversion mode
268 w.set_discen(false);
269 });
270
271 r.cr2().modify(|w| {
272 // Enable DMA mode
273 w.set_dma(true);
274 // Enable continuous conversions
275 w.set_cont(true);
276 // DMA requests are issues as long as DMA=1 and data are converted.
277 w.set_dds(vals::Dds::CONTINUOUS);
278 // EOC flag is set at the end of each conversion.
279 w.set_eocs(vals::Eocs::EACH_CONVERSION);
280 });
303 } 281 }
304 282
305 pub(super) fn teardown_adc() { 283 pub(super) fn teardown_dma() {
306 let r = T::regs(); 284 let r = T::regs();
307 285
308 // Stop ADC 286 // Stop ADC
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 170b08a25..e816907d1 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -9,8 +9,11 @@ use pac::adc::vals::{OversamplingRatio, OversamplingShift, Rovsm, Trovs};
9#[cfg(adc_g0)] 9#[cfg(adc_g0)]
10pub use pac::adc::vals::{Ovsr, Ovss, Presc}; 10pub use pac::adc::vals::{Ovsr, Ovss, Presc};
11 11
12#[allow(unused_imports)]
13use super::SealedAdcChannel;
12use super::{ 14use super::{
13 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, 15 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, Temperature, Vbat, VrefInt,
16 blocking_delay_us,
14}; 17};
15 18
16#[cfg(any(adc_v3, adc_g0, adc_u0))] 19#[cfg(any(adc_v3, adc_g0, adc_u0))]
@@ -32,61 +35,55 @@ pub const VREF_CALIB_MV: u32 = 3000;
32// TODO: Use [#![feature(variant_count)]](https://github.com/rust-lang/rust/issues/73662) when stable 35// TODO: Use [#![feature(variant_count)]](https://github.com/rust-lang/rust/issues/73662) when stable
33const SAMPLE_TIMES_CAPACITY: usize = 2; 36const SAMPLE_TIMES_CAPACITY: usize = 2;
34 37
35pub struct VrefInt; 38#[cfg(adc_g0)]
36impl<T: Instance> AdcChannel<T> for VrefInt {} 39impl<T: Instance> super::VrefConverter for T {
37impl<T: Instance> SealedAdcChannel<T> for VrefInt { 40 const CHANNEL: u8 = 13;
38 fn channel(&self) -> u8 { 41}
39 cfg_if! { 42#[cfg(any(adc_h5, adc_h7rs))]
40 if #[cfg(adc_g0)] { 43impl<T: Instance> super::VrefConverter for T {
41 let val = 13; 44 const CHANNEL: u8 = 17;
42 } else if #[cfg(any(adc_h5, adc_h7rs))] { 45}
43 let val = 17; 46#[cfg(adc_u0)]
44 } else if #[cfg(adc_u0)] { 47impl<T: Instance> super::VrefConverter for T {
45 let val = 12; 48 const CHANNEL: u8 = 12;
46 } else { 49}
47 let val = 0; 50#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
48 } 51impl<T: Instance> super::VrefConverter for T {
49 } 52 const CHANNEL: u8 = 0;
50 val
51 }
52} 53}
53 54
54pub struct Temperature; 55#[cfg(adc_g0)]
55impl<T: Instance> AdcChannel<T> for Temperature {} 56impl<T: Instance> super::TemperatureConverter for T {
56impl<T: Instance> SealedAdcChannel<T> for Temperature { 57 const CHANNEL: u8 = 12;
57 fn channel(&self) -> u8 { 58}
58 cfg_if! { 59#[cfg(any(adc_h5, adc_h7rs))]
59 if #[cfg(adc_g0)] { 60impl<T: Instance> super::TemperatureConverter for T {
60 let val = 12; 61 const CHANNEL: u8 = 16;
61 } else if #[cfg(any(adc_h5, adc_h7rs))] { 62}
62 let val = 16; 63#[cfg(adc_u0)]
63 } else if #[cfg(adc_u0)] { 64impl<T: Instance> super::TemperatureConverter for T {
64 let val = 11; 65 const CHANNEL: u8 = 11;
65 } else { 66}
66 let val = 17; 67#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
67 } 68impl<T: Instance> super::TemperatureConverter for T {
68 } 69 const CHANNEL: u8 = 17;
69 val
70 }
71} 70}
72 71
73pub struct Vbat; 72#[cfg(adc_g0)]
74impl<T: Instance> AdcChannel<T> for Vbat {} 73impl<T: Instance> super::VBatConverter for T {
75impl<T: Instance> SealedAdcChannel<T> for Vbat { 74 const CHANNEL: u8 = 14;
76 fn channel(&self) -> u8 { 75}
77 cfg_if! { 76#[cfg(any(adc_h5, adc_h7rs))]
78 if #[cfg(adc_g0)] { 77impl<T: Instance> super::VBatConverter for T {
79 let val = 14; 78 const CHANNEL: u8 = 2;
80 } else if #[cfg(any(adc_h5, adc_h7rs))] { 79}
81 let val = 2; 80#[cfg(adc_u0)]
82 } else if #[cfg(any(adc_h5, adc_h7rs))] { 81impl<T: Instance> super::VBatConverter for T {
83 let val = 13; 82 const CHANNEL: u8 = 13;
84 } else { 83}
85 let val = 18; 84#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
86 } 85impl<T: Instance> super::VBatConverter for T {
87 } 86 const CHANNEL: u8 = 18;
88 val
89 }
90} 87}
91 88
92cfg_if! { 89cfg_if! {
@@ -201,7 +198,7 @@ impl<'d, T: Instance> Adc<'d, T> {
201 } 198 }
202 199
203 #[cfg(any(adc_v3, adc_g0, adc_u0))] 200 #[cfg(any(adc_v3, adc_g0, adc_u0))]
204 pub(super) fn teardown_adc() { 201 pub(super) fn teardown_dma() {
205 //disable dma control 202 //disable dma control
206 #[cfg(not(any(adc_g0, adc_u0)))] 203 #[cfg(not(any(adc_g0, adc_u0)))]
207 T::regs().cfgr().modify(|reg| { 204 T::regs().cfgr().modify(|reg| {
@@ -218,10 +215,7 @@ impl<'d, T: Instance> Adc<'d, T> {
218 pub fn new(adc: Peri<'d, T>) -> Self { 215 pub fn new(adc: Peri<'d, T>) -> Self {
219 Self::init_regulator(); 216 Self::init_regulator();
220 Self::init_calibrate(); 217 Self::init_calibrate();
221 Self { 218 Self { adc }
222 adc,
223 sample_time: SampleTime::from_bits(0),
224 }
225 } 219 }
226 220
227 #[cfg(adc_g0)] 221 #[cfg(adc_g0)]
@@ -257,10 +251,7 @@ impl<'d, T: Instance> Adc<'d, T> {
257 251
258 Self::init_calibrate(); 252 Self::init_calibrate();
259 253
260 Self { 254 Self { adc }
261 adc,
262 sample_time: SampleTime::from_bits(0),
263 }
264 } 255 }
265 256
266 // Enable ADC only when it is not already running. 257 // Enable ADC only when it is not already running.
@@ -342,16 +333,6 @@ impl<'d, T: Instance> Adc<'d, T> {
342 Vbat {} 333 Vbat {}
343 } 334 }
344 335
345 /// Set the ADC sample time.
346 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
347 self.sample_time = sample_time;
348 }
349
350 /// Get the ADC sample time.
351 pub fn sample_time(&self) -> SampleTime {
352 self.sample_time
353 }
354
355 /// Set the ADC resolution. 336 /// Set the ADC resolution.
356 pub fn set_resolution(&mut self, resolution: Resolution) { 337 pub fn set_resolution(&mut self, resolution: Resolution) {
357 #[cfg(not(any(adc_g0, adc_u0)))] 338 #[cfg(not(any(adc_g0, adc_u0)))]
@@ -413,8 +394,8 @@ impl<'d, T: Instance> Adc<'d, T> {
413 } 394 }
414 395
415 /// Read an ADC channel. 396 /// Read an ADC channel.
416 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 397 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
417 self.read_channel(channel) 398 self.read_channel(channel, sample_time)
418 } 399 }
419 400
420 /// Read one or multiple ADC channels using DMA. 401 /// Read one or multiple ADC channels using DMA.
@@ -616,7 +597,7 @@ impl<'d, T: Instance> Adc<'d, T> {
616 &mut self, 597 &mut self,
617 dma: Peri<'a, impl RxDma<T>>, 598 dma: Peri<'a, impl RxDma<T>>,
618 dma_buf: &'a mut [u16], 599 dma_buf: &'a mut [u16],
619 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, 600 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, SampleTime)>,
620 ) -> RingBufferedAdc<'a, T> { 601 ) -> RingBufferedAdc<'a, T> {
621 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 602 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
622 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); 603 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty");
@@ -665,8 +646,8 @@ impl<'d, T: Instance> Adc<'d, T> {
665 let mut channel_mask = 0; 646 let mut channel_mask = 0;
666 647
667 // Configure channels and ranks 648 // Configure channels and ranks
668 for (_i, (channel, sample_time)) in sequence.enumerate() { 649 for (_i, (mut channel, sample_time)) in sequence.enumerate() {
669 Self::configure_channel(channel, sample_time); 650 Self::configure_channel(&mut channel, sample_time);
670 651
671 // Each channel is sampled according to sequence 652 // Each channel is sampled according to sequence
672 #[cfg(not(any(adc_g0, adc_u0)))] 653 #[cfg(not(any(adc_g0, adc_u0)))]
@@ -745,13 +726,13 @@ impl<'d, T: Instance> Adc<'d, T> {
745 Self::set_channel_sample_time(channel.channel(), sample_time); 726 Self::set_channel_sample_time(channel.channel(), sample_time);
746 } 727 }
747 728
748 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 729 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
749 self.enable(); 730 self.enable();
750 #[cfg(not(adc_g0))] 731 #[cfg(not(adc_g0))]
751 Self::configure_channel(channel, self.sample_time); 732 Self::configure_channel(channel, sample_time);
752 #[cfg(adc_g0)] 733 #[cfg(adc_g0)]
753 T::regs().smpr().write(|reg| { 734 T::regs().smpr().write(|reg| {
754 reg.set_sample_time(0, self.sample_time); 735 reg.set_sample_time(0, sample_time);
755 reg.set_smpsel(channel.channel().into(), Smpsel::SMP1); 736 reg.set_smpsel(channel.channel().into(), Smpsel::SMP1);
756 }); 737 });
757 // Select channel 738 // Select channel
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index c7d0103a6..2f7baf3bf 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -5,7 +5,8 @@ use pac::adc::vals::{Adstp, Difsel, Dmngt, Exten, Pcsel};
5use pac::adccommon::vals::Presc; 5use pac::adccommon::vals::Presc;
6 6
7use super::{ 7use super::{
8 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, 8 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, Temperature, Vbat,
9 VrefInt, blocking_delay_us,
9}; 10};
10use crate::dma::Transfer; 11use crate::dma::Transfer;
11use crate::time::Hertz; 12use crate::time::Hertz;
@@ -25,52 +26,40 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
25const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); 26const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);
26 27
27#[cfg(stm32g4)] 28#[cfg(stm32g4)]
28const VREF_CHANNEL: u8 = 18; 29impl<T: Instance> super::VrefConverter for T {
30 const CHANNEL: u8 = 18;
31}
29#[cfg(stm32g4)] 32#[cfg(stm32g4)]
30const TEMP_CHANNEL: u8 = 16; 33impl<T: Instance> super::TemperatureConverter for T {
34 const CHANNEL: u8 = 16;
35}
31 36
32#[cfg(stm32h7)] 37#[cfg(stm32h7)]
33const VREF_CHANNEL: u8 = 19; 38impl<T: Instance> super::VrefConverter for T {
39 const CHANNEL: u8 = 19;
40}
34#[cfg(stm32h7)] 41#[cfg(stm32h7)]
35const TEMP_CHANNEL: u8 = 18; 42impl<T: Instance> super::TemperatureConverter for T {
43 const CHANNEL: u8 = 18;
44}
36 45
37// TODO this should be 14 for H7a/b/35 46// TODO this should be 14 for H7a/b/35
38#[cfg(not(stm32u5))] 47#[cfg(not(stm32u5))]
39const VBAT_CHANNEL: u8 = 17; 48impl<T: Instance> super::VBatConverter for T {
49 const CHANNEL: u8 = 17;
50}
40 51
41#[cfg(stm32u5)] 52#[cfg(stm32u5)]
42const VREF_CHANNEL: u8 = 0; 53impl<T: Instance> super::VrefConverter for T {
43#[cfg(stm32u5)] 54 const CHANNEL: u8 = 0;
44const TEMP_CHANNEL: u8 = 19;
45#[cfg(stm32u5)]
46const VBAT_CHANNEL: u8 = 18;
47
48// 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
49/// Internal voltage reference channel.
50pub struct VrefInt;
51impl<T: Instance> AdcChannel<T> for VrefInt {}
52impl<T: Instance> SealedAdcChannel<T> for VrefInt {
53 fn channel(&self) -> u8 {
54 VREF_CHANNEL
55 }
56} 55}
57 56#[cfg(stm32u5)]
58/// Internal temperature channel. 57impl<T: Instance> super::TemperatureConverter for T {
59pub struct Temperature; 58 const CHANNEL: u8 = 19;
60impl<T: Instance> AdcChannel<T> for Temperature {}
61impl<T: Instance> SealedAdcChannel<T> for Temperature {
62 fn channel(&self) -> u8 {
63 TEMP_CHANNEL
64 }
65} 59}
66 60#[cfg(stm32u5)]
67/// Internal battery voltage channel. 61impl<T: Instance> super::VBatConverter for T {
68pub struct Vbat; 62 const CHANNEL: u8 = 18;
69impl<T: Instance> AdcChannel<T> for Vbat {}
70impl<T: Instance> SealedAdcChannel<T> for Vbat {
71 fn channel(&self) -> u8 {
72 VBAT_CHANNEL
73 }
74} 63}
75 64
76// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 65// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
@@ -190,10 +179,7 @@ impl<'d, T: Instance> Adc<'d, T> {
190 }; 179 };
191 T::regs().cr().modify(|w| w.set_boost(boost)); 180 T::regs().cr().modify(|w| w.set_boost(boost));
192 } 181 }
193 let mut s = Self { 182 let mut s = Self { adc };
194 adc,
195 sample_time: SampleTime::from_bits(0),
196 };
197 s.power_up(); 183 s.power_up();
198 s.configure_differential_inputs(); 184 s.configure_differential_inputs();
199 185
@@ -277,16 +263,6 @@ impl<'d, T: Instance> Adc<'d, T> {
277 Vbat {} 263 Vbat {}
278 } 264 }
279 265
280 /// Set the ADC sample time.
281 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
282 self.sample_time = sample_time;
283 }
284
285 /// Get the ADC sample time.
286 pub fn sample_time(&self) -> SampleTime {
287 self.sample_time
288 }
289
290 /// Set the ADC resolution. 266 /// Set the ADC resolution.
291 pub fn set_resolution(&mut self, resolution: Resolution) { 267 pub fn set_resolution(&mut self, resolution: Resolution) {
292 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); 268 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
@@ -335,8 +311,8 @@ impl<'d, T: Instance> Adc<'d, T> {
335 } 311 }
336 312
337 /// Read an ADC channel. 313 /// Read an ADC channel.
338 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 314 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
339 self.read_channel(channel) 315 self.read_channel(channel, sample_time)
340 } 316 }
341 317
342 /// Read one or multiple ADC channels using DMA. 318 /// Read one or multiple ADC channels using DMA.
@@ -472,8 +448,8 @@ impl<'d, T: Instance> Adc<'d, T> {
472 } 448 }
473 } 449 }
474 450
475 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { 451 fn read_channel(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 {
476 Self::configure_channel(channel, self.sample_time); 452 Self::configure_channel(channel, sample_time);
477 453
478 T::regs().sqr1().modify(|reg| { 454 T::regs().sqr1().modify(|reg| {
479 reg.set_sq(0, channel.channel()); 455 reg.set_sq(0, channel.channel());
diff --git a/embassy-stm32/src/adc/watchdog_v1.rs b/embassy-stm32/src/adc/watchdog_v1.rs
index bbe8e1971..b12e0d333 100644
--- a/embassy-stm32/src/adc/watchdog_v1.rs
+++ b/embassy-stm32/src/adc/watchdog_v1.rs
@@ -1,7 +1,7 @@
1use core::future::poll_fn; 1use core::future::poll_fn;
2use core::task::Poll; 2use core::task::Poll;
3 3
4use stm32_metapac::adc::vals::{Align, Awdsgl, Res}; 4use stm32_metapac::adc::vals::{Align, Awdsgl, Res, SampleTime};
5 5
6use crate::adc::{Adc, AdcChannel, Instance}; 6use crate::adc::{Adc, AdcChannel, Instance};
7 7
@@ -67,7 +67,7 @@ impl<'d, T: Instance> Adc<'d, T> {
67 /// let v_high = adc.monitor_watchdog().await; 67 /// let v_high = adc.monitor_watchdog().await;
68 /// info!("ADC sample is high {}", v_high); 68 /// info!("ADC sample is high {}", v_high);
69 /// ``` 69 /// ```
70 pub async fn monitor_watchdog(&mut self) -> u16 { 70 pub async fn monitor_watchdog(&mut self, sample_time: SampleTime) -> u16 {
71 assert!( 71 assert!(
72 match T::regs().cfgr1().read().awdsgl() { 72 match T::regs().cfgr1().read().awdsgl() {
73 Awdsgl::SINGLE_CHANNEL => T::regs().cfgr1().read().awdch() != 0, 73 Awdsgl::SINGLE_CHANNEL => T::regs().cfgr1().read().awdch() != 0,
@@ -76,7 +76,7 @@ impl<'d, T: Instance> Adc<'d, T> {
76 "`set_channel` should be called before `monitor`", 76 "`set_channel` should be called before `monitor`",
77 ); 77 );
78 assert!(T::regs().chselr().read().0 != 0); 78 assert!(T::regs().chselr().read().0 != 0);
79 T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.into())); 79 T::regs().smpr().modify(|reg| reg.set_smp(sample_time.into()));
80 Self::start_awd(); 80 Self::start_awd();
81 81
82 let sample = poll_fn(|cx| { 82 let sample = poll_fn(|cx| {
diff --git a/examples/stm32c0/src/bin/adc.rs b/examples/stm32c0/src/bin/adc.rs
index 1f54b0b18..b52c9e7f8 100644
--- a/examples/stm32c0/src/bin/adc.rs
+++ b/examples/stm32c0/src/bin/adc.rs
@@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) {
17 info!("ADC STM32C0 example."); 17 info!("ADC STM32C0 example.");
18 18
19 // We need to set certain sample time to be able to read temp sensor. 19 // We need to set certain sample time to be able to read temp sensor.
20 let mut adc = Adc::new(p.ADC1, SampleTime::CYCLES12_5, Resolution::BITS12); 20 let mut adc = Adc::new(p.ADC1, Resolution::BITS12);
21 let mut temp = adc.enable_temperature().degrade_adc(); 21 let mut temp = adc.enable_temperature().degrade_adc();
22 let mut vref = adc.enable_vrefint().degrade_adc(); 22 let mut vref = adc.enable_vrefint().degrade_adc();
23 let mut pin0 = p.PA0.degrade_adc(); 23 let mut pin0 = p.PA0.degrade_adc();
@@ -27,9 +27,9 @@ async fn main(_spawner: Spawner) {
27 27
28 loop { 28 loop {
29 info!("============================"); 29 info!("============================");
30 let blocking_temp = adc.blocking_read(&mut temp); 30 let blocking_temp = adc.blocking_read(&mut temp, SampleTime::CYCLES12_5);
31 let blocking_vref = adc.blocking_read(&mut vref); 31 let blocking_vref = adc.blocking_read(&mut vref, SampleTime::CYCLES12_5);
32 let blocing_pin0 = adc.blocking_read(&mut pin0); 32 let blocing_pin0 = adc.blocking_read(&mut pin0, SampleTime::CYCLES12_5);
33 info!( 33 info!(
34 "Blocking ADC read: vref = {}, temp = {}, pin0 = {}.", 34 "Blocking ADC read: vref = {}, temp = {}, pin0 = {}.",
35 blocking_vref, blocking_temp, blocing_pin0 35 blocking_vref, blocking_temp, blocing_pin0
diff --git a/examples/stm32f0/src/bin/adc-watchdog.rs b/examples/stm32f0/src/bin/adc-watchdog.rs
index ff98aac8e..6879dd10a 100644
--- a/examples/stm32f0/src/bin/adc-watchdog.rs
+++ b/examples/stm32f0/src/bin/adc-watchdog.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{self, Adc, WatchdogChannels}; 6use embassy_stm32::adc::{self, Adc, SampleTime, WatchdogChannels};
7use embassy_stm32::bind_interrupts; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::peripherals::ADC1; 8use embassy_stm32::peripherals::ADC1;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -23,12 +23,12 @@ async fn main(_spawner: Spawner) {
23 loop { 23 loop {
24 // Wait for pin to go high 24 // Wait for pin to go high
25 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0, 0x07F); 25 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0, 0x07F);
26 let v_high = adc.monitor_watchdog().await; 26 let v_high = adc.monitor_watchdog(SampleTime::CYCLES13_5).await;
27 info!("ADC sample is high {}", v_high); 27 info!("ADC sample is high {}", v_high);
28 28
29 // Wait for pin to go low 29 // Wait for pin to go low
30 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0x01f, 0xFFF); 30 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0x01f, 0xFFF);
31 let v_low = adc.monitor_watchdog().await; 31 let v_low = adc.monitor_watchdog(SampleTime::CYCLES13_5).await;
32 info!("ADC sample is low {}", v_low); 32 info!("ADC sample is low {}", v_low);
33 } 33 }
34} 34}
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs
index 8825e2687..fafeeffaf 100644
--- a/examples/stm32f0/src/bin/adc.rs
+++ b/examples/stm32f0/src/bin/adc.rs
@@ -19,11 +19,10 @@ async fn main(_spawner: Spawner) {
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC1, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES71_5);
23 let mut pin = p.PA1; 22 let mut pin = p.PA1;
24 23
25 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
26 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES13_5).await;
27 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
28 // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf
29 // 6.3.4 Embedded reference voltage 28 // 6.3.4 Embedded reference voltage
@@ -33,7 +32,7 @@ async fn main(_spawner: Spawner) {
33 }; 32 };
34 33
35 loop { 34 loop {
36 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES13_5).await;
37 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
38 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
39 } 38 }
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs
index 541ff159e..2451aee3d 100644
--- a/examples/stm32f1/src/bin/adc.rs
+++ b/examples/stm32f1/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::Adc; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::peripherals::ADC1; 7use embassy_stm32::peripherals::ADC1;
8use embassy_stm32::{adc, bind_interrupts}; 8use embassy_stm32::{adc, bind_interrupts};
9use embassy_time::Timer; 9use embassy_time::Timer;
@@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) {
22 let mut pin = p.PB1; 22 let mut pin = p.PB1;
23 23
24 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
25 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES13_5).await;
26 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
27 // From http://www.st.com/resource/en/datasheet/CD00161566.pdf 27 // From http://www.st.com/resource/en/datasheet/CD00161566.pdf
28 // 5.3.4 Embedded reference voltage 28 // 5.3.4 Embedded reference voltage
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
32 }; 32 };
33 33
34 loop { 34 loop {
35 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES13_5).await;
36 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
37 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
38 } 38 }
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs
index a993b00ca..486f160ec 100644
--- a/examples/stm32f334/src/bin/adc.rs
+++ b/examples/stm32f334/src/bin/adc.rs
@@ -40,24 +40,22 @@ async fn main(_spawner: Spawner) -> ! {
40 40
41 let mut adc = Adc::new(p.ADC1, Irqs); 41 let mut adc = Adc::new(p.ADC1, Irqs);
42 42
43 adc.set_sample_time(SampleTime::CYCLES601_5);
44
45 info!("enable vrefint..."); 43 info!("enable vrefint...");
46 44
47 let mut vrefint = adc.enable_vref(); 45 let mut vrefint = adc.enable_vref();
48 let mut temperature = adc.enable_temperature(); 46 let mut temperature = adc.enable_temperature();
49 47
50 loop { 48 loop {
51 let vref = adc.read(&mut vrefint).await; 49 let vref = adc.read(&mut vrefint, SampleTime::CYCLES601_5).await;
52 info!("read vref: {} (should be {})", vref, vrefint.value()); 50 info!("read vref: {} (should be {})", vref, vrefint.calibrated_value());
53 51
54 let temp = adc.read(&mut temperature).await; 52 let temp = adc.read(&mut temperature, SampleTime::CYCLES601_5).await;
55 info!("read temperature: {}", temp); 53 info!("read temperature: {}", temp);
56 54
57 let pin = adc.read(&mut p.PA0).await; 55 let pin = adc.read(&mut p.PA0, SampleTime::CYCLES601_5).await;
58 info!("read pin: {}", pin); 56 info!("read pin: {}", pin);
59 57
60 let pin_mv = (pin as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; 58 let pin_mv = (pin as u32 * vrefint.calibrated_value() as u32 / vref as u32) * 3300 / 4095;
61 info!("computed pin mv: {}", pin_mv); 59 info!("computed pin mv: {}", pin_mv);
62 60
63 Timer::after_millis(500).await; 61 Timer::after_millis(500).await;
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs
index 3e621f2a1..9555fd35d 100644
--- a/examples/stm32f334/src/bin/opamp.rs
+++ b/examples/stm32f334/src/bin/opamp.rs
@@ -42,8 +42,6 @@ async fn main(_spawner: Spawner) -> ! {
42 let mut adc = Adc::new(p.ADC2, Irqs); 42 let mut adc = Adc::new(p.ADC2, Irqs);
43 let mut opamp = OpAmp::new(p.OPAMP2); 43 let mut opamp = OpAmp::new(p.OPAMP2);
44 44
45 adc.set_sample_time(SampleTime::CYCLES601_5);
46
47 info!("enable vrefint..."); 45 info!("enable vrefint...");
48 46
49 let mut vrefint = adc.enable_vref(); 47 let mut vrefint = adc.enable_vref();
@@ -51,16 +49,16 @@ async fn main(_spawner: Spawner) -> ! {
51 let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow()); 49 let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow());
52 50
53 loop { 51 loop {
54 let vref = adc.read(&mut vrefint).await; 52 let vref = adc.read(&mut vrefint, SampleTime::CYCLES601_5).await;
55 info!("read vref: {} (should be {})", vref, vrefint.value()); 53 info!("read vref: {} (should be {})", vref, vrefint.calibrated_value());
56 54
57 let temp = adc.read(&mut temperature).await; 55 let temp = adc.read(&mut temperature, SampleTime::CYCLES601_5).await;
58 info!("read temperature: {}", temp); 56 info!("read temperature: {}", temp);
59 57
60 let buffer = adc.read(&mut buffer).await; 58 let buffer = adc.read(&mut buffer, SampleTime::CYCLES601_5).await;
61 info!("read buffer: {}", buffer); 59 info!("read buffer: {}", buffer);
62 60
63 let pin_mv = (buffer as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; 61 let pin_mv = (buffer as u32 * vrefint.calibrated_value() as u32 / vref as u32) * 3300 / 4095;
64 info!("computed pin mv: {}", pin_mv); 62 info!("computed pin mv: {}", pin_mv);
65 63
66 Timer::after_millis(500).await; 64 Timer::after_millis(500).await;
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index 423d29225..5628cb827 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -4,7 +4,7 @@
4use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs; 4use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::adc::{Adc, Temperature, VrefInt}; 7use embassy_stm32::adc::{Adc, SampleTime, Temperature, VrefInt};
8use embassy_time::{Delay, Timer}; 8use embassy_time::{Delay, Timer};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
@@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
23 // Startup delay can be combined to the maximum of either 23 // Startup delay can be combined to the maximum of either
24 delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us())); 24 delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
25 25
26 let vrefint_sample = adc.blocking_read(&mut vrefint); 26 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
27 27
28 let convert_to_millivolts = |sample| { 28 let convert_to_millivolts = |sample| {
29 // From http://www.st.com/resource/en/datasheet/DM00071990.pdf 29 // From http://www.st.com/resource/en/datasheet/DM00071990.pdf
@@ -50,16 +50,16 @@ async fn main(_spawner: Spawner) {
50 50
51 loop { 51 loop {
52 // Read pin 52 // Read pin
53 let v = adc.blocking_read(&mut pin); 53 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES112);
54 info!("PC1: {} ({} mV)", v, convert_to_millivolts(v)); 54 info!("PC1: {} ({} mV)", v, convert_to_millivolts(v));
55 55
56 // Read internal temperature 56 // Read internal temperature
57 let v = adc.blocking_read(&mut temp); 57 let v = adc.blocking_read(&mut temp, SampleTime::CYCLES112);
58 let celcius = convert_to_celcius(v); 58 let celcius = convert_to_celcius(v);
59 info!("Internal temp: {} ({} C)", v, celcius); 59 info!("Internal temp: {} ({} C)", v, celcius);
60 60
61 // Read internal voltage reference 61 // Read internal voltage reference
62 let v = adc.blocking_read(&mut vrefint); 62 let v = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
63 info!("VrefInt: {}", v); 63 info!("VrefInt: {}", v);
64 64
65 Timer::after_millis(100).await; 65 Timer::after_millis(100).await;
diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs
index f8da91336..01b881c79 100644
--- a/examples/stm32f4/src/bin/adc_dma.rs
+++ b/examples/stm32f4/src/bin/adc_dma.rs
@@ -27,8 +27,8 @@ async fn adc_task(p: Peripherals) {
27 p.DMA2_CH0, 27 p.DMA2_CH0,
28 adc_data, 28 adc_data,
29 [ 29 [
30 (&mut p.PA0.degrade_adc(), SampleTime::CYCLES112), 30 (p.PA0.degrade_adc(), SampleTime::CYCLES112),
31 (&mut p.PA2.degrade_adc(), SampleTime::CYCLES112), 31 (p.PA2.degrade_adc(), SampleTime::CYCLES112),
32 ] 32 ]
33 .into_iter(), 33 .into_iter(),
34 ); 34 );
@@ -36,8 +36,8 @@ async fn adc_task(p: Peripherals) {
36 p.DMA2_CH2, 36 p.DMA2_CH2,
37 adc_data2, 37 adc_data2,
38 [ 38 [
39 (&mut p.PA1.degrade_adc(), SampleTime::CYCLES112), 39 (p.PA1.degrade_adc(), SampleTime::CYCLES112),
40 (&mut p.PA3.degrade_adc(), SampleTime::CYCLES112), 40 (p.PA3.degrade_adc(), SampleTime::CYCLES112),
41 ] 41 ]
42 .into_iter(), 42 .into_iter(),
43 ); 43 );
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs
index 6689e3b5d..0f226d34e 100644
--- a/examples/stm32f7/src/bin/adc.rs
+++ b/examples/stm32f7/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::Adc; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_time::Timer; 7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) {
16 let mut pin = p.PA3; 16 let mut pin = p.PA3;
17 17
18 let mut vrefint = adc.enable_vrefint(); 18 let mut vrefint = adc.enable_vrefint();
19 let vrefint_sample = adc.blocking_read(&mut vrefint); 19 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
20 let convert_to_millivolts = |sample| { 20 let convert_to_millivolts = |sample| {
21 // From http://www.st.com/resource/en/datasheet/DM00273119.pdf 21 // From http://www.st.com/resource/en/datasheet/DM00273119.pdf
22 // 6.3.27 Reference voltage 22 // 6.3.27 Reference voltage
@@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) {
26 }; 26 };
27 27
28 loop { 28 loop {
29 let v = adc.blocking_read(&mut pin); 29 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES112);
30 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 30 info!("--> {} - {} mV", v, convert_to_millivolts(v));
31 Timer::after_millis(100).await; 31 Timer::after_millis(100).await;
32 } 32 }
diff --git a/examples/stm32g0/src/bin/adc.rs b/examples/stm32g0/src/bin/adc.rs
index 7d8653ef2..972e43b55 100644
--- a/examples/stm32g0/src/bin/adc.rs
+++ b/examples/stm32g0/src/bin/adc.rs
@@ -13,11 +13,10 @@ async fn main(_spawner: Spawner) {
13 info!("Hello World!"); 13 info!("Hello World!");
14 14
15 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 }); 15 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 });
16 adc.set_sample_time(SampleTime::CYCLES79_5);
17 let mut pin = p.PA1; 16 let mut pin = p.PA1;
18 17
19 let mut vrefint = adc.enable_vrefint(); 18 let mut vrefint = adc.enable_vrefint();
20 let vrefint_sample = adc.blocking_read(&mut vrefint); 19 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
21 let convert_to_millivolts = |sample| { 20 let convert_to_millivolts = |sample| {
22 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 21 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
23 // 6.3.3 Embedded internal reference voltage 22 // 6.3.3 Embedded internal reference voltage
@@ -27,7 +26,7 @@ async fn main(_spawner: Spawner) {
27 }; 26 };
28 27
29 loop { 28 loop {
30 let v = adc.blocking_read(&mut pin); 29 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
31 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 30 info!("--> {} - {} mV", v, convert_to_millivolts(v));
32 Timer::after_millis(100).await; 31 Timer::after_millis(100).await;
33 } 32 }
diff --git a/examples/stm32g0/src/bin/adc_oversampling.rs b/examples/stm32g0/src/bin/adc_oversampling.rs
index 834d1cd4a..f6979889d 100644
--- a/examples/stm32g0/src/bin/adc_oversampling.rs
+++ b/examples/stm32g0/src/bin/adc_oversampling.rs
@@ -17,7 +17,6 @@ async fn main(_spawner: Spawner) {
17 info!("Adc oversample test"); 17 info!("Adc oversample test");
18 18
19 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 }); 19 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 });
20 adc.set_sample_time(SampleTime::CYCLES1_5);
21 let mut pin = p.PA1; 20 let mut pin = p.PA1;
22 21
23 adc.set_oversampling_ratio(Ovsr::MUL16); 22 adc.set_oversampling_ratio(Ovsr::MUL16);
@@ -25,7 +24,7 @@ async fn main(_spawner: Spawner) {
25 adc.oversampling_enable(true); 24 adc.oversampling_enable(true);
26 25
27 loop { 26 loop {
28 let v = adc.blocking_read(&mut pin); 27 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES1_5);
29 info!("--> {} ", v); //max 65520 = 0xFFF0 28 info!("--> {} ", v); //max 65520 = 0xFFF0
30 Timer::after_millis(100).await; 29 Timer::after_millis(100).await;
31 } 30 }
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 920142a18..695f37115 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -29,10 +29,9 @@ async fn main(_spawner: Spawner) {
29 info!("Hello World!"); 29 info!("Hello World!");
30 30
31 let mut adc = Adc::new(p.ADC2); 31 let mut adc = Adc::new(p.ADC2);
32 adc.set_sample_time(SampleTime::CYCLES24_5);
33 32
34 loop { 33 loop {
35 let measured = adc.blocking_read(&mut p.PA7); 34 let measured = adc.blocking_read(&mut p.PA7, SampleTime::CYCLES24_5);
36 info!("measured: {}", measured); 35 info!("measured: {}", measured);
37 Timer::after_millis(500).await; 36 Timer::after_millis(500).await;
38 } 37 }
diff --git a/examples/stm32g4/src/bin/adc_differential.rs b/examples/stm32g4/src/bin/adc_differential.rs
index 301f0da84..a6e2f7d33 100644
--- a/examples/stm32g4/src/bin/adc_differential.rs
+++ b/examples/stm32g4/src/bin/adc_differential.rs
@@ -33,14 +33,13 @@ async fn main(_spawner: Spawner) {
33 let mut p = embassy_stm32::init(config); 33 let mut p = embassy_stm32::init(config);
34 34
35 let mut adc = Adc::new(p.ADC1); 35 let mut adc = Adc::new(p.ADC1);
36 adc.set_sample_time(SampleTime::CYCLES247_5);
37 adc.set_differential(&mut p.PA0, true); //p:pa0,n:pa1 36 adc.set_differential(&mut p.PA0, true); //p:pa0,n:pa1
38 37
39 // can also use 38 // can also use
40 // adc.set_differential_channel(1, true); 39 // adc.set_differential_channel(1, true);
41 info!("adc initialized"); 40 info!("adc initialized");
42 loop { 41 loop {
43 let measured = adc.blocking_read(&mut p.PA0); 42 let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES247_5);
44 info!("data: {}", measured); 43 info!("data: {}", measured);
45 Timer::after_millis(500).await; 44 Timer::after_millis(500).await;
46 } 45 }
diff --git a/examples/stm32g4/src/bin/adc_oversampling.rs b/examples/stm32g4/src/bin/adc_oversampling.rs
index 1e464183a..cb99ab2a7 100644
--- a/examples/stm32g4/src/bin/adc_oversampling.rs
+++ b/examples/stm32g4/src/bin/adc_oversampling.rs
@@ -33,7 +33,6 @@ async fn main(_spawner: Spawner) {
33 let mut p = embassy_stm32::init(config); 33 let mut p = embassy_stm32::init(config);
34 34
35 let mut adc = Adc::new(p.ADC1); 35 let mut adc = Adc::new(p.ADC1);
36 adc.set_sample_time(SampleTime::CYCLES6_5);
37 // From https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf 36 // From https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
38 // page652 Oversampler 37 // page652 Oversampler
39 // Table 172. Maximum output results vs N and M. Grayed values indicates truncation 38 // Table 172. Maximum output results vs N and M. Grayed values indicates truncation
@@ -50,7 +49,7 @@ async fn main(_spawner: Spawner) {
50 adc.enable_regular_oversampling_mode(Rovsm::RESUMED, Trovs::AUTOMATIC, true); 49 adc.enable_regular_oversampling_mode(Rovsm::RESUMED, Trovs::AUTOMATIC, true);
51 50
52 loop { 51 loop {
53 let measured = adc.blocking_read(&mut p.PA0); 52 let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES6_5);
54 info!("data: 0x{:X}", measured); //max 0xFFF0 -> 65520 53 info!("data: 0x{:X}", measured); //max 0xFFF0 -> 65520
55 Timer::after_millis(500).await; 54 Timer::after_millis(500).await;
56 } 55 }
diff --git a/examples/stm32h5/src/bin/adc.rs b/examples/stm32h5/src/bin/adc.rs
index 0566320d4..c919b1a95 100644
--- a/examples/stm32h5/src/bin/adc.rs
+++ b/examples/stm32h5/src/bin/adc.rs
@@ -45,14 +45,12 @@ async fn main(_spawner: Spawner) {
45 45
46 let mut adc = Adc::new(p.ADC1); 46 let mut adc = Adc::new(p.ADC1);
47 47
48 adc.set_sample_time(SampleTime::CYCLES24_5);
49
50 let mut vrefint_channel = adc.enable_vrefint(); 48 let mut vrefint_channel = adc.enable_vrefint();
51 49
52 loop { 50 loop {
53 let vrefint = adc.blocking_read(&mut vrefint_channel); 51 let vrefint = adc.blocking_read(&mut vrefint_channel, SampleTime::CYCLES24_5);
54 info!("vrefint: {}", vrefint); 52 info!("vrefint: {}", vrefint);
55 let measured = adc.blocking_read(&mut p.PA0); 53 let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES24_5);
56 info!("measured: {}", measured); 54 info!("measured: {}", measured);
57 Timer::after_millis(500).await; 55 Timer::after_millis(500).await;
58 } 56 }
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index a53c9d8d5..fc45541bf 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -46,14 +46,12 @@ async fn main(_spawner: Spawner) {
46 46
47 let mut adc = Adc::new(p.ADC3); 47 let mut adc = Adc::new(p.ADC3);
48 48
49 adc.set_sample_time(SampleTime::CYCLES32_5);
50
51 let mut vrefint_channel = adc.enable_vrefint(); 49 let mut vrefint_channel = adc.enable_vrefint();
52 50
53 loop { 51 loop {
54 let vrefint = adc.blocking_read(&mut vrefint_channel); 52 let vrefint = adc.blocking_read(&mut vrefint_channel, SampleTime::CYCLES32_5);
55 info!("vrefint: {}", vrefint); 53 info!("vrefint: {}", vrefint);
56 let measured = adc.blocking_read(&mut p.PC0); 54 let measured = adc.blocking_read(&mut p.PC0, SampleTime::CYCLES32_5);
57 info!("measured: {}", measured); 55 info!("measured: {}", measured);
58 Timer::after_millis(500).await; 56 Timer::after_millis(500).await;
59 } 57 }
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs
index 9dd09bc45..83be74ed9 100644
--- a/examples/stm32l0/src/bin/adc.rs
+++ b/examples/stm32l0/src/bin/adc.rs
@@ -19,11 +19,10 @@ async fn main(_spawner: Spawner) {
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC1, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES79_5);
23 let mut pin = p.PA1; 22 let mut pin = p.PA1;
24 23
25 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
26 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES79_5).await;
27 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
28 // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf
29 // 6.3.3 Embedded internal reference voltage 28 // 6.3.3 Embedded internal reference voltage
@@ -33,7 +32,7 @@ async fn main(_spawner: Spawner) {
33 }; 32 };
34 33
35 loop { 34 loop {
36 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES79_5).await;
37 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
38 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
39 } 38 }
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index 40e907940..835bf5411 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::Config; 5use embassy_stm32::Config;
6use embassy_stm32::adc::{Adc, Resolution}; 6use embassy_stm32::adc::{Adc, Resolution, SampleTime};
7use {defmt_rtt as _, panic_probe as _}; 7use {defmt_rtt as _, panic_probe as _};
8 8
9#[cortex_m_rt::entry] 9#[cortex_m_rt::entry]
@@ -23,7 +23,7 @@ fn main() -> ! {
23 let mut channel = p.PC0; 23 let mut channel = p.PC0;
24 24
25 loop { 25 loop {
26 let v = adc.blocking_read(&mut channel); 26 let v = adc.blocking_read(&mut channel, SampleTime::from_bits(0));
27 info!("--> {}", v); 27 info!("--> {}", v);
28 } 28 }
29} 29}
diff --git a/examples/stm32l4/src/bin/adc_dma.rs b/examples/stm32l4/src/bin/adc_dma.rs
index 7a9200edd..ab1e9d2e9 100644
--- a/examples/stm32l4/src/bin/adc_dma.rs
+++ b/examples/stm32l4/src/bin/adc_dma.rs
@@ -21,18 +21,14 @@ async fn main(_spawner: Spawner) {
21 let p = embassy_stm32::init(config); 21 let p = embassy_stm32::init(config);
22 22
23 let mut adc = Adc::new(p.ADC1); 23 let mut adc = Adc::new(p.ADC1);
24 let mut adc_pin0 = p.PA0.degrade_adc(); 24 let adc_pin0 = p.PA0.degrade_adc();
25 let mut adc_pin1 = p.PA1.degrade_adc(); 25 let adc_pin1 = p.PA1.degrade_adc();
26 let mut adc_dma_buf = [0u16; DMA_BUF_LEN]; 26 let mut adc_dma_buf = [0u16; DMA_BUF_LEN];
27 let mut measurements = [0u16; DMA_BUF_LEN / 2]; 27 let mut measurements = [0u16; DMA_BUF_LEN / 2];
28 let mut ring_buffered_adc = adc.into_ring_buffered( 28 let mut ring_buffered_adc = adc.into_ring_buffered(
29 p.DMA1_CH1, 29 p.DMA1_CH1,
30 &mut adc_dma_buf, 30 &mut adc_dma_buf,
31 [ 31 [(adc_pin0, SampleTime::CYCLES640_5), (adc_pin1, SampleTime::CYCLES640_5)].into_iter(),
32 (&mut adc_pin0, SampleTime::CYCLES640_5),
33 (&mut adc_pin1, SampleTime::CYCLES640_5),
34 ]
35 .into_iter(),
36 ); 32 );
37 33
38 info!("starting measurement loop"); 34 info!("starting measurement loop");
diff --git a/examples/stm32u0/src/bin/adc.rs b/examples/stm32u0/src/bin/adc.rs
index 32a54299d..4fbc6f17f 100644
--- a/examples/stm32u0/src/bin/adc.rs
+++ b/examples/stm32u0/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::Config; 5use embassy_stm32::Config;
6use embassy_stm32::adc::{Adc, Resolution}; 6use embassy_stm32::adc::{Adc, Resolution, SampleTime};
7use embassy_time::Duration; 7use embassy_time::Duration;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -23,7 +23,7 @@ fn main() -> ! {
23 let mut channel = p.PC0; 23 let mut channel = p.PC0;
24 24
25 loop { 25 loop {
26 let v = adc.blocking_read(&mut channel); 26 let v = adc.blocking_read(&mut channel, SampleTime::CYCLES12_5);
27 info!("--> {}", v); 27 info!("--> {}", v);
28 embassy_time::block_for(Duration::from_millis(200)); 28 embassy_time::block_for(Duration::from_millis(200));
29 } 29 }
diff --git a/examples/stm32u5/src/bin/adc.rs b/examples/stm32u5/src/bin/adc.rs
index 91e33053e..99944f7c7 100644
--- a/examples/stm32u5/src/bin/adc.rs
+++ b/examples/stm32u5/src/bin/adc.rs
@@ -2,8 +2,7 @@
2#![no_main] 2#![no_main]
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::adc; 5use embassy_stm32::adc::{self, AdcChannel, SampleTime, adc4};
6use embassy_stm32::adc::{AdcChannel, adc4};
7use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
8 7
9#[embassy_executor::main] 8#[embassy_executor::main]
@@ -18,7 +17,6 @@ async fn main(_spawner: embassy_executor::Spawner) {
18 let mut adc1_pin2 = p.PA2; // A1 17 let mut adc1_pin2 = p.PA2; // A1
19 adc1.set_resolution(adc::Resolution::BITS14); 18 adc1.set_resolution(adc::Resolution::BITS14);
20 adc1.set_averaging(adc::Averaging::Samples1024); 19 adc1.set_averaging(adc::Averaging::Samples1024);
21 adc1.set_sample_time(adc::SampleTime::CYCLES160_5);
22 let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14); 20 let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14);
23 21
24 // **** ADC2 init **** 22 // **** ADC2 init ****
@@ -27,7 +25,6 @@ async fn main(_spawner: embassy_executor::Spawner) {
27 let mut adc2_pin2 = p.PB0; // A3 25 let mut adc2_pin2 = p.PB0; // A3
28 adc2.set_resolution(adc::Resolution::BITS14); 26 adc2.set_resolution(adc::Resolution::BITS14);
29 adc2.set_averaging(adc::Averaging::Samples1024); 27 adc2.set_averaging(adc::Averaging::Samples1024);
30 adc2.set_sample_time(adc::SampleTime::CYCLES160_5);
31 let max2 = adc::resolution_to_max_count(adc::Resolution::BITS14); 28 let max2 = adc::resolution_to_max_count(adc::Resolution::BITS14);
32 29
33 // **** ADC4 init **** 30 // **** ADC4 init ****
@@ -36,33 +33,32 @@ async fn main(_spawner: embassy_executor::Spawner) {
36 let mut adc4_pin2 = p.PC0; // A5 33 let mut adc4_pin2 = p.PC0; // A5
37 adc4.set_resolution(adc4::Resolution::BITS12); 34 adc4.set_resolution(adc4::Resolution::BITS12);
38 adc4.set_averaging(adc4::Averaging::Samples256); 35 adc4.set_averaging(adc4::Averaging::Samples256);
39 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
40 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 36 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
41 37
42 // **** ADC1 blocking read **** 38 // **** ADC1 blocking read ****
43 let raw: u16 = adc1.blocking_read(&mut adc1_pin1); 39 let raw: u16 = adc1.blocking_read(&mut adc1_pin1, SampleTime::CYCLES160_5);
44 let volt: f32 = 3.3 * raw as f32 / max1 as f32; 40 let volt: f32 = 3.3 * raw as f32 / max1 as f32;
45 info!("Read adc1 pin 1 {}", volt); 41 info!("Read adc1 pin 1 {}", volt);
46 42
47 let raw: u16 = adc1.blocking_read(&mut adc1_pin2); 43 let raw: u16 = adc1.blocking_read(&mut adc1_pin2, SampleTime::CYCLES160_5);
48 let volt: f32 = 3.3 * raw as f32 / max1 as f32; 44 let volt: f32 = 3.3 * raw as f32 / max1 as f32;
49 info!("Read adc1 pin 2 {}", volt); 45 info!("Read adc1 pin 2 {}", volt);
50 46
51 // **** ADC2 blocking read **** 47 // **** ADC2 blocking read ****
52 let raw: u16 = adc2.blocking_read(&mut adc2_pin1); 48 let raw: u16 = adc2.blocking_read(&mut adc2_pin1, SampleTime::CYCLES160_5);
53 let volt: f32 = 3.3 * raw as f32 / max2 as f32; 49 let volt: f32 = 3.3 * raw as f32 / max2 as f32;
54 info!("Read adc2 pin 1 {}", volt); 50 info!("Read adc2 pin 1 {}", volt);
55 51
56 let raw: u16 = adc2.blocking_read(&mut adc2_pin2); 52 let raw: u16 = adc2.blocking_read(&mut adc2_pin2, SampleTime::CYCLES160_5);
57 let volt: f32 = 3.3 * raw as f32 / max2 as f32; 53 let volt: f32 = 3.3 * raw as f32 / max2 as f32;
58 info!("Read adc2 pin 2 {}", volt); 54 info!("Read adc2 pin 2 {}", volt);
59 55
60 // **** ADC4 blocking read **** 56 // **** ADC4 blocking read ****
61 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 57 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
62 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 58 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
63 info!("Read adc4 pin 1 {}", volt); 59 info!("Read adc4 pin 1 {}", volt);
64 60
65 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 61 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
66 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 62 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
67 info!("Read adc4 pin 2 {}", volt); 63 info!("Read adc4 pin 2 {}", volt);
68 64
diff --git a/examples/stm32wba/src/bin/adc.rs b/examples/stm32wba/src/bin/adc.rs
index 8c80470b8..177aab3f3 100644
--- a/examples/stm32wba/src/bin/adc.rs
+++ b/examples/stm32wba/src/bin/adc.rs
@@ -17,15 +17,15 @@ async fn main(_spawner: embassy_executor::Spawner) {
17 let mut adc4_pin2 = p.PA1; // A5 17 let mut adc4_pin2 = p.PA1; // A5
18 adc4.set_resolution(adc4::Resolution::BITS12); 18 adc4.set_resolution(adc4::Resolution::BITS12);
19 adc4.set_averaging(adc4::Averaging::Samples256); 19 adc4.set_averaging(adc4::Averaging::Samples256);
20 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5); 20
21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
22 22
23 // **** ADC4 blocking read **** 23 // **** ADC4 blocking read ****
24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
25 let volt: f32 = 3.0 * raw as f32 / max4 as f32; 25 let volt: f32 = 3.0 * raw as f32 / max4 as f32;
26 info!("Read adc4 pin 1 {}", volt); 26 info!("Read adc4 pin 1 {}", volt);
27 27
28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
29 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 29 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
30 info!("Read adc4 pin 2 {}", volt); 30 info!("Read adc4 pin 2 {}", volt);
31 31
diff --git a/examples/stm32wba6/src/bin/adc.rs b/examples/stm32wba6/src/bin/adc.rs
index 8c80470b8..0887e124c 100644
--- a/examples/stm32wba6/src/bin/adc.rs
+++ b/examples/stm32wba6/src/bin/adc.rs
@@ -17,15 +17,14 @@ async fn main(_spawner: embassy_executor::Spawner) {
17 let mut adc4_pin2 = p.PA1; // A5 17 let mut adc4_pin2 = p.PA1; // A5
18 adc4.set_resolution(adc4::Resolution::BITS12); 18 adc4.set_resolution(adc4::Resolution::BITS12);
19 adc4.set_averaging(adc4::Averaging::Samples256); 19 adc4.set_averaging(adc4::Averaging::Samples256);
20 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 20 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
22 21
23 // **** ADC4 blocking read **** 22 // **** ADC4 blocking read ****
24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 23 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
25 let volt: f32 = 3.0 * raw as f32 / max4 as f32; 24 let volt: f32 = 3.0 * raw as f32 / max4 as f32;
26 info!("Read adc4 pin 1 {}", volt); 25 info!("Read adc4 pin 1 {}", volt);
27 26
28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 27 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
29 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 28 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
30 info!("Read adc4 pin 2 {}", volt); 29 info!("Read adc4 pin 2 {}", volt);
31 30
diff --git a/examples/stm32wl/src/bin/adc.rs b/examples/stm32wl/src/bin/adc.rs
index 6b21b086b..adabe0df8 100644
--- a/examples/stm32wl/src/bin/adc.rs
+++ b/examples/stm32wl/src/bin/adc.rs
@@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) {
18 info!("Hello World!"); 18 info!("Hello World!");
19 19
20 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Sync { div: CkModePclk::DIV1 }); 20 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Sync { div: CkModePclk::DIV1 });
21 adc.set_sample_time(SampleTime::CYCLES79_5); 21
22 let mut pin = p.PB2; 22 let mut pin = p.PB2;
23 23
24 let mut vrefint = adc.enable_vrefint(); 24 let mut vrefint = adc.enable_vrefint();
25 let vrefint_sample = adc.blocking_read(&mut vrefint); 25 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
26 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
27 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
28 // 6.3.3 Embedded internal reference voltage 28 // 6.3.3 Embedded internal reference voltage
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
32 }; 32 };
33 33
34 loop { 34 loop {
35 let v = adc.blocking_read(&mut pin); 35 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
36 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
37 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
38 } 38 }
diff --git a/examples/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs
index 8b830a1e6..4e0574d97 100644
--- a/examples/stm32wle5/src/bin/adc.rs
+++ b/examples/stm32wle5/src/bin/adc.rs
@@ -73,11 +73,10 @@ async fn async_main(_spawner: Spawner) {
73 info!("Hello World!"); 73 info!("Hello World!");
74 74
75 let mut adc = Adc::new(p.ADC1); 75 let mut adc = Adc::new(p.ADC1);
76 adc.set_sample_time(SampleTime::CYCLES79_5);
77 let mut pin = p.PA10; 76 let mut pin = p.PA10;
78 77
79 let mut vrefint = adc.enable_vrefint(); 78 let mut vrefint = adc.enable_vrefint();
80 let vrefint_sample = adc.blocking_read(&mut vrefint); 79 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
81 let convert_to_millivolts = |sample| { 80 let convert_to_millivolts = |sample| {
82 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 81 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
83 // 6.3.3 Embedded internal reference voltage 82 // 6.3.3 Embedded internal reference voltage
@@ -87,7 +86,7 @@ async fn async_main(_spawner: Spawner) {
87 }; 86 };
88 87
89 loop { 88 loop {
90 let v = adc.blocking_read(&mut pin); 89 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
91 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 90 info!("--> {} - {} mV", v, convert_to_millivolts(v));
92 Timer::after_secs(1).await; 91 Timer::after_secs(1).await;
93 } 92 }
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
index d34bbb255..747b11e7f 100644
--- a/tests/stm32/src/bin/dac.rs
+++ b/tests/stm32/src/bin/dac.rs
@@ -10,7 +10,7 @@ use core::f32::consts::PI;
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::{Adc, SampleTime};
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_time::Timer; 15use embassy_time::Timer;
16use micromath::F32Ext; 16use micromath::F32Ext;
@@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) {
37 dac.set(Value::Bit8(0)); 37 dac.set(Value::Bit8(0));
38 // Now wait a little to obtain a stable value 38 // Now wait a little to obtain a stable value
39 Timer::after_millis(30).await; 39 Timer::after_millis(30).await;
40 let offset = adc.blocking_read(&mut adc_pin); 40 let offset = adc.blocking_read(&mut adc_pin, SampleTime::from_bits(0));
41 41
42 for v in 0..=255 { 42 for v in 0..=255 {
43 // First set the DAC output value 43 // First set the DAC output value
@@ -48,7 +48,10 @@ async fn main(_spawner: Spawner) {
48 Timer::after_millis(30).await; 48 Timer::after_millis(30).await;
49 49
50 // Need to steal the peripherals here because PA4 is obviously in use already 50 // Need to steal the peripherals here because PA4 is obviously in use already
51 let measured = adc.blocking_read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); 51 let measured = adc.blocking_read(
52 &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4,
53 SampleTime::from_bits(0),
54 );
52 // Calibrate and normalize the measurement to get close to the dac_output_val 55 // Calibrate and normalize the measurement to get close to the dac_output_val
53 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; 56 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
54 57
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs
index e6400f28e..2fe0cf1f1 100644
--- a/tests/stm32/src/bin/dac_l1.rs
+++ b/tests/stm32/src/bin/dac_l1.rs
@@ -10,7 +10,7 @@ use core::f32::consts::PI;
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::{Adc, SampleTime};
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::{bind_interrupts, peripherals}; 15use embassy_stm32::{bind_interrupts, peripherals};
16use embassy_time::Timer; 16use embassy_time::Timer;
@@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) {
47 dac.set(Value::Bit8(0)); 47 dac.set(Value::Bit8(0));
48 // Now wait a little to obtain a stable value 48 // Now wait a little to obtain a stable value
49 Timer::after_millis(30).await; 49 Timer::after_millis(30).await;
50 let offset = adc.read(&mut adc_pin).await; 50 let offset = adc.read(&mut adc_pin, SampleTime::from_bits(0)).await;
51 51
52 for v in 0..=255 { 52 for v in 0..=255 {
53 // First set the DAC output value 53 // First set the DAC output value
@@ -58,7 +58,12 @@ async fn main(_spawner: Spawner) {
58 Timer::after_millis(30).await; 58 Timer::after_millis(30).await;
59 59
60 // Need to steal the peripherals here because PA4 is obviously in use already 60 // Need to steal the peripherals here because PA4 is obviously in use already
61 let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4).await; 61 let measured = adc
62 .read(
63 &mut unsafe { embassy_stm32::Peripherals::steal() }.PA4,
64 SampleTime::from_bits(0),
65 )
66 .await;
62 // Calibrate and normalize the measurement to get close to the dac_output_val 67 // Calibrate and normalize the measurement to get close to the dac_output_val
63 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; 68 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
64 69