Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions src/Power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@
#include "concurrency/LockGuard.h"
#endif

#if defined(ARCH_STM32WL) && defined(BATTERY_PIN)
#include "stm32yyxx_ll_adc.h"

/* Analog read resolution */
#if defined(LL_ADC_RESOLUTION_12B)
#define LL_ADC_RESOLUTION LL_ADC_RESOLUTION_12B
#define BATTERY_SENSE_RESOLUTION_BITS 12
#elif defined(LL_ADC_DS_DATA_WIDTH_12_BIT)
#define LL_ADC_RESOLUTION LL_ADC_DS_DATA_WIDTH_12_BIT
#define BATTERY_SENSE_RESOLUTION_BITS 12
#else
#error "ADC resolution could not be defined!"
#endif
#define ADC_RANGE (1 << BATTERY_SENSE_RESOLUTION_BITS)
#endif

#if defined(DEBUG_HEAP_MQTT) && !MESHTASTIC_EXCLUDE_MQTT
#include "mqtt/MQTT.h"
#include "target_specific.h"
Expand Down Expand Up @@ -328,11 +344,17 @@ class AnalogBatteryLevel : public HasBatteryLevel
float scaled = 0;

battery_adcEnable();
#ifdef ARCH_ESP32 // ADC block for espressif platforms
#ifdef ARCH_STM32WL
// STM32 ADC with VREFINT runtime calibration
Vref = __LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION);
raw = analogRead(BATTERY_PIN);
scaled = __LL_ADC_CALC_DATA_TO_VOLTAGE(Vref, raw, LL_ADC_RESOLUTION);
scaled *= operativeAdcMultiplier;
#elif defined(ARCH_ESP32) // ADC block for espressif platforms
raw = espAdcRead();
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
scaled *= operativeAdcMultiplier;
#else // block for all other platforms
#else // block for all other platforms
#ifdef ARCH_NRF52
concurrency::LockGuard saadcGuard(concurrency::nrf52SaadcLock);
#endif
Expand Down Expand Up @@ -530,6 +552,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
bool initial_read_done = false;
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
#ifdef ARCH_STM32WL
// 3300mV placeholder for STM32 errata where VREFINT factory calibration may be missing
// (e.g. STM32U0, see DS14756 Rev 3 §2.4.1 "VREFINT offset")
uint32_t Vref = 3300;
#endif

#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT)

Expand Down Expand Up @@ -639,7 +666,9 @@ bool Power::analogInit()
#define BATTERY_SENSE_RESOLUTION_BITS 10
#endif

#ifdef ARCH_ESP32 // ESP32 needs special analog stuff
#ifdef ARCH_STM32WL
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS);
#elif defined(ARCH_ESP32) // ESP32 needs special analog stuff

#ifndef ADC_WIDTH // max resolution by default
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
Expand All @@ -649,7 +678,7 @@ bool Power::analogInit()
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
adc1_config_width(width);
adc1_config_channel_atten(adc_channel, atten);
#else // ADC2
#else // ADC2
adc2_config_channel_atten(adc_channel, atten);
#ifndef CONFIG_IDF_TARGET_ESP32S3
// ADC2 wifi bug workaround
Expand Down Expand Up @@ -679,7 +708,7 @@ bool Power::analogInit()

// NRF52 ADC init moved to powerHAL_init in nrf52 platform

#ifndef ARCH_ESP32
#if !defined(ARCH_ESP32) && !defined(ARCH_STM32WL)
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS);
#endif

Expand Down
5 changes: 5 additions & 0 deletions src/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@

// Device specific curves go in variant.h
#ifndef OCV_ARRAY
#if defined(ARCH_STM32WL) && BATTERY_PIN == AVBAT
// STM32 VDD/VBAT absolute maximum is 4V so use an LFP curve
Comment thread
ndoo marked this conversation as resolved.
#define OCV_ARRAY 3650, 3400, 3340, 3320, 3300, 3280, 3270, 3260, 3240, 3200, 2500
#else
#define OCV_ARRAY 4190, 4050, 3990, 3890, 3800, 3720, 3630, 3530, 3420, 3300, 3100
#endif
#endif

/*Note: 12V lead acid is 6 cells, most board accept only 1 cell LiIon/LiPo*/
#ifndef NUM_CELLS
Expand Down
5 changes: 5 additions & 0 deletions variants/stm32/rak3172/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ Do not expect a working Meshtastic device with this target.
#define LED_POWER PA0 // Green LED
#define LED_STATE_ON 1

#define BATTERY_PIN AVBAT
// ADC_MULTIPLIER: 3.0 = internal 1:3 bridge divider (DS13105§3.18.3)
// Margin: 1.10 = AVBAT divider tolerance ±10% (Table 82)
#define ADC_MULTIPLIER (1.01f * 3)

#define RAK3172
#define SERIAL_PRINT_PORT 1

Expand Down
10 changes: 10 additions & 0 deletions variants/stm32/russell/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
// #define EXT_CHRG_DETECT PA5
// #define EXT_PWR_DETECT PA4

#define BATTERY_PIN AVBAT
// ADC_MULTIPLIER: 3.0 = internal 1:3 bridge divider (DS13105§3.18.3)
// Margin: 1.10 = AVBAT divider tolerance ±10% (Table 82)
#define ADC_MULTIPLIER (1.01f * 3)
/*
Sample OCV curve for Li-SOCl2 primary lithium cells (e.g. Saft cells have fresh OCV of 3.67V)
#define NUM_OCV_POINTS 11
#define OCV_ARRAY 3670, 3650, 3630, 3610, 3590, 3560, 3530, 3480, 3400, 3200, 2500
*/

// Bosch Sensortec BME280
#define HAS_SENSOR 1

Expand Down
Loading