Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Firmware/RTK_Surveyor/NVM.ino
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,10 @@ void recordSystemSettingsToFile(File *settingsFile)
settingsFile->printf("%s=%d\r\n", "gnssUartInterruptsCore", settings.gnssUartInterruptsCore);
settingsFile->printf("%s=%d\r\n", "bluetoothInterruptsCore", settings.bluetoothInterruptsCore);
settingsFile->printf("%s=%d\r\n", "i2cInterruptsCore", settings.i2cInterruptsCore);
settingsFile->printf("%s=%d\r\n", "rtcmTimeoutBeforeUsingLBand_s", settings.rtcmTimeoutBeforeUsingLBand_s);

//Add new settings above
//<------------------------------------------------------------>
}

// Given a fileName, parse the file and load the given settings struct
Expand Down Expand Up @@ -1328,6 +1332,11 @@ bool parseLine(char *str, Settings *settings)
settings->enableNetworkFailover = d;
else if (strcmp(settingName, "printNetworkStatus") == 0)
settings->printNetworkStatus = d;
else if (strcmp(settingName, "rtcmTimeoutBeforeUsingLBand_s") == 0)
settings->rtcmTimeoutBeforeUsingLBand_s = d;

//Add new settings above
//<------------------------------------------------------------>

// Check for bulk settings (WiFi credentials, constellations, message rates, ESPNOW Peers)
// Must be last on else list
Expand Down
3 changes: 3 additions & 0 deletions Firmware/RTK_Surveyor/NtripClient.ino
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,9 @@ void ntripClientUpdate()
// Restart the NTRIP receive data timer
ntripClientTimer = millis();

// Record the arrival of RTCM from the WiFi connection. This resets the RTCM timeout used on the L-Band.
rtcmLastPacketReceived = millis();

// Push RTCM to GNSS module over I2C / SPI
theGNSS.pushRawData(rtcmData, rtcmCount);
netIncomingRTCM = true;
Expand Down
8 changes: 8 additions & 0 deletions Firmware/RTK_Surveyor/RTK_Surveyor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,12 @@ class SFE_UBLOX_GNSS_SUPER_DERIVED : public SFE_UBLOX_GNSS_SUPER

SFE_UBLOX_GNSS_SUPER_DERIVED theGNSS;

#ifdef COMPILE_L_BAND
static SFE_UBLOX_GNSS_SUPER i2cLBand; // NEO-D9S

void checkRXMCOR(UBX_RXM_COR_data_t *ubxDataStruct);
#endif

volatile struct timeval
gnssSyncTv; // This holds the time the RTC was sync'd to GNSS time via Time Pulse interrupt - used by NTP
struct timeval previousGnssSyncTv; // This holds the time of the previous RTC sync
Expand Down Expand Up @@ -360,6 +366,8 @@ int64_t ARPECEFZ = 0;
uint16_t ARPECEFH = 0;

const byte haeNumberOfDecimals = 8; // Used for printing and transmitting lat/lon
bool lBandCommunicationEnabled = false;
unsigned long rtcmLastPacketReceived = 0; //Monitors the last time we received RTCM. Proctors PMP vs RTCM prioritization.
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// Battery fuel gauge and PWM LEDs
Expand Down
5 changes: 5 additions & 0 deletions Firmware/RTK_Surveyor/Tasks.ino
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ void btReadTask(void *e)
btEscapeCharsReceived = 0; // Update timeout check for escape char and partial frame

bluetoothIncomingRTCM = true;

// Record the arrival of RTCM from the Bluetooth connection (a phone or tablet is providing the RTCM
// via NTRIP). This resets the RTCM timeout used on the L-Band.
rtcmLastPacketReceived = millis();

} // End just a character in the stream

} // End btPrintEcho == false && bluetoothRxDataAvailable()
Expand Down
109 changes: 109 additions & 0 deletions Firmware/RTK_Surveyor/ZED.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Enable data output from the NEO
bool zedEnableLBandCommunication()
{
bool response = true;

#ifdef COMPILE_L_BAND

response &= theGNSS.setRXMCORcallbackPtr(&checkRXMCOR); // Enable callback to check if the PMP data is being decrypted successfully

if (productVariant == RTK_FACET_LBAND_DIRECT)
{
// Setup for ZED to NEO serial communication
response &= theGNSS.setVal32(UBLOX_CFG_UART2INPROT_UBX, true); // Configure ZED for UBX input on UART2

// Disable PMP callback over I2C. Enable UARTs.
response &= i2cLBand.setRXMPMPmessageCallbackPtr(nullptr); // Disable PMP callback to push raw PMP over I2C

response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 0); // Disable UBX-RXM-PMP on NEO's I2C port

response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on NEO's UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on NEO's UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2_BAUDRATE, settings.radioPortBaud); // Match baudrate with ZED
}
else if (productVariant == RTK_FACET_LBAND)
{
// Older versions of the Facet L-Band had solder jumpers that could be closed to directly connect the NEO
// to the ZED. If the user has explicitly disabled I2C corrections, enable a UART connection.
if (settings.useI2cForLbandCorrections == true)
{
response &= theGNSS.setVal32(UBLOX_CFG_UART2INPROT_UBX, settings.enableUART2UBXIn);

i2cLBand.setRXMPMPmessageCallbackPtr(&pushRXMPMP); // Enable PMP callback to push raw PMP over I2C

response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Enable UBX-RXM-PMP on NEO's I2C port

response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 0); // Disable UBX output on NEO's UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 0); // Disable UBX-RXM-PMP on NEO's UART2
}
else // Setup ZED to NEO serial communication
{
response &= theGNSS.setVal32(UBLOX_CFG_UART2INPROT_UBX, true); // Configure ZED for UBX input on UART2

i2cLBand.setRXMPMPmessageCallbackPtr(nullptr); // Disable PMP callback to push raw PMP over I2C

response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 0); // Disable UBX-RXM-PMP on NEO's I2C port

response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2
response &=
i2cLBand.addCfgValset(UBLOX_CFG_UART2_BAUDRATE, settings.radioPortBaud); // Match baudrate with ZED
}
}
else
{
systemPrintln("zedEnableLBandCorrections: Unknown platform");
return (false);
}

response &= i2cLBand.sendCfgValset();

#endif

return (response);
}

// Disable data output from the NEO
bool zedDisableLBandCommunication()
{
bool response = true;

#ifdef COMPILE_L_BAND
response &= i2cLBand.setRXMPMPmessageCallbackPtr(nullptr); // Disable PMP callback no matter the platform
response &= theGNSS.setRXMCORcallbackPtr(nullptr); // Disable callback to check if the PMP data is being decrypted successfully

if (productVariant == RTK_FACET_LBAND_DIRECT)
{
response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 0); // Disable UBX output from NEO's UART2
}
else if (productVariant == RTK_FACET_LBAND)
{
// Older versions of the Facet L-Band had solder jumpers that could be closed to directly connect the NEO
// to the ZED. Check if the user has explicitly set I2C corrections.
if (settings.useI2cForLbandCorrections == true)
{
response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 0); // Disable UBX-RXM-PMP from NEO's I2C port
}
else // Setup ZED to NEO serial communication
{
response &= i2cLBand.newCfgValset();
response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 0); // Disable UBX output from NEO's UART2
}
}
else
{
systemPrintln("zedEnableLBandCorrections: Unknown platform");
return (false);
}

response &= i2cLBand.sendCfgValset();

#endif

return (response);
}
55 changes: 23 additions & 32 deletions Firmware/RTK_Surveyor/menuPP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

#define MQTT_CERT_SIZE 2000

static SFE_UBLOX_GNSS_SUPER i2cLBand; // NEO-D9S

// The PointPerfect token is provided at compile time via build flags
#ifndef POINTPERFECT_TOKEN
#define POINTPERFECT_TOKEN \
Expand Down Expand Up @@ -1031,38 +1029,9 @@ void beginLBand()
response &=
i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1, 0); // Diasable UBX-RXM-PMP on UART1. Not used.

// Determine if we should use callback to harvest/sent encrypted messages over I2C
// If not, it is assumed the ZED UART2 is directly connected to NEO UART2
if (settings.useI2cForLbandCorrections == true)
{
// Enable PMP over I2C. Disable UARTs
response &= theGNSS.setVal32(UBLOX_CFG_UART2INPROT_UBX, settings.enableUART2UBXIn);

i2cLBand.setRXMPMPmessageCallbackPtr(&pushRXMPMP); // Enable PMP callback

response &=
i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Ensure UBX-RXM-PMP is enabled on I2C port

response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 0); // Disable UBX output on UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 0); // Disable UBX-RXM-PMP on UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2_BAUDRATE, settings.radioPortBaud); // match baudrate with ZED
}
else // Setup for ZED to NEO serial communication
{
response &= theGNSS.setVal32(UBLOX_CFG_UART2INPROT_UBX, true); // Configure ZED for UBX input on UART2

// Disable PMP callback over I2C. Enable UARTs.
i2cLBand.setRXMPMPmessageCallbackPtr(nullptr); // Enable PMP callback
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 0); // Disable UBX-RXM-PMP on I2C port

response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2
response &= i2cLBand.addCfgValset(UBLOX_CFG_UART2_BAUDRATE, settings.radioPortBaud); // match baudrate with ZED
}

response &= i2cLBand.sendCfgValset();

theGNSS.setRXMCORcallbackPtr(&checkRXMCOR); // Callback to check if the PMP data is being decrypted successfully
lBandCommunicationEnabled = zedEnableLBandCommunication();

if (response == false)
systemPrintln("L-Band failed to configure");
Expand Down Expand Up @@ -1277,6 +1246,28 @@ void updateLBand()
lbandTimeToFix = millis();
log_d("Time to first L-Band fix: %ds", lbandTimeToFix / 1000);
}

if ((millis() - rtcmLastPacketReceived) / 1000 > settings.rtcmTimeoutBeforeUsingLBand_s)
{
// If we have not received RTCM in a certain amount of time,
// and if communication was disabled because RTCM was being received at some point,
// re-enableL-Band communcation
if (lBandCommunicationEnabled == false)
{
log_d("Enabling L-Band communication due to RTCM timeout");
lBandCommunicationEnabled = zedEnableLBandCommunication();
}
}
else
{
// If we *have* recently received RTCM then disable corrections from then NEO-D9S L-Band receiver
if (lBandCommunicationEnabled == true)
{
log_d("Disabling L-Band communication due to RTCM reception");
lBandCommunicationEnabled = !zedDisableLBandCommunication(); //zedDisableLBandCommunication() returns true if we successfully disabled
}
}
}

#endif // COMPILE_L_BAND
}
14 changes: 14 additions & 0 deletions Firmware/RTK_Surveyor/menuSystem.ino
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,8 @@ void menuOperation()
systemPrint("11) Use I2C for L-Band Corrections: ");
systemPrintf("%s\r\n", settings.useI2cForLbandCorrections ? "Enabled" : "Disabled");

systemPrintf("12) RTCM timeout before L-Band override (seconds): %d\r\n", settings.rtcmTimeoutBeforeUsingLBand_s);

systemPrintln("---- Interrupts ----");
systemPrint("30) Bluetooth Interrupts Core: ");
systemPrintln(settings.bluetoothInterruptsCore);
Expand Down Expand Up @@ -948,6 +950,18 @@ void menuOperation()
settings.useI2cForLbandCorrectionsConfigured = true; //Record that the user has manually modified the settings.
settings.useI2cForLbandCorrections ^= 1;
}
else if (incoming == 12)
{
systemPrint("Enter the number of seconds before L-Band is used once RTCM is absent (1 to 255): ");
int rtcmTimeoutBeforeUsingLBand_s = getNumber(); // Returns EXIT, TIMEOUT, or long
if ((rtcmTimeoutBeforeUsingLBand_s != INPUT_RESPONSE_GETNUMBER_EXIT) && (rtcmTimeoutBeforeUsingLBand_s != INPUT_RESPONSE_GETNUMBER_TIMEOUT))
{
if (rtcmTimeoutBeforeUsingLBand_s < 1 || rtcmTimeoutBeforeUsingLBand_s > 255)
systemPrintln("Error: RTCM timeout out of range");
else
settings.rtcmTimeoutBeforeUsingLBand_s = rtcmTimeoutBeforeUsingLBand_s; // Recorded to NVM and file
}
}

else if (incoming == 30)
{
Expand Down
6 changes: 6 additions & 0 deletions Firmware/RTK_Surveyor/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,12 @@ typedef struct
bool debugPvtServer = false;
bool enablePvtServer = false;
uint16_t pvtServerPort = 2948; // PVT server port, 2948 is GPS Daemon: http://tcp-udp-ports.com/port-2948.htm

uint8_t rtcmTimeoutBeforeUsingLBand_s = 10; //If 10s have passed without RTCM, enable PMP corrections over L-Band if available

//Add new settings above
//<------------------------------------------------------------>

} Settings;
Settings settings;

Expand Down