summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2016-11-30 12:04:21 +1100
committerDamien George <damien.p.george@gmail.com>2016-11-30 12:58:53 +1100
commit87215a0f0480dd0324a1b9c1d3fc3a5c2806249d (patch)
treeb1a9c17434064ef4f502e2cafdf1a1acfc08727c
parent295266178c298bcf69f5954decd9493dbe195e5a (diff)
stmhal/adc: Provide more accurate measure of VBAT and VREFINT.
By using factory calibration values.
-rw-r--r--stmhal/adc.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/stmhal/adc.c b/stmhal/adc.c
index 1f8f24c33..24ae60934 100644
--- a/stmhal/adc.c
+++ b/stmhal/adc.c
@@ -55,14 +55,28 @@
#define ADCx_CLK_ENABLE __ADC1_CLK_ENABLE
#define ADC_NUM_CHANNELS (19)
-#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
+#if defined(MCU_SERIES_F4)
+
+#define ADC_FIRST_GPIO_CHANNEL (0)
+#define ADC_LAST_GPIO_CHANNEL (15)
+#define ADC_CAL_ADDRESS (0x1fff7a2a)
+
+#elif defined(MCU_SERIES_F7)
+
#define ADC_FIRST_GPIO_CHANNEL (0)
#define ADC_LAST_GPIO_CHANNEL (15)
+#define ADC_CAL_ADDRESS (0x1ff0f44a)
+
#elif defined(MCU_SERIES_L4)
+
#define ADC_FIRST_GPIO_CHANNEL (1)
#define ADC_LAST_GPIO_CHANNEL (16)
+#define ADC_CAL_ADDRESS (0x1fff75aa)
+
#else
+
#error Unsupported processor
+
#endif
#if defined(STM32F405xx) || defined(STM32F415xx) || \
@@ -84,6 +98,10 @@
#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
+// scale and calibration values for VBAT and VREF
+#define ADC_SCALE (3.3f / 4095)
+#define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS)
+
typedef struct _pyb_obj_adc_t {
mp_obj_base_t base;
mp_obj_t pin_name;
@@ -513,6 +531,9 @@ int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
}
#if MICROPY_PY_BUILTINS_FLOAT
+// correction factor for reference value
+STATIC volatile float adc_refcor = 1.0f;
+
float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
uint32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_VBAT);
@@ -520,8 +541,16 @@ float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
// be 12-bits.
raw_value <<= (12 - adc_get_resolution(adcHandle));
- // multiplier is 3.3/4095
- return raw_value * VBAT_DIV * 0.8058608058608059e-3f;
+ #if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
+ // ST docs say that (at least on STM32F42x and STM32F43x), VBATE must
+ // be disabled when TSVREFE is enabled for TEMPSENSOR and VREFINT
+ // conversions to work. VBATE is enabled by the above call to read
+ // the channel, and here we disable VBATE so a subsequent call for
+ // TEMPSENSOR or VREFINT works correctly.
+ ADC->CCR &= ~ADC_CCR_VBATE;
+ #endif
+
+ return raw_value * VBAT_DIV * ADC_SCALE * adc_refcor;
}
float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) {
@@ -531,8 +560,10 @@ float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) {
// be 12-bits.
raw_value <<= (12 - adc_get_resolution(adcHandle));
- // multiplier is 3.3/4095
- return raw_value * 0.8058608058608059e-3f;
+ // update the reference correction factor
+ adc_refcor = ((float)(*VREFIN_CAL)) / ((float)raw_value);
+
+ return (*VREFIN_CAL) * ADC_SCALE;
}
#endif