diff --git a/Firmware/RTK_mosaic-T_Firmware/Begin.ino b/Firmware/RTK_mosaic-T_Firmware/Begin.ino index 0050683..6e94b60 100644 --- a/Firmware/RTK_mosaic-T_Firmware/Begin.ino +++ b/Firmware/RTK_mosaic-T_Firmware/Begin.ino @@ -515,37 +515,21 @@ void updateTCXO() // updateTCXOClockBias is only called by STATE_GNSS_FINETIME when gnssPVTUpdated was true // So we know that gnssClockBias_ms is valid // Use gnssClockBias_ms as the default -// If we have Fugro from FugroTimeOffset, use that -// If we have Galileo from FugroTimeOffset, use that +// If we have non-composite GPS from FugroTimeOffset, use that - if enabled +// If we have non-composite Galileo from FugroTimeOffset, use that - if enabled void updateTCXOClockBias() { tcxoClockBias_ms = gnssClockBias_ms; // Default to the PVTGeodetic RxClkBias snprintf(rxClkBiasSource, sizeof(rxClkBiasSource), "PVT"); - int ts = getFugroTimeSystemFromName("Fugro"); - if (fugroClkBiases[ts].updated) // If we have the Fugro bias, use that + if (settings.preferNonCompositeGPSBias || settings.preferNonCompositeGalileoBias) // These are mutex { - tcxoClockBias_ms = fugroClkBiases[ts].RxClkBias_ms; - fugroClkBiases[ts].updated = false; - snprintf(rxClkBiasSource, sizeof(rxClkBiasSource), "Fugro"); - } - - ts = getFugroTimeSystemFromName("Galileo"); - if (fugroClkBiases[ts].updated) // If we have the Galileo bias, use that - { - tcxoClockBias_ms = fugroClkBiases[ts].RxClkBias_ms; - fugroClkBiases[ts].updated = false; - snprintf(rxClkBiasSource, sizeof(rxClkBiasSource), "Galileo"); + uint8_t index = mosaicTimeSystemIndexFromName(settings.preferNonCompositeGPSBias ? "GPS" : "Galileo"); + if (fugroTimeSystems[index].updated) // If we have the preferred non-composite bias, use that + { + tcxoClockBias_ms = fugroTimeSystems[index].RxClkBias_ms; + fugroTimeSystems[index].updated = false; + snprintf(rxClkBiasSource, sizeof(rxClkBiasSource), fugroTimeSystems[index].name); + } } } - -int getFugroTimeSystemFromName(const char *name) -{ - for (int i = 0; i < NUM_FUGRO_CLK_BIASES; i++) - { - if (strcmp(name, fugroClkBiases[i].name) == 0) - return i; - } - - return 0; // Should never happen! -} \ No newline at end of file diff --git a/Firmware/RTK_mosaic-T_Firmware/Display.ino b/Firmware/RTK_mosaic-T_Firmware/Display.ino index 72f158e..4825668 100644 --- a/Firmware/RTK_mosaic-T_Firmware/Display.ino +++ b/Firmware/RTK_mosaic-T_Firmware/Display.ino @@ -219,7 +219,7 @@ void displayGNSSFail(uint16_t displayTime) void displayBadBias(uint16_t displayTime) { - displayMessage("Bad RxClkBias Restarting", displayTime); + displayMessage("Bad RxClkBias Restarting...", displayTime); } void displayNoRingBuffer(uint16_t displayTime) @@ -362,9 +362,7 @@ void displayMessage(const char *message, uint16_t displayTime) token = strtok(nullptr, " "); } - uint8_t yPos = (oled->getHeight() / 2) - (fontHeight / 2); - if (wordCount == 2) - yPos -= (fontHeight / 2); + uint8_t yPos = (oled->getHeight() / 2) - ((fontHeight / 2) * wordCount); oled->erase(); diff --git a/Firmware/RTK_mosaic-T_Firmware/NVM.ino b/Firmware/RTK_mosaic-T_Firmware/NVM.ino index 98847bd..8cbb6de 100644 --- a/Firmware/RTK_mosaic-T_Firmware/NVM.ino +++ b/Firmware/RTK_mosaic-T_Firmware/NVM.ino @@ -96,6 +96,8 @@ void recordSystemSettingsToFile(File *settingsFile) settingsFile->printf("%s=%d\r\n", "rxClkBiasLimitCount", settings.rxClkBiasLimitCount); settingsFile->printf("%s=%0.3e\r\n", "Pk", settings.Pk); settingsFile->printf("%s=%0.3e\r\n", "Ik", settings.Ik); + settingsFile->printf("%s=%d\r\n", "preferNonCompositeGPSBias", settings.preferNonCompositeGPSBias); + settingsFile->printf("%s=%d\r\n", "preferNonCompositeGalileoBias", settings.preferNonCompositeGalileoBias); //settingsFile->printf("%s=%d\r\n", "", settings.); @@ -360,6 +362,10 @@ bool parseLine(char *str, Settings *settings) settings->Pk = d; else if (strcmp(settingName, "Ik") == 0) settings->Ik = d; + else if (strcmp(settingName, "preferNonCompositeGPSBias") == 0) + settings->preferNonCompositeGPSBias = d; + else if (strcmp(settingName, "preferNonCompositeGalileoBias") == 0) + settings->preferNonCompositeGalileoBias = d; //else if (strcmp(settingName, "") == 0) // settings-> = d; diff --git a/Firmware/RTK_mosaic-T_Firmware/RTK_mosaic-T_Firmware.ino b/Firmware/RTK_mosaic-T_Firmware/RTK_mosaic-T_Firmware.ino index 5006fe4..ce3a791 100644 --- a/Firmware/RTK_mosaic-T_Firmware/RTK_mosaic-T_Firmware.ino +++ b/Firmware/RTK_mosaic-T_Firmware/RTK_mosaic-T_Firmware.ino @@ -119,26 +119,6 @@ double gnssClockBias_ms = 0.0; // IPStatus 4058 IPAddress gnssIP = IPAddress((uint32_t)0); -// FugroTimeOffset 4255 -typedef struct { - const uint8_t TimeSystem; - const char name[8]; - double RxClkBias_ms; - bool updated; -} fugroClkBias; -fugroClkBias fugroClkBiases[] = { - { 0, "GPS", 0.0, false }, - { 1, "Galileo", 0.0, false }, - { 3, "GLONASS", 0.0, false }, - { 4, "BeiDou", 0.0, false }, - { 5, "QZSS", 0.0, false }, - { 100, "Fugro", 0.0, false }, -}; -#define NUM_FUGRO_CLK_BIASES (sizeof(fugroClkBiases) / sizeof(fugroClkBias)) - -double tcxoClockBias_ms; // Updated by updateTCXOClockBias -char rxClkBiasSource[8]; // PVT or Fugro or Galileo - //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // GPS parse table diff --git a/Firmware/RTK_mosaic-T_Firmware/Tasks.ino b/Firmware/RTK_mosaic-T_Firmware/Tasks.ino index a0ce7ff..b13645a 100644 --- a/Firmware/RTK_mosaic-T_Firmware/Tasks.ino +++ b/Firmware/RTK_mosaic-T_Firmware/Tasks.ino @@ -668,6 +668,7 @@ void processConsumerMessage(PARSE_STATE *parse, uint8_t type) for (int b = 0; b < N; b++) // For each block { + uint8_t SysUsage = parse->buffer[20 + (b * SBLength) + 0]; uint8_t TimeSystem = parse->buffer[20 + (b * SBLength) + 2]; union { @@ -679,12 +680,13 @@ void processConsumerMessage(PARSE_STATE *parse, uint8_t type) for (int i = 0; i < 8; i++) dblUnsigned64.unsigned64 |= ((uint64_t)parse->buffer[20 + (b * SBLength) + 4 + i]) << (i * 8); + // If this block contains a non-composite clock indicator, store it for (int TS = 0; TS < NUM_FUGRO_CLK_BIASES; TS++) { - if (fugroClkBiases[TS].TimeSystem == TimeSystem) + if (fugroTimeSystems[TS].SysUsage == SysUsage) { - fugroClkBiases[TS].RxClkBias_ms = dblUnsigned64.dbl; - fugroClkBiases[TS].updated = true; + fugroTimeSystems[TS].RxClkBias_ms = dblUnsigned64.dbl; + fugroTimeSystems[TS].updated = true; break; } } diff --git a/Firmware/RTK_mosaic-T_Firmware/menuSystem.ino b/Firmware/RTK_mosaic-T_Firmware/menuSystem.ino index 1957bc7..3534aa6 100644 --- a/Firmware/RTK_mosaic-T_Firmware/menuSystem.ino +++ b/Firmware/RTK_mosaic-T_Firmware/menuSystem.ino @@ -373,22 +373,28 @@ void menuOperation() systemPrint("5) Ik (PI I term): "); systemPrintf("%.3e\r\n", settings.Ik); - systemPrint("6) Pulse-Per-Second Interval: "); + systemPrint("6) Prefer non-composite GPS bias - if available: "); + systemPrintf("%s\r\n", settings.preferNonCompositeGPSBias ? "Enabled" : "Disabled"); + + systemPrint("7) Prefer non-composite Galileo bias - if available: "); + systemPrintf("%s\r\n", settings.preferNonCompositeGalileoBias ? "Enabled" : "Disabled"); + + systemPrint("8) Pulse-Per-Second Interval: "); systemPrintln(mosaicPPSParametersInterval[settings.ppsInterval]); - systemPrint("7) Pulse-Per-Second Polarity: "); + systemPrint("9) Pulse-Per-Second Polarity: "); systemPrintln(mosaicPPSParametersPolarity[settings.ppsPolarity]); - systemPrint("8) Pulse-Per-Second Delay (ns): "); + systemPrint("10) Pulse-Per-Second Delay (ns): "); systemPrintln(settings.ppsDelay_ns); - systemPrint("9) Pulse-Per-Second Time Scale: "); + systemPrint("11) Pulse-Per-Second Time Scale: "); systemPrintln(mosaicPPSParametersTimeScale[settings.ppsTimeScale]); - systemPrint("10) Pulse-Per-Second Max Sync Age (s): "); + systemPrint("12) Pulse-Per-Second Max Sync Age (s): "); systemPrintln(settings.ppsMaxSyncAge_s); - systemPrint("11) Pulse-Per-Second Pulse Width (ms): "); + systemPrint("13) Pulse-Per-Second Pulse Width (ms): "); systemPrintln(settings.ppsPulseWidth_ms); systemPrintln("\r\nx) Exit"); @@ -441,7 +447,6 @@ void menuOperation() else { settings.Pk = p; // Recorded to NVM at main menu exit - ppsStarted = false; // Restart PPS afterwards } } else if (incoming == 5) @@ -453,24 +458,35 @@ void menuOperation() else { settings.Ik = i; // Recorded to NVM at main menu exit - ppsStarted = false; // Restart PPS afterwards } } else if (incoming == 6) + { + settings.preferNonCompositeGPSBias ^= 1; + if (settings.preferNonCompositeGPSBias) + settings.preferNonCompositeGalileoBias = false; + } + else if (incoming == 7) + { + settings.preferNonCompositeGalileoBias ^= 1; + if (settings.preferNonCompositeGalileoBias) + settings.preferNonCompositeGPSBias = false; + } + else if (incoming == 8) { settings.ppsInterval++; if ((settings.ppsInterval >= mosaicPPSParametersIntervalEntries) || (settings.ppsInterval < 0)) settings.ppsInterval = 0; ppsStarted = false; // Restart PPS afterwards } - else if (incoming == 7) + else if (incoming == 9) { settings.ppsPolarity++; if ((settings.ppsPolarity >= mosaicPPSParametersPolarityEntries) || (settings.ppsPolarity < 0)) settings.ppsPolarity = 0; ppsStarted = false; // Restart PPS afterwards } - else if (incoming == 8) + else if (incoming == 10) { systemPrint("Enter Pulse-Per-Second Delay in nanoseconds: "); double dly = getDouble(); @@ -482,14 +498,14 @@ void menuOperation() ppsStarted = false; // Restart PPS afterwards } } - else if (incoming == 9) + else if (incoming == 11) { settings.ppsTimeScale++; if ((settings.ppsTimeScale >= mosaicPPSParametersTimeScaleEntries) || (settings.ppsTimeScale < 0)) settings.ppsPolarity = 0; ppsStarted = false; // Restart PPS afterwards } - else if (incoming == 10) + else if (incoming == 12) { systemPrint("Enter Max Sync Age in seconds (0 to 3600): "); int syncAge = getNumber(); // Returns EXIT, TIMEOUT, or long @@ -505,7 +521,7 @@ void menuOperation() } } } - else if (incoming == 11) + else if (incoming == 13) { systemPrint("Enter Pulse Width in milliseconds: "); double width = getDouble(); diff --git a/Firmware/RTK_mosaic-T_Firmware/settings.h b/Firmware/RTK_mosaic-T_Firmware/settings.h index 5121e3d..8e9f75e 100644 --- a/Firmware/RTK_mosaic-T_Firmware/settings.h +++ b/Firmware/RTK_mosaic-T_Firmware/settings.h @@ -69,42 +69,55 @@ typedef enum MOSAIC_TIME_SYSTEM_FUGRO = 100, } mosaicTimeSystemIds; -const uint8_t mosaicTimeSystemIndexTable[] = { - MOSAIC_TIME_SYSTEM_GPS, - MOSAIC_TIME_SYSTEM_GALILEO, - MOSAIC_TIME_SYSTEM_GLONASS, - MOSAIC_TIME_SYSTEM_BEIDOU, - MOSAIC_TIME_SYSTEM_QZSS, - MOSAIC_TIME_SYSTEM_FUGRO, +// FugroTimeOffset 4255 +typedef struct { + const uint8_t TimeSystem; + const uint8_t SysUsage; + const char name[8]; + double RxClkBias_ms; + bool updated; +} fugroTimeSystem; + +fugroTimeSystem fugroTimeSystems[] = { + { MOSAIC_TIME_SYSTEM_GPS, 0x01, "GPS", 0.0, false }, + { MOSAIC_TIME_SYSTEM_GALILEO, 0x02, "Galileo", 0.0, false }, + { MOSAIC_TIME_SYSTEM_GLONASS, 0x04, "GLONASS", 0.0, false }, + { MOSAIC_TIME_SYSTEM_BEIDOU, 0x08, "BeiDou", 0.0, false }, + { MOSAIC_TIME_SYSTEM_QZSS, 0, "QZSS", 0.0, false }, + { MOSAIC_TIME_SYSTEM_FUGRO, 0, "Fugro", 0.0, false }, }; -const int mosaicTimeSystemIndexTableEntries = sizeof(mosaicTimeSystemIndexTable) / sizeof(mosaicTimeSystemIndexTable[0]); + +#define NUM_FUGRO_CLK_BIASES (sizeof(fugroTimeSystems) / sizeof(fugroTimeSystem)) uint8_t mosaicTimeSystemIndexFromId(uint8_t id) { int i = 0; - for (; i < mosaicTimeSystemIndexTableEntries; i++) { - if (mosaicTimeSystemIndexTable[i] == id) + for (; i < NUM_FUGRO_CLK_BIASES; i++) { + if (fugroTimeSystems[i].TimeSystem == id) break; } return (uint8_t)i; } -const char *const mosaicTimeSystemTable[] = { - "GPS", - "Galileo", - "GLONASS", - "BeiDou", - "QZSS", - "Fugro", -}; -const int mosaicTimeSystemTableEntries = sizeof(mosaicTimeSystemTable) / sizeof(mosaicTimeSystemTable[0]); - const char * mosaicTimeSystemNameFromId(uint8_t id) { uint8_t index = mosaicTimeSystemIndexFromId(id); static const char unknown[] = "Unknown"; - if (index >= mosaicTimeSystemIndexTableEntries) + if (index >= NUM_FUGRO_CLK_BIASES) return unknown; - return mosaicTimeSystemTable[index]; + return fugroTimeSystems[index].name; +} + +uint8_t mosaicTimeSystemIndexFromName(const char *name) +{ + for (uint8_t i = 0; i < NUM_FUGRO_CLK_BIASES; i++) + { + if (strcmp(name, fugroTimeSystems[i].name) == 0) + return i; + } + + return 0; // Should never happen! } +double tcxoClockBias_ms; // Updated by updateTCXOClockBias +char rxClkBiasSource[8]; const char *const mosaicPVTErrorTable[] = { "None", @@ -251,6 +264,8 @@ typedef struct int rxClkBiasLimitCount = 3; // Consider the clock locked when the bias is <= rxClkBiasLockLimit_ms for this many successive readings. Default: 3 double Pk = 0.25; // PI P term double Ik = 0.01; // PI I term + bool preferNonCompositeGPSBias = false; // Prefer non-composite GPS bias - if available. Mutex with preferNonCompositeGalileoBias + bool preferNonCompositeGalileoBias = false; // Prefer non-composite Galileo bias - if available. Mutex with preferNonCompositeGPSBias // Add new settings above <------------------------------------------------------------> diff --git a/Firmware/RTK_mosaic-T_Firmware/support.ino b/Firmware/RTK_mosaic-T_Firmware/support.ino index c1039d2..c228201 100644 --- a/Firmware/RTK_mosaic-T_Firmware/support.ino +++ b/Firmware/RTK_mosaic-T_Firmware/support.ino @@ -691,8 +691,6 @@ void verifyTables() reportFatalError("Fix platformFilePrefixTable to match ProductVariant"); if (platformPrefixTableEntries != (RTK_UNKNOWN + 1)) reportFatalError("Fix platformPrefixTable to match ProductVariant"); - if (mosaicTimeSystemIndexTableEntries != mosaicTimeSystemTableEntries) - reportFatalError("Fix mosaicTimeSystemIndexTable to match mosaicTimeSystemTable"); tasksValidateTables(); }