diff options
| -rw-r--r-- | embassy-stm32/src/adc/v3.rs | 61 |
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 | ||
