summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2019-04-30 02:16:33 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-04 03:17:54 -0700
commitb26d8bdc5ef3ed670c5f797f0b412696cb9ac16a (patch)
treebc5d63c984ca5bb87c97db18e17e5819f1a11634
parentfd12ea66de5374065983a1ba1a8f698e300020b6 (diff)
downloadchrome-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.c36
-rw-r--r--chip/stm32/adc_chip.h17
-rw-r--r--chip/stm32/registers.h10
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)