stm32/adc: Deselect VBAT after reading to prevent battery drain.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
b603066bc2
commit
80883a82c0
@ -380,16 +380,14 @@ STATIC uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32
|
||||
adc_config_channel(adcHandle, channel);
|
||||
uint32_t raw_value = adc_read_channel(adcHandle);
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
// ST docs say that (at least on STM32F42x and STM32F43x), VBATE must
|
||||
// be disabled when TSVREFE is enabled for TEMPSENSOR and VREFINT
|
||||
// conversions to work. VBATE is enabled by the above call to read
|
||||
// the channel, and here we disable VBATE so a subsequent call for
|
||||
// TEMPSENSOR or VREFINT works correctly.
|
||||
if (channel == ADC_CHANNEL_VBAT) {
|
||||
ADC->CCR &= ~ADC_CCR_VBATE;
|
||||
}
|
||||
#endif
|
||||
// It's also good to disable the VBAT switch to prevent battery drain,
|
||||
// so disable it for all MCUs.
|
||||
adc_deselect_vbat(adcHandle->Instance, channel);
|
||||
|
||||
return raw_value;
|
||||
}
|
||||
|
@ -29,4 +29,35 @@
|
||||
extern const mp_obj_type_t pyb_adc_type;
|
||||
extern const mp_obj_type_t pyb_adc_all_type;
|
||||
|
||||
#if defined(ADC_CHANNEL_VBAT)
|
||||
|
||||
static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) {
|
||||
(void)adc;
|
||||
|
||||
if (channel == ADC_CHANNEL_VBAT) {
|
||||
ADC_Common_TypeDef *adc_common;
|
||||
|
||||
#if defined(STM32F0) || defined(STM32WB)
|
||||
adc_common = ADC1_COMMON;
|
||||
#elif defined(STM32F4) || defined(STM32L4)
|
||||
adc_common = ADC_COMMON_REGISTER(0);
|
||||
#elif defined(STM32F7)
|
||||
adc_common = ADC123_COMMON;
|
||||
#elif defined(STM32H7)
|
||||
adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON;
|
||||
#endif
|
||||
|
||||
adc_common->CCR &= ~LL_ADC_PATH_INTERNAL_VBAT;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) {
|
||||
(void)adc;
|
||||
(void)channel;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_STM32_ADC_H
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
#include "stm32f4xx_hal_usart.h"
|
||||
#include "stm32f4xx_hal_wwdg.h"
|
||||
#include "stm32f4xx_ll_adc.h"
|
||||
#include "stm32f4xx_ll_rtc.h"
|
||||
|
||||
// Enable various HAL modules
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#include "stm32f7xx_hal_usart.h"
|
||||
#include "stm32f7xx_hal_wwdg.h"
|
||||
#include "stm32f7xx_ll_adc.h"
|
||||
#include "stm32f7xx_ll_rtc.h"
|
||||
|
||||
// Enable various HAL modules
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "adc.h"
|
||||
|
||||
#if defined(STM32F0) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
|
||||
#define ADC_V2 (1)
|
||||
@ -335,10 +336,15 @@ STATIC uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
// Select, configure and read the channel.
|
||||
adc_config_channel(adc, channel, sample_time);
|
||||
uint32_t raw = adc_read_channel(adc);
|
||||
|
||||
// If VBAT was sampled then deselect it to prevent battery drain.
|
||||
adc_deselect_vbat(adc, channel);
|
||||
|
||||
// Scale raw reading to 16 bit value using a Taylor expansion (for bits <= 16).
|
||||
uint32_t bits = adc_get_bits(adc);
|
||||
// Scale raw reading to 16 bit value using a Taylor expansion (for 8 <= bits <= 16)
|
||||
#if defined(STM32H7)
|
||||
if (bits < 8) {
|
||||
// For 6 and 7 bits
|
||||
|
Loading…
Reference in New Issue
Block a user