提交 cb38f779 编写于 作者: Y Yuuki NAGAO 提交者: Damien George

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: NYuuki NAGAO <wf.yn386@gmail.com>
上级 0a31b9bf
...@@ -458,9 +458,18 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel) ...@@ -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) { STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
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); HAL_ADC_Start(adcHandle);
adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT); adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT);
uint32_t value = adcHandle->Instance->DR; value = adcHandle->Instance->DR;
}
HAL_ADC_Stop(adcHandle); HAL_ADC_Stop(adcHandle);
return value; return value;
} }
......
...@@ -371,13 +371,22 @@ STATIC void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp ...@@ -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) { STATIC uint32_t adc_read_channel(ADC_TypeDef *adc) {
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
{
#if ADC_V2 #if ADC_V2
adc->CR |= ADC_CR_ADSTART; adc->CR |= ADC_CR_ADSTART;
#else #else
adc->CR2 |= ADC_CR2_SWSTART; adc->CR2 |= ADC_CR2_SWSTART;
#endif #endif
adc_wait_eoc(adc, ADC_EOC_TIMEOUT_MS); adc_wait_eoc(adc, ADC_EOC_TIMEOUT_MS);
uint32_t value = adc->DR; value = adc->DR;
}
return value; return value;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册