diff --git a/platformio.ini b/platformio.ini
index 40ba8830e..eb39e70ab 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -83,9 +83,8 @@ lib_deps =
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git
- https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
- https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
+ https://github.com/meshtastic/TinyGPSPlus.git
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it
SPI
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index bcd371eb8..a15e385a8 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -63,7 +63,7 @@ class GPSStatus : public Status
int32_t getLatitude() const {
if (radioConfig.preferences.fixed_position){
-#if GPS_EXTRAVERBOSE
+#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed latitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
@@ -75,7 +75,7 @@ class GPSStatus : public Status
int32_t getLongitude() const {
if (radioConfig.preferences.fixed_position){
-#if GPS_EXTRAVERBOSE
+#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed longitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
@@ -87,7 +87,7 @@ class GPSStatus : public Status
int32_t getAltitude() const {
if (radioConfig.preferences.fixed_position){
-#if GPS_EXTRAVERBOSE
+#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed altitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
@@ -105,7 +105,7 @@ class GPSStatus : public Status
bool matches(const GPSStatus *newStatus) const
{
-#if GPS_EXTRAVERBOSE
+#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
newStatus->p.pos_timestamp, p.pos_timestamp);
#endif
diff --git a/src/configuration.h b/src/configuration.h
index 252da74dc..cb60609ec 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -100,6 +100,10 @@ along with this program. If not, see .
#define GPS_TX_PIN 12
#endif
+#ifndef TTGO_T_ECHO
+#define GPS_UBLOX
+#endif
+
// -----------------------------------------------------------------------------
// LoRa SPI
// -----------------------------------------------------------------------------
@@ -149,6 +153,10 @@ along with this program. If not, see .
#define GPS_BAUDRATE 9600
+#ifndef GPS_THREAD_INTERVAL
+#define GPS_THREAD_INTERVAL 100
+#endif
+
#if defined(TBEAM_V10)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TBEAM
diff --git a/src/gps/Air530GPS.cpp b/src/gps/Air530GPS.cpp
deleted file mode 100644
index 46070eb30..000000000
--- a/src/gps/Air530GPS.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "configuration.h"
-#include "Air530GPS.h"
-#include
-
-/*
-Helpful translations from the Air530 GPS datasheet
-
-Sat acquision mode
-捕获电流值@3.3v 42.6 mA
-
-sat tracking mode
-跟踪电流值@3.3v 36.7 mA
-
-Low power mode
-低功耗模式@3.3V 0.85 mA
-(发送指令:$PGKC051,0)
-
-Super low power mode
-超低功耗模式@3.3V 31 uA
-(发送指令:$PGKC105,4)
-
-To exit sleep use WAKE pin
-
-Commands to enter sleep
-6、Command: 105
-进入周期性低功耗模式
-Arguments:
-
-Arg1: “0”,正常运行模式 (normal mode)
-“1”,周期超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (periodic low power tracking mode - keeps sat positions, use wake to wake up)
-“2”,周期低功耗模式 (periodic low power mode)
-“4”,直接进入超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (super low power consumption mode immediately, need WAKE to resume)
-“8”,自动低功耗模式,可以通过串口唤醒 (automatic low power mode, wake by sending characters to serial port)
-“9”, 自动超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (automatic low power tracking when possible, need wake pin to resume)
-
-(Arg 2 & 3 only valid if Arg1 is "1" or "2")
-Arg2:运行时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
-ON time in msecs
-
-Arg3:睡眠时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
-Sleep time in msecs
-
-Example:
-$PGKC105,8*3F
-This will set automatic low power mode with waking when we send chars to the serial port. Possibly do this as soon as we get a
-new location. When we wake again in a minute we send a character to wake up.
-
-*/
-
-
-void Air530GPS::sendCommand(const char *cmd) {
- uint8_t sum = 0;
-
- // Skip the $
- assert(cmd[0] == '$');
- const char *p = cmd + 1;
- while(*p)
- sum ^= *p++;
-
- assert(_serial_gps);
-
- _serial_gps->write(cmd);
- _serial_gps->printf("*%02x\r\n", sum);
-
- // DEBUG_MSG("xsum %02x\n", sum);
-}
-
-void Air530GPS::sleep() {
- NMEAGPS::sleep();
-#ifdef PIN_GPS_WAKE
- sendCommand("$PGKC105,4");
-#endif
-}
-
-/// wake the GPS into normal operation mode
-void Air530GPS::wake()
-{
-#if 1
- NMEAGPS::wake();
-#else
- // For power testing - keep GPS sleeping forever
- sleep();
-#endif
-}
\ No newline at end of file
diff --git a/src/gps/Air530GPS.h b/src/gps/Air530GPS.h
deleted file mode 100644
index 535b08029..000000000
--- a/src/gps/Air530GPS.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include "NMEAGPS.h"
-
-/**
- * A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
- *
- * When new data is available it will notify observers.
- */
-class Air530GPS : public NMEAGPS
-{
- protected:
- /// If possible force the GPS into sleep/low power mode
- virtual void sleep() override;
-
- /// wake the GPS into normal operation mode
- virtual void wake() override;
-
- private:
- /// Send a NMEA cmd with checksum
- void sendCommand(const char *str);
-};
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index c1e480347..a02142697 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -16,12 +16,6 @@ HardwareSerial *GPS::_serial_gps = &Serial1;
HardwareSerial *GPS::_serial_gps = NULL;
#endif
-#ifdef GPS_I2C_ADDRESS
-uint8_t GPS::i2cAddress = GPS_I2C_ADDRESS;
-#else
-uint8_t GPS::i2cAddress = 0;
-#endif
-
GPS *gps;
/// Multiple GPS instances might use the same serial port (in sequence), but we can
@@ -41,6 +35,75 @@ bool GPS::setupGPS()
#endif
#ifndef NO_ESP32
_serial_gps->setRxBufferSize(2048); // the default is 256
+#endif
+#ifdef TTGO_T_ECHO
+ // Switch to 4800 baud, then close and reopen port
+ _serial_gps->write("$PCAS01,0*1C\r\n");
+ delay(250);
+ _serial_gps->end();
+ delay(250);
+ _serial_gps->begin(4800);
+ delay(250);
+ // Initialize the L76K Chip, use GPS + GLONASS
+ _serial_gps->write("$PCAS04,5*1C\r\n");
+ delay(250);
+ // only ask for RMC and GGA
+ _serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
+ delay(250);
+ // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
+ _serial_gps->write("$PCAS11,3*1E\r\n");
+ delay(250);
+
+#endif
+#ifdef GPS_UBLOX
+ // Set the UART port to output NMEA only
+ byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x91, 0xAF};
+ _serial_gps->write(_message_nmea,sizeof(_message_nmea));
+ delay(250);
+
+ // disable GGL
+ byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x05,0x3A};
+ _serial_gps->write(_message_GGL,sizeof(_message_GGL));
+ delay(250);
+
+ // disable GSA
+ byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x06,0x41};
+ _serial_gps->write(_message_GSA,sizeof(_message_GSA));
+ delay(250);
+
+ // disable GSV
+ byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x07,0x48};
+ _serial_gps->write(_message_GSV,sizeof(_message_GSV));
+ delay(250);
+
+ // disable VTG
+ byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x09,0x56};
+ _serial_gps->write(_message_VTG,sizeof(_message_VTG));
+ delay(250);
+
+ // enable RMC
+ byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x09,0x54};
+ _serial_gps->write(_message_RMC,sizeof(_message_RMC));
+ delay(250);
+
+ // enable GGA
+ byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
+ 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x38};
+ _serial_gps->write(_message_GGA,sizeof(_message_GGA));
+ delay(250);
#endif
}
@@ -51,7 +114,7 @@ bool GPS::setup()
{
// Master power for the GPS
#ifdef PIN_GPS_EN
- digitalWrite(PIN_GPS_EN, PIN_GPS_EN);
+ digitalWrite(PIN_GPS_EN, 1);
pinMode(PIN_GPS_EN, OUTPUT);
#endif
@@ -257,7 +320,6 @@ int32_t GPS::runOnce()
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
// Once we get a location we no longer desperately want an update
- // or if we got a time and we are in GpsOpTimeOnly mode
// DEBUG_MSG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
if ((gotLoc && gotTime) || tooLong || (gotTime && getGpsOp() == GpsOperation_GpsOpTimeOnly)) {
@@ -280,7 +342,7 @@ int32_t GPS::runOnce()
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
- return isAwake ? 100 : 5000;
+ return isAwake ? GPS_THREAD_INTERVAL : 5000;
}
void GPS::forceWake(bool on)
@@ -318,13 +380,7 @@ int GPS::prepareDeepSleep(void *unused)
return 0;
}
-#ifdef GPS_TX_PIN
-#include "UBloxGPS.h"
-#endif
-
-#ifdef HAS_AIR530_GPS
-#include "Air530GPS.h"
-#elif !defined(NO_GPS)
+#ifndef NO_GPS
#include "NMEAGPS.h"
#endif
@@ -339,29 +395,11 @@ GPS *createGps()
#else
DEBUG_MSG("Using MSL altitude model\n");
#endif
-// If we don't have bidirectional comms, we can't even try talking to UBLOX
-#ifdef GPS_TX_PIN
- // Init GPS - first try ublox
- UBloxGPS *ublox = new UBloxGPS();
-
- if (!ublox->setup()) {
- DEBUG_MSG("ERROR: No UBLOX GPS found\n");
- delete ublox;
- ublox = NULL;
- } else {
- return ublox;
- }
-#endif
-
if (GPS::_serial_gps) {
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
// assume NMEA at 9600 baud.
DEBUG_MSG("Hoping that NMEA might work\n");
-#ifdef HAS_AIR530_GPS
- GPS *new_gps = new Air530GPS();
-#else
GPS *new_gps = new NMEAGPS();
-#endif
new_gps->setup();
return new_gps;
}
diff --git a/src/gps/GPS.h b/src/gps/GPS.h
index 4764d1fb3..5724889fe 100644
--- a/src/gps/GPS.h
+++ b/src/gps/GPS.h
@@ -40,9 +40,6 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps;
- /** If !0 we will attempt to connect to the GPS over I2C */
- static uint8_t i2cAddress;
-
Position p = Position_init_default;
GPS() : concurrency::OSThread("GPS") {}
diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp
index d0d5e46e2..8a8181f3b 100644
--- a/src/gps/NMEAGPS.cpp
+++ b/src/gps/NMEAGPS.cpp
@@ -5,7 +5,7 @@
#include
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
-#define GPS_SOL_EXPIRY_MS 300 // in millis
+#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
static int32_t toDegInt(RawDegrees d)
@@ -64,11 +64,12 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
- DEBUG_MSG("NMEA GPS time %d\n", t.tm_sec);
-
- perhapsSetRTC(RTCQualityGPS, t);
-
- return true;
+ if (t.tm_mon > -1){
+ DEBUG_MSG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+ perhapsSetRTC(RTCQualityGPS, t);
+ return true;
+ } else
+ return false;
} else
return false;
}
@@ -116,7 +117,7 @@ bool NMEAGPS::lookForLocation()
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
{
- DEBUG_MSG("SOME data is TOO OLD\n");
+ DEBUG_MSG("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
@@ -127,10 +128,17 @@ bool NMEAGPS::lookForLocation()
// We know the solution is fresh and valid, so just read the data
auto loc = reader.location.value();
- // Some GPSes (Air530) seem to send a zero longitude when the current fix is bogus
// Bail out EARLY to avoid overwriting previous good data (like #857)
- if(toDegInt(loc.lat) == 0) {
- DEBUG_MSG("Ignoring bogus NMEA position\n");
+ if (toDegInt(loc.lat) > 900000000) {
+#ifdef GPS_EXTRAVERBOSE
+ DEBUG_MSG("Bail out EARLY on LAT %i\n",toDegInt(loc.lat));
+#endif
+ return false;
+ }
+ if (toDegInt(loc.lng) > 1800000000) {
+#ifdef GPS_EXTRAVERBOSE
+ DEBUG_MSG("Bail out EARLY on LNG %i\n",toDegInt(loc.lng));
+#endif
return false;
}
diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp
deleted file mode 100644
index 70fc91ecd..000000000
--- a/src/gps/UBloxGPS.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-#include "configuration.h"
-#include "UBloxGPS.h"
-#include "RTC.h"
-#include "error.h"
-#include "sleep.h"
-#include
-
-// if gps_update_interval below this value, do not powercycle the GPS
-#define UBLOX_POWEROFF_THRESHOLD 90
-
-#define PDOP_INVALID 9999
-
-// #define UBX_MODE_NMEA
-
-extern RadioConfig radioConfig;
-
-UBloxGPS::UBloxGPS() {}
-
-bool UBloxGPS::tryConnect()
-{
- bool c = false;
-
- if (_serial_gps)
- c = ublox.begin(*_serial_gps);
-
- if (!c && i2cAddress) {
- extern bool neo6M; // Super skanky - if we are talking to the device i2c we assume it is a neo7 on a RAK815, which
- // supports the newer API
- neo6M = true;
-
- c = ublox.begin(Wire, i2cAddress);
- }
-
- if (c)
- setConnected();
-
- return c;
-}
-
-bool UBloxGPS::setupGPS()
-{
- GPS::setupGPS();
-
- // uncomment to see debug info
- // ublox.enableDebugging(Serial);
-
- // try a second time, the ublox lib serial parsing is buggy?
- // see https://github.com/meshtastic/Meshtastic-device/issues/376
- for (int i = 0; (i < 3) && !tryConnect(); i++)
- delay(500);
-
- if (isConnected()) {
-#ifdef UBX_MODE_NMEA
- DEBUG_MSG("Connected to UBLOX GPS, downgrading to NMEA mode\n");
- DEBUG_MSG("- GPS errors below are related and safe to ignore\n");
-#else
- DEBUG_MSG("Connected to UBLOX GPS successfully\n");
-#endif
-
- if (!setUBXMode())
- RECORD_CRITICALERROR(CriticalErrorCode_UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
-
-#ifdef UBX_MODE_NMEA
- return false;
-#else
- return true;
-#endif
-
- } else {
- return false;
- }
-}
-
-bool UBloxGPS::setUBXMode()
-{
-#ifdef UBX_MODE_NMEA
- if (_serial_gps) {
- ublox.setUART1Output(COM_TYPE_NMEA, 1000);
- }
- if (i2cAddress) {
- ublox.setI2COutput(COM_TYPE_NMEA, 1000);
- }
-
- return false; // pretend initialization failed to force NMEA mode
-#endif
-
- if (_serial_gps) {
- if (!ublox.setUART1Output(COM_TYPE_UBX, 1000)) // Use native API
- return false;
- }
- if (i2cAddress) {
- if (!ublox.setI2COutput(COM_TYPE_UBX, 1000))
- return false;
- }
-
- if (!ublox.setNavigationFrequency(1, 1000)) // Produce 4x/sec to keep the amount of time we stall in getPVT low
- return false;
-
- // 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);
-
- // per https://github.com/meshtastic/Meshtastic-device/issues/376 powerSaveMode might not work with the marginal
- // TTGO antennas
- // if (!ublox.powerSaveMode(true, 2000)) // use power save mode, the default timeout (1100ms seems a bit too tight)
- // return false;
-
- if (!ublox.saveConfiguration(3000))
- return false;
-
- return true;
-}
-
-/**
- * Reset our GPS back to factory settings
- *
- * @return true for success
- */
-bool UBloxGPS::factoryReset()
-{
- bool ok = false;
-
- // It is useful to force back into factory defaults (9600baud, NMEA to test the behavior of boards that don't have
- // GPS_TX connected)
- ublox.factoryReset();
- delay(5000);
- tryConnect(); // sets isConnected
-
- // try a second time, the ublox lib serial parsing is buggy?
- for (int i = 0; (i < 3) && !tryConnect(); i++)
- delay(500);
-
- DEBUG_MSG("GPS Factory reset success=%d\n", isConnected());
- if (isConnected())
- ok = setUBXMode();
-
- return ok;
-}
-
-/** Idle processing while GPS is looking for lock */
-void UBloxGPS::whileActive()
-{
- ublox.flushPVT(); // reset ALL freshness flags first
- ublox.getT(maxWait()); // ask for new time data - hopefully ready when we come back
-
- // Ask for a new position fix - hopefully it will have results ready by next time
- // the order here is important, because we only check for has latitude when reading
-
- //ublox.getSIV(maxWait()); // redundant with getPDOP below
- ublox.getPDOP(maxWait()); // will trigger getSOL on NEO6, getP on others
- ublox.getP(maxWait()); // will trigger getPosLLH on NEO6, getP on others
-
- // the fixType flag will be checked and updated in lookForLocation()
-}
-
-/**
- * Perform any processing that should be done only while the GPS is awake and looking for a fix.
- * Override this method to check for new locations
- *
- * @return true if we've acquired a new location
- */
-bool UBloxGPS::lookForTime()
-{
- if (ublox.moduleQueried.gpsSecond) {
- /* 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(0);
- t.tm_min = ublox.getMinute(0);
- t.tm_hour = ublox.getHour(0);
- t.tm_mday = ublox.getDay(0);
- t.tm_mon = ublox.getMonth(0) - 1;
- t.tm_year = ublox.getYear(0) - 1900;
- t.tm_isdst = false;
- perhapsSetRTC(RTCQualityGPS, t);
- return true;
- }
-
- return false;
-}
-
-/**
- * Perform any processing that should be done only while the GPS is awake and looking for a fix.
- * Override this method to check for new locations
- *
- * @return true if we've acquired a new location
- */
-bool UBloxGPS::lookForLocation()
-{
- bool foundLocation = false;
-
- // check if a complete GPS solution set is available for reading
- // (some of these, like lat/lon are redundant and can be removed)
- if ( ! (ublox.moduleQueried.fixType &&
- ublox.moduleQueried.latitude &&
- ublox.moduleQueried.longitude &&
- ublox.moduleQueried.altitude &&
- ublox.moduleQueried.pDOP &&
- ublox.moduleQueried.SIV &&
- ublox.moduleQueried.gpsDay))
- {
- // Not ready? No problem! We'll try again later.
- return false;
- }
-
- fixType = ublox.getFixType();
-#ifdef UBLOX_EXTRAVERBOSE
- DEBUG_MSG("FixType=%d\n", fixType);
-#endif
-
-
- // check if GPS has an acceptable lock
- if (! hasLock()) {
- ublox.flushPVT(); // reset ALL freshness flags
- return false;
- }
-
- // read lat/lon/alt/dop data into temporary variables to avoid
- // overwriting global variables with potentially invalid data
- int32_t tmp_dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it
- int32_t tmp_lat = ublox.getLatitude(0);
- int32_t tmp_lon = ublox.getLongitude(0);
- int32_t tmp_alt_msl = ublox.getAltitudeMSL(0);
- int32_t tmp_alt_hae = ublox.getAltitude(0);
- int32_t max_dop = PDOP_INVALID;
- if (radioConfig.preferences.gps_max_dop)
- max_dop = radioConfig.preferences.gps_max_dop * 100; // scaling
-
- // Note: heading is only currently implmented in the ublox for the 8m chipset - therefore
- // don't read it here - it will generate an ignored getPVT command on the 6ms
- // heading = ublox.getHeading(0);
-
- // read positional timestamp
- struct tm t;
- t.tm_sec = ublox.getSecond(0);
- t.tm_min = ublox.getMinute(0);
- t.tm_hour = ublox.getHour(0);
- t.tm_mday = ublox.getDay(0);
- t.tm_mon = ublox.getMonth(0) - 1;
- t.tm_year = ublox.getYear(0) - 1900;
- t.tm_isdst = false;
-
- time_t tmp_ts = mktime(&t);
-
- // FIXME - can opportunistically attempt to set RTC from GPS timestamp?
-
- // bogus lat lon is reported as 0 or 0 (can be bogus just for one)
- // Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
- // FIXME - NULL ISLAND is a real location on Earth!
- foundLocation = (tmp_lat != 0) && (tmp_lon != 0) &&
- (tmp_lat <= 900000000) && (tmp_lat >= -900000000) &&
- (tmp_dop < max_dop);
-
- // only if entire dataset is valid, update globals from temp vars
- if (foundLocation) {
- p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
- p.longitude_i = tmp_lon;
- p.latitude_i = tmp_lat;
- if (fixType > 2) {
- // if fix is 2d, ignore altitude data
- p.altitude = tmp_alt_msl / 1000;
- p.altitude_hae = tmp_alt_hae / 1000;
- p.alt_geoid_sep = (tmp_alt_hae - tmp_alt_msl) / 1000;
- } else {
-#ifdef GPS_EXTRAVERBOSE
- DEBUG_MSG("no altitude data (fixType=%d)\n", fixType);
-#endif
- // clean up old values in case it's a 3d-2d fix transition
- p.altitude = p.altitude_hae = p.alt_geoid_sep = 0;
- }
- p.pos_timestamp = tmp_ts;
- p.PDOP = tmp_dop;
- p.fix_type = fixType;
- p.sats_in_view = ublox.getSIV(0);
- // In debug logs, identify position by @timestamp:stage (stage 1 = birth)
- DEBUG_MSG("lookForLocation() new pos@%x:1\n", tmp_ts);
- } else {
- // INVALID solution - should never happen
- DEBUG_MSG("Invalid location lat/lon/hae/dop %d/%d/%d/%d - discarded\n",
- tmp_lat, tmp_lon, tmp_alt_hae, tmp_dop);
- }
-
- ublox.flushPVT(); // reset ALL freshness flags at the end
-
- return foundLocation;
-}
-
-bool UBloxGPS::hasLock()
-{
- if (radioConfig.preferences.gps_accept_2d)
- return (fixType >= 2 && fixType <= 4);
- else
- return (fixType >= 3 && fixType <= 4);
-}
-
-bool UBloxGPS::whileIdle()
-{
- // if using i2c or serial look too see if any chars are ready
- return ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
-}
-
-/// If possible force the GPS into sleep/low power mode
-/// Note: ublox doesn't need a wake method, because as soon as we send chars to the GPS it will wake up
-void UBloxGPS::sleep()
-{
- if (radioConfig.preferences.gps_update_interval > UBLOX_POWEROFF_THRESHOLD) {
- // Tell GPS to power down until we send it characters on serial port (we leave vcc connected)
- ublox.powerOff();
- // setGPSPower(false);
- }
-}
-
-void UBloxGPS::wake()
-{
- if (radioConfig.preferences.gps_update_interval > UBLOX_POWEROFF_THRESHOLD) {
- fixType = 0; // assume we have no fix yet
- }
-
- // this is idempotent
- setGPSPower(true);
-
- // Note: no delay needed because now we leave gps power on always and instead use ublox.powerOff()
- // Give time for the GPS to boot
- // delay(200);
-}
\ No newline at end of file
diff --git a/src/gps/UBloxGPS.h b/src/gps/UBloxGPS.h
deleted file mode 100644
index 3d940832f..000000000
--- a/src/gps/UBloxGPS.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include "GPS.h"
-#include "Observer.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
-{
- SFE_UBLOX_GPS ublox;
- uint8_t fixType = 0;
-
- public:
- UBloxGPS();
-
- /**
- * Reset our GPS back to factory settings
- *
- * @return true for success
- */
- bool factoryReset() override;
-
- protected:
- /**
- * Returns true if we succeeded
- */
- virtual bool setupGPS() override;
-
- /** Subclasses should look for serial rx characters here and feed it to their GPS parser
- *
- * Return true if we received a valid message from the GPS
- */
- virtual bool whileIdle() override;
-
- /** Idle processing while GPS is looking for lock */
- virtual void whileActive() override;
-
- /**
- * Perform any processing that should be done only while the GPS is awake and looking for a fix.
- * Override this method to check for new locations
- *
- * @return true if we've acquired a time
- */
- virtual bool lookForTime() override;
-
- /**
- * Perform any processing that should be done only while the GPS is awake and looking for a fix.
- * Override this method to check for new locations
- *
- * @return true if we've acquired a new location
- */
- virtual bool lookForLocation() override;
- virtual bool hasLock() override;
-
- /// If possible force the GPS into sleep/low power mode
- virtual void sleep() override;
- virtual void wake() override;
-
- private:
- /// Attempt to connect to our GPS, returns false if no gps is present
- bool tryConnect();
-
- /// Switch to our desired operating mode and save the settings to flash
- /// returns true for success
- bool setUBXMode();
-
- uint16_t maxWait() const { return i2cAddress ? 300 : 0; /*If using i2c we must poll with wait */ }
-};
diff --git a/src/main.cpp b/src/main.cpp
index d3804ef2c..00a540b51 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -408,6 +408,12 @@ void setup()
initDeepSleep();
+ // Testing this fix für erratic T-Echo boot behaviour
+#if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON)
+ pinMode(PIN_EINK_PWR_ON, OUTPUT);
+ digitalWrite(PIN_EINK_PWR_ON, HIGH);
+#endif
+
#ifdef VEXT_ENABLE
pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
diff --git a/variants/t-echo/variant.h b/variants/t-echo/variant.h
index a1471c67b..97e6de985 100644
--- a/variants/t-echo/variant.h
+++ b/variants/t-echo/variant.h
@@ -226,7 +226,7 @@ External serial flash WP25R1635FZUIL0
#define PIN_SPI1_SCK PIN_EINK_SCLK
/*
- * Air530 GPS pins
+ * GPS pins
*/
#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake
@@ -235,6 +235,8 @@ External serial flash WP25R1635FZUIL0
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
+#define GPS_THREAD_INTERVAL 50
+
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX