sforkowany z mirror/meshtastic-firmware
Merge pull request #2019 from code8buster/gps-toggle-final
Adds a flag to turn the GPS power rail off entirely on tbeamraytac-diy
rodzic
941786669b
commit
220859d0aa
|
@ -51,6 +51,7 @@ class ButtonThread : public concurrency::OSThread
|
|||
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
|
||||
#endif
|
||||
userButton.attachClick(userButtonPressed);
|
||||
userButton.setClickTicks(300);
|
||||
userButton.attachDuringLongPress(userButtonPressedLong);
|
||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||
userButton.attachMultiClick(userButtonMultiPressed);
|
||||
|
@ -159,9 +160,21 @@ class ButtonThread : public concurrency::OSThread
|
|||
|
||||
static void userButtonDoublePressed()
|
||||
{
|
||||
#if defined(USE_EINK) && defined(PIN_EINK_EN)
|
||||
#if defined(USE_EINK) && defined(PIN_EINK_EN)
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(GPS_POWER_TOGGLE)
|
||||
if(config.position.gps_enabled)
|
||||
{
|
||||
DEBUG_MSG("Flag set to false for gps power\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_MSG("Flag set to true to restore power\n");
|
||||
}
|
||||
config.position.gps_enabled = !(config.position.gps_enabled);
|
||||
doGPSpowersave(config.position.gps_enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void userButtonMultiPressed()
|
||||
|
|
|
@ -20,16 +20,19 @@ class GPSStatus : public Status
|
|||
bool hasLock = false; // default to false, until we complete our first read
|
||||
bool isConnected = false; // Do we have a GPS we are talking to
|
||||
|
||||
bool isPowerSaving = false; //Are we in power saving state
|
||||
|
||||
Position p = Position_init_default;
|
||||
|
||||
public:
|
||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||
|
||||
// preferred method
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
|
||||
GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const Position &pos) : Status()
|
||||
{
|
||||
this->hasLock = hasLock;
|
||||
this->isConnected = isConnected;
|
||||
this->isPowerSaving = isPowerSaving;
|
||||
|
||||
// all-in-one struct copy
|
||||
this->p = pos;
|
||||
|
@ -44,6 +47,8 @@ class GPSStatus : public Status
|
|||
|
||||
bool getIsConnected() const { return isConnected; }
|
||||
|
||||
bool getIsPowerSaving() const { return isPowerSaving;}
|
||||
|
||||
int32_t getLatitude() const
|
||||
{
|
||||
if (config.position.fixed_position) {
|
||||
|
@ -94,7 +99,7 @@ class GPSStatus : public Status
|
|||
#ifdef GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||
#endif
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving ||
|
||||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
||||
|
|
|
@ -270,21 +270,30 @@ bool GPS::setup()
|
|||
pinMode(PIN_GPS_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_PMU
|
||||
if(config.position.gps_enabled){
|
||||
setGPSPower(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PIN_GPS_RESET
|
||||
digitalWrite(PIN_GPS_RESET, 1); // assert for 10ms
|
||||
pinMode(PIN_GPS_RESET, OUTPUT);
|
||||
delay(10);
|
||||
digitalWrite(PIN_GPS_RESET, 0);
|
||||
#endif
|
||||
|
||||
setAwake(true); // Wake GPS power before doing any init
|
||||
bool ok = setupGPS();
|
||||
|
||||
if (ok) {
|
||||
notifySleepObserver.observe(¬ifySleep);
|
||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
||||
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||
}
|
||||
if (config.position.gps_enabled==false) {
|
||||
setAwake(false);
|
||||
doGPSpowersave(false);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -293,6 +302,7 @@ GPS::~GPS()
|
|||
// we really should unregister our sleep observer
|
||||
notifySleepObserver.unobserve(¬ifySleep);
|
||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||
}
|
||||
|
||||
bool GPS::hasLock()
|
||||
|
@ -405,7 +415,7 @@ void GPS::publishUpdate()
|
|||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p);
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +426,7 @@ int32_t GPS::runOnce()
|
|||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
} else {
|
||||
if(gnssModel == GNSS_MODEL_UBLOX){
|
||||
if((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)){
|
||||
// reset the GPS on next bootup
|
||||
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
|
@ -518,6 +528,7 @@ int GPS::prepareDeepSleep(void *unused)
|
|||
DEBUG_MSG("GPS deep sleep!\n");
|
||||
|
||||
// For deep sleep we also want abandon any lock attempts (because we want minimum power)
|
||||
getSleepTime();
|
||||
setAwake(false);
|
||||
|
||||
return 0;
|
||||
|
@ -653,6 +664,11 @@ GPS *createGps()
|
|||
return new_gps;
|
||||
}
|
||||
}
|
||||
else{
|
||||
GPS *new_gps = new NMEAGPS();
|
||||
new_gps->setup();
|
||||
return new_gps;
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ class GPS : private concurrency::OSThread
|
|||
|
||||
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
|
||||
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||
|
||||
public:
|
||||
/** If !NULL we will use this serial port to construct our GPS */
|
||||
|
@ -77,6 +78,8 @@ class GPS : private concurrency::OSThread
|
|||
/// Return true if we are connected to a GPS
|
||||
bool isConnected() const { return hasGPS; }
|
||||
|
||||
bool isPowerSaving() const { return !config.position.gps_enabled;}
|
||||
|
||||
/**
|
||||
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
||||
* called after the CPU wakes from light-sleep state
|
||||
|
|
|
@ -512,6 +512,22 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
|
|||
}
|
||||
}
|
||||
|
||||
//Draw status when gps is disabled by PMU
|
||||
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps){
|
||||
String displayLine = "";
|
||||
displayLine = "GPS disabled";
|
||||
int16_t xPos = display->getStringWidth(displayLine);
|
||||
#ifdef HAS_PMU
|
||||
if (!config.position.gps_enabled){
|
||||
display->drawString(x + xPos, y, displayLine);
|
||||
#ifdef GPS_POWER_TOGGLE
|
||||
display->drawString(x + xPos, y - 2 + FONT_HEIGHT_SMALL, " by button");
|
||||
#endif
|
||||
//display->drawString(x + xPos, y + 2, displayLine);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||
{
|
||||
String displayLine = "";
|
||||
|
@ -1384,7 +1400,16 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||
// Display nodes status
|
||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
|
||||
// Display GPS status
|
||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
|
||||
if (!config.position.gps_enabled){
|
||||
int16_t yPos = y + 2;
|
||||
#ifdef GPS_POWER_TOGGLE
|
||||
yPos = (y + 10 + FONT_HEIGHT_SMALL);
|
||||
#endif
|
||||
drawGPSpowerstat(display, x, yPos, gpsStatus);
|
||||
} else {
|
||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
|
||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
|
||||
}
|
||||
|
||||
display->setColor(WHITE);
|
||||
// Draw the channel name
|
||||
|
@ -1643,7 +1668,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||
char chUtil[13];
|
||||
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
||||
|
||||
if (config.position.gps_enabled) {
|
||||
// Line 3
|
||||
if (config.display.gps_format !=
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
||||
|
@ -1651,7 +1676,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||
|
||||
// Line 4
|
||||
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
||||
|
||||
} else {
|
||||
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
}
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
#ifdef SHOW_REDRAWS
|
||||
if (heartbeat)
|
||||
|
|
|
@ -29,7 +29,9 @@ Observable<void *> preflightSleep;
|
|||
|
||||
/// Called to tell observers we are now entering sleep and you should prepare. Must return 0
|
||||
/// notifySleep will be called for light or deep sleep, notifyDeepSleep is only called for deep sleep
|
||||
/// notifyGPSSleep will be called when config.position.gps_enabled is set to 0 or from buttonthread when GPS_POWER_TOGGLE is enabled.
|
||||
Observable<void *> notifySleep, notifyDeepSleep;
|
||||
Observable<void *> notifyGPSSleep;
|
||||
|
||||
// deep sleep support
|
||||
RTC_DATA_ATTR int bootCount = 0;
|
||||
|
@ -167,6 +169,36 @@ static void waitEnterSleep()
|
|||
notifySleep.notifyObservers(NULL);
|
||||
}
|
||||
|
||||
void doGPSpowersave(bool on)
|
||||
{
|
||||
#ifdef HAS_PMU
|
||||
if (on)
|
||||
{
|
||||
DEBUG_MSG("Turning GPS back on\n");
|
||||
gps->forceWake(1);
|
||||
setGPSPower(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_MSG("Turning off GPS chip\n");
|
||||
notifyGPSSleep.notifyObservers(NULL);
|
||||
setGPSPower(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PIN_GPS_WAKE
|
||||
if (on)
|
||||
{
|
||||
DEBUG_MSG("Waking GPS");
|
||||
gps->forceWake(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_MSG("GPS entering sleep");
|
||||
notifyGPSSleep.notifyObservers(NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void doDeepSleep(uint64_t msecToWake)
|
||||
{
|
||||
DEBUG_MSG("Entering deep sleep for %lu seconds\n", msecToWake / 1000);
|
||||
|
|
|
@ -13,7 +13,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t msecToWake);
|
|||
extern esp_sleep_source_t wakeCause;
|
||||
#endif
|
||||
void setGPSPower(bool on);
|
||||
|
||||
void doGPSpowersave(bool on);
|
||||
// Perform power on init that we do on each wake from deep sleep
|
||||
void initDeepSleep();
|
||||
|
||||
|
@ -37,4 +37,6 @@ extern Observable<void *> notifySleep;
|
|||
/// Called to tell observers we are now entering (deep) sleep and you should prepare. Must return 0
|
||||
extern Observable<void *> notifyDeepSleep;
|
||||
|
||||
/// Called to tell GPS thread to enter deep sleep independently of LoRa/MCU sleep, prior to full poweroff. Must return 0
|
||||
extern Observable<void *> notifyGPSSleep;
|
||||
void enableModemSleep();
|
|
@ -6,4 +6,5 @@ lib_deps =
|
|||
${esp32_base.lib_deps}
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TBEAM_V10 -I variants/tbeam
|
||||
-DGPS_POWER_TOGGLE ; comment this line to disable double press function on the user button to turn off gps entirely.
|
||||
upload_speed = 921600
|
||||
|
|
Ładowanie…
Reference in New Issue