From d1ea58975755e146457a8345065e4ca357555275 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:14:21 +0000 Subject: [PATCH] Allow NRF52 ADC overrides; begin simplifying analog battery logic (#3134) * Isolate esp32 adc logic gymnastics, try simplifying getBattVoltage * Set sense resolution for pico platforms * try silencing cppcheck when variant has no battery pin * ADC channel for esp-idf calibration * Missed an rp2040 device --------- Co-authored-by: Ben Meadors --- src/Power.cpp | 104 +++++++++++++++------------- variants/lora_relay_v1/variant.h | 1 + variants/lora_relay_v2/variant.h | 1 + variants/nano-g2-ultra/variant.h | 2 +- variants/rak11200/variant.h | 2 + variants/rak11310/variant.h | 1 + variants/rak4631/variant.h | 2 +- variants/rak4631_epaper/variant.h | 2 +- variants/rpipico/variant.h | 1 + variants/rpipicow/variant.h | 1 + variants/senselora_rp2040/variant.h | 1 + variants/t-echo/variant.h | 2 +- 12 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 12e92b3f1..dc8a43d46 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -164,7 +164,8 @@ class AnalogBatteryLevel : public HasBatteryLevel #endif #ifndef BATTERY_SENSE_SAMPLES -#define BATTERY_SENSE_SAMPLES 30 +#define BATTERY_SENSE_SAMPLES \ + 30 // Set the number of samples, it has an effect of increasing sensitivity in complex electromagnetic environment. #endif #ifdef BATTERY_PIN @@ -176,66 +177,71 @@ class AnalogBatteryLevel : public HasBatteryLevel if (millis() - last_read_time_ms > min_read_interval) { last_read_time_ms = millis(); - // Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic - // environment. uint32_t raw = 0; -#ifdef ARCH_ESP32 -#ifndef BAT_MEASURE_ADC_UNIT // ADC1 -#ifdef ADC_CTRL - if (heltec_version == 5) { - pinMode(ADC_CTRL, OUTPUT); - digitalWrite(ADC_CTRL, HIGH); - delay(10); - } -#endif - for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { - raw += adc1_get_raw(adc_channel); - } -#ifdef ADC_CTRL - if (heltec_version == 5) { - digitalWrite(ADC_CTRL, LOW); - } -#endif -#else // ADC2 - int32_t adc_buf = 0; - for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { - // ADC2 wifi bug workaround, see - // https://github.com/espressif/arduino-esp32/issues/102 - WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b); - SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV); - adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf); - raw += adc_buf; - } -#endif // BAT_MEASURE_ADC_UNIT -#else // !ARCH_ESP32 + float scaled = 0; + +#ifdef 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 for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) { raw += analogRead(BATTERY_PIN); } -#endif raw = raw / BATTERY_SENSE_SAMPLES; - float scaled; -#ifdef ARCH_ESP32 - scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs); - scaled *= operativeAdcMultiplier; -#else -#ifndef VBAT_RAW_TO_SCALED - scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw; -#else - scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h -#endif // VBAT RAW TO SCALED -#endif // ARCH_ESP32 - // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled)); - + scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw; +#endif + // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled)); last_read_value = scaled; return scaled; } else { return last_read_value; } -#else - return 0; #endif // BATTERY_PIN + return 0; } +#if defined(ARCH_ESP32) && !defined(HAS_PMU) && defined(BATTERY_PIN) + /** + * ESP32 specific function for getting calibrated ADC reads + */ + uint32_t espAdcRead() + { + + uint32_t raw = 0; + +#ifndef BAT_MEASURE_ADC_UNIT // ADC1 +#ifdef ADC_CTRL + if (heltec_version == 5) { + pinMode(ADC_CTRL, OUTPUT); + digitalWrite(ADC_CTRL, HIGH); + delay(10); + } +#endif + for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { + raw += adc1_get_raw(adc_channel); + } +#ifdef ADC_CTRL + if (heltec_version == 5) { + digitalWrite(ADC_CTRL, LOW); + } +#endif +#else // ADC2 + int32_t adc_buf = 0; + for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) { + // ADC2 wifi bug workaround, see + // https://github.com/espressif/arduino-esp32/issues/102 + WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b); + SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV); + adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf); + raw += adc_buf; + } +#endif // BAT_MEASURE_ADC_UNIT + raw = raw / BATTERY_SENSE_SAMPLES; + return raw; + } +#endif + /** * return true if there is a battery installed in this unit */ @@ -894,4 +900,4 @@ bool Power::axpChipInit() #else return false; #endif -} +} \ No newline at end of file diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h index b310223d7..9cfb69337 100644 --- a/variants/lora_relay_v1/variant.h +++ b/variants/lora_relay_v1/variant.h @@ -80,6 +80,7 @@ static const uint8_t A5 = PIN_A5; // Other pins #define PIN_AREF PIN_A5 #define PIN_VBAT PIN_A4 +#define BATTERY_PIN PIN_VBAT #define PIN_NFC1 (33) #define PIN_NFC2 (2) #define PIN_PIEZO (37) diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h index 172da17f7..3afe8620e 100644 --- a/variants/lora_relay_v2/variant.h +++ b/variants/lora_relay_v2/variant.h @@ -100,6 +100,7 @@ static const uint8_t A5 = PIN_A5; // Other pins #define PIN_AREF PIN_A5 #define PIN_VBAT PIN_A4 +#define BATTERY_PIN PIN_VBAT #define PIN_NFC1 (33) #define PIN_NFC2 (2) #define PIN_PIEZO (37) diff --git a/variants/nano-g2-ultra/variant.h b/variants/nano-g2-ultra/variant.h index d69235fd4..c328d2271 100644 --- a/variants/nano-g2-ultra/variant.h +++ b/variants/nano-g2-ultra/variant.h @@ -170,7 +170,7 @@ External serial flash W25Q16JV_IQ // Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K)) #define VBAT_DIVIDER (0.5F) // Compensation factor for the VBAT divider -#define VBAT_DIVIDER_COMP (2.0) +#define VBAT_DIVIDER_COMP (2.0F) // Fixed calculation of milliVolt from compensation value #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #undef AREF_VOLTAGE diff --git a/variants/rak11200/variant.h b/variants/rak11200/variant.h index 007ed8f15..3399594e5 100644 --- a/variants/rak11200/variant.h +++ b/variants/rak11200/variant.h @@ -56,6 +56,8 @@ static const uint8_t SCK = 33; #define LED_PIN LED_BLUE #define PIN_VBAT WB_A0 +#define BATTERY_PIN PIN_VBAT +#define ADC_CHANNEL ADC1_GPIO36_CHANNEL // https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/ diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h index 6334157f5..ba3d4fed7 100644 --- a/variants/rak11310/variant.h +++ b/variants/rak11310/variant.h @@ -12,6 +12,7 @@ // #define EXT_NOTIFY_OUT 4 #define BATTERY_PIN 26 +#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION // ratio of voltage divider = 3.0 (R17=200k, R18=100k) #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index 956bcd772..cc18a901f 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -254,7 +254,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG // Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) #define VBAT_DIVIDER (0.4F) // Compensation factor for the VBAT divider -#define VBAT_DIVIDER_COMP (1.73) +#define VBAT_DIVIDER_COMP (1.73F) // Fixed calculation of milliVolt from compensation value #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #undef AREF_VOLTAGE diff --git a/variants/rak4631_epaper/variant.h b/variants/rak4631_epaper/variant.h index bc2eddfee..d8a5e5597 100644 --- a/variants/rak4631_epaper/variant.h +++ b/variants/rak4631_epaper/variant.h @@ -223,7 +223,7 @@ static const uint8_t SCK = PIN_SPI_SCK; // Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) #define VBAT_DIVIDER (0.4F) // Compensation factor for the VBAT divider -#define VBAT_DIVIDER_COMP (1.73) +#define VBAT_DIVIDER_COMP (1.73F) // Fixed calculation of milliVolt from compensation value #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #undef AREF_VOLTAGE diff --git a/variants/rpipico/variant.h b/variants/rpipico/variant.h index aeda3d833..ad6d0b211 100644 --- a/variants/rpipico/variant.h +++ b/variants/rpipico/variant.h @@ -22,6 +22,7 @@ #define BATTERY_PIN 26 // ratio of voltage divider = 3.0 (R17=200k, R18=100k) #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic +#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION #define USE_SX1262 diff --git a/variants/rpipicow/variant.h b/variants/rpipicow/variant.h index c48b901ac..27117680f 100644 --- a/variants/rpipicow/variant.h +++ b/variants/rpipicow/variant.h @@ -24,6 +24,7 @@ #define BATTERY_PIN 26 // ratio of voltage divider = 3.0 (R17=200k, R18=100k) #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic +#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION #define USE_SX1262 diff --git a/variants/senselora_rp2040/variant.h b/variants/senselora_rp2040/variant.h index 9eda65521..2f68cf034 100644 --- a/variants/senselora_rp2040/variant.h +++ b/variants/senselora_rp2040/variant.h @@ -8,6 +8,7 @@ #define LED_PIN PIN_LED #undef BATTERY_PIN +#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION #undef LORA_SCK #undef LORA_MISO diff --git a/variants/t-echo/variant.h b/variants/t-echo/variant.h index 8679dbde9..345091c2f 100644 --- a/variants/t-echo/variant.h +++ b/variants/t-echo/variant.h @@ -213,7 +213,7 @@ External serial flash WP25R1635FZUIL0 // Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K)) #define VBAT_DIVIDER (0.5F) // Compensation factor for the VBAT divider -#define VBAT_DIVIDER_COMP (2.0) +#define VBAT_DIVIDER_COMP (2.0F) // Fixed calculation of milliVolt from compensation value #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) #undef AREF_VOLTAGE