stm32/adc: Factor out conversion logic
Also guard errata workaround correctly.
This commit is contained in:
parent
b6f84efd90
commit
e2e0464d04
@ -229,6 +229,27 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// Perform a single conversion.
|
||||||
|
fn convert(&mut self) -> u16 {
|
||||||
|
unsafe {
|
||||||
|
T::regs().isr().modify(|reg| {
|
||||||
|
reg.set_eos(true);
|
||||||
|
reg.set_eoc(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start conversion
|
||||||
|
T::regs().cr().modify(|reg| {
|
||||||
|
reg.set_adstart(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
while !T::regs().isr().read().eos() {
|
||||||
|
// spin
|
||||||
|
}
|
||||||
|
|
||||||
|
T::regs().dr().read().0 as u16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Make sure bits are off
|
// Make sure bits are off
|
||||||
@ -259,38 +280,16 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
// Select channel
|
// Select channel
|
||||||
T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
|
T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
|
||||||
|
|
||||||
// Start conversion
|
// Some models are affected by an erratum:
|
||||||
T::regs().isr().modify(|reg| {
|
// If we perform conversions slower than 1 kHz, the first read ADC value can be
|
||||||
reg.set_eos(true);
|
// corrupted, so we discard it and measure again.
|
||||||
reg.set_eoc(true);
|
//
|
||||||
});
|
// STM32L471xx: Section 2.7.3
|
||||||
T::regs().cr().modify(|reg| {
|
// STM32G4: Section 2.7.3
|
||||||
reg.set_adstart(true);
|
#[cfg(any(rcc_l4, rcc_g4))]
|
||||||
});
|
let _ = self.convert();
|
||||||
|
|
||||||
while !T::regs().isr().read().eos() {
|
let val = self.convert();
|
||||||
// spin
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read ADC value first time and discard it, as per errata sheet.
|
|
||||||
// The errata states that if we do conversions slower than 1 kHz, the
|
|
||||||
// first read ADC value can be corrupted, so we discard it and measure again.
|
|
||||||
|
|
||||||
let _ = T::regs().dr().read();
|
|
||||||
|
|
||||||
T::regs().isr().modify(|reg| {
|
|
||||||
reg.set_eos(true);
|
|
||||||
reg.set_eoc(true);
|
|
||||||
});
|
|
||||||
T::regs().cr().modify(|reg| {
|
|
||||||
reg.set_adstart(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
while !T::regs().isr().read().eos() {
|
|
||||||
// spin
|
|
||||||
}
|
|
||||||
|
|
||||||
let val = T::regs().dr().read().0 as u16;
|
|
||||||
|
|
||||||
T::regs().cr().modify(|reg| reg.set_addis(true));
|
T::regs().cr().modify(|reg| reg.set_addis(true));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user