aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/adc/v3.rs61
1 files changed, 30 insertions, 31 deletions
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 2781fc4dc..d80c9ffc0 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -229,6 +229,27 @@ impl<'d, T: Instance> Adc<'d, T> {
229 } 229 }
230 */ 230 */
231 231
232 /// Perform a single conversion.
233 fn convert(&mut self) -> u16 {
234 unsafe {
235 T::regs().isr().modify(|reg| {
236 reg.set_eos(true);
237 reg.set_eoc(true);
238 });
239
240 // Start conversion
241 T::regs().cr().modify(|reg| {
242 reg.set_adstart(true);
243 });
244
245 while !T::regs().isr().read().eos() {
246 // spin
247 }
248
249 T::regs().dr().read().0 as u16
250 }
251 }
252
232 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 253 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
233 unsafe { 254 unsafe {
234 // Make sure bits are off 255 // Make sure bits are off
@@ -259,38 +280,16 @@ impl<'d, T: Instance> Adc<'d, T> {
259 // Select channel 280 // Select channel
260 T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); 281 T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
261 282
262 // Start conversion 283 // Some models are affected by an erratum:
263 T::regs().isr().modify(|reg| { 284 // If we perform conversions slower than 1 kHz, the first read ADC value can be
264 reg.set_eos(true); 285 // corrupted, so we discard it and measure again.
265 reg.set_eoc(true); 286 //
266 }); 287 // STM32L471xx: Section 2.7.3
267 T::regs().cr().modify(|reg| { 288 // STM32G4: Section 2.7.3
268 reg.set_adstart(true); 289 #[cfg(any(rcc_l4, rcc_g4))]
269 }); 290 let _ = self.convert();
270
271 while !T::regs().isr().read().eos() {
272 // spin
273 }
274
275 // Read ADC value first time and discard it, as per errata sheet.
276 // The errata states that if we do conversions slower than 1 kHz, the
277 // first read ADC value can be corrupted, so we discard it and measure again.
278
279 let _ = T::regs().dr().read();
280
281 T::regs().isr().modify(|reg| {
282 reg.set_eos(true);
283 reg.set_eoc(true);
284 });
285 T::regs().cr().modify(|reg| {
286 reg.set_adstart(true);
287 });
288
289 while !T::regs().isr().read().eos() {
290 // spin
291 }
292 291
293 let val = T::regs().dr().read().0 as u16; 292 let val = self.convert();
294 293
295 T::regs().cr().modify(|reg| reg.set_addis(true)); 294 T::regs().cr().modify(|reg| reg.set_addis(true));
296 295