Optimise GPS Baud Rate cycle

Previously, our baud rate cycled through one list twice.

There were some rarer baudrates in there, so this code
separates out those into a dedicated list that is only
run through if detection fails for common bauds. We also
only run through each baud rate once.
This commit is contained in:
Tom Fifield 2024-10-20 12:38:59 +11:00
parent 57667f1028
commit 95e47eb926
2 changed files with 39 additions and 22 deletions

View File

@ -420,21 +420,34 @@ bool GPS::setup()
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) { if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate. // if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
if (speedSelect == 0 && GPS_BAUDRATE != serialSpeeds[speedSelect]) { if (probeTries == 0 && GPS_BAUDRATE != 9600) {
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds; speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
if (speedSelect == 0) {
speedSelect = std::find(rareSerialSpeeds, std::end(rareSerialSpeeds), GPS_BAUDRATE) - rareSerialSpeeds;
probeTries = 1;
}
} }
if (probeTries == 0) {
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]); LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
gnssModel = probe(serialSpeeds[speedSelect]); gnssModel = probe(serialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) { if (gnssModel == GNSS_MODEL_UNKNOWN) {
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) { if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
speedSelect = 0; speedSelect = 0;
if (--probeTries == 0) { ++probeTries;
}
}
}
// Rare Serial Speeds
if (probeTries == 1) {
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 9600."); LOG_WARN("Giving up on GPS probe and setting to 9600.");
return true; return true;
} }
return false;
} }
return false;
} }
} else { } else {
gnssModel = GNSS_MODEL_UNKNOWN; gnssModel = GNSS_MODEL_UNKNOWN;
@ -662,7 +675,8 @@ bool GPS::setup()
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300); 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 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); SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
delay(750); delay(750);
// Next enable wanted NMEA messages in RAM layer // Next enable wanted NMEA messages in RAM layer
@ -924,10 +938,10 @@ void GPS::down()
#endif #endif
if (softsleepSupported) { if (softsleepSupported) {
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP? // How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
// Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050 // GPS_SOFTSLEEP? Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M
// https://www.desmos.com/calculator/6gvjghoumr // and M10050 https://www.desmos.com/calculator/6gvjghoumr This is not particularly accurate, but probably an
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold // impromevement over a single, fixed threshold
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22)); uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000); LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
@ -1279,10 +1293,12 @@ GPS *GPS::createGps()
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
new GpioNotTransformer( 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 { } else {
new GpioUnaryTransformer( 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 +1406,8 @@ bool GPS::factoryReset()
_serial_gps->write("$PMTK104*37\r\n"); _serial_gps->write("$PMTK104*37\r\n");
// No PMTK_ACK for this command. // No PMTK_ACK for this command.
delay(100); delay(100);
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX. // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
// Factory Reset // UBLOX. Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset)); _serial_gps->write(_message_reset, sizeof(_message_reset));
@ -1430,8 +1446,8 @@ bool GPS::lookForTime()
auto d = reader.date; auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
/* Convert to unix time /* 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 The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1,
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/ */
struct tm t; struct tm t;
t.tm_sec = ti.second() + round(ti.age() / 1000); t.tm_sec = ti.second() + round(ti.age() / 1000);

View File

@ -75,13 +75,14 @@ class GPS : private concurrency::OSThread
uint8_t fixType = 0; // fix type from GPGSA uint8_t fixType = 0; // fix type from GPGSA
#endif #endif
private: private:
const int serialSpeeds[6] = {9600, 115200, 38400, 4800, 57600, 9600}; const int serialSpeeds[6] = {9600, 115200, 38400};
const int rareSerialSpeeds[6] = {4800, 57600, 9600};
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0; uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
uint32_t rx_gpio = 0; uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0; uint32_t tx_gpio = 0;
int speedSelect = 0; int speedSelect = 0;
int probeTries = 2; int probeTries = 0;
/** /**
* hasValidLocation - indicates that the position variables contain a complete * hasValidLocation - indicates that the position variables contain a complete