2020-02-01 16:30:53 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
Main module
|
|
|
|
|
|
|
|
# Modified by Kyle T. Gabriel to fix issue with incorrect GPS data for TTNMapper
|
|
|
|
|
|
|
|
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
#include "GPS.h"
|
|
|
|
#include "MeshRadio.h"
|
2020-02-02 20:45:32 +00:00
|
|
|
#include "MeshService.h"
|
2020-02-08 04:59:21 +00:00
|
|
|
#include "NodeDB.h"
|
2020-02-15 19:15:43 +00:00
|
|
|
#include "Periodic.h"
|
2020-03-19 02:15:51 +00:00
|
|
|
#include "PowerFSM.h"
|
|
|
|
#include "configuration.h"
|
2020-02-19 15:58:51 +00:00
|
|
|
#include "esp32/pm.h"
|
|
|
|
#include "esp_pm.h"
|
2020-03-26 16:24:53 +00:00
|
|
|
#include "power.h"
|
2020-03-19 02:15:51 +00:00
|
|
|
#include "rom/rtc.h"
|
|
|
|
#include "screen.h"
|
2020-02-22 01:01:26 +00:00
|
|
|
#include "sleep.h"
|
2020-03-19 02:15:51 +00:00
|
|
|
#include <Wire.h>
|
|
|
|
#include <driver/rtc_io.h>
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-04-10 19:18:48 +00:00
|
|
|
#ifndef NO_ESP32
|
|
|
|
#include "BluetoothUtil.h"
|
|
|
|
#endif
|
|
|
|
|
2020-03-28 22:31:22 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-02-01 16:30:53 +00:00
|
|
|
#include "axp20x.h"
|
|
|
|
AXP20X_Class axp;
|
|
|
|
bool pmu_irq = false;
|
|
|
|
#endif
|
2020-02-12 17:13:49 +00:00
|
|
|
|
2020-03-15 23:47:38 +00:00
|
|
|
// Global Screen singleton
|
|
|
|
#ifdef I2C_SDA
|
|
|
|
meshtastic::Screen screen(SSD1306_ADDRESS, I2C_SDA, I2C_SCL);
|
|
|
|
#else
|
|
|
|
// Fake values for pins to keep build happy, we won't ever initialize it.
|
|
|
|
meshtastic::Screen screen(SSD1306_ADDRESS, 0, 0);
|
|
|
|
#endif
|
|
|
|
|
2020-03-26 16:24:53 +00:00
|
|
|
// Global power status singleton
|
|
|
|
static meshtastic::PowerStatus powerStatus;
|
2020-02-23 18:49:37 +00:00
|
|
|
|
|
|
|
bool ssd1306_found;
|
|
|
|
bool axp192_found;
|
|
|
|
|
2020-02-01 16:30:53 +00:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Application
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void scanI2Cdevice(void)
|
|
|
|
{
|
2020-03-19 02:15:51 +00:00
|
|
|
byte err, addr;
|
|
|
|
int nDevices = 0;
|
|
|
|
for (addr = 1; addr < 127; addr++) {
|
|
|
|
Wire.beginTransmission(addr);
|
|
|
|
err = Wire.endTransmission();
|
|
|
|
if (err == 0) {
|
|
|
|
DEBUG_MSG("I2C device found at address 0x%x\n", addr);
|
|
|
|
|
|
|
|
nDevices++;
|
|
|
|
|
|
|
|
if (addr == SSD1306_ADDRESS) {
|
|
|
|
ssd1306_found = true;
|
|
|
|
DEBUG_MSG("ssd1306 display found\n");
|
|
|
|
}
|
2020-03-28 22:31:22 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-03-19 02:15:51 +00:00
|
|
|
if (addr == AXP192_SLAVE_ADDRESS) {
|
|
|
|
axp192_found = true;
|
|
|
|
DEBUG_MSG("axp192 PMU found\n");
|
|
|
|
}
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-03-19 02:15:51 +00:00
|
|
|
} else if (err == 4) {
|
|
|
|
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
|
|
|
}
|
2020-02-01 16:30:53 +00:00
|
|
|
}
|
2020-03-19 02:15:51 +00:00
|
|
|
if (nDevices == 0)
|
|
|
|
DEBUG_MSG("No I2C devices found\n");
|
|
|
|
else
|
|
|
|
DEBUG_MSG("done\n");
|
2020-02-01 16:30:53 +00:00
|
|
|
}
|
|
|
|
|
2020-03-28 22:31:22 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-03-26 16:24:53 +00:00
|
|
|
/// Reads power status to powerStatus singleton.
|
|
|
|
//
|
|
|
|
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
|
|
|
void readPowerStatus()
|
|
|
|
{
|
|
|
|
powerStatus.haveBattery = axp.isBatteryConnect();
|
|
|
|
if (powerStatus.haveBattery) {
|
|
|
|
powerStatus.batteryVoltageMv = axp.getBattVoltage();
|
|
|
|
}
|
|
|
|
powerStatus.usb = axp.isVBUSPlug();
|
|
|
|
powerStatus.charging = axp.isChargeing();
|
|
|
|
}
|
2020-03-28 22:31:22 +00:00
|
|
|
#endif // TBEAM_V10
|
2020-03-26 16:24:53 +00:00
|
|
|
|
2020-02-01 16:30:53 +00:00
|
|
|
/**
|
|
|
|
* Init the power manager chip
|
2020-03-19 02:15:51 +00:00
|
|
|
*
|
|
|
|
* axp192 power
|
|
|
|
DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192
|
|
|
|
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
|
|
|
|
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
|
|
|
|
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
|
2020-02-01 16:30:53 +00:00
|
|
|
*/
|
2020-02-02 00:14:34 +00:00
|
|
|
void axp192Init()
|
|
|
|
{
|
2020-03-28 22:31:22 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-03-19 02:15:51 +00:00
|
|
|
if (axp192_found) {
|
|
|
|
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
|
|
|
|
DEBUG_MSG("AXP192 Begin PASS\n");
|
|
|
|
|
|
|
|
// axp.setChgLEDMode(LED_BLINK_4HZ);
|
|
|
|
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("----------------------------------------\n");
|
|
|
|
|
|
|
|
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
|
|
|
|
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power
|
|
|
|
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
|
|
|
|
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
|
|
|
|
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
|
|
|
|
axp.setDCDC1Voltage(3300); // for the OLED power
|
|
|
|
|
|
|
|
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
2020-02-04 16:17:44 +00:00
|
|
|
|
2020-02-17 00:03:16 +00:00
|
|
|
#if 0
|
|
|
|
// cribbing from https://github.com/m5stack/M5StickC/blob/master/src/AXP192.cpp to fix charger to be more like 300ms.
|
|
|
|
// I finally found an english datasheet. Will look at this later - but suffice it to say the default code from TTGO has 'issues'
|
|
|
|
|
|
|
|
axp.adc1Enable(0xff, 1); // turn on all adcs
|
|
|
|
uint8_t val = 0xc2;
|
|
|
|
axp._writeByte(0x33, 1, &val); // Bat charge voltage to 4.2, Current 280mA
|
|
|
|
val = 0b11110010;
|
|
|
|
// Set ADC sample rate to 200hz
|
|
|
|
// axp._writeByte(0x84, 1, &val);
|
|
|
|
|
|
|
|
// Not connected
|
|
|
|
//val = 0xfc;
|
|
|
|
//axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection
|
|
|
|
|
|
|
|
//not used
|
|
|
|
//val = 0x46;
|
|
|
|
//axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection
|
|
|
|
#endif
|
2020-03-19 02:15:51 +00:00
|
|
|
axp.debugCharging();
|
2020-02-04 16:17:44 +00:00
|
|
|
|
2020-02-12 17:13:49 +00:00
|
|
|
#ifdef PMU_IRQ
|
2020-03-27 19:29:51 +00:00
|
|
|
pinMode(PMU_IRQ, INPUT);
|
2020-03-19 02:15:51 +00:00
|
|
|
attachInterrupt(
|
2020-03-27 19:29:51 +00:00
|
|
|
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
2020-03-19 02:15:51 +00:00
|
|
|
|
|
|
|
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
|
2020-03-27 19:29:51 +00:00
|
|
|
axp.enableIRQ(AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ | AXP202_CHARGING_FINISHED_IRQ | AXP202_CHARGING_IRQ |
|
|
|
|
AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ,
|
2020-03-19 02:15:51 +00:00
|
|
|
1);
|
2020-03-27 19:29:51 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
axp.clearIRQ();
|
2020-02-12 17:13:49 +00:00
|
|
|
#endif
|
2020-03-26 16:24:53 +00:00
|
|
|
readPowerStatus();
|
2020-03-19 02:15:51 +00:00
|
|
|
} else {
|
|
|
|
DEBUG_MSG("AXP192 Begin FAIL\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("AXP192 not found\n");
|
2020-02-02 00:14:34 +00:00
|
|
|
}
|
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 20:55:26 +00:00
|
|
|
const char *getDeviceName()
|
|
|
|
{
|
2020-03-19 02:15:51 +00:00
|
|
|
uint8_t dmac[6];
|
|
|
|
assert(esp_efuse_mac_get_default(dmac) == ESP_OK);
|
2020-02-02 20:55:26 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Meshtastic_ab3c
|
|
|
|
static char name[20];
|
|
|
|
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
|
|
|
|
return name;
|
2020-02-02 20:55:26 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 00:14:34 +00:00
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
// Debug
|
|
|
|
#ifdef DEBUG_PORT
|
2020-03-19 02:15:51 +00:00
|
|
|
DEBUG_PORT.begin(SERIAL_BAUD);
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
initDeepSleep();
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-02-01 22:23:21 +00:00
|
|
|
#ifdef VEXT_ENABLE
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(VEXT_ENABLE, OUTPUT);
|
|
|
|
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-02-01 22:23:21 +00:00
|
|
|
|
|
|
|
#ifdef RESET_OLED
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(RESET_OLED, OUTPUT);
|
|
|
|
digitalWrite(RESET_OLED, 1);
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-02-01 22:23:21 +00:00
|
|
|
|
2020-02-04 15:31:32 +00:00
|
|
|
#ifdef I2C_SDA
|
2020-03-19 02:15:51 +00:00
|
|
|
Wire.begin(I2C_SDA, I2C_SCL);
|
|
|
|
scanI2Cdevice();
|
2020-02-04 15:31:32 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Buttons & LED
|
2020-02-01 22:23:21 +00:00
|
|
|
#ifdef BUTTON_PIN
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
|
|
|
digitalWrite(BUTTON_PIN, 1);
|
2020-02-01 22:23:21 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
#ifdef LED_PIN
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(LED_PIN, OUTPUT);
|
|
|
|
digitalWrite(LED_PIN, 1); // turn on for now
|
2020-02-01 16:30:53 +00:00
|
|
|
#endif
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Hello
|
|
|
|
DEBUG_MSG("Meshtastic swver=%s, hwver=%s\n", xstr(APP_VERSION), xstr(HW_VERSION));
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Don't init display if we don't have one or we are waking headless due to a timer event
|
|
|
|
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
|
|
|
ssd1306_found = false; // forget we even have the hardware
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Initialize the screen first so we can show the logo while we start up everything else.
|
|
|
|
if (ssd1306_found)
|
|
|
|
screen.setup();
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
axp192Init();
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
screen.print("Started...\n");
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Init GPS
|
|
|
|
gps.setup();
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
service.init();
|
2020-02-05 05:24:11 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
|
|
|
|
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state
|
|
|
|
setCPUFast(false); // 80MHz is fine for our slow peripherals
|
2020-02-01 16:30:53 +00:00
|
|
|
}
|
|
|
|
|
2020-02-15 19:15:43 +00:00
|
|
|
uint32_t ledBlinker()
|
|
|
|
{
|
2020-03-19 02:15:51 +00:00
|
|
|
static bool ledOn;
|
|
|
|
ledOn ^= 1;
|
2020-02-15 19:15:43 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
setLed(ledOn);
|
2020-02-15 19:15:43 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
2020-03-26 16:24:53 +00:00
|
|
|
return powerStatus.charging ? 1000 : (ledOn ? 2 : 1000);
|
2020-02-15 19:15:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Periodic ledPeriodic(ledBlinker);
|
|
|
|
|
2020-02-17 00:03:16 +00:00
|
|
|
#if 0
|
|
|
|
// Turn off for now
|
|
|
|
|
2020-03-26 16:24:53 +00:00
|
|
|
uint32_t axpDebugRead()
|
2020-02-17 00:03:16 +00:00
|
|
|
{
|
|
|
|
axp.debugCharging();
|
|
|
|
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
|
|
|
|
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
|
|
|
|
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
|
|
|
|
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
|
2020-03-26 16:24:53 +00:00
|
|
|
DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect());
|
|
|
|
DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug());
|
|
|
|
DEBUG_MSG("is charging %d\n", axp.isChargeing());
|
2020-02-17 00:03:16 +00:00
|
|
|
|
|
|
|
return 30 * 1000;
|
|
|
|
}
|
|
|
|
|
2020-03-26 16:24:53 +00:00
|
|
|
Periodic axpDebugOutput(axpDebugRead);
|
2020-02-21 12:57:08 +00:00
|
|
|
#endif
|
2020-02-17 00:03:16 +00:00
|
|
|
|
2020-02-02 00:14:34 +00:00
|
|
|
void loop()
|
|
|
|
{
|
2020-03-19 02:15:51 +00:00
|
|
|
uint32_t msecstosleep = 1000 * 30; // How long can we sleep before we again need to service the main loop?
|
2020-02-08 00:12:55 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
powerFSM.run_machine();
|
|
|
|
gps.loop();
|
|
|
|
service.loop();
|
2020-02-21 18:51:36 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
ledPeriodic.loop();
|
|
|
|
// axpDebugOutput.loop();
|
2020-04-10 19:18:48 +00:00
|
|
|
|
|
|
|
#ifndef NO_ESP32
|
2020-03-19 02:15:51 +00:00
|
|
|
loopBLE();
|
2020-04-10 19:18:48 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// for debug printing
|
2020-04-06 16:39:44 +00:00
|
|
|
// service.radio.radioIf.canSleep();
|
2020-03-14 05:42:43 +00:00
|
|
|
|
2020-02-12 17:13:49 +00:00
|
|
|
#ifdef PMU_IRQ
|
2020-03-27 19:37:47 +00:00
|
|
|
if (pmu_irq) {
|
|
|
|
pmu_irq = false;
|
|
|
|
axp.readIRQ();
|
2020-02-21 19:39:10 +00:00
|
|
|
|
2020-03-27 19:37:47 +00:00
|
|
|
DEBUG_MSG("pmu irq!\n");
|
2020-03-27 19:29:51 +00:00
|
|
|
|
2020-03-27 19:37:47 +00:00
|
|
|
if (axp.isChargingIRQ()) {
|
|
|
|
DEBUG_MSG("Battery start charging\n");
|
|
|
|
}
|
|
|
|
if (axp.isChargingDoneIRQ()) {
|
|
|
|
DEBUG_MSG("Battery fully charged\n");
|
|
|
|
}
|
|
|
|
if (axp.isVbusRemoveIRQ()) {
|
|
|
|
DEBUG_MSG("USB unplugged\n");
|
|
|
|
}
|
|
|
|
if (axp.isVbusPlugInIRQ()) {
|
|
|
|
DEBUG_MSG("USB plugged In\n");
|
|
|
|
}
|
|
|
|
if (axp.isBattPlugInIRQ()) {
|
|
|
|
DEBUG_MSG("Battery inserted\n");
|
|
|
|
}
|
|
|
|
if (axp.isBattRemoveIRQ()) {
|
|
|
|
DEBUG_MSG("Battery removed\n");
|
|
|
|
}
|
|
|
|
if (axp.isPEKShortPressIRQ()) {
|
|
|
|
DEBUG_MSG("PEK short button press\n");
|
2020-03-19 02:15:51 +00:00
|
|
|
}
|
2020-02-24 19:21:08 +00:00
|
|
|
|
2020-03-26 16:24:53 +00:00
|
|
|
readPowerStatus();
|
2020-03-27 19:37:47 +00:00
|
|
|
axp.clearIRQ();
|
2020-03-19 02:15:51 +00:00
|
|
|
}
|
2020-03-26 16:24:53 +00:00
|
|
|
#endif // T_BEAM_V10
|
2020-02-02 21:55:44 +00:00
|
|
|
|
2020-02-01 22:23:21 +00:00
|
|
|
#ifdef BUTTON_PIN
|
2020-03-19 02:15:51 +00:00
|
|
|
// if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of
|
|
|
|
// this boilerplate)
|
|
|
|
static bool wasPressed = false;
|
|
|
|
|
|
|
|
if (!digitalRead(BUTTON_PIN)) {
|
|
|
|
if (!wasPressed) { // just started a new press
|
|
|
|
DEBUG_MSG("pressing\n");
|
|
|
|
|
|
|
|
// doLightSleep();
|
|
|
|
// esp_pm_dump_locks(stdout); // FIXME, do this someplace better
|
|
|
|
wasPressed = true;
|
|
|
|
|
|
|
|
powerFSM.trigger(EVENT_PRESS);
|
|
|
|
}
|
|
|
|
} else if (wasPressed) {
|
|
|
|
// we just did a release
|
|
|
|
wasPressed = false;
|
2020-02-02 00:14:34 +00:00
|
|
|
}
|
2020-02-23 18:49:37 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Show boot screen for first 3 seconds, then switch to normal operation.
|
|
|
|
static bool showingBootScreen = true;
|
|
|
|
if (showingBootScreen && (millis() > 3000)) {
|
|
|
|
screen.stopBootScreen();
|
|
|
|
showingBootScreen = false;
|
|
|
|
}
|
2020-03-15 23:47:38 +00:00
|
|
|
|
2020-03-26 16:24:53 +00:00
|
|
|
// Update the screen last, after we've figured out what to show.
|
|
|
|
screen.debug()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes());
|
|
|
|
screen.debug()->setChannelNameStatus(channelSettings.name);
|
|
|
|
screen.debug()->setPowerStatus(powerStatus);
|
|
|
|
// TODO(#4): use something based on hdop to show GPS "signal" strength.
|
|
|
|
screen.debug()->setGPSStatus(gps.hasLock() ? "ok" : ":(");
|
|
|
|
screen.loop();
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in)
|
|
|
|
// i.e. don't just keep spinning in loop as fast as we can.
|
|
|
|
// DEBUG_MSG("msecs %d\n", msecstosleep);
|
2020-02-08 01:48:12 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// FIXME - until button press handling is done by interrupt (see polling above) we can't sleep very long at all or buttons
|
|
|
|
// feel slow
|
|
|
|
msecstosleep = 10;
|
2020-02-21 12:57:08 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
delay(msecstosleep);
|
2020-03-15 20:27:00 +00:00
|
|
|
}
|