diff --git a/.clang-format b/.clang-format index a6c6401..cb22f9d 100644 --- a/.clang-format +++ b/.clang-format @@ -12,7 +12,7 @@ AlignOperands: Align AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false AllowShortEnumsOnASingleLine: false AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: false @@ -24,8 +24,8 @@ AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: MultiLine -BinPackArguments: true -BinPackParameters: true +BinPackArguments: false +BinPackParameters: false BraceWrapping: AfterCaseLabel: false AfterClass: false @@ -54,7 +54,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 500 +ColumnLimit: 200 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false diff --git a/platformio.ini b/platformio.ini index 586c350..21cc642 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,7 +11,7 @@ lib_deps = adafruit/Adafruit GFX Library @ 1.11.5 adafruit/Adafruit SSD1306 @ 2.5.7 bblanchon/ArduinoJson @ 6.21.2 - lewisxhe/AXP202X_Library @ 1.1.3 + lewisxhe/XPowersLib @ 0.1.8 sandeepmistry/LoRa @ 0.8.0 peterus/APRS-Decoder-Lib @ 0.0.6 mikalhart/TinyGPSPlus @ 1.0.3 @@ -23,6 +23,10 @@ check_flags = cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK check_skip_packages = yes +[env:ttgo-t-beam-AXP2101-v1_2] +board = ttgo-t-beam +build_flags = -Werror -Wall -DTTGO_T_Beam_V1_2 + [env:ttgo-t-beam-v1] board = ttgo-t-beam build_flags = -Werror -Wall -DTTGO_T_Beam_V1_0 diff --git a/src/LoRa_APRS_Tracker.cpp b/src/LoRa_APRS_Tracker.cpp index 0a959d7..1ce44f1 100644 --- a/src/LoRa_APRS_Tracker.cpp +++ b/src/LoRa_APRS_Tracker.cpp @@ -13,15 +13,22 @@ #include "pins.h" #include "power_management.h" -#define VERSION "22.19.0" +#define VERSION "23.36.0" logging::Logger logger; Configuration Config; BeaconManager BeaconMan; -PowerManagement powerManagement; -OneButton userButton = OneButton(BUTTON_PIN, true, true); +#ifdef TTGO_T_Beam_V1_0 +AXP192 axp; +PowerManagement *powerManagement = &axp; +#endif +#ifdef TTGO_T_Beam_V1_2 +AXP2101 axp; +PowerManagement *powerManagement = &axp; +#endif +OneButton userButton = OneButton(BUTTON_PIN, true, true); HardwareSerial ss(1); TinyGPSPlus gps; @@ -66,15 +73,27 @@ void setup() { #ifdef TTGO_T_Beam_V1_0 Wire.begin(SDA, SCL); - if (!powerManagement.begin(Wire)) { + if (powerManagement->begin(Wire)) { logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "AXP192", "init done!"); } else { logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "AXP192", "init failed!"); } - powerManagement.activateLoRa(); - powerManagement.activateOLED(); - powerManagement.activateGPS(); - powerManagement.activateMeasurement(); + powerManagement->activateLoRa(); + powerManagement->activateOLED(); + powerManagement->activateGPS(); + powerManagement->activateMeasurement(); +#endif +#ifdef TTGO_T_Beam_V1_2 + Wire.begin(SDA, SCL); + if (powerManagement->begin(Wire)) { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "AXP2101", "init done!"); + } else { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "AXP2101", "init failed!"); + } + powerManagement->activateLoRa(); + powerManagement->activateOLED(); + powerManagement->activateGPS(); + powerManagement->activateMeasurement(); #endif delay(500); @@ -180,20 +199,15 @@ void loop() { static String batteryChargeCurrent = ""; #ifdef TTGO_T_Beam_V1_0 static unsigned int rate_limit_check_battery = 0; - if (!(rate_limit_check_battery++ % 60)) - BatteryIsConnected = powerManagement.isBatteryConnect(); + if (!(rate_limit_check_battery++ % 60)) { + BatteryIsConnected = powerManagement->isBatteryConnect(); + } if (BatteryIsConnected) { - batteryVoltage = String(powerManagement.getBatteryVoltage(), 2); - batteryChargeCurrent = String(powerManagement.getBatteryChargeDischargeCurrent(), 0); + batteryVoltage = String(powerManagement->getBatteryVoltage(), 2); + batteryChargeCurrent = String(powerManagement->getBatteryChargeDischargeCurrent(), 0); } #endif - if (powerManagement.isChargeing()) { - powerManagement.enableChgLed(); - } else { - powerManagement.disableChgLed(); - } - if (!send_update && gps_loc_update && BeaconMan.getCurrentBeaconConfig()->smart_beacon.active) { uint32_t lastTx = millis() - lastTxTime; currentHeading = gps.course.deg(); @@ -222,7 +236,8 @@ void loop() { if (send_update && gps_loc_update) { send_update = false; - nextBeaconTimeStamp = now() + (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active ? BeaconMan.getCurrentBeaconConfig()->smart_beacon.slow_rate : (BeaconMan.getCurrentBeaconConfig()->timeout * SECS_PER_MIN)); + nextBeaconTimeStamp = + now() + (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active ? BeaconMan.getCurrentBeaconConfig()->smart_beacon.slow_rate : (BeaconMan.getCurrentBeaconConfig()->timeout * SECS_PER_MIN)); APRSMessage msg; String lat; @@ -328,7 +343,20 @@ void loop() { if (gps_time_update) { - show_display(BeaconMan.getCurrentBeaconConfig()->callsign, createDateString(now()) + " " + createTimeString(now()), String("Sats: ") + gps.satellites.value() + " HDOP: " + gps.hdop.hdop(), String("Next Bcn: ") + (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active ? "~" : "") + createTimeString(nextBeaconTimeStamp), BatteryIsConnected ? (String("Bat: ") + batteryVoltage + "V, " + batteryChargeCurrent + "mA") : "Powered via USB", String("Smart Beacon: " + getSmartBeaconState())); + show_display(BeaconMan.getCurrentBeaconConfig()->callsign, + createDateString(now()) + " " + createTimeString(now()), + String("Sats: ") + gps.satellites.value() + " HDOP: " + gps.hdop.hdop(), + String("Next Bcn: ") + (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active ? "~" : "") + createTimeString(nextBeaconTimeStamp), + BatteryIsConnected ? (String("Bat: ") + batteryVoltage + "V, " + batteryChargeCurrent + "mA") : "Powered via USB", + String("Smart Beacon: " + getSmartBeaconState())); + + Serial.println(BeaconMan.getCurrentBeaconConfig()->callsign); + Serial.println(createDateString(now()) + " " + createTimeString(now())); + Serial.println(String("Sats: ") + gps.satellites.value() + " HDOP: " + gps.hdop.hdop()); + Serial.println(String("Next Bcn: ") + (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active ? "~" : "") + createTimeString(nextBeaconTimeStamp)); + Serial.println(BatteryIsConnected ? (String("Bat: ") + batteryVoltage + "V, " + batteryChargeCurrent + "mA") : "Powered via USB"); + Serial.println(String("Smart Beacon: " + getSmartBeaconState())); + Serial.println(); if (BeaconMan.getCurrentBeaconConfig()->smart_beacon.active) { // Change the Tx internal based on the current speed @@ -348,13 +376,16 @@ void loop() { would lead to decrease of beacon rate in between 5 to 20 km/h. what is even below the slow speed rate. */ - txInterval = min(BeaconMan.getCurrentBeaconConfig()->smart_beacon.slow_rate, BeaconMan.getCurrentBeaconConfig()->smart_beacon.fast_speed * BeaconMan.getCurrentBeaconConfig()->smart_beacon.fast_rate / curr_speed) * 1000; + txInterval = min(BeaconMan.getCurrentBeaconConfig()->smart_beacon.slow_rate, + BeaconMan.getCurrentBeaconConfig()->smart_beacon.fast_speed * BeaconMan.getCurrentBeaconConfig()->smart_beacon.fast_rate / curr_speed) * + 1000; } } } if ((Config.debug == false) && (millis() > 5000 && gps.charsProcessed() < 10)) { - logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "GPS", + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, + "GPS", "No GPS frames detected! Try to reset the GPS Chip with this " "firmware: https://github.com/lora-aprs/TTGO-T-Beam_GPS-reset"); show_display("No GPS frames detected!", "Try to reset the GPS Chip", "https://github.com/lora-aprs/TTGO-T-Beam_GPS-reset", 2000); @@ -366,11 +397,13 @@ void load_config() { Config = confmg.readConfiguration(); BeaconMan.loadConfig(Config.beacons); if (BeaconMan.getCurrentBeaconConfig()->callsign == "NOCALL-7") { - logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Config", + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, + "Config", "You have to change your settings in 'data/tracker.json' and " "upload it via \"Upload File System image\"!"); - show_display("ERROR", "You have to change your settings in 'data/tracker.json' and " - "upload it via \"Upload File System image\"!"); + show_display("ERROR", + "You have to change your settings in 'data/tracker.json' and " + "upload it via \"Upload File System image\"!"); while (true) { } } diff --git a/src/pins.h b/src/pins.h index 88e47ab..4835883 100644 --- a/src/pins.h +++ b/src/pins.h @@ -16,7 +16,7 @@ #define GPS_TX 12 #endif -#ifdef TTGO_T_Beam_V1_0 +#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) #define GPS_RX 12 #define GPS_TX 34 #endif diff --git a/src/power_management.cpp b/src/power_management.cpp index d9527a4..e9b1613 100644 --- a/src/power_management.cpp +++ b/src/power_management.cpp @@ -1,86 +1,218 @@ +#include +#include #include "power_management.h" -// cppcheck-suppress uninitMemberVar -PowerManagement::PowerManagement() { +AXP192::AXP192() { } // cppcheck-suppress unusedFunction -bool PowerManagement::begin(TwoWire &port) { - bool result = axp.begin(port, AXP192_SLAVE_ADDRESS); - if (!result) { - axp.setDCDC1Voltage(3300); +bool AXP192::begin(TwoWire &port) { + _pmu = new XPowersAXP192(port); + if (!_pmu->init()) { + delete _pmu; + _pmu = 0; + return false; } - return result; + + // lora radio power channel + _pmu->setPowerChannelVoltage(XPOWERS_LDO2, 3300); + + // oled module power channel, + // disable it will cause abnormal communication between boot and AXP power supply, + // do not turn it off + _pmu->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); + + // gnss module power channel - now turned on in setGpsPower + _pmu->setPowerChannelVoltage(XPOWERS_LDO3, 3300); + + // protected oled power source + //_pmu->setProtectedChannel(XPOWERS_DCDC1); + // protected esp32 power source + _pmu->setProtectedChannel(XPOWERS_DCDC3); + + // disable not use channel + _pmu->disablePowerOutput(XPOWERS_DCDC2); + + // disable all axp chip interrupt + _pmu->disableIRQ(XPOWERS_AXP192_ALL_IRQ); + + // Set constant current charging current + _pmu->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA); + + // Set up the charging voltage + _pmu->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); + + _pmu->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); + + return true; } // cppcheck-suppress unusedFunction -void PowerManagement::activateLoRa() { - axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); +void AXP192::activateLoRa() { + _pmu->enablePowerOutput(XPOWERS_LDO2); } // cppcheck-suppress unusedFunction -void PowerManagement::deactivateLoRa() { - axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); +void AXP192::deactivateLoRa() { + _pmu->disablePowerOutput(XPOWERS_LDO2); } // cppcheck-suppress unusedFunction -void PowerManagement::activateGPS() { - axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); +void AXP192::activateGPS() { + _pmu->enablePowerOutput(XPOWERS_LDO3); } // cppcheck-suppress unusedFunction -void PowerManagement::deactivateGPS() { - axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); +void AXP192::deactivateGPS() { + _pmu->disablePowerOutput(XPOWERS_LDO3); } // cppcheck-suppress unusedFunction -void PowerManagement::activateOLED() { - axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); +void AXP192::activateOLED() { + _pmu->enablePowerOutput(XPOWERS_DCDC1); } // cppcheck-suppress unusedFunction -void PowerManagement::decativateOLED() { - axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); +void AXP192::deactivateOLED() { + _pmu->disablePowerOutput(XPOWERS_DCDC1); } // cppcheck-suppress unusedFunction -void PowerManagement::disableChgLed() { - axp.setChgLEDMode(AXP20X_LED_OFF); +void AXP192::activateMeasurement() { + _pmu->enableBattVoltageMeasure(); } // cppcheck-suppress unusedFunction -void PowerManagement::enableChgLed() { - axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL); +void AXP192::deactivateMeasurement() { + _pmu->disableBattVoltageMeasure(); } // cppcheck-suppress unusedFunction -void PowerManagement::activateMeasurement() { - axp.adc1Enable(AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, true); +double AXP192::getBatteryVoltage() { + return _pmu->getBattVoltage() / 1000.0; } // cppcheck-suppress unusedFunction -void PowerManagement::deactivateMeasurement() { - axp.adc1Enable(AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, false); -} - -// cppcheck-suppress unusedFunction -double PowerManagement::getBatteryVoltage() { - return axp.getBattVoltage() / 1000.0; -} - -// cppcheck-suppress unusedFunction -double PowerManagement::getBatteryChargeDischargeCurrent() { - if (axp.isChargeing()) { - return axp.getBattChargeCurrent(); +double AXP192::getBatteryChargeDischargeCurrent() { + if (isCharging()) { + return ((XPowersAXP192 *)_pmu)->getBatteryChargeCurrent(); } - return -1.0 * axp.getBattDischargeCurrent(); + return -1.0 * ((XPowersAXP192 *)_pmu)->getBattDischargeCurrent(); } -bool PowerManagement::isBatteryConnect() { - return axp.isBatteryConnect(); +bool AXP192::isBatteryConnect() { + return _pmu->isBatteryConnect(); } -bool PowerManagement::isChargeing() { - return axp.isChargeing(); +bool AXP192::isCharging() { + return _pmu->isCharging(); +} + +AXP2101::AXP2101() { +} + +// cppcheck-suppress unusedFunction +bool AXP2101::begin(TwoWire &port) { + _pmu = new XPowersAXP2101(port); + if (!_pmu->init()) { + delete _pmu; + _pmu = 0; + return false; + } + + // Unuse power channel + _pmu->disablePowerOutput(XPOWERS_DCDC2); + _pmu->disablePowerOutput(XPOWERS_DCDC3); + _pmu->disablePowerOutput(XPOWERS_DCDC4); + _pmu->disablePowerOutput(XPOWERS_DCDC5); + _pmu->disablePowerOutput(XPOWERS_ALDO1); + _pmu->disablePowerOutput(XPOWERS_ALDO4); + _pmu->disablePowerOutput(XPOWERS_BLDO1); + _pmu->disablePowerOutput(XPOWERS_BLDO2); + _pmu->disablePowerOutput(XPOWERS_DLDO1); + _pmu->disablePowerOutput(XPOWERS_DLDO2); + + // GNSS RTC PowerVDD 3300mV + _pmu->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); + _pmu->enablePowerOutput(XPOWERS_VBACKUP); + + // LoRa VDD 3300mV + _pmu->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + _pmu->enablePowerOutput(XPOWERS_ALDO2); + + // GNSS VDD 3300mV + _pmu->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + _pmu->enablePowerOutput(XPOWERS_ALDO3); + + // disable all axp chip interrupt + _pmu->disableIRQ(XPOWERS_AXP192_ALL_IRQ); + + // Set constant current charging current + _pmu->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA); + + // Set up the charging voltage + _pmu->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); + + _pmu->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); + + return true; +} + +// cppcheck-suppress unusedFunction +void AXP2101::activateLoRa() { + _pmu->enablePowerOutput(XPOWERS_ALDO2); +} + +// cppcheck-suppress unusedFunction +void AXP2101::deactivateLoRa() { + _pmu->disablePowerOutput(XPOWERS_ALDO2); +} + +// cppcheck-suppress unusedFunction +void AXP2101::activateGPS() { + _pmu->enablePowerOutput(XPOWERS_ALDO3); +} + +// cppcheck-suppress unusedFunction +void AXP2101::deactivateGPS() { + _pmu->disablePowerOutput(XPOWERS_ALDO3); +} + +// cppcheck-suppress unusedFunction +void AXP2101::activateOLED() { + _pmu->enablePowerOutput(XPOWERS_DCDC1); +} + +// cppcheck-suppress unusedFunction +void AXP2101::deactivateOLED() { + _pmu->disablePowerOutput(XPOWERS_DCDC1); +} + +// cppcheck-suppress unusedFunction +void AXP2101::activateMeasurement() { + _pmu->enableBattVoltageMeasure(); +} + +// cppcheck-suppress unusedFunction +void AXP2101::deactivateMeasurement() { + _pmu->disableBattVoltageMeasure(); +} + +// cppcheck-suppress unusedFunction +double AXP2101::getBatteryVoltage() { + return _pmu->getBattVoltage() / 1000.0; +} + +// cppcheck-suppress unusedFunction +double AXP2101::getBatteryChargeDischargeCurrent() { + return 0.0; +} + +bool AXP2101::isBatteryConnect() { + return _pmu->isBatteryConnect(); +} + +bool AXP2101::isCharging() { + return _pmu->isCharging(); } diff --git a/src/power_management.h b/src/power_management.h index 73edfbf..45ff6ea 100644 --- a/src/power_management.h +++ b/src/power_management.h @@ -1,12 +1,43 @@ #ifndef POWER_MANAGEMENT_H_ #define POWER_MANAGEMENT_H_ -#include -#include +#include +#include class PowerManagement { public: - PowerManagement(); + ~PowerManagement() { + } + + virtual bool begin(TwoWire &port) = 0; + + virtual void activateLoRa() = 0; + virtual void deactivateLoRa() = 0; + + virtual void activateGPS() = 0; + virtual void deactivateGPS() = 0; + + virtual void activateOLED() = 0; + virtual void deactivateOLED() = 0; + + virtual void activateMeasurement() = 0; + virtual void deactivateMeasurement() = 0; + + virtual double getBatteryVoltage() = 0; + + virtual double getBatteryChargeDischargeCurrent() = 0; + + virtual bool isBatteryConnect() = 0; + virtual bool isCharging() = 0; + +protected: + XPowersLibInterface *_pmu = 0; +}; + +class AXP192 : public PowerManagement { +public: + AXP192(); + bool begin(TwoWire &port); void activateLoRa(); @@ -16,7 +47,7 @@ public: void deactivateGPS(); void activateOLED(); - void decativateOLED(); + void deactivateOLED(); void enableChgLed(); void disableChgLed(); @@ -28,10 +59,35 @@ public: double getBatteryChargeDischargeCurrent(); bool isBatteryConnect(); - bool isChargeing(); + bool isCharging(); +}; -private: - AXP20X_Class axp; +class AXP2101 : public PowerManagement { +public: + AXP2101(); + + bool begin(TwoWire &port); + + void activateLoRa(); + void deactivateLoRa(); + + void activateGPS(); + void deactivateGPS(); + + void activateOLED(); + void deactivateOLED(); + + void enableChgLed(); + void disableChgLed(); + + void activateMeasurement(); + void deactivateMeasurement(); + + double getBatteryVoltage(); + double getBatteryChargeDischargeCurrent(); + + bool isBatteryConnect(); + bool isCharging(); }; #endif