mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
stm32f0: fix potential hang in adc initialization
Fix bug that can cause ADC initialization to hang and eventually watchdog. Problem was that you need at least 4 ADC clock cycles between end of ADC calibration and enabling ADC (setting ADEN). Fix is to (1) move some ADC configuration to between end of cal and setting ADEN, and then just to be safe, (2) continually set ADEN until we see ADRDY (ADC ready). See bug report for more information. BUG=chrome-os-partner:32561 BRANCH=samus TEST=load onto a samus that regularly has ADC problems on boot. Using power+refresh verify that without this change PD hangs some of the time, and with this change it never hangs. Change-Id: Ifa4c3240ad7e1612647cc74e2105e6545ed19db4 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/221984 Reviewed-by: Vic Yang <victoryang@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
ac261c00c1
commit
1eec1e3cd4
@@ -109,18 +109,20 @@ static void adc_init(void)
|
||||
while (STM32_ADC_CR & STM32_ADC_CR_ADCAL)
|
||||
;
|
||||
}
|
||||
/* As per ST recommendation, ensure two cycles before setting ADEN */
|
||||
asm volatile("nop; nop;");
|
||||
/* ADC enabled */
|
||||
STM32_ADC_CR = STM32_ADC_ISR_ADRDY;
|
||||
while (!(STM32_ADC_ISR & STM32_ADC_ISR_ADRDY))
|
||||
;
|
||||
/* Single conversion, right aligned, 12-bit */
|
||||
STM32_ADC_CFGR1 = 1 << 12; /* (1 << 15) => AUTOOFF */;
|
||||
/* clock is ADCCLK */
|
||||
/* clock is ADCCLK (ADEN must be off when writing this reg) */
|
||||
STM32_ADC_CFGR2 = 0;
|
||||
/* Sampling time : 71.5 ADC clock cycles, about 5us */
|
||||
STM32_ADC_SMPR = 6;
|
||||
|
||||
/*
|
||||
* ADC enable (note: takes 4 ADC clocks between end of calibration
|
||||
* and setting ADEN).
|
||||
*/
|
||||
STM32_ADC_CR = STM32_ADC_CR_ADEN;
|
||||
while (!(STM32_ADC_ISR & STM32_ADC_ISR_ADRDY))
|
||||
STM32_ADC_CR = STM32_ADC_CR_ADEN;
|
||||
/* Disable interrupts */
|
||||
STM32_ADC_IER = 0;
|
||||
/* Analog watchdog IRQ */
|
||||
|
||||
@@ -294,19 +294,19 @@ static void adc_init(void)
|
||||
while (STM32_ADC_CR & STM32_ADC_CR_ADCAL)
|
||||
;
|
||||
|
||||
/* As per ST recommendation, ensure two cycles before setting ADEN */
|
||||
asm volatile("nop; nop;");
|
||||
|
||||
/* ADC enabled */
|
||||
STM32_ADC_CR = STM32_ADC_CR_ADEN;
|
||||
while (!(STM32_ADC_ISR & STM32_ADC_ISR_ADRDY))
|
||||
;
|
||||
|
||||
/* Single conversion, right aligned, 12-bit */
|
||||
STM32_ADC_CFGR1 = 1 << 12; /* (1 << 15) => AUTOOFF */;
|
||||
/* clock is ADCCLK */
|
||||
/* clock is ADCCLK (ADEN must be off when writing this reg) */
|
||||
STM32_ADC_CFGR2 = 0;
|
||||
/* Sampling time : 13.5 ADC clock cycles. */
|
||||
STM32_ADC_SMPR = 2;
|
||||
|
||||
/*
|
||||
* ADC enable (note: takes 4 ADC clocks between end of calibration
|
||||
* and setting ADEN).
|
||||
*/
|
||||
STM32_ADC_CR = STM32_ADC_CR_ADEN;
|
||||
while (!(STM32_ADC_ISR & STM32_ADC_ISR_ADRDY))
|
||||
STM32_ADC_CR = STM32_ADC_CR_ADEN;
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_DEFAULT);
|
||||
|
||||
Reference in New Issue
Block a user