Skip to content

Commit 3b2ef55

Browse files
chris-durandrleh
authored andcommitted
[stm32] Fix hang during F3/G4/L3 adc initialization for slow ADC clocks
Setting ADC_CR_ADEN after calibration is only possible after 4 ADC clock cycles have elapsed. In case the ADC clock is much slower than the CPU clock that flag was never set and the initialization blocked infinitely waiting for the ready flag to get set.
1 parent 98b1337 commit 3b2ef55

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/modm/platform/adc/stm32f3/adc_impl.hpp.in

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,18 @@ modm::platform::Adc{{ id }}::initialize(const ClockMode clk,
6565
ADC{{ id }}->CR |= static_cast<uint32_t>(VoltageRegulatorState::Enabled);
6666
modm::delay_us(10); // FIXME: this is ugly -> find better solution
6767

68-
// Clear ready flag
69-
ADC{{ id }}->ISR |= ADC_ISR_ADRDY;
68+
acknowledgeInterruptFlag(InterruptFlag::Ready);
7069

7170
calibrate(cal, true); // blocking calibration
7271

7372
ADC{{ id }}->CR |= ADC_CR_ADEN;
7473
if (blocking) {
75-
while(not isReady());
74+
// ADEN can only be set 4 ADC clock cycles after ADC_CR_ADCAL gets
75+
// cleared. Setting it in a loop ensures the flag gets set for ADC
76+
// clocks slower than the CPU clock.
77+
while (not isReady()) {
78+
ADC{{ id }}->CR |= ADC_CR_ADEN;
79+
}
7680
acknowledgeInterruptFlag(InterruptFlag::Ready);
7781
}
7882
}

0 commit comments

Comments
 (0)