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>
This commit is contained in:
parent
0a31b9bf78
commit
cb38f77918
2 changed files with 27 additions and 9 deletions
|
|
@ -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) {
|
||||||
HAL_ADC_Start(adcHandle);
|
uint32_t value;
|
||||||
adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT);
|
#if defined(STM32G4)
|
||||||
uint32_t value = adcHandle->Instance->DR;
|
// 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);
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC uint32_t adc_read_channel(ADC_TypeDef *adc) {
|
STATIC uint32_t adc_read_channel(ADC_TypeDef *adc) {
|
||||||
#if ADC_V2
|
uint32_t value;
|
||||||
adc->CR |= ADC_CR_ADSTART;
|
#if defined(STM32G4)
|
||||||
#else
|
// For STM32G4 there is errata 2.7.7, "Wrong ADC result if conversion done late after
|
||||||
adc->CR2 |= ADC_CR2_SWSTART;
|
// 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
|
#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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue