diff --git a/include/battery.h b/include/battery.h deleted file mode 100644 index b4a83676..00000000 --- a/include/battery.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BATTERY_H -#define _BATTERY_H - -#include -#include - -#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate -#define NO_OF_SAMPLES 64 // we do some multisampling to get better values - -uint16_t read_voltage(void); -void calibrate_voltage(void); -bool batt_sufficient(void); - -#endif diff --git a/include/globals.h b/include/globals.h index a112e481..67ec93d2 100644 --- a/include/globals.h +++ b/include/globals.h @@ -121,6 +121,7 @@ extern time_t userUTCTime; #include "led.h" #include "payload.h" #include "blescan.h" +#include "power.h" #if (HAS_GPS) #include "gpsread.h" @@ -142,10 +143,6 @@ extern time_t userUTCTime; #include "button.h" #endif -#ifdef BAT_MEASURE_ADC -#include "battery.h" -#endif - #ifdef HAS_ANTENNA_SWITCH #include "antenna.h" #endif diff --git a/include/ota.h b/include/ota.h index 41ab5767..59bf876c 100644 --- a/include/ota.h +++ b/include/ota.h @@ -4,7 +4,6 @@ #ifdef USE_OTA #include "globals.h" -#include "battery.h" #include #include #include diff --git a/include/power.h b/include/power.h index f557edb4..849ea3b1 100644 --- a/include/power.h +++ b/include/power.h @@ -2,12 +2,20 @@ #define _POWER_H #include +#include +#include #include "i2cscan.h" +#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate +#define NO_OF_SAMPLES 64 // we do some multisampling to get better values + #ifdef HAS_PMU #include #endif void AXP192_init(void); +uint16_t read_voltage(void); +void calibrate_voltage(void); +uint8_t getBattLevel (void); #endif \ No newline at end of file diff --git a/src/battery.cpp b/src/battery.cpp deleted file mode 100644 index 39b78683..00000000 --- a/src/battery.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "globals.h" - -// Local logging tag -static const char TAG[] = __FILE__; - -#ifdef BAT_MEASURE_ADC -esp_adc_cal_characteristics_t *adc_characs = - (esp_adc_cal_characteristics_t *)calloc( - 1, sizeof(esp_adc_cal_characteristics_t)); - -static const adc1_channel_t adc_channel = BAT_MEASURE_ADC; -static const adc_atten_t atten = ADC_ATTEN_DB_11; -static const adc_unit_t unit = ADC_UNIT_1; -#endif - -void calibrate_voltage(void) { -#ifdef BAT_MEASURE_ADC - // configure ADC - ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12)); - ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten)); - // calibrate ADC - esp_adc_cal_value_t val_type = esp_adc_cal_characterize( - unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_characs); - // show ADC characterization base - if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { - ESP_LOGI(TAG, - "ADC characterization based on Two Point values stored in eFuse"); - } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { - ESP_LOGI(TAG, - "ADC characterization based on reference voltage stored in eFuse"); - } else { - ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); - } -#endif -} - -uint16_t read_voltage() { -#ifdef BAT_MEASURE_ADC - // multisample ADC - uint32_t adc_reading = 0; - for (int i = 0; i < NO_OF_SAMPLES; i++) { - adc_reading += adc1_get_raw(adc_channel); - } - adc_reading /= NO_OF_SAMPLES; - // Convert ADC reading to voltage in mV - uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_characs); -#ifdef BAT_VOLTAGE_DIVIDER - voltage *= BAT_VOLTAGE_DIVIDER; -#endif - -#ifdef BAT_MEASURE_EN // turn ext. power off - digitalWrite(EXT_POWER_SW, EXT_POWER_OFF); -#endif - -#ifdef HAS_PMU - voltage = axp.getBattVoltage(); -#endif - - return (uint16_t)voltage; -#else - return 0; -#endif -} - -bool batt_sufficient() { -#ifdef BAT_MEASURE_ADC - uint16_t volts = read_voltage(); - return ((volts < 1000) || - (volts > OTA_MIN_BATT)); // no battery or battery sufficient -#else - return true; -#endif -} \ No newline at end of file diff --git a/src/cyclic.cpp b/src/cyclic.cpp index a4ba6703..0b51d88b 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -54,7 +54,7 @@ void doHousekeeping() { #endif // read battery voltage into global variable -#ifdef BAT_MEASURE_ADC +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) batt_voltage = read_voltage(); ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage); #endif diff --git a/src/display.cpp b/src/display.cpp index d6cb3d3e..e6d17301 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -188,7 +188,7 @@ void draw_page(time_t t, uint8_t page) { case 0: // update Battery status (line 2) -#ifdef BAT_MEASURE_ADC +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) u8x8.setCursor(0, 2); u8x8.printf("B:%.2fV", batt_voltage / 1000.0); #endif diff --git a/src/main.cpp b/src/main.cpp index 3a466e68..2c5fc606 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -248,7 +248,7 @@ void setup() { #endif // initialize battery status -#ifdef BAT_MEASURE_ADC +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) strcat_P(features, " BATT"); calibrate_voltage(); batt_voltage = read_voltage(); diff --git a/src/ota.cpp b/src/ota.cpp index fc1662bc..1a1e9052 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -41,7 +41,7 @@ inline String getHeaderValue(String header, String headerName) { void start_ota_update() { // check battery status if we can before doing ota - if (!batt_sufficient()) { + if (getBattLevel() == MCMD_DEVS_BATT_MIN) { ESP_LOGE(TAG, "Battery voltage %dmV too low for OTA", batt_voltage); return; } diff --git a/src/power.cpp b/src/power.cpp index 3a492256..5797da26 100644 --- a/src/power.cpp +++ b/src/power.cpp @@ -2,12 +2,15 @@ #include "globals.h" #include "power.h" +// Local logging tag +static const char TAG[] = __FILE__; + #ifdef HAS_PMU +AXP20X_Class axp; + void AXP192_init(void) { - - AXP20X_Class axp; - + if (axp.begin(Wire, AXP192_PRIMARY_ADDRESS)) ESP_LOGI(TAG, "AXP192 PMU initialization failed"); else { @@ -39,4 +42,91 @@ void AXP192_init(void) { ESP_LOGI(TAG, "AXP192 PMU initialized."); } } -#endif // HAS_PMU \ No newline at end of file +#endif // HAS_PMU + +#ifdef BAT_MEASURE_ADC +esp_adc_cal_characteristics_t *adc_characs = + (esp_adc_cal_characteristics_t *)calloc( + 1, sizeof(esp_adc_cal_characteristics_t)); + +static const adc1_channel_t adc_channel = BAT_MEASURE_ADC; +static const adc_atten_t atten = ADC_ATTEN_DB_11; +static const adc_unit_t unit = ADC_UNIT_1; +#endif + +void calibrate_voltage(void) { +#ifdef BAT_MEASURE_ADC + // configure ADC + ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12)); + ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten)); + // calibrate ADC + esp_adc_cal_value_t val_type = esp_adc_cal_characterize( + unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_characs); + // show ADC characterization base + if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { + ESP_LOGI(TAG, + "ADC characterization based on Two Point values stored in eFuse"); + } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { + ESP_LOGI(TAG, + "ADC characterization based on reference voltage stored in eFuse"); + } else { + ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); + } +#endif +} + + +uint8_t getBattLevel() { + /* + return values: + MCMD_DEVS_EXT_POWER = 0x00, // external power supply + MCMD_DEVS_BATT_MIN = 0x01, // min battery value + MCMD_DEVS_BATT_MAX = 0xFE, // max battery value + MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level + */ +#if (defined HAS_PMU || defined BAT_MEASURE_ADC) + uint16_t voltage = read_voltage(); + + switch (voltage) { + case 0: + return MCMD_DEVS_BATT_NOINFO; + case 0xffff: + return MCMD_DEVS_EXT_POWER; + default: + return (voltage > OTA_MIN_BATT ? MCMD_DEVS_BATT_MAX : MCMD_DEVS_BATT_MIN); + } +#else // we don't have any info on battery level + return MCMD_DEVS_BATT_NOINFO; +#endif +} // getBattLevel() + +// u1_t os_getBattLevel(void) { return getBattLevel(); }; + + +uint16_t read_voltage() { + + uint16_t voltage = 0; + +#ifdef HAS_PMU + voltage = axp.isVBUSPlug() ? 0xffff : axp.getBattVoltage(); +#else + +#ifdef BAT_MEASURE_ADC + // multisample ADC + uint32_t adc_reading = 0; + for (int i = 0; i < NO_OF_SAMPLES; i++) { + adc_reading += adc1_get_raw(adc_channel); + } + adc_reading /= NO_OF_SAMPLES; + // Convert ADC reading to voltage in mV + voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_characs); +#endif + +#ifdef BAT_VOLTAGE_DIVIDER + voltage *= BAT_VOLTAGE_DIVIDER; +#endif + +#endif // HAS_PMU + + return voltage; +} \ No newline at end of file