From 933d5424da90113a152aae44df141915ffaf8401 Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 4 May 2020 11:15:05 -0700 Subject: [PATCH] abstract out the UBlox GPS driver --- .vscode/settings.json | 2 + platformio.ini | 2 +- src/PowerFSM.cpp | 2 +- src/esp32/MeshBluetoothService.cpp | 2 +- src/gps/GPS.cpp | 171 ++--------------------------- src/gps/GPS.h | 62 +++++------ src/gps/UBloxGPS.cpp | 153 ++++++++++++++++++++++++++ src/gps/UBloxGPS.h | 41 +++++++ src/main.cpp | 13 ++- src/mesh/MeshService.cpp | 28 ++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/Router.cpp | 2 +- src/sleep.cpp | 9 +- 13 files changed, 263 insertions(+), 226 deletions(-) create mode 100644 src/gps/UBloxGPS.cpp create mode 100644 src/gps/UBloxGPS.h diff --git a/.vscode/settings.json b/.vscode/settings.json index dfe3b542f..bfef8191b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -50,7 +50,9 @@ "cassert": "cpp" }, "cSpell.words": [ + "Blox", "Meshtastic", + "Ublox", "descs", "protobufs" ] diff --git a/platformio.ini b/platformio.ini index 936a8e6c3..b64bcf002 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,7 +31,7 @@ board_build.partitions = partition-table.csv ; note: we add src to our include search path so that lmic_project_config can override ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc -build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Ilib/nanopb/include -Os -Wl,-Map,.pio/build/output.map +build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Os -Wl,-Map,.pio/build/output.map -DAXP_DEBUG_PORT=Serial -DHW_VERSION_${sysenv.COUNTRY} -DAPP_VERSION=${sysenv.APP_VERSION} diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 4c4944b0f..ed6eaf4ff 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -87,7 +87,7 @@ static void lsIdle() static void lsExit() { // setGPSPower(true); // restore GPS power - gps.startLock(); + gps->startLock(); } static void nbEnter() diff --git a/src/esp32/MeshBluetoothService.cpp b/src/esp32/MeshBluetoothService.cpp index 9b3f14804..ecda8bf40 100644 --- a/src/esp32/MeshBluetoothService.cpp +++ b/src/esp32/MeshBluetoothService.cpp @@ -178,7 +178,7 @@ class MyNodeInfoCharacteristic : public ProtobufCharacteristic void onRead(BLECharacteristic *c) { // update gps connection state - myNodeInfo.has_gps = gps.isConnected; + myNodeInfo.has_gps = gps->isConnected; ProtobufCharacteristic::onRead(c); diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index f78ad906c..9273a6ed2 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -6,89 +6,23 @@ #include #ifdef GPS_RX_PIN -HardwareSerial _serial_gps(GPS_SERIAL_NUM); +HardwareSerial _serial_gps_real(GPS_SERIAL_NUM); +HardwareSerial &GPS::_serial_gps = _serial_gps_real; #else // Assume NRF52 -HardwareSerial &_serial_gps = Serial1; +HardwareSerial &GPS::_serial_gps = Serial1; #endif bool timeSetFromGPS; // We try to set our time from GPS each time we wake from sleep -GPS gps; +GPS *gps; // stuff that really should be in in the instance instead... static uint32_t timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock -static bool wantNewLocation = true; - -GPS::GPS() : PeriodicTask() {} - -void GPS::setup() -{ - PeriodicTask::setup(); - - readFromRTC(); // read the main CPU RTC at first - -#ifdef GPS_RX_PIN - _serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); -#else - _serial_gps.begin(GPS_BAUDRATE); -#endif - // _serial_gps.setRxBufferSize(1024); // the default is 256 - // ublox.enableDebugging(Serial); - - // note: the lib's implementation has the wrong docs for what the return val is - // it is not a bool, it returns zero for success - isConnected = ublox.begin(_serial_gps); - - // try a second time, the ublox lib serial parsing is buggy? - if (!isConnected) - isConnected = ublox.begin(_serial_gps); - - if (isConnected) { - DEBUG_MSG("Connected to UBLOX GPS successfully\n"); - - bool factoryReset = false; - bool ok; - if (factoryReset) { - // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have - // GPS_TX connected) - ublox.factoryReset(); - delay(2000); - isConnected = ublox.begin(_serial_gps); - DEBUG_MSG("Factory reset success=%d\n", isConnected); - if (isConnected) { - ublox.assumeAutoPVT(true, true); // Just parse NEMA for now - } - } else { - ok = ublox.setUART1Output(COM_TYPE_UBX, 500); // Use native API - assert(ok); - ok = ublox.setNavigationFrequency(1, 500); // Produce 4x/sec to keep the amount of time we stall in getPVT low - assert(ok); - // ok = ublox.setAutoPVT(false); // Not implemented on NEO-6M - // assert(ok); - // ok = ublox.setDynamicModel(DYN_MODEL_BIKE); // probably PEDESTRIAN but just in case assume bike speeds - // assert(ok); - ok = ublox.powerSaveMode(); // use power save mode - assert(ok); - } - ok = ublox.saveConfiguration(3000); - assert(ok); - } else { - // Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just - // assume NEMA at 9600 baud. - DEBUG_MSG("ERROR: No bidirectional GPS found, hoping that it still might work\n"); - - // tell lib, we are expecting the module to send PVT messages by itself to our Rx pin - // you can set second parameter to "false" if you want to control the parsing and eviction of the data (need to call - // checkUblox cyclically) - ublox.assumeAutoPVT(true, true); - } -} - -void GPS::readFromRTC() +void readFromRTC() { struct timeval tv; /* btw settimeofday() is helpfull here too*/ @@ -102,7 +36,7 @@ void GPS::readFromRTC() } /// If we haven't yet set our RTC this boot, set it from a GPS derived time -void GPS::perhapsSetRTC(const struct timeval *tv) +void perhapsSetRTC(const struct timeval *tv) { if (!timeSetFromGPS) { timeSetFromGPS = true; @@ -118,101 +52,12 @@ void GPS::perhapsSetRTC(const struct timeval *tv) #include -uint32_t GPS::getTime() +uint32_t getTime() { return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs; } -uint32_t GPS::getValidTime() +uint32_t getValidTime() { return timeSetFromGPS ? getTime() : 0; } - -/// Returns true if we think the board can enter deep or light sleep now (we might be trying to get a GPS lock) -bool GPS::canSleep() -{ - return true; // we leave GPS on during sleep now, so sleep is okay !wantNewLocation; -} - -/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs -void GPS::prepareSleep() -{ - if (isConnected) - ublox.powerOff(); -} - -void GPS::doTask() -{ - uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix - - if (isConnected) { - // Consume all characters that have arrived - - // getPVT automatically calls checkUblox - ublox.checkUblox(); // See if new data is available. Process bytes as they come in. - - // If we don't have a fix (a quick check), don't try waiting for a solution) - // Hmmm my fix type reading returns zeros for fix, which doesn't seem correct, because it is still sptting out positions - // turn off for now - // fixtype = ublox.getFixType(); - DEBUG_MSG("fix type %d\n", fixtype); - } - - // DEBUG_MSG("sec %d\n", ublox.getSecond()); - // DEBUG_MSG("lat %d\n", ublox.getLatitude()); - - // any fix that has time - if (!timeSetFromGPS && ublox.getT()) { - struct timeval tv; - - /* Convert to unix time -The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 -(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). -*/ - struct tm t; - t.tm_sec = ublox.getSecond(); - t.tm_min = ublox.getMinute(); - t.tm_hour = ublox.getHour(); - t.tm_mday = ublox.getDay(); - t.tm_mon = ublox.getMonth() - 1; - t.tm_year = ublox.getYear() - 1900; - t.tm_isdst = false; - time_t res = mktime(&t); - tv.tv_sec = res; - tv.tv_usec = 0; // time.centisecond() * (10 / 1000); - - DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); - if (t.tm_year < 0 || t.tm_year >= 300) - DEBUG_MSG("Ignoring invalid GPS time\n"); - else - perhapsSetRTC(&tv); - } - - if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only - { - // we only notify if position has changed - latitude = ublox.getLatitude(); - longitude = ublox.getLongitude(); - altitude = ublox.getAltitude() / 1000; // in mm convert to meters - DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d\n", latitude * 1e-7, longitude * 1e-7, altitude); - - hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0 - if (hasValidLocation) { - wantNewLocation = false; - notifyObservers(NULL); - // ublox.powerOff(); - } - } else // we didn't get a location update, go back to sleep and hope the characters show up - wantNewLocation = true; - - // Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over - // the serial - setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 10 * 1000); -} - -void GPS::startLock() -{ - DEBUG_MSG("Looking for GPS lock\n"); - wantNewLocation = true; - setPeriod(1); -} diff --git a/src/gps/GPS.h b/src/gps/GPS.h index c3c403278..7a1a79a04 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -2,54 +2,50 @@ #include "Observer.h" #include "PeriodicTask.h" -#include "SparkFun_Ublox_Arduino_Library.h" #include "sys/time.h" +/// If we haven't yet set our RTC this boot, set it from a GPS derived time +void perhapsSetRTC(const struct timeval *tv); + +/// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero +uint32_t getTime(); + +/// Return time since 1970 in secs. If we don't have a GPS lock return zero +uint32_t getValidTime(); + +void readFromRTC(); + /** * A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading) * * When new data is available it will notify observers. */ -class GPS : public PeriodicTask, public Observable +class GPS : public Observable { - SFE_UBLOX_GPS ublox; + protected: + bool hasValidLocation = false; // default to false, until we complete our first read + + static HardwareSerial &_serial_gps; public: - uint32_t latitude, longitude; // as an int mult by 1e-7 to get value as double - uint32_t altitude; - bool isConnected; // Do we have a GPS we are talking to + uint32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double + uint32_t altitude = 0; + bool isConnected = false; // Do we have a GPS we are talking to - GPS(); + virtual ~GPS() {} - /// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero - uint32_t getTime(); - - /// Return time since 1970 in secs. If we don't have a GPS lock return zero - uint32_t getValidTime(); - - void setup(); - - virtual void doTask(); - - /// If we haven't yet set our RTC this boot, set it from a GPS derived time - void perhapsSetRTC(const struct timeval *tv); - - /// Returns true if we think the board can enter deep or light sleep now (we might be trying to get a GPS lock) - bool canSleep(); - - /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs - void prepareSleep(); - - /// Restart our lock attempt - try to get and broadcast a GPS reading ASAP - void startLock(); + /** + * Returns true if we succeeded + */ + virtual bool setup() = 0; /// Returns ture if we have acquired GPS lock. bool hasLock() const { return hasValidLocation; } - private: - void readFromRTC(); - - bool hasValidLocation = false; // default to false, until we complete our first read + /** + * Restart our lock attempt - try to get and broadcast a GPS reading ASAP + * called after the CPU wakes from light-sleep state */ + virtual void startLock() {} }; -extern GPS gps; +extern GPS *gps; diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp new file mode 100644 index 000000000..881fd2977 --- /dev/null +++ b/src/gps/UBloxGPS.cpp @@ -0,0 +1,153 @@ +#include "UBloxGPS.h" +#include "sleep.h" +#include + +UBloxGPS::UBloxGPS() : PeriodicTask() +{ + notifySleepObserver.observe(¬ifySleep); +} + +bool UBloxGPS::setup() +{ + PeriodicTask::setup(); + +#ifdef GPS_RX_PIN + _serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); +#else + _serial_gps.begin(GPS_BAUDRATE); +#endif + // _serial_gps.setRxBufferSize(1024); // the default is 256 + // ublox.enableDebugging(Serial); + + // note: the lib's implementation has the wrong docs for what the return val is + // it is not a bool, it returns zero for success + isConnected = ublox.begin(_serial_gps); + + // try a second time, the ublox lib serial parsing is buggy? + if (!isConnected) + isConnected = ublox.begin(_serial_gps); + + if (isConnected) { + DEBUG_MSG("Connected to UBLOX GPS successfully\n"); + + bool factoryReset = false; + bool ok; + if (factoryReset) { + // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have + // GPS_TX connected) + ublox.factoryReset(); + delay(2000); + isConnected = ublox.begin(_serial_gps); + DEBUG_MSG("Factory reset success=%d\n", isConnected); + if (isConnected) { + ublox.assumeAutoPVT(true, true); // Just parse NEMA for now + } + } else { + ok = ublox.setUART1Output(COM_TYPE_UBX, 500); // Use native API + assert(ok); + ok = ublox.setNavigationFrequency(1, 500); // Produce 4x/sec to keep the amount of time we stall in getPVT low + assert(ok); + // ok = ublox.setAutoPVT(false); // Not implemented on NEO-6M + // assert(ok); + // ok = ublox.setDynamicModel(DYN_MODEL_BIKE); // probably PEDESTRIAN but just in case assume bike speeds + // assert(ok); + ok = ublox.powerSaveMode(); // use power save mode + assert(ok); + } + ok = ublox.saveConfiguration(3000); + assert(ok); + + return true; + } else { + // Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just + // assume NEMA at 9600 baud. + DEBUG_MSG("ERROR: No bidirectional GPS found, hoping that it still might work\n"); + + return false; + } +} + +/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs +int UBloxGPS::prepareSleep(void *unused) +{ + if (isConnected) + ublox.powerOff(); + + return 0; +} + +void UBloxGPS::doTask() +{ + uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix + + if (isConnected) { + // Consume all characters that have arrived + + // getPVT automatically calls checkUblox + ublox.checkUblox(); // See if new data is available. Process bytes as they come in. + + // If we don't have a fix (a quick check), don't try waiting for a solution) + // Hmmm my fix type reading returns zeros for fix, which doesn't seem correct, because it is still sptting out positions + // turn off for now + // fixtype = ublox.getFixType(); + DEBUG_MSG("fix type %d\n", fixtype); + } + + // DEBUG_MSG("sec %d\n", ublox.getSecond()); + // DEBUG_MSG("lat %d\n", ublox.getLatitude()); + + // any fix that has time + if (ublox.getT()) { + struct timeval tv; + + /* Convert to unix time +The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 +(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). +*/ + struct tm t; + t.tm_sec = ublox.getSecond(); + t.tm_min = ublox.getMinute(); + t.tm_hour = ublox.getHour(); + t.tm_mday = ublox.getDay(); + t.tm_mon = ublox.getMonth() - 1; + t.tm_year = ublox.getYear() - 1900; + t.tm_isdst = false; + time_t res = mktime(&t); + tv.tv_sec = res; + tv.tv_usec = 0; // time.centisecond() * (10 / 1000); + + DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); + if (t.tm_year < 0 || t.tm_year >= 300) + DEBUG_MSG("Ignoring invalid GPS time\n"); + else + perhapsSetRTC(&tv); + } + + if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only + { + // we only notify if position has changed + latitude = ublox.getLatitude(); + longitude = ublox.getLongitude(); + altitude = ublox.getAltitude() / 1000; // in mm convert to meters + DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d\n", latitude * 1e-7, longitude * 1e-7, altitude); + + hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0 + if (hasValidLocation) { + wantNewLocation = false; + notifyObservers(NULL); + // ublox.powerOff(); + } + } else // we didn't get a location update, go back to sleep and hope the characters show up + wantNewLocation = true; + + // Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over + // the serial + setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 10 * 1000); +} + +void UBloxGPS::startLock() +{ + DEBUG_MSG("Looking for GPS lock\n"); + wantNewLocation = true; + setPeriod(1); +} diff --git a/src/gps/UBloxGPS.h b/src/gps/UBloxGPS.h new file mode 100644 index 000000000..39b125981 --- /dev/null +++ b/src/gps/UBloxGPS.h @@ -0,0 +1,41 @@ +#pragma once + +#include "GPS.h" +#include "Observer.h" +#include "PeriodicTask.h" +#include "SparkFun_Ublox_Arduino_Library.h" + +/** + * A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading) + * + * When new data is available it will notify observers. + */ +class UBloxGPS : public GPS, public PeriodicTask +{ + SFE_UBLOX_GPS ublox; + + bool wantNewLocation = true; + + CallbackObserver notifySleepObserver = CallbackObserver(this, &UBloxGPS::prepareSleep); + + public: + UBloxGPS(); + + /** + * Returns true if we succeeded + */ + virtual bool setup(); + + virtual void doTask(); + + /** + * Restart our lock attempt - try to get and broadcast a GPS reading ASAP + * called after the CPU wakes from light-sleep state */ + virtual void startLock(); + + private: + + /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs + /// always returns 0 to indicate okay to sleep + int prepareSleep(void *unused); +}; diff --git a/src/main.cpp b/src/main.cpp index 7e1b39ab7..b70ddb99f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,13 +21,13 @@ */ -#include "GPS.h" #include "MeshRadio.h" #include "MeshService.h" #include "NodeDB.h" #include "Periodic.h" #include "PowerFSM.h" #include "Router.h" +#include "UBloxGPS.h" #include "configuration.h" #include "error.h" #include "power.h" @@ -188,8 +188,13 @@ void setup() screen.print("Started...\n"); - // Init GPS - gps.setup(); + readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) + + // Init GPS - first try ublox + gps = new UBloxGPS(); + if (!gps->setup()) { + // FIXME - fallback to NEMA + } service.init(); @@ -306,7 +311,7 @@ void loop() 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.debug()->setGPSStatus(gps->hasLock() ? "good" : "bad"); // 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. diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 1b05e0c51..7e9fc4486 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -84,7 +84,7 @@ void MeshService::init() sendOwnerPeriod.setup(); nodeDB.init(); - gpsObserver.observe(&gps); + gpsObserver.observe(gps); packetReceivedObserver.observe(&router.notifyPacketReceived); } @@ -153,7 +153,7 @@ void MeshService::handleIncomingPosition(const MeshPacket *mp) tv.tv_sec = secs; tv.tv_usec = 0; - gps.perhapsSetRTC(&tv); + perhapsSetRTC(&tv); } } else { DEBUG_MSG("Ignoring incoming packet - not a position\n"); @@ -165,7 +165,7 @@ int MeshService::handleFromRadio(const MeshPacket *mp) powerFSM.trigger(EVENT_RECEIVED_PACKET); // Possibly keep the node from sleeping // If it is a position packet, perhaps set our clock (if we don't have a GPS of our own, otherwise wait for that to work) - if (!gps.isConnected) + if (!gps->isConnected) handleIncomingPosition(mp); else { DEBUG_MSG("Ignoring incoming time, because we have a GPS\n"); @@ -234,8 +234,8 @@ void MeshService::handleToRadio(MeshPacket &p) if (p.id == 0) p.id = generatePacketId(); // If the phone didn't supply one, then pick one - p.rx_time = gps.getValidTime(); // Record the time the packet arrived from the phone - // (so we update our nodedb for the local node) + p.rx_time = getValidTime(); // Record the time the packet arrived from the phone + // (so we update our nodedb for the local node) // Send the packet into the mesh @@ -258,7 +258,7 @@ void MeshService::sendToMesh(MeshPacket *p) // nodes shouldn't trust it anyways) Note: for now, we allow a device with a local GPS to include the time, so that gpsless // devices can get time. if (p->has_payload && p->payload.has_position) { - if (!gps.isConnected) { + if (!gps->isConnected) { DEBUG_MSG("Stripping time %u from position send\n", p->payload.position.time); p->payload.position.time = 0; } else @@ -286,7 +286,7 @@ MeshPacket *MeshService::allocForSending() p->from = nodeDB.getNodeNum(); p->to = NODENUM_BROADCAST; p->id = generatePacketId(); - p->rx_time = gps.getValidTime(); // Just in case we process the packet locally - make sure it has a valid timestamp + p->rx_time = getValidTime(); // Just in case we process the packet locally - make sure it has a valid timestamp return p; } @@ -315,7 +315,7 @@ void MeshService::sendOurPosition(NodeNum dest, bool wantReplies) p->payload.has_position = true; p->payload.position = node->position; p->payload.want_response = wantReplies; - p->payload.position.time = gps.getValidTime(); // This nodedb timestamp might be stale, so update it if our clock is valid. + p->payload.position.time = getValidTime(); // This nodedb timestamp might be stale, so update it if our clock is valid. sendToMesh(p); } @@ -329,12 +329,12 @@ int MeshService::onGPSChanged(void *unused) Position &pos = p->payload.position; // !zero or !zero lat/long means valid - if (gps.latitude != 0 || gps.longitude != 0) { - if (gps.altitude != 0) - pos.altitude = gps.altitude; - pos.latitude_i = gps.latitude; - pos.longitude_i = gps.longitude; - pos.time = gps.getValidTime(); + if (gps->latitude != 0 || gps->longitude != 0) { + if (gps->altitude != 0) + pos.altitude = gps->altitude; + pos.latitude_i = gps->latitude; + pos.longitude_i = gps->longitude; + pos.time = getValidTime(); } // We limit our GPS broadcasts to a max rate diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 0559754a3..73b3391d6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -246,7 +246,7 @@ const NodeInfo *NodeDB::readNextInfo() /// Given a node, return how many seconds in the past (vs now) that we last heard from it uint32_t sinceLastSeen(const NodeInfo *n) { - uint32_t now = gps.getTime(); + uint32_t now = getTime(); uint32_t last_seen = n->position.time; int delta = (int)(now - last_seen); diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index b5a34a801..6e5734e59 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -68,7 +68,7 @@ void Router::handleReceived(MeshPacket *p) { // FIXME, this class shouldn't EVER need to know about the GPS, move getValidTime() into a non gps dependent function // Also, we should set the time from the ISR and it should have msec level resolution - p->rx_time = gps.getValidTime(); // store the arrival timestamp for the phone + p->rx_time = getValidTime(); // store the arrival timestamp for the phone DEBUG_MSG("Notifying observers of received packet fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id); notifyPacketReceived.notifyObservers(p); diff --git a/src/sleep.cpp b/src/sleep.cpp index 9693a8fc6..4f5fa2fdc 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -29,6 +29,7 @@ extern AXP20X_Class axp; Observable 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 Observable notifySleep, notifyDeepSleep; // deep sleep support @@ -125,12 +126,6 @@ static bool doPreflightSleep() /// Tell devices we are going to sleep and wait for them to handle things static void waitEnterSleep() { - /* - former hardwired code - now moved into notifySleep callbacks: - // Put radio in sleep mode (will still draw power but only 0.2uA) - service.radio.radioIf.sleep(); - */ - uint32_t now = millis(); while (!doPreflightSleep()) { delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) @@ -144,7 +139,6 @@ static void waitEnterSleep() // Code that still needs to be moved into notifyObservers Serial.flush(); // send all our characters before we stop cpu clock setBluetoothEnable(false); // has to be off before calling light sleep - gps.prepareSleep(); // abandon in-process parsing notifySleep.notifyObservers(NULL); } @@ -157,6 +151,7 @@ void doDeepSleep(uint64_t msecToWake) // not using wifi yet, but once we are this is needed to shutoff the radio hw // esp_wifi_stop(); waitEnterSleep(); + notifySleep.notifyObservers(NULL); // also tell the regular sleep handlers notifyDeepSleep.notifyObservers(NULL); screen.setOn(false); // datasheet says this will draw only 10ua