summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuuki NAGAO <wf.yn386@gmail.com>2023-07-08 11:14:00 +0900
committerDamien George <damien@micropython.org>2023-07-13 12:40:52 +1000
commitcb38f77918b7c7dde2904b7f13ad38aaf69d7350 (patch)
treee3fa90e2bcb3909d667169734284f2af35192a0a
parent0a31b9bf78b5ac57ef7c4df4a161779991106649 (diff)
stm32/adc: Add workaround for ADC errata with G4 MCUs.
For STM32G4, there is a errata on ADC that may get wrong ADC result. According to the errata sheet, this can be avoid by performing two consecutive ADC conversions and keep second result. Signed-off-by: Yuuki NAGAO <wf.yn386@gmail.com>
-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;
}