mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-31 23:21:06 +00:00
Merge branch 'master' into apollo
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "PortduinoGlue.h"
|
||||
#include "meshUtils.h"
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#endif
|
||||
|
||||
@@ -412,30 +413,42 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the GPS based on the model detected.
|
||||
* We detect the GPS by cycling through a set of baud rates, first common then rare.
|
||||
* For each baud rate, we run GPS::Probe to send commands and match the responses
|
||||
* to known GPS responses.
|
||||
* @retval Whether setup reached the end of its potential to configure the GPS.
|
||||
*/
|
||||
bool GPS::setup()
|
||||
{
|
||||
|
||||
if (!didSerialInit) {
|
||||
int msglen = 0;
|
||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
|
||||
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
|
||||
if (speedSelect == 0 && GPS_BAUDRATE != serialSpeeds[speedSelect]) {
|
||||
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
|
||||
if (probeTries < 2) {
|
||||
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
||||
speedSelect = 0;
|
||||
++probeTries;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
||||
speedSelect = 0;
|
||||
if (--probeTries == 0) {
|
||||
LOG_WARN("Giving up on GPS probe and setting to 9600.");
|
||||
// Rare Serial Speeds
|
||||
if (probeTries == 2) {
|
||||
LOG_DEBUG("Probing for GPS at %d", rareSerialSpeeds[speedSelect]);
|
||||
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(rareSerialSpeeds) / sizeof(int)) {
|
||||
LOG_WARN("Giving up on GPS probe and setting to %d", GPS_BAUDRATE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
} else {
|
||||
gnssModel = GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
@@ -475,6 +488,18 @@ bool GPS::setup()
|
||||
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
|
||||
_serial_gps->write("$PMTK886,1*29\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
|
||||
// PA1616S is used in some GPS breakout boards from Adafruit
|
||||
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
|
||||
_serial_gps->write("$PMTK353,1,0,0,0,0*2A\r\n");
|
||||
// Above command will reset the GPS and takes longer before it will accept new commands
|
||||
delay(1000);
|
||||
// Only ask for RMC and GGA (GNRMC and GNGGA)
|
||||
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
|
||||
delay(250);
|
||||
// Enable SBAS / WAAS
|
||||
_serial_gps->write("$PMTK301,2*2E\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
|
||||
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
|
||||
@@ -662,7 +687,8 @@ bool GPS::setup()
|
||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300);
|
||||
delay(750); // will cause a receiver restart so wait a bit
|
||||
|
||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
|
||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic
|
||||
// sleep.
|
||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
|
||||
delay(750);
|
||||
// Next enable wanted NMEA messages in RAM layer
|
||||
@@ -924,10 +950,10 @@ void GPS::down()
|
||||
#endif
|
||||
|
||||
if (softsleepSupported) {
|
||||
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP?
|
||||
// Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050
|
||||
// https://www.desmos.com/calculator/6gvjghoumr
|
||||
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold
|
||||
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
|
||||
// GPS_SOFTSLEEP? Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M
|
||||
// and M10050 https://www.desmos.com/calculator/6gvjghoumr This is not particularly accurate, but probably an
|
||||
// improvement over a single, fixed threshold
|
||||
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
|
||||
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
|
||||
|
||||
@@ -1143,6 +1169,7 @@ GnssModel_t GPS::probe(int serialSpeed)
|
||||
delay(20);
|
||||
|
||||
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
||||
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||
@@ -1279,10 +1306,12 @@ GPS *GPS::createGps()
|
||||
|
||||
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
|
||||
new GpioNotTransformer(
|
||||
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
virtPin,
|
||||
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
} else {
|
||||
new GpioUnaryTransformer(
|
||||
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
virtPin,
|
||||
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1390,8 +1419,8 @@ bool GPS::factoryReset()
|
||||
_serial_gps->write("$PMTK104*37\r\n");
|
||||
// No PMTK_ACK for this command.
|
||||
delay(100);
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
|
||||
// Factory Reset
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
|
||||
// UBLOX. Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset, sizeof(_message_reset));
|
||||
@@ -1430,8 +1459,8 @@ bool GPS::lookForTime()
|
||||
auto d = reader.date;
|
||||
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
|
||||
/* 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).
|
||||
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 = ti.second() + round(ti.age() / 1000);
|
||||
@@ -1664,7 +1693,9 @@ bool GPS::whileActive()
|
||||
}
|
||||
}
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
if (debugmsg != "") {
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
}
|
||||
#endif
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef enum {
|
||||
GNSS_MODEL_UC6580,
|
||||
GNSS_MODEL_UNKNOWN,
|
||||
GNSS_MODEL_MTK_L76B,
|
||||
GNSS_MODEL_MTK_PA1616S,
|
||||
GNSS_MODEL_AG3335,
|
||||
GNSS_MODEL_AG3352
|
||||
} GnssModel_t;
|
||||
@@ -75,13 +76,21 @@ class GPS : private concurrency::OSThread
|
||||
uint8_t fixType = 0; // fix type from GPGSA
|
||||
#endif
|
||||
private:
|
||||
const int serialSpeeds[6] = {9600, 115200, 38400, 4800, 57600, 9600};
|
||||
#if GPS_BAUDRATE_FIXED
|
||||
// if GPS_BAUDRATE is specified in variant, only try that.
|
||||
const int serialSpeeds[1] = {GPS_BAUDRATE};
|
||||
const int rareSerialSpeeds[1] = {GPS_BAUDRATE};
|
||||
#else
|
||||
const int serialSpeeds[3] = {9600, 115200, 38400};
|
||||
const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
|
||||
#endif
|
||||
|
||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
|
||||
uint32_t rx_gpio = 0;
|
||||
uint32_t tx_gpio = 0;
|
||||
|
||||
int speedSelect = 0;
|
||||
int probeTries = 2;
|
||||
int probeTries = 0;
|
||||
|
||||
/**
|
||||
* hasValidLocation - indicates that the position variables contain a complete
|
||||
|
||||
@@ -70,9 +70,9 @@ bool GPSUpdateScheduling::isUpdateDue()
|
||||
// Have we been searching for a GPS position for too long?
|
||||
bool GPSUpdateScheduling::searchedTooLong()
|
||||
{
|
||||
uint32_t maxSearchMs =
|
||||
Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
|
||||
uint32_t minimumOrConfiguredSecs =
|
||||
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
|
||||
// If broadcast interval set to max, no such thing as "too long"
|
||||
if (maxSearchMs == UINT32_MAX)
|
||||
return false;
|
||||
@@ -115,4 +115,4 @@ void GPSUpdateScheduling::updateLockTimePrediction()
|
||||
uint32_t GPSUpdateScheduling::predictedSearchDurationMs()
|
||||
{
|
||||
return GPSUpdateScheduling::predictedMsToGetLock;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user