diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2019-04-30 02:16:33 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-04 03:17:54 -0700 |
commit | b26d8bdc5ef3ed670c5f797f0b412696cb9ac16a (patch) | |
tree | bc5d63c984ca5bb87c97db18e17e5819f1a11634 | |
parent | fd12ea66de5374065983a1ba1a8f698e300020b6 (diff) | |
download | chrome-ec-b26d8bdc5ef3ed670c5f797f0b412696cb9ac16a.tar.gz |
stm32f0: Set ADC sampling rate before every read
Currently, the sampling rate is set only once in adc_init. This patch
makes EC set the sampling rate every time ADC is sampled.
This patch also adds STM32_ADC_SMPR_DEFAULT so that zero can be used to
specify the default sampling rate.
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
BUG=b/131579158
BRANCH=none
TEST=Verified ADC readings match with externally measured voltage
for LCM_ID, BATT_ID, and USBC_THERM.
TEST=buildall
Change-Id: I73a1352dec907c2a8724e2f3f3d0258a706910a7
Reviewed-on: https://chromium-review.googlesource.com/1589253
Commit-Ready: Daisuke Nojiri <dnojiri@chromium.org>
Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: YH Lin <yueherngl@chromium.org>
Reviewed-by: Nick Sanders <nsanders@chromium.org>
-rw-r--r-- | chip/stm32/adc-stm32f0.c | 36 | ||||
-rw-r--r-- | chip/stm32/adc_chip.h | 17 | ||||
-rw-r--r-- | chip/stm32/registers.h | 10 |
3 files changed, 39 insertions, 24 deletions
diff --git a/chip/stm32/adc-stm32f0.c b/chip/stm32/adc-stm32f0.c index add5c0c30c..8e2ac70bdb 100644 --- a/chip/stm32/adc-stm32f0.c +++ b/chip/stm32/adc-stm32f0.c @@ -36,15 +36,15 @@ static const struct dma_option dma_single = { STM32_DMA_CCR_MSIZE_32_BIT | STM32_DMA_CCR_PSIZE_32_BIT, }; +#ifndef CONFIG_ADC_SAMPLE_TIME +#define CONFIG_ADC_SAMPLE_TIME STM32_ADC_SMPR_13_5_CY +#endif + static const struct adc_profile_t profile = { /* Sample all channels once using DMA */ .cfgr1_reg = STM32_ADC_CFGR1_OVRMOD, .cfgr2_reg = 0, -#ifdef CONFIG_ADC_SAMPLE_TIME .smpr_reg = CONFIG_ADC_SAMPLE_TIME, -#else - .smpr_reg = STM32_ADC_SMPR_13_5_CY, -#endif .ier_reg = 0, .dma_option = &dma_single, .dma_buffer_size = 1, @@ -52,6 +52,11 @@ static const struct adc_profile_t profile = { #endif #ifdef CONFIG_ADC_PROFILE_FAST_CONTINUOUS + +#ifndef CONFIG_ADC_SAMPLE_TIME +#define CONFIG_ADC_SAMPLE_TIME STM32_ADC_SMPR_1_5_CY +#endif + static const struct dma_option dma_continuous = { STM32_DMAC_ADC, (void *)&STM32_ADC_DR, STM32_DMA_CCR_MSIZE_32_BIT | STM32_DMA_CCR_PSIZE_32_BIT | @@ -64,11 +69,7 @@ static const struct adc_profile_t profile = { STM32_ADC_CFGR1_CONT | STM32_ADC_CFGR1_DMACFG, .cfgr2_reg = 0, -#ifdef CONFIG_ADC_SAMPLE_TIME .smpr_reg = CONFIG_ADC_SAMPLE_TIME, -#else - .smpr_reg = STM32_ADC_SMPR_1_5_CY, -#endif /* Fire interrupt at end of sequence. */ .ier_reg = STM32_ADC_IER_EOSEQIE, .dma_option = &dma_continuous, @@ -100,8 +101,6 @@ static void adc_init(const struct adc_t *adc) 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 = adc->sample_rate ? adc->sample_rate : profile.smpr_reg; /* * ADC enable (note: takes 4 ADC clocks between end of calibration @@ -112,8 +111,15 @@ static void adc_init(const struct adc_t *adc) STM32_ADC_CR = STM32_ADC_CR_ADEN; } -static void adc_configure(int ain_id) +static void adc_configure(int ain_id, enum stm32_adc_smpr sample_rate) { + /* Sampling time */ + if (sample_rate == STM32_ADC_SMPR_DEFAULT || + sample_rate >= STM32_ADC_SMPR_COUNT) + STM32_ADC_SMPR = profile.smpr_reg; + else + STM32_ADC_SMPR = STM32_ADC_SMPR_SMP(sample_rate); + /* Select channel to convert */ STM32_ADC_CHSELR = BIT(ain_id); @@ -128,7 +134,7 @@ static int watchdog_delay_ms; static void adc_continuous_read(int ain_id) { - adc_configure(ain_id); + adc_configure(ain_id, STM32_ADC_SMPR_DEFAULT); /* CONT=1 -> continuous mode on */ STM32_ADC_CFGR1 |= STM32_ADC_CFGR1_CONT; @@ -152,7 +158,7 @@ static void adc_continuous_stop(void) static void adc_interval_read(int ain_id, int interval_ms) { - adc_configure(ain_id); + adc_configure(ain_id, STM32_ADC_SMPR_DEFAULT); /* EXTEN=01 -> hardware trigger detection on rising edge */ STM32_ADC_CFGR1 = (STM32_ADC_CFGR1 & ~STM32_ADC_CFGR1_EXTEN_MASK) @@ -210,7 +216,7 @@ static int adc_enable_watchdog_no_lock(void) /* Select channel */ STM32_ADC_CFGR1 = (STM32_ADC_CFGR1 & ~STM32_ADC_CFGR1_AWDCH_MASK) | (watchdog_ain_id << 26); - adc_configure(watchdog_ain_id); + adc_configure(watchdog_ain_id, STM32_ADC_SMPR_DEFAULT); /* Clear AWD interrupt flag */ STM32_ADC_ISR = 0x80; @@ -309,7 +315,7 @@ int adc_read_channel(enum adc_channel ch) adc_disable_watchdog_no_lock(); } - adc_configure(adc->channel); + adc_configure(adc->channel, adc->sample_rate); /* Clear flags */ STM32_ADC_ISR = 0xe; diff --git a/chip/stm32/adc_chip.h b/chip/stm32/adc_chip.h index 7d67ce2c6f..b84d57cb73 100644 --- a/chip/stm32/adc_chip.h +++ b/chip/stm32/adc_chip.h @@ -10,6 +10,19 @@ #include "stdint.h" +enum stm32_adc_smpr { + STM32_ADC_SMPR_DEFAULT = 0, + STM32_ADC_SMPR_1_5_CY, + STM32_ADC_SMPR_7_5_CY, + STM32_ADC_SMPR_13_5_CY, + STM32_ADC_SMPR_28_5_CY, + STM32_ADC_SMPR_41_5_CY, + STM32_ADC_SMPR_55_5_CY, + STM32_ADC_SMPR_71_5_CY, + STM32_ADC_SMPR_239_5_CY, + STM32_ADC_SMPR_COUNT, +}; + /* Data structure to define ADC channels. */ struct adc_t { const char *name; @@ -17,7 +30,9 @@ struct adc_t { int factor_div; int shift; int channel; - uint32_t sample_rate; /* Sampling Rate of the channel */ +#ifdef CHIP_FAMILY_STM32F0 + enum stm32_adc_smpr sample_rate; /* Sampling Rate of the channel */ +#endif }; /* diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index a6c9636098..23215b26db 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -2266,14 +2266,8 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_ADC_CFGR2 REG32(STM32_ADC1_BASE + 0x10) /* Sampling time selection - 1.5 ADC cycles min, 239.5 cycles max */ #define STM32_ADC_SMPR REG32(STM32_ADC1_BASE + 0x14) -#define STM32_ADC_SMPR_1_5_CY 0x0 -#define STM32_ADC_SMPR_7_5_CY 0x1 -#define STM32_ADC_SMPR_13_5_CY 0x2 -#define STM32_ADC_SMPR_28_5_CY 0x3 -#define STM32_ADC_SMPR_41_5_CY 0x4 -#define STM32_ADC_SMPR_55_5_CY 0x5 -#define STM32_ADC_SMPR_71_5_CY 0x6 -#define STM32_ADC_SMPR_239_5_CY 0x7 +/* Macro to convert enum stm32_adc_smpr to SMP bits of the ADC_SMPR register */ +#define STM32_ADC_SMPR_SMP(s) ((s) - 1) #define STM32_ADC_TR REG32(STM32_ADC1_BASE + 0x20) #define STM32_ADC_CHSELR REG32(STM32_ADC1_BASE + 0x28) #define STM32_ADC_DR REG32(STM32_ADC1_BASE + 0x40) |