diff options
author | YH Lin <yueherngl@google.com> | 2019-03-11 14:24:26 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-03-13 10:38:54 -0700 |
commit | ffc86c893578ac273630a7766f9cca13ba31d645 (patch) | |
tree | aed7a6deac5ea07579ec11676992f98e659f2a05 /chip/stm32/adc-stm32f0.c | |
parent | 946bbd9a353a22a77d86af2a83d8ac5d1a66d665 (diff) | |
download | chrome-ec-ffc86c893578ac273630a7766f9cca13ba31d645.tar.gz |
adc-stm32f0: initialize adc upon invocation of channel read
In some scenarios ADC read needs to be done before hook_init handler
take place therefore calling adc_init() directly upon invocation of
adc_read_channel, instead of waiting for the hook_init handler to
initialize adc.
BUG=b:126770302
BRANCH=None
TEST=Test together with CL:1507320.
Change-Id: I8161e8a2d0051e01804e47eb87f28b3548f1d2ac
Signed-off-by: YH Lin <yueherngl@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1515821
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'chip/stm32/adc-stm32f0.c')
-rw-r--r-- | chip/stm32/adc-stm32f0.c | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/chip/stm32/adc-stm32f0.c b/chip/stm32/adc-stm32f0.c index 20c1013bf8..0f31e3b286 100644 --- a/chip/stm32/adc-stm32f0.c +++ b/chip/stm32/adc-stm32f0.c @@ -69,6 +69,41 @@ static const struct adc_profile_t profile = { }; #endif +static void adc_init(void) +{ + /* + * If clock is already enabled, and ADC module is enabled + * then this is a warm reboot and ADC is already initialized. + */ + if (STM32_RCC_APB2ENR & (1 << 9) && (STM32_ADC_CR & STM32_ADC_CR_ADEN)) + return; + + /* Enable ADC clock */ + clock_enable_module(MODULE_ADC, 1); + /* check HSI14 in RCC ? ON by default */ + + /* ADC calibration (done with ADEN = 0) */ + STM32_ADC_CR = STM32_ADC_CR_ADCAL; /* set ADCAL = 1, ADC off */ + /* wait for the end of calibration */ + while (STM32_ADC_CR & STM32_ADC_CR_ADCAL) + ; + + /* Single conversion, right aligned, 12-bit */ + STM32_ADC_CFGR1 = profile.cfgr1_reg; + /* clock is ADCCLK (ADEN must be off when writing this reg) */ + STM32_ADC_CFGR2 = profile.cfgr2_reg; + /* Sampling time */ + STM32_ADC_SMPR = profile.smpr_reg; + + /* + * 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; +} + static void adc_configure(int ain_id) { /* Select channel to convert */ @@ -258,6 +293,9 @@ int adc_read_channel(enum adc_channel ch) int restore_watchdog = 0; mutex_lock(&adc_lock); + + adc_init(); + if (adc_watchdog_enabled()) { restore_watchdog = 1; adc_disable_watchdog_no_lock(); @@ -293,39 +331,3 @@ void adc_disable(void) * STM32_ADC_CR_ADDIS bit will be cleared by hardware. */ } - -static void adc_init(void) -{ - /* - * If clock is already enabled, and ADC module is enabled - * then this is a warm reboot and ADC is already initialized. - */ - if (STM32_RCC_APB2ENR & (1 << 9) && (STM32_ADC_CR & STM32_ADC_CR_ADEN)) - return; - - /* Enable ADC clock */ - clock_enable_module(MODULE_ADC, 1); - /* check HSI14 in RCC ? ON by default */ - - /* ADC calibration (done with ADEN = 0) */ - STM32_ADC_CR = STM32_ADC_CR_ADCAL; /* set ADCAL = 1, ADC off */ - /* wait for the end of calibration */ - while (STM32_ADC_CR & STM32_ADC_CR_ADCAL) - ; - - /* Single conversion, right aligned, 12-bit */ - STM32_ADC_CFGR1 = profile.cfgr1_reg; - /* clock is ADCCLK (ADEN must be off when writing this reg) */ - STM32_ADC_CFGR2 = profile.cfgr2_reg; - /* Sampling time */ - STM32_ADC_SMPR = profile.smpr_reg; - - /* - * 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_INIT_ADC); |