summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/adc.c15
-rw-r--r--ports/stm32/machine_adc.c21
2 files changed, 27 insertions, 9 deletions
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 93eaa93f0..ec4a18cde 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -458,9 +458,18 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
}
STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
- HAL_ADC_Start(adcHandle);
- adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT);
- uint32_t value = adcHandle->Instance->DR;
+ uint32_t value;
+ #if defined(STM32G4)
+ // For STM32G4 there is errata 2.7.7, "Wrong ADC result if conversion done late after
+ // calibration or previous conversion". According to the errata, this can be avoided
+ // by performing two consecutive ADC conversions and keeping the second result.
+ for (uint8_t i = 0; i < 2; i++)
+ #endif
+ {
+ HAL_ADC_Start(adcHandle);
+ adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT);
+ value = adcHandle->Instance->DR;
+ }
HAL_ADC_Stop(adcHandle);
return value;
}
diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c
index 041b06723..fee3d698d 100644
--- a/ports/stm32/machine_adc.c
+++ b/ports/stm32/machine_adc.c
@@ -371,13 +371,22 @@ STATIC void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp
}
STATIC uint32_t adc_read_channel(ADC_TypeDef *adc) {
- #if ADC_V2
- adc->CR |= ADC_CR_ADSTART;
- #else
- adc->CR2 |= ADC_CR2_SWSTART;
+ uint32_t value;
+ #if defined(STM32G4)
+ // For STM32G4 there is errata 2.7.7, "Wrong ADC result if conversion done late after
+ // calibration or previous conversion". According to the errata, this can be avoided
+ // by performing two consecutive ADC conversions and keeping the second result.
+ for (uint8_t i = 0; i < 2; i++)
#endif
- adc_wait_eoc(adc, ADC_EOC_TIMEOUT_MS);
- uint32_t value = adc->DR;
+ {
+ #if ADC_V2
+ adc->CR |= ADC_CR_ADSTART;
+ #else
+ adc->CR2 |= ADC_CR2_SWSTART;
+ #endif
+ adc_wait_eoc(adc, ADC_EOC_TIMEOUT_MS);
+ value = adc->DR;
+ }
return value;
}