8000 stm32/adc: Fix calibrated volt/temp readings on H7 by using 16bit scale. · msuszko/micropython@0555ada · GitHub
[go: up one dir, main page]

Skip to content

Commit 0555ada

Browse files
committed
stm32/adc: Fix calibrated volt/temp readings on H7 by using 16bit scale.
1 parent 1b4031e commit 0555ada

File tree

1 file changed

+16
-23
lines changed

1 file changed

+16
-23
lines changed

ports/stm32/adc.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#define ADC_CAL_ADDRESS (0x1ffff7ba)
6868
#define ADC_CAL1 ((uint16_t*)0x1ffff7b8)
6969
#define ADC_CAL2 ((uint16_t*)0x1ffff7c2)
70+
#define ADC_CAL_BITS (12)
7071

7172
#elif defined(STM32F4)
7273

@@ -76,6 +77,7 @@
7677
#define ADC_CAL_ADDRESS (0x1fff7a2a)
7778
#define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
7879
#define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
80+
#define ADC_CAL_BITS (12)
7981

8082
#elif defined(STM32F7)
8183

@@ -91,6 +93,7 @@
9193

9294
#define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
9395
#define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
96+
#define ADC_CAL_BITS (12)
9497

9598
#elif defined(STM32H7)
9699

@@ -100,6 +103,7 @@
100103
#define ADC_CAL_ADDRESS (0x1FF1E860)
101104
#define ADC_CAL1 ((uint16_t*)(0x1FF1E820))
102105
#define ADC_CAL2 ((uint16_t*)(0x1FF1E840))
106+
#define ADC_CAL_BITS (16)
103107
#define ADC_CHANNEL_VBAT ADC_CHANNEL_VBAT_DIV4
104108

105109
#elif defined(STM32L4)
@@ -110,6 +114,7 @@
110114
#define ADC_CAL_A 10000 DDRESS (0x1fff75aa)
111115
#define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS - 2))
112116
#define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 0x20))
117+
#define ADC_CAL_BITS (12)
113118

114119
#else
115120

@@ -149,7 +154,7 @@
149154
#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
150155

151156
// scale and calibration values for VBAT and VREF
152-
#define ADC_SCALE (ADC_SCALE_V / 4095)
157+
#define ADC_SCALE (ADC_SCALE_V / ((1 << ADC_CAL_BITS) - 1))
153158
#define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS)
154159

155160
typedef struct _pyb_obj_adc_t {
@@ -699,13 +704,14 @@ int adc_get_resolution(ADC_HandleTypeDef *adcHandle) {
699704
return 12;
700705
}
701706

702-
int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
703-
int32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_TEMPSENSOR);
704-
705-
// Note: constants assume 12-bit resolution, so we scale the raw value to
706-
// be 12-bits.
707-
raw_value <<= (12 - adc_get_resolution(adcHandle));
707+
STATIC uint32_t adc_config_and_read_ref(ADC_HandleTypeDef *adcHandle, uint32_t channel) {
708+
uint32_t raw_value = adc_config_and_read_channel(adcHandle, channel);
709+
// Scale raw reading to the number of bits used by the calibration constants
710+
return raw_value << (ADC_CAL_BITS - adc_get_resolution(adcHandle));
711+
}
708712

713+
int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
714+
int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);
709715
return ((raw_value - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
710716
}
711717

@@ -714,31 +720,18 @@ int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
714720
STATIC volatile float adc_refcor = 1.0f;
715721

716722
float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
717-
int32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_TEMPSENSOR);
718-
719-
// constants assume 12-bit resolution so we scale the raw value to 12-bits
720-
raw_value <<= (12 - adc_get_resolution(adcHandle));
721-
723+
int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);
722724
float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0;
723725
return (((float)raw_value * adc_refcor - *ADC_CAL1) / core_temp_avg_slope) + 30.0f;
724726
}
725727

726728
float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
727-
uint32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_VBAT);
728-
729-
// Note: constants assume 12-bit resolution, so we scale the raw value to
730-
// be 12-bits.
731-
raw_value <<= (12 - adc_get_resolution(adcHandle));
732-
729+
uint32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_VBAT);
733730
return raw_value * VBAT_DIV * ADC_SCALE * adc_refcor;
734731
}
735732

736733
float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) {
737-
uint32_t raw_value = adc_config_and_read_channel(adcHandle, ADC_CHANNEL_VREFINT);
738-
739-
// Note: constants assume 12-bit resolution, so we scale the raw value to
740-
// be 12-bits.
741-
raw_value <<= (12 - adc_get_resolution(adcHandle));
734+
uint32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_VREFINT);
742735

743736
// update the reference correction factor
744737
adc_refcor = ((float)(*VREFIN_CAL)) / ((float)raw_value);

0 commit comments

Comments
 (0)
0