From 6ba8b18add549b8c08e4be5db0c4b725f8f02b65 Mon Sep 17 00:00:00 2001 From: Michael Shipman Date: Thu, 25 Jan 2024 20:41:19 -0500 Subject: [PATCH] adding console support to (Not)Xbee Joint test code --- Code/BITS/BITSv5/test/BITSv5.h | 20 - Code/BITS/BITSv5/test/MAX_M10S.cpp | 0 Code/BITS/BITSv5/test/MAX_M10S.h | 4 - .../SparkFun_u-blox_GNSS_Arduino_Library.cpp | 20731 ---------------- .../SparkFun_u-blox_GNSS_Arduino_Library.h | 3731 --- Code/BITS/BITSv5/test/test.cpp | 2 +- Code/BITS/BITSv5/test/u-blox_config_keys.h | 1229 - Code/BITS/BITSv5/test/u-blox_structs.h | 2787 --- Code/Not_XbeeJoint/test/test.cpp | 57 +- 9 files changed, 45 insertions(+), 28516 deletions(-) delete mode 100644 Code/BITS/BITSv5/test/BITSv5.h delete mode 100644 Code/BITS/BITSv5/test/MAX_M10S.cpp delete mode 100644 Code/BITS/BITSv5/test/MAX_M10S.h delete mode 100644 Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.cpp delete mode 100644 Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.h delete mode 100644 Code/BITS/BITSv5/test/u-blox_config_keys.h delete mode 100644 Code/BITS/BITSv5/test/u-blox_structs.h diff --git a/Code/BITS/BITSv5/test/BITSv5.h b/Code/BITS/BITSv5/test/BITSv5.h deleted file mode 100644 index b431d7be..00000000 --- a/Code/BITS/BITSv5/test/BITSv5.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _BITSv5_H -#define _BITSv5_H - -#define CS_PIN 25 -#define SCK_PIN 26 -#define MOSI_PIN 27 -#define MISO_PIN 24 -#define TXEN_PIN 8 -#define DIO1_PIN 10 -#define BUSY_PIN 11 -#define SW_PIN 9 -#define SDA_PIN 20 -#define SCL_PIN 21 - -#define INCLUDE_DEBUG \ - 1 // controls if debug conditionals are included at compile time - -extern short debug_msgs; // controls if debug messages are printed - -#endif \ No newline at end of file diff --git a/Code/BITS/BITSv5/test/MAX_M10S.cpp b/Code/BITS/BITSv5/test/MAX_M10S.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Code/BITS/BITSv5/test/MAX_M10S.h b/Code/BITS/BITSv5/test/MAX_M10S.h deleted file mode 100644 index 2a54ac83..00000000 --- a/Code/BITS/BITSv5/test/MAX_M10S.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _MAXM10S_H -#define _MAXM10S_H - -#endif \ No newline at end of file diff --git a/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.cpp deleted file mode 100644 index 4d15ab34..00000000 --- a/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ /dev/null @@ -1,20731 +0,0 @@ -/* - This is a library written for the u-blox ZED-F9P and NEO-M8P-2 - SparkFun sells these at its website: www.sparkfun.com - Do you like this library? Help support SparkFun. Buy a board! - https://www.sparkfun.com/products/16481 - https://www.sparkfun.com/products/15136 - https://www.sparkfun.com/products/15005 - https://www.sparkfun.com/products/15733 - https://www.sparkfun.com/products/15193 - https://www.sparkfun.com/products/15210 - - Original version by Nathan Seidle @ SparkFun Electronics, September 6th, 2018 - v2.0 rework by Paul Clark @ SparkFun Electronics, December 31st, 2020 - - This library handles configuring and handling the responses - from a u-blox GPS module. Works with most modules from u-blox including - the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others. - - https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library - - Development environment specifics: - Arduino IDE 1.8.13 - - SparkFun code, firmware, and software is released under the MIT - License(http://opensource.org/licenses/MIT). The MIT License (MIT) Copyright - (c) 2016 SparkFun Electronics Permission is hereby granted, free of charge, to - any person obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#include "SparkFun_u-blox_GNSS_Arduino_Library.h" - -#include - -#include "hardware/gpio.h" - -SFE_UBLOX_GNSS::SFE_UBLOX_GNSS(void) { - // Constructor - if (debugPin >= 0) { - gpio_init(debugPin); - gpio_set_dir(debugPin, GPIO_OUT); - gpio_put(debugPin, 1); - } - - _logNMEA.all = 0; // Default to passing no NMEA messages to the file buffer - _processNMEA.all = - SFE_UBLOX_FILTER_NMEA_ALL; // Default to passing all NMEA messages to - // processNMEA - - // Support for platforms like ESP32 which do not support multiple I2C - // restarts If _i2cStopRestart is true, endTransmission will always use a - // stop. If false, a restart will be used where needed. -#if defined(ARDUINO_ARCH_ESP32) - _i2cStopRestart = true; // Always use a stop -#else - _i2cStopRestart = false; // Use a restart where needed -#endif -} - -SFE_UBLOX_GNSS::~SFE_UBLOX_GNSS(void) { - // Destructor - - end(); // Delete all allocated memory - excluding payloadCfg, payloadAuto - // and spiBuffer - - if (payloadCfg != NULL) { - delete[] payloadCfg; // Created with new[] - payloadCfg = NULL; // Redundant? - } - - if (payloadAuto != NULL) { - delete[] payloadAuto; // Created with new[] - payloadAuto = NULL; // Redundant? - } - - if (spiBuffer != NULL) { - delete[] spiBuffer; // Created with new[] - spiBuffer = NULL; // Redundant? - } -} - -// Stop all automatic message processing. Free all used RAM -void SFE_UBLOX_GNSS::end(void) { - // Note: payloadCfg is not deleted - - // Note: payloadAuto is not deleted - - // Note: spiBuffer is not deleted - - if (ubxFileBuffer != - NULL) // Check if RAM has been allocated for the file buffer - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - printf( - "end: the file buffer has been deleted. You will need to " - "call setFileBufferSize before .begin to create a new one.\n"); - } -#endif - delete[] ubxFileBuffer; // Created with new[] - ubxFileBuffer = NULL; // Redundant? - fileBufferSize = 0; // Reset file buffer size. User will have to call - // setFileBufferSize again - fileBufferMaxAvail = 0; - } - - if (moduleSWVersion != NULL) { - delete moduleSWVersion; // Created with new moduleSWVersion_t - moduleSWVersion = NULL; // Redundant? - } - - if (currentGeofenceParams != NULL) { - delete currentGeofenceParams; // Created with new geofenceParams_t - currentGeofenceParams = NULL; // Redundant? - } - - if (packetUBXNAVTIMELS != NULL) { - delete packetUBXNAVTIMELS; // Created with new UBX_NAV_TIMELS_t - packetUBXNAVTIMELS = NULL; // Redundant? - } - - if (packetUBXNAVPOSECEF != NULL) { - if (packetUBXNAVPOSECEF->callbackData != NULL) { - delete packetUBXNAVPOSECEF - ->callbackData; // Created with new UBX_NAV_POSECEF_data_t - } - delete packetUBXNAVPOSECEF; // Created with new UBX_NAV_POSECEF_t - packetUBXNAVPOSECEF = NULL; // Redundant? - } - - if (packetUBXNAVSTATUS != NULL) { - if (packetUBXNAVSTATUS->callbackData != NULL) { - delete packetUBXNAVSTATUS->callbackData; - } - delete packetUBXNAVSTATUS; - packetUBXNAVSTATUS = NULL; // Redundant? - } - - if (packetUBXNAVDOP != NULL) { - if (packetUBXNAVDOP->callbackData != NULL) { - delete packetUBXNAVDOP->callbackData; - } - delete packetUBXNAVDOP; - packetUBXNAVDOP = NULL; // Redundant? - } - - if (packetUBXNAVATT != NULL) { - if (packetUBXNAVATT->callbackData != NULL) { - delete packetUBXNAVATT->callbackData; - } - delete packetUBXNAVATT; - packetUBXNAVATT = NULL; // Redundant? - } - - if (packetUBXNAVPVT != NULL) { - if (packetUBXNAVPVT->callbackData != NULL) { - delete packetUBXNAVPVT->callbackData; -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - printf("end: packetUBXNAVPVT->callbackData has been deleted\n"); - } -#endif - } - delete packetUBXNAVPVT; - packetUBXNAVPVT = NULL; // Redundant? -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - printf("end: packetUBXNAVPVT has been deleted"); - } -#endif - } - - if (packetUBXNAVODO != NULL) { - if (packetUBXNAVODO->callbackData != NULL) { - delete packetUBXNAVODO->callbackData; - } - delete packetUBXNAVODO; - packetUBXNAVODO = NULL; // Redundant? - } - - if (packetUBXNAVVELECEF != NULL) { - if (packetUBXNAVVELECEF->callbackData != NULL) { - delete packetUBXNAVVELECEF->callbackData; - } - delete packetUBXNAVVELECEF; - packetUBXNAVVELECEF = NULL; // Redundant? - } - - if (packetUBXNAVVELNED != NULL) { - if (packetUBXNAVVELNED->callbackData != NULL) { - delete packetUBXNAVVELNED->callbackData; - } - delete packetUBXNAVVELNED; - packetUBXNAVVELNED = NULL; // Redundant? - } - - if (packetUBXNAVHPPOSECEF != NULL) { - if (packetUBXNAVHPPOSECEF->callbackData != NULL) { - delete packetUBXNAVHPPOSECEF->callbackData; - } - delete packetUBXNAVHPPOSECEF; - packetUBXNAVHPPOSECEF = NULL; // Redundant? - } - - if (packetUBXNAVHPPOSLLH != NULL) { - if (packetUBXNAVHPPOSLLH->callbackData != NULL) { - delete packetUBXNAVHPPOSLLH->callbackData; - } - delete packetUBXNAVHPPOSLLH; - packetUBXNAVHPPOSLLH = NULL; // Redundant? - } - - if (packetUBXNAVPVAT != NULL) { - if (packetUBXNAVPVAT->callbackData != NULL) { - delete packetUBXNAVPVAT->callbackData; - } - delete packetUBXNAVPVAT; - packetUBXNAVPVAT = NULL; // Redundant? - } - - if (packetUBXNAVTIMEUTC != NULL) { - if (packetUBXNAVTIMEUTC->callbackData != NULL) { - delete packetUBXNAVTIMEUTC->callbackData; - } - delete packetUBXNAVTIMEUTC; - packetUBXNAVTIMEUTC = NULL; // Redundant? - } - - if (packetUBXNAVCLOCK != NULL) { - if (packetUBXNAVCLOCK->callbackData != NULL) { - delete packetUBXNAVCLOCK->callbackData; - } - delete packetUBXNAVCLOCK; - packetUBXNAVCLOCK = NULL; // Redundant? - } - - if (packetUBXNAVSVIN != NULL) { - if (packetUBXNAVSVIN->callbackData != NULL) { - delete packetUBXNAVSVIN->callbackData; - } - delete packetUBXNAVSVIN; - packetUBXNAVSVIN = NULL; // Redundant? - } - - if (packetUBXNAVSAT != NULL) { - if (packetUBXNAVSAT->callbackData != NULL) { - delete packetUBXNAVSAT->callbackData; - } - delete packetUBXNAVSAT; - packetUBXNAVSAT = NULL; // Redundant? - } - - if (packetUBXNAVRELPOSNED != NULL) { - if (packetUBXNAVRELPOSNED->callbackData != NULL) { - delete packetUBXNAVRELPOSNED->callbackData; - } - delete packetUBXNAVRELPOSNED; - packetUBXNAVRELPOSNED = NULL; // Redundant? - } - - if (packetUBXNAVAOPSTATUS != NULL) { - if (packetUBXNAVAOPSTATUS->callbackData != NULL) { - delete packetUBXNAVAOPSTATUS->callbackData; - } - delete packetUBXNAVAOPSTATUS; - packetUBXNAVAOPSTATUS = NULL; // Redundant? - } - - if (packetUBXNAVEOE != NULL) { - if (packetUBXNAVEOE->callbackData != NULL) { - delete packetUBXNAVEOE->callbackData; - } - delete packetUBXNAVEOE; - packetUBXNAVEOE = NULL; // Redundant? - } - - if (packetUBXRXMPMP != NULL) { - if (packetUBXRXMPMP->callbackData != NULL) { - delete packetUBXRXMPMP->callbackData; - } - delete packetUBXRXMPMP; - packetUBXRXMPMP = NULL; // Redundant? - } - - if (packetUBXRXMPMPmessage != NULL) { - if (packetUBXRXMPMPmessage->callbackData != NULL) { - delete packetUBXRXMPMPmessage->callbackData; - } - delete packetUBXRXMPMPmessage; - packetUBXRXMPMPmessage = NULL; // Redundant? - } - - if (packetUBXRXMQZSSL6message != NULL) { - if (packetUBXRXMQZSSL6message->callbackData != NULL) { - delete[] packetUBXRXMQZSSL6message->callbackData; - } - delete packetUBXRXMQZSSL6message; - packetUBXRXMQZSSL6message = NULL; // Redundant? - } - - if (packetUBXRXMCOR != NULL) { - if (packetUBXRXMCOR->callbackData != NULL) { - delete packetUBXRXMCOR->callbackData; - } - delete packetUBXRXMCOR; - packetUBXRXMCOR = NULL; // Redundant? - } - - if (packetUBXRXMSFRBX != NULL) { - if (packetUBXRXMSFRBX->callbackData != NULL) { - delete packetUBXRXMSFRBX->callbackData; - } - delete packetUBXRXMSFRBX; - packetUBXRXMSFRBX = NULL; // Redundant? - } - - if (packetUBXRXMRAWX != NULL) { - if (packetUBXRXMRAWX->callbackData != NULL) { - delete packetUBXRXMRAWX->callbackData; - } - delete packetUBXRXMRAWX; - packetUBXRXMRAWX = NULL; // Redundant? - } - - if (packetUBXCFGRATE != NULL) { - delete packetUBXCFGRATE; - packetUBXCFGRATE = NULL; // Redundant? - } - - if (packetUBXTIMTM2 != NULL) { - if (packetUBXTIMTM2->callbackData != NULL) { - delete packetUBXTIMTM2->callbackData; - } - delete packetUBXTIMTM2; - packetUBXTIMTM2 = NULL; // Redundant? - } - - if (packetUBXESFALG != NULL) { - if (packetUBXESFALG->callbackData != NULL) { - delete packetUBXESFALG->callbackData; - } - delete packetUBXESFALG; - packetUBXESFALG = NULL; // Redundant? - } - - if (packetUBXESFSTATUS != NULL) { - if (packetUBXESFSTATUS->callbackData != NULL) { - delete packetUBXESFSTATUS->callbackData; - } - delete packetUBXESFSTATUS; - packetUBXESFSTATUS = NULL; // Redundant? - } - - if (packetUBXESFINS != NULL) { - if (packetUBXESFINS->callbackData != NULL) { - delete packetUBXESFINS->callbackData; - } - delete packetUBXESFINS; - packetUBXESFINS = NULL; // Redundant? - } - - if (packetUBXESFMEAS != NULL) { - if (packetUBXESFMEAS->callbackData != NULL) { - delete packetUBXESFMEAS->callbackData; - } - delete packetUBXESFMEAS; - packetUBXESFMEAS = NULL; // Redundant? - } - - if (packetUBXESFRAW != NULL) { - if (packetUBXESFRAW->callbackData != NULL) { - delete packetUBXESFRAW->callbackData; - } - delete packetUBXESFRAW; - packetUBXESFRAW = NULL; // Redundant? - } - - if (packetUBXMGAACK != NULL) { - delete packetUBXMGAACK; - packetUBXMGAACK = NULL; // Redundant? - } - - if (packetUBXMGADBD != NULL) { - delete packetUBXMGADBD; - packetUBXMGADBD = NULL; // Redundant? - } - - if (packetUBXHNRATT != NULL) { - if (packetUBXHNRATT->callbackData != NULL) { - delete packetUBXHNRATT->callbackData; - } - delete packetUBXHNRATT; - packetUBXHNRATT = NULL; // Redundant? - } - - if (packetUBXHNRINS != NULL) { - if (packetUBXHNRINS->callbackData != NULL) { - delete packetUBXHNRINS->callbackData; - } - delete packetUBXHNRINS; - packetUBXHNRINS = NULL; // Redundant? - } - - if (packetUBXHNRPVT != NULL) { - if (packetUBXHNRPVT->callbackData != NULL) { - delete packetUBXHNRPVT->callbackData; - } - delete packetUBXHNRPVT; - packetUBXHNRPVT = NULL; // Redundant? - } - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - if (storageNMEAGPGGA != NULL) { - if (storageNMEAGPGGA->callbackCopy != NULL) { - delete storageNMEAGPGGA->callbackCopy; - } - delete storageNMEAGPGGA; - storageNMEAGPGGA = NULL; // Redundant? - } - - if (storageNMEAGNGGA != NULL) { - if (storageNMEAGNGGA->callbackCopy != NULL) { - delete storageNMEAGNGGA->callbackCopy; - } - delete storageNMEAGNGGA; - storageNMEAGNGGA = NULL; // Redundant? - } - - if (storageNMEAGPVTG != NULL) { - if (storageNMEAGPVTG->callbackCopy != NULL) { - delete storageNMEAGPVTG->callbackCopy; - } - delete storageNMEAGPVTG; - storageNMEAGPVTG = NULL; // Redundant? - } - - if (storageNMEAGNVTG != NULL) { - if (storageNMEAGNVTG->callbackCopy != NULL) { - delete storageNMEAGNVTG->callbackCopy; - } - delete storageNMEAGNVTG; - storageNMEAGNVTG = NULL; // Redundant? - } - - if (storageNMEAGPRMC != NULL) { - if (storageNMEAGPRMC->callbackCopy != NULL) { - delete storageNMEAGPRMC->callbackCopy; - } - delete storageNMEAGPRMC; - storageNMEAGPRMC = NULL; // Redundant? - } - - if (storageNMEAGNRMC != NULL) { - if (storageNMEAGNRMC->callbackCopy != NULL) { - delete storageNMEAGNRMC->callbackCopy; - } - delete storageNMEAGNRMC; - storageNMEAGNRMC = NULL; // Redundant? - } - - if (storageNMEAGPZDA != NULL) { - if (storageNMEAGPZDA->callbackCopy != NULL) { - delete storageNMEAGPZDA->callbackCopy; - } - delete storageNMEAGPZDA; - storageNMEAGPZDA = NULL; // Redundant? - } - - if (storageNMEAGNZDA != NULL) { - if (storageNMEAGNZDA->callbackCopy != NULL) { - delete storageNMEAGNZDA->callbackCopy; - } - delete storageNMEAGNZDA; - storageNMEAGNZDA = NULL; // Redundant? - } -#endif -} - -// Allow the user to change packetCfgPayloadSize. Handy if you want to process -// big messages like RAWX This can be called before .begin if required / desired -bool SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) { - bool success = true; - - if ((payloadSize == 0) && (payloadCfg != NULL)) { - // Zero payloadSize? Dangerous! But we'll free the memory anyway... - delete[] payloadCfg; // Created with new[] - payloadCfg = NULL; // Redundant? - packetCfg.payload = payloadCfg; - packetCfgPayloadSize = payloadSize; - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - - printf("setPacketCfgPayloadSize: Zero payloadSize!\n"); - } - - else if (payloadCfg == - NULL) // Memory has not yet been allocated - so use new - { - payloadCfg = new uint8_t[payloadSize]; - packetCfg.payload = payloadCfg; - if (payloadCfg == NULL) { - success = false; - packetCfgPayloadSize = 0; - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - - printf("setPacketCfgPayloadSize: RAM alloc failed!\n"); - - } else - packetCfgPayloadSize = payloadSize; - } - - else // Memory has already been allocated - so resize - { - uint8_t *newPayload = new uint8_t[payloadSize]; - - if (newPayload == NULL) // Check if the alloc was successful - { - success = false; // Report failure. Don't change payloadCfg, - // packetCfg.payload or packetCfgPayloadSize - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - - printf("setPacketCfgPayloadSize: RAM resize failed!\n"); - - } else { - memcpy(newPayload, payloadCfg, - payloadSize <= packetCfgPayloadSize - ? payloadSize - : packetCfgPayloadSize); // Copy as much existing data - // as we can - delete[] payloadCfg; // Free payloadCfg. Created with new[] - payloadCfg = newPayload; // Point to the newPayload - packetCfg.payload = payloadCfg; // Update the packet pointer - packetCfgPayloadSize = - payloadSize; // Update the packet payload size - } - } - - return (success); -} - -// Return the number of free bytes remaining in packetCfgPayload -size_t SFE_UBLOX_GNSS::getPacketCfgSpaceRemaining() { - return (packetCfgPayloadSize - packetCfg.len); -} - -// Initialize the I2C port -bool SFE_UBLOX_GNSS::begin(TwoWire &wirePort, uint8_t deviceAddress, - uint16_t maxWait, bool assumeSuccess) { - commType = COMM_TYPE_I2C; - _i2cPort = &wirePort; // Grab which port the user wants us to use - _signsOfLife = false; // Clear the _signsOfLife flag. It will be set true - // if valid traffic is seen. - - // We expect caller to begin their I2C port, with the speed of their choice - // external to the library But if they forget, we start the hardware here. - - // We're moving away from the practice of starting Wire hardware in a - // library. This is to avoid cross platform issues. ie, there are some - // platforms that don't handle multiple starts to the wire hardware. Also, - // every time you start the wire hardware the clock speed reverts back to - // 100kHz regardless of previous Wire.setClocks(). - //_i2cPort->begin(); - - _gpsI2Caddress = deviceAddress; // Store the I2C address from user - - // New in v2.0: allocate memory for the packetCfg payload here - if - // required. (The user may have called setPacketCfgPayloadSize already) - if (packetCfgPayloadSize == 0) setPacketCfgPayloadSize(MAX_PAYLOAD_SIZE); - - // New in v2.0: allocate memory for the file buffer - if required. (The user - // should have called setFileBufferSize already) - createFileBuffer(); - - // Call isConnected up to three times - tests on the NEO-M8U show the CFG - // RATE poll occasionally being ignored - bool connected = isConnected(maxWait); - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - second attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - third attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if ((!connected) && assumeSuccess && - _signsOfLife) // Advanced users can assume success if required. Useful - // if the port is outputting messages at high navigation - // rate. - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("begin: third attempt failed. Assuming success...")); - } -#endif - return (true); - } - - return (connected); -} - -// Initialize the Serial port -bool SFE_UBLOX_GNSS::begin(Stream &serialPort, uint16_t maxWait, - bool assumeSuccess) { - commType = COMM_TYPE_SERIAL; - _serialPort = &serialPort; // Grab which port the user wants us to use - _signsOfLife = false; // Clear the _signsOfLife flag. It will be set true - // if valid traffic is seen. - - // New in v2.0: allocate memory for the packetCfg payload here - if - // required. (The user may have called setPacketCfgPayloadSize already) - if (packetCfgPayloadSize == 0) setPacketCfgPayloadSize(MAX_PAYLOAD_SIZE); - - // New in v2.0: allocate memory for the file buffer - if required. (The user - // should have called setFileBufferSize already) - createFileBuffer(); - - // Get rid of any stale serial data already in the processor's RX buffer - while (_serialPort->available()) _serialPort->read(); - - // If assumeSuccess is true, the user must really want begin to succeed. So, - // let's empty the module's serial transmit buffer too! Keep discarding new - // serial data until we see a gap of 2ms - hopefully indicating that the - // module's TX buffer is empty. - if (assumeSuccess) { - unsigned long startTime = millis(); - unsigned long lastActivity = startTime; - bool keepGoing = true; - while (keepGoing && (millis() < (startTime + (unsigned long)maxWait))) { - while (_serialPort->available()) // Discard any new data - { - _serialPort->read(); - lastActivity = millis(); - } - - if (millis() > - (lastActivity + (unsigned long)2)) // Check if we have seen no - // new data for at least 2ms - keepGoing = false; - } - } - - // Call isConnected up to three times - tests on the NEO-M8U show the CFG - // RATE poll occasionally being ignored - bool connected = isConnected(maxWait); - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - second attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - third attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if ((!connected) && assumeSuccess && - _signsOfLife) // Advanced users can assume success if required. Useful - // if the port is outputting messages at high navigation - // rate. - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("begin: third attempt failed. Assuming success...")); - } -#endif - return (true); - } - - return (connected); -} - -// Initialize for SPI -bool SFE_UBLOX_GNSS::begin(SPIClass &spiPort, uint8_t csPin, uint32_t spiSpeed, - uint16_t maxWait, bool assumeSuccess) { - commType = COMM_TYPE_SPI; - _spiPort = &spiPort; - _csPin = csPin; - _spiSpeed = spiSpeed; - _signsOfLife = false; // Clear the _signsOfLife flag. It will be set true - // if valid traffic is seen. - - // Initialize the chip select pin - pinMode(_csPin, OUTPUT); - digitalWrite(_csPin, HIGH); - - // New in v2.0: allocate memory for the packetCfg payload here - if - // required. (The user may have called setPacketCfgPayloadSize already) - if (packetCfgPayloadSize == 0) setPacketCfgPayloadSize(MAX_PAYLOAD_SIZE); - - createFileBuffer(); - - // Create the SPI buffer - if (spiBuffer == NULL) // Memory has not yet been allocated - so use new - { - spiBuffer = new uint8_t[getSpiTransactionSize()]; - } - - if (spiBuffer == NULL) { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->print( - F("begin (SPI): memory allocation failed for SPI Buffer!")); - return (false); - } - } else { - // Initialize/clear the SPI buffer - fill it with 0xFF as this is what - // is received from the UBLOX module if there's no data to be processed - for (uint8_t i = 0; i < getSpiTransactionSize(); i++) { - spiBuffer[i] = 0xFF; - } - } - - // Call isConnected up to three times - tests on the NEO-M8U show the CFG - // RATE poll occasionally being ignored - bool connected = isConnected(maxWait); - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - second attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if (!connected) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("begin: isConnected - third attempt")); - } -#endif - connected = isConnected(maxWait); - } - - if ((!connected) && assumeSuccess && - _signsOfLife) // Advanced users can assume success if required. Useful - // if the port is outputting messages at high navigation - // rate. - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("begin: third attempt failed. Assuming success...")); - } -#endif - return (true); - } - - return (connected); -} - -// Allow the user to change I2C polling wait (the minimum interval between I2C -// data requests - to avoid pounding the bus) i2cPollingWait defaults to 100ms -// and is adjusted automatically when setNavigationFrequency() or -// setHNRNavigationRate() are called. But if the user is using callbacks, it -// might be advantageous to be able to set the polling wait manually. -void SFE_UBLOX_GNSS::setI2CpollingWait(uint8_t newPollingWait_ms) { - i2cPollingWait = newPollingWait_ms; -} - -// Allow the user to change SPI polling wait -// (the minimum interval between SPI data requests when no data is available - -// to avoid pounding the bus) -void SFE_UBLOX_GNSS::setSPIpollingWait(uint8_t newPollingWait_ms) { - spiPollingWait = newPollingWait_ms; -} - -// Sets the global size for I2C transactions -// Most platforms use 32 bytes (the default) but this allows users to increase -// the transaction size if the platform supports it Note: If the transaction -// size is set larger than the platforms buffer size, bad things will happen. -void SFE_UBLOX_GNSS::setI2CTransactionSize(uint8_t transactionSize) { - if (transactionSize < 8) - transactionSize = 8; // Ensure transactionSize is at least 8 bytes - // otherwise sendI2cCommand will have problems! - - i2cTransactionSize = transactionSize; -} -uint8_t SFE_UBLOX_GNSS::getI2CTransactionSize(void) { - return (i2cTransactionSize); -} - -// Sets the global size for the SPI buffer/transactions. -// Call this **before** begin()! -// Note: if the buffer size is too small, incoming characters may be lost if the -// message sent is larger than this buffer. If too big, you may run out of SRAM -// on constrained architectures! -void SFE_UBLOX_GNSS::setSpiTransactionSize(uint8_t transactionSize) { - if (spiBuffer == NULL) { - spiTransactionSize = transactionSize; - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("setSpiTransactionSize: you need to call " - "setSpiTransactionSize _before_ begin!")); - } -#endif - } -} -uint8_t SFE_UBLOX_GNSS::getSpiTransactionSize(void) { - return (spiTransactionSize); -} - -// Sets the size of maxNMEAByteCount -void SFE_UBLOX_GNSS::setMaxNMEAByteCount(int8_t newMax) { - maxNMEAByteCount = newMax; -} -int8_t SFE_UBLOX_GNSS::getMaxNMEAByteCount(void) { return (maxNMEAByteCount); } - -// Returns true if I2C device ack's -bool SFE_UBLOX_GNSS::isConnected(uint16_t maxWait) { - if (commType == COMM_TYPE_I2C) { - _i2cPort->beginTransmission((uint8_t)_gpsI2Caddress); - if (_i2cPort->endTransmission() != 0) - return false; // Sensor did not ack - } - - // Query port configuration to see whether we get a meaningful response - // We could simply request the config for any port but, just for giggles, - // let's request the config for most appropriate port - if (commType == COMM_TYPE_I2C) - return (getPortSettingsInternal(COM_PORT_I2C, maxWait)); - else if (commType == COMM_TYPE_SERIAL) - return (getPortSettingsInternal( - COM_PORT_UART1, - maxWait)); // Could be UART2 - but this is just a response check - else // if (commType == COMM_TYPE_SPI) - return (getPortSettingsInternal(COM_PORT_SPI, maxWait)); -} - -// Enable or disable the printing of sent/response HEX values. -// Use this in conjunction with 'Transport Logging' from the Universal Reader -// Assistant to see what they're doing that we're not -void SFE_UBLOX_GNSS::enableDebugging(Stream &debugPort, - bool printLimitedDebug) { - _debugSerial = - &debugPort; // Grab which port the user wants us to use for debugging - if (printLimitedDebug == false) { - _printDebug = - true; // Should we print the commands we send? Good for debugging - } else { - _printLimitedDebug = true; // Should we print limited debug messages? - // Good for debugging high navigation rates - } -} -void SFE_UBLOX_GNSS::disableDebugging(void) { - _printDebug = false; // Turn off extra print statements - _printLimitedDebug = false; -} - -// Safely print messages -void SFE_UBLOX_GNSS::debugPrint(char *message) { - if (_printDebug == true) { - _debugSerial->print(message); - } -} -// Safely print messages -void SFE_UBLOX_GNSS::debugPrintln(char *message) { - if (_printDebug == true) { - _debugSerial->println(message); - } -} - -const char *SFE_UBLOX_GNSS::statusString(sfe_ublox_status_e stat) { - switch (stat) { - case SFE_UBLOX_STATUS_SUCCESS: - return "Success"; - break; - case SFE_UBLOX_STATUS_FAIL: - return "General Failure"; - break; - case SFE_UBLOX_STATUS_CRC_FAIL: - return "CRC Fail"; - break; - case SFE_UBLOX_STATUS_TIMEOUT: - return "Timeout"; - break; - case SFE_UBLOX_STATUS_COMMAND_NACK: - return "Command not acknowledged (NACK)"; - break; - case SFE_UBLOX_STATUS_OUT_OF_RANGE: - return "Out of range"; - break; - case SFE_UBLOX_STATUS_INVALID_ARG: - return "Invalid Arg"; - break; - case SFE_UBLOX_STATUS_INVALID_OPERATION: - return "Invalid operation"; - break; - case SFE_UBLOX_STATUS_MEM_ERR: - return "Memory Error"; - break; - case SFE_UBLOX_STATUS_HW_ERR: - return "Hardware Error"; - break; - case SFE_UBLOX_STATUS_DATA_SENT: - return "Data Sent"; - break; - case SFE_UBLOX_STATUS_DATA_RECEIVED: - return "Data Received"; - break; - case SFE_UBLOX_STATUS_I2C_COMM_FAILURE: - return "I2C Comm Failure"; - break; - case SFE_UBLOX_STATUS_DATA_OVERWRITTEN: - return "Data Packet Overwritten"; - break; - default: - return "Unknown Status"; - break; - } - return "None"; -} - -// Check for the arrival of new I2C/Serial/SPI data - -// Allow the user to disable the "7F" check (e.g.) when logging RAWX data -void SFE_UBLOX_GNSS::disableUBX7Fcheck(bool disabled) { - ubx7FcheckDisabled = disabled; -} - -// Called regularly to check for available bytes on the user' specified port -bool SFE_UBLOX_GNSS::checkUblox(uint8_t requestedClass, uint8_t requestedID) { - return checkUbloxInternal(&packetCfg, requestedClass, requestedID); -} - -// PRIVATE: Called regularly to check for available bytes on the user' specified -// port -bool SFE_UBLOX_GNSS::checkUbloxInternal(ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID) { - if (commType == COMM_TYPE_I2C) - return (checkUbloxI2C(incomingUBX, requestedClass, requestedID)); - else if (commType == COMM_TYPE_SERIAL) - return (checkUbloxSerial(incomingUBX, requestedClass, requestedID)); - else if (commType == COMM_TYPE_SPI) - return (checkUbloxSpi(incomingUBX, requestedClass, requestedID)); - return false; -} - -// Polls I2C for data, passing any new bytes to process() -// Returns true if new bytes are available -bool SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID) { - if (millis() - lastCheck >= i2cPollingWait) { - // Get the number of bytes available from the module - uint16_t bytesAvailable = 0; - _i2cPort->beginTransmission(_gpsI2Caddress); - _i2cPort->write(0xFD); // 0xFD (MSB) and 0xFE (LSB) are the registers - // that contain number of bytes available - uint8_t i2cError = _i2cPort->endTransmission( - false); // Always send a restart command. Do not release the bus. - // ESP32 supports this. - if (i2cError != 0) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - _debugSerial->print( - F("checkUbloxI2C: I2C error: endTransmission returned ")); - _debugSerial->println(i2cError); - } -#endif - return (false); // Sensor did not ACK - } - - // Forcing requestFrom to use a restart would be unwise. If - // bytesAvailable is zero, we want to surrender the bus. - uint8_t bytesReturned = _i2cPort->requestFrom((uint8_t)_gpsI2Caddress, - static_cast(2)); - if (bytesReturned != 2) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - _debugSerial->print( - F("checkUbloxI2C: I2C error: requestFrom 0xFD returned ")); - _debugSerial->println(bytesReturned); - } -#endif - return (false); // Sensor did not return 2 bytes - } else // if (_i2cPort->available()) - { - uint8_t msb = _i2cPort->read(); - uint8_t lsb = _i2cPort->read(); - // if (lsb == 0xFF) - // { - // //I believe this is a u-blox bug. Device should never present - // an 0xFF. if ((_printDebug == true) || (_printLimitedDebug == - // true)) // This is important. Print this if doing limited - // debugging - // { - // _debugSerial->print(F("checkUbloxI2C: u-blox bug? Length lsb - // is 0xFF. i2cPollingWait is ")); - // _debugSerial->println(i2cPollingWait); - // } - // if (debugPin >= 0) - // { - // digitalWrite((uint8_t)debugPin, LOW); - // delay(10); - // digitalWrite((uint8_t)debugPin, HIGH); - // } - // lastCheck = millis(); //Put off checking to avoid I2C bus - // traffic return (false); - // } - // if (msb == 0xFF) - // { - // //I believe this is a u-blox bug. Device should never present - // an 0xFF. if ((_printDebug == true) || (_printLimitedDebug == - // true)) // This is important. Print this if doing limited - // debugging - // { - // _debugSerial->print(F("checkUbloxI2C: u-blox bug? Length msb - // is 0xFF. i2cPollingWait is ")); - // _debugSerial->println(i2cPollingWait); - // } - // if (debugPin >= 0) - // { - // digitalWrite((uint8_t)debugPin, LOW); - // delay(10); - // digitalWrite((uint8_t)debugPin, HIGH); - // } - // lastCheck = millis(); //Put off checking to avoid I2C bus - // traffic return (false); - // } - bytesAvailable = (uint16_t)msb << 8 | lsb; - } - - if (bytesAvailable == 0) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("checkUbloxI2C: OK, zero bytes available")); - } -#endif - lastCheck = millis(); // Put off checking to avoid I2C bus traffic - return (false); - } - - // Check for undocumented bit error. We found this doing logic scans. - // This error is rare but if we incorrectly interpret the first bit of - // the two 'data available' bytes as 1 then we have far too many bytes - // to check. May be related to I2C setup time violations: - // https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues/40 - if (bytesAvailable & ((uint16_t)1 << 15)) { - // Clear the MSbit - bytesAvailable &= ~((uint16_t)1 << 15); - - // if ((_printDebug == true) || (_printLimitedDebug == true)) // - // This is important. Print this if doing limited debugging - // { - // _debugSerial->print(F("checkUbloxI2C: Bytes available error: - // ")); _debugSerial->println(bytesAvailable); if (debugPin >= 0) - // { - // digitalWrite((uint8_t)debugPin, LOW); - // delay(10); - // digitalWrite((uint8_t)debugPin, HIGH); - // } - // } - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (bytesAvailable > 100) { - if (_printDebug == true) { - _debugSerial->print(F("checkUbloxI2C: Large packet of ")); - _debugSerial->print(bytesAvailable); - _debugSerial->println(F(" bytes received")); - } - } else { - if (_printDebug == true) { - _debugSerial->print(F("checkUbloxI2C: Reading ")); - _debugSerial->print(bytesAvailable); - _debugSerial->println(F(" bytes")); - } - } -#endif - - while (bytesAvailable) { - // From the u-blox integration manual: - // "There are two forms of DDC read transfer. The "random access" - // form includes a peripheral register - // address and thus allows any register to be read. The second - // "current address" form omits the register address. If this - // second form is used, then an address pointer in the receiver is - // used to determine which register to read. This address pointer - // will increment after each read unless it is already pointing at - // register 0xFF, the highest addressable register, in which case - // it remains unaltered." - // This means that after reading bytesAvailable from 0xFD and 0xFE, - // the address pointer will already be pointing at 0xFF, so we do - // not need to write it here. The next four lines can be commented. - //_i2cPort->beginTransmission(_gpsI2Caddress); - //_i2cPort->write(0xFF); //0xFF is the register - // to read data from - // if (_i2cPort->endTransmission(false) != 0) //Send a restart - // command. Do not release bus. - // return (false); //Sensor did not ACK - - // Limit to 32 bytes or whatever the buffer limit is for given - // platform - uint16_t bytesToRead = bytesAvailable; // 16-bit - if (bytesToRead > - i2cTransactionSize) // Limit for i2cTransactionSize is 8-bit - bytesToRead = i2cTransactionSize; - - // TRY_AGAIN: - - // Here it would be desireable to use a restart where possible / - // supported, but only if there will be multiple reads. However, if - // an individual requestFrom fails, we could end up leaving the bus - // hanging. On balance, it is probably safest to not use restarts - // here. - uint8_t bytesReturned = _i2cPort->requestFrom( - (uint8_t)_gpsI2Caddress, (uint8_t)bytesToRead); - if ((uint16_t)bytesReturned == bytesToRead) { - for (uint16_t x = 0; x < bytesToRead; x++) { - uint8_t incoming = - _i2cPort->read(); // Grab the actual character - - // Check to see if the first read is 0x7F. If it is, the - // module is not ready to respond. Stop, wait, and try - // again. Note: the integration manual says: - //"If there is no data awaiting transmission from the - // receiver, then this register will deliver the value 0xFF, - // which cannot be the first byte of a valid message." - // But it can be the first byte waiting to be read from the - // buffer if we have already read part of the message. - // Therefore I think this check needs to be commented. - // if (x == 0) - // { - // if ((incoming == 0x7F) && (ubx7FcheckDisabled == - // false)) - // { - // if ((_printDebug == true) || (_printLimitedDebug == - // true)) // This is important. Print this if doing - // limited debugging - // { - // _debugSerial->println(F("checkUbloxU2C: u-blox - // error, module not ready with data (7F error)")); - // } - // delay(5); //In logic analyzation, the module - // starting responding after 1.48ms if (debugPin >= 0) - // { - // digitalWrite((uint8_t)debugPin, LOW); - // delay(10); - // digitalWrite((uint8_t)debugPin, HIGH); - // } - // goto TRY_AGAIN; - // } - // } - - process(incoming, incomingUBX, requestedClass, - requestedID); // Process this valid character - } - } else - return (false); // Sensor did not respond - - bytesAvailable -= bytesToRead; - } - } - - return (true); - -} // end checkUbloxI2C() - -// Checks Serial for data, passing any new bytes to process() -bool SFE_UBLOX_GNSS::checkUbloxSerial(ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID) { - while (_serialPort->available()) { - process(_serialPort->read(), incomingUBX, requestedClass, requestedID); - } - return (true); - -} // end checkUbloxSerial() - -// Checks SPI for data, passing any new bytes to process() -bool SFE_UBLOX_GNSS::checkUbloxSpi(ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID) { - // Process the contents of the SPI buffer if not empty! - for (uint8_t i = 0; i < spiBufferIndex; i++) { - process(spiBuffer[i], incomingUBX, requestedClass, requestedID); - } - spiBufferIndex = 0; - - _spiPort->beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - digitalWrite(_csPin, LOW); - uint8_t byteReturned = _spiPort->transfer(0xFF); - - // Note to future self: I think the 0xFF check might cause problems when - // attempting to process (e.g.) RAWX data which could legitimately contain - // 0xFF within the data stream. But the currentSentence check will certainly - // help! - - // If we are not receiving a sentence (currentSentence == NONE) and the - // byteReturned is 0xFF, i.e. the module has no data for us, then delay for - if ((byteReturned == 0xFF) && - (currentSentence == SFE_UBLOX_SENTENCE_TYPE_NONE)) { - digitalWrite(_csPin, HIGH); - _spiPort->endTransaction(); - delay(spiPollingWait); - return (true); - } - - while ((byteReturned != 0xFF) || - (currentSentence != SFE_UBLOX_SENTENCE_TYPE_NONE)) { - process(byteReturned, incomingUBX, requestedClass, requestedID); - byteReturned = _spiPort->transfer(0xFF); - } - digitalWrite(_csPin, HIGH); - _spiPort->endTransaction(); - return (true); - -} // end checkUbloxSpi() - -// PRIVATE: Check if we have storage allocated for an incoming "automatic" -// message -bool SFE_UBLOX_GNSS::checkAutomatic(uint8_t Class, uint8_t ID) { - bool result = false; - switch (Class) { - case UBX_CLASS_NAV: { - switch (ID) { - case UBX_NAV_POSECEF: - if (packetUBXNAVPOSECEF != NULL) result = true; - break; - case UBX_NAV_STATUS: - if (packetUBXNAVSTATUS != NULL) result = true; - break; - case UBX_NAV_DOP: - if (packetUBXNAVDOP != NULL) result = true; - break; - case UBX_NAV_ATT: - if (packetUBXNAVATT != NULL) result = true; - break; - case UBX_NAV_PVT: - if (packetUBXNAVPVT != NULL) result = true; - break; - case UBX_NAV_ODO: - if (packetUBXNAVODO != NULL) result = true; - break; - case UBX_NAV_VELECEF: - if (packetUBXNAVVELECEF != NULL) result = true; - break; - case UBX_NAV_VELNED: - if (packetUBXNAVVELNED != NULL) result = true; - break; - case UBX_NAV_HPPOSECEF: - if (packetUBXNAVHPPOSECEF != NULL) result = true; - break; - case UBX_NAV_HPPOSLLH: - if (packetUBXNAVHPPOSLLH != NULL) result = true; - break; - case UBX_NAV_PVAT: - if (packetUBXNAVPVAT != NULL) result = true; - break; - case UBX_NAV_TIMEUTC: - if (packetUBXNAVTIMEUTC != NULL) result = true; - break; - case UBX_NAV_CLOCK: - if (packetUBXNAVCLOCK != NULL) result = true; - break; - case UBX_NAV_TIMELS: - if (packetUBXNAVTIMELS != NULL) result = true; - break; - case UBX_NAV_SVIN: - if (packetUBXNAVSVIN != NULL) result = true; - break; - case UBX_NAV_SAT: - if (packetUBXNAVSAT != NULL) result = true; - break; - case UBX_NAV_RELPOSNED: - if (packetUBXNAVRELPOSNED != NULL) result = true; - break; - case UBX_NAV_AOPSTATUS: - if (packetUBXNAVAOPSTATUS != NULL) result = true; - break; - case UBX_NAV_EOE: - if (packetUBXNAVEOE != NULL) result = true; - break; - } - } break; - case UBX_CLASS_RXM: { - switch (ID) { - case UBX_RXM_SFRBX: - if (packetUBXRXMSFRBX != NULL) result = true; - break; - case UBX_RXM_RAWX: - if (packetUBXRXMRAWX != NULL) result = true; - break; - case UBX_RXM_PMP: - if ((packetUBXRXMPMP != NULL) || - (packetUBXRXMPMPmessage != NULL)) - result = true; - break; - case UBX_RXM_QZSSL6: - if (packetUBXRXMQZSSL6message != NULL) result = true; - break; - case UBX_RXM_COR: - if (packetUBXRXMCOR != NULL) result = true; - break; - } - } break; - case UBX_CLASS_CFG: { - switch (ID) { - case UBX_CFG_PRT: - if (packetUBXCFGPRT != NULL) result = true; - break; - case UBX_CFG_RATE: - if (packetUBXCFGRATE != NULL) result = true; - break; - } - } break; - case UBX_CLASS_TIM: { - switch (ID) { - case UBX_TIM_TM2: - if (packetUBXTIMTM2 != NULL) result = true; - break; - } - } break; - case UBX_CLASS_ESF: { - switch (ID) { - case UBX_ESF_ALG: - if (packetUBXESFALG != NULL) result = true; - break; - case UBX_ESF_INS: - if (packetUBXESFINS != NULL) result = true; - break; - case UBX_ESF_MEAS: - if (packetUBXESFMEAS != NULL) result = true; - break; - case UBX_ESF_RAW: - if (packetUBXESFRAW != NULL) result = true; - break; - case UBX_ESF_STATUS: - if (packetUBXESFSTATUS != NULL) result = true; - break; - } - } break; - case UBX_CLASS_MGA: { - switch (ID) { - case UBX_MGA_ACK_DATA0: - if (packetUBXMGAACK != NULL) result = true; - break; - case UBX_MGA_DBD: - if (packetUBXMGADBD != NULL) result = true; - break; - } - } break; - case UBX_CLASS_HNR: { - switch (ID) { - case UBX_HNR_PVT: - if (packetUBXHNRPVT != NULL) result = true; - break; - case UBX_HNR_ATT: - if (packetUBXHNRATT != NULL) result = true; - break; - case UBX_HNR_INS: - if (packetUBXHNRINS != NULL) result = true; - break; - } - } break; - } - return (result); -} - -// PRIVATE: Calculate how much RAM is needed to store the payload for a given -// automatic message -uint16_t SFE_UBLOX_GNSS::getMaxPayloadSize(uint8_t Class, uint8_t ID) { - uint16_t maxSize = 0; - switch (Class) { - case UBX_CLASS_NAV: { - switch (ID) { - case UBX_NAV_POSECEF: - maxSize = UBX_NAV_POSECEF_LEN; - break; - case UBX_NAV_STATUS: - maxSize = UBX_NAV_STATUS_LEN; - break; - case UBX_NAV_DOP: - maxSize = UBX_NAV_DOP_LEN; - break; - case UBX_NAV_ATT: - maxSize = UBX_NAV_ATT_LEN; - break; - case UBX_NAV_PVT: - maxSize = UBX_NAV_PVT_LEN; - break; - case UBX_NAV_ODO: - maxSize = UBX_NAV_ODO_LEN; - break; - case UBX_NAV_VELECEF: - maxSize = UBX_NAV_VELECEF_LEN; - break; - case UBX_NAV_VELNED: - maxSize = UBX_NAV_VELNED_LEN; - break; - case UBX_NAV_HPPOSECEF: - maxSize = UBX_NAV_HPPOSECEF_LEN; - break; - case UBX_NAV_HPPOSLLH: - maxSize = UBX_NAV_HPPOSLLH_LEN; - break; - case UBX_NAV_PVAT: - maxSize = UBX_NAV_PVAT_LEN; - break; - case UBX_NAV_TIMEUTC: - maxSize = UBX_NAV_TIMEUTC; - break; - case UBX_NAV_CLOCK: - maxSize = UBX_NAV_CLOCK_LEN; - break; - case UBX_NAV_TIMELS: - maxSize = UBX_NAV_TIMELS_LEN; - break; - case UBX_NAV_SVIN: - maxSize = UBX_NAV_SVIN_LEN; - break; - case UBX_NAV_SAT: - maxSize = UBX_NAV_SAT_MAX_LEN; - break; - case UBX_NAV_RELPOSNED: - maxSize = UBX_NAV_RELPOSNED_LEN_F9; - break; - case UBX_NAV_AOPSTATUS: - maxSize = UBX_NAV_AOPSTATUS_LEN; - break; - case UBX_NAV_EOE: - maxSize = UBX_NAV_EOE_LEN; - break; - } - } break; - case UBX_CLASS_RXM: { - switch (ID) { - case UBX_RXM_SFRBX: - maxSize = UBX_RXM_SFRBX_MAX_LEN; - break; - case UBX_RXM_RAWX: - maxSize = UBX_RXM_RAWX_MAX_LEN; - break; - case UBX_RXM_PMP: - maxSize = UBX_RXM_PMP_MAX_LEN; - break; - case UBX_RXM_QZSSL6: - maxSize = UBX_RXM_QZSSL6_MAX_LEN; - break; - case UBX_RXM_COR: - maxSize = UBX_RXM_COR_LEN; - break; - } - } break; - case UBX_CLASS_CFG: { - switch (ID) { - case UBX_CFG_PRT: - maxSize = UBX_CFG_PRT_LEN; - break; - case UBX_CFG_RATE: - maxSize = UBX_CFG_RATE_LEN; - break; - } - } break; - case UBX_CLASS_TIM: { - switch (ID) { - case UBX_TIM_TM2: - maxSize = UBX_TIM_TM2_LEN; - break; - } - } break; - case UBX_CLASS_ESF: { - switch (ID) { - case UBX_ESF_ALG: - maxSize = UBX_ESF_ALG_LEN; - break; - case UBX_ESF_INS: - maxSize = UBX_ESF_INS_LEN; - break; - case UBX_ESF_MEAS: - maxSize = UBX_ESF_MEAS_MAX_LEN; - break; - case UBX_ESF_RAW: - maxSize = UBX_ESF_RAW_MAX_LEN; - break; - case UBX_ESF_STATUS: - maxSize = UBX_ESF_STATUS_MAX_LEN; - break; - } - } break; - case UBX_CLASS_MGA: { - switch (ID) { - case UBX_MGA_ACK_DATA0: - maxSize = UBX_MGA_ACK_DATA0_LEN; - break; - case UBX_MGA_DBD: - maxSize = UBX_MGA_DBD_LEN; // UBX_MGA_DBD_LEN is actually a - // maximum length. The packets - // could be shorter than this. - break; - } - } break; - case UBX_CLASS_HNR: { - switch (ID) { - case UBX_HNR_PVT: - maxSize = UBX_HNR_PVT_LEN; - break; - case UBX_HNR_ATT: - maxSize = UBX_HNR_ATT_LEN; - break; - case UBX_HNR_INS: - maxSize = UBX_HNR_INS_LEN; - break; - } - } break; - } - return (maxSize); -} - -// Processes NMEA and UBX binary sentences one byte at a time -// Take a given byte and file it into the proper array -void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, - uint8_t requestedClass, uint8_t requestedID) { - if (_outputPort != NULL) - _outputPort->write(incoming); // Echo this byte to the serial port - if ((currentSentence == SFE_UBLOX_SENTENCE_TYPE_NONE) || - (currentSentence == SFE_UBLOX_SENTENCE_TYPE_NMEA)) { - if (incoming == - UBX_SYNCH_1) // UBX binary frames start with 0xB5, aka μ - { - // This is the start of a binary sentence. Reset flags. - // We still don't know the response class - ubxFrameCounter = 0; - currentSentence = SFE_UBLOX_SENTENCE_TYPE_UBX; - // Reset the packetBuf.counter even though we will need to reset it - // again when ubxFrameCounter == 2 - packetBuf.counter = 0; - ignoreThisPayload = - false; // We should not ignore this payload - yet - // Store data in packetBuf until we know if we have a requested - // class and ID match - activePacketBuffer = SFE_UBLOX_PACKET_PACKETBUF; - } else if (incoming == '$') { - nmeaByteCounter = 0; // Reset the NMEA byte counter - currentSentence = SFE_UBLOX_SENTENCE_TYPE_NMEA; - } else if (incoming == 0xD3) // RTCM frames start with 0xD3 - { - rtcmFrameCounter = 0; - currentSentence = SFE_UBLOX_SENTENCE_TYPE_RTCM; - } else { - // This character is unknown or we missed the previous start of a - // sentence - } - } - - // Depending on the sentence, pass the character to the individual processor - if (currentSentence == SFE_UBLOX_SENTENCE_TYPE_UBX) { - // Decide what type of response this is - if ((ubxFrameCounter == 0) && (incoming != UBX_SYNCH_1)) // ISO 'μ' - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Something went wrong. Reset. - else if ((ubxFrameCounter == 1) && - (incoming != UBX_SYNCH_2)) // ASCII 'b' - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Something went wrong. Reset. - // Note to future self: - // There may be some duplication / redundancy in the next few lines as - // processUBX will also load information into packetBuf, but we'll do it - // here too for clarity - else if (ubxFrameCounter == 2) // Class - { - // Record the class in packetBuf until we know what to do with it - packetBuf.cls = incoming; // (Duplication) - rollingChecksumA = 0; // Reset our rolling checksums here (not when - // we receive the 0xB5) - rollingChecksumB = 0; - packetBuf.counter = 0; // Reset the packetBuf.counter (again) - packetBuf.valid = - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; // Reset the packet - // validity (redundant?) - packetBuf.startingSpot = - incomingUBX->startingSpot; // Copy the startingSpot - } else if (ubxFrameCounter == 3) // ID - { - // Record the ID in packetBuf until we know what to do with it - packetBuf.id = incoming; // (Duplication) - // We can now identify the type of response - // If the packet we are receiving is not an ACK then check for a - // class and ID match - if (packetBuf.cls != UBX_CLASS_ACK) { - // This is not an ACK so check for a class and ID match - if ((packetBuf.cls == requestedClass) && - (packetBuf.id == requestedID)) { - // This is not an ACK and we have a class and ID match - // So start diverting data into incomingUBX (usually - // packetCfg) - activePacketBuffer = SFE_UBLOX_PACKET_PACKETCFG; - incomingUBX->cls = - packetBuf.cls; // Copy the class and ID into - // incomingUBX (usually packetCfg) - incomingUBX->id = packetBuf.id; - incomingUBX->counter = - packetBuf.counter; // Copy over the .counter too - } - // This is not an ACK and we do not have a complete class and ID - // match So let's check if this is an "automatic" message which - // has its own storage defined - else if (checkAutomatic(packetBuf.cls, packetBuf.id)) { - // This is not the message we were expecting but it has its - // own storage and so we should process it anyway. We'll try - // to use packetAuto to buffer the message (so it can't - // overwrite anything in packetCfg). We need to allocate - // memory for the packetAuto payload (payloadAuto) - and - // delete it once reception is complete. - uint16_t maxPayload = getMaxPayloadSize( - packetBuf.cls, - packetBuf.id); // Calculate how much RAM we need - if (maxPayload == 0) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->print( - F("process: getMaxPayloadSize returned ZERO!! " - "Class: 0x")); - _debugSerial->print(packetBuf.cls); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(packetBuf.id); - } -#endif - } - if (payloadAuto != - NULL) // Check if memory is already allocated - this - // should be impossible! - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("process: memory is already allocated for " - "payloadAuto! Deleting...")); - } -#endif - delete[] payloadAuto; // Created with new[] - payloadAuto = NULL; // Redundant? - packetAuto.payload = payloadAuto; - } - payloadAuto = new uint8_t[maxPayload]; // Allocate RAM for - // payloadAuto - packetAuto.payload = payloadAuto; - if (payloadAuto == NULL) // Check if the alloc failed - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->print( - F("process: memory allocation failed for " - "\"automatic\" message: Class: 0x")); - _debugSerial->print(packetBuf.cls, HEX); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(packetBuf.id, HEX); - _debugSerial->println( - F("process: \"automatic\" message could " - "overwrite data")); - } -#endif - // The RAM allocation failed so fall back to using - // incomingUBX (usually packetCfg) even though we risk - // overwriting data - activePacketBuffer = SFE_UBLOX_PACKET_PACKETCFG; - incomingUBX->cls = - packetBuf.cls; // Copy the class and ID into - // incomingUBX (usually packetCfg) - incomingUBX->id = packetBuf.id; - incomingUBX->counter = - packetBuf.counter; // Copy over the .counter too - } else { - // The RAM allocation was successful so we start - // diverting data into packetAuto and process it - activePacketBuffer = SFE_UBLOX_PACKET_PACKETAUTO; - packetAuto.cls = - packetBuf - .cls; // Copy the class and ID into packetAuto - packetAuto.id = packetBuf.id; - packetAuto.counter = - packetBuf.counter; // Copy over the .counter too - packetAuto.startingSpot = - packetBuf.startingSpot; // And the starting spot? - // (Probably redundant) -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("process: incoming \"automatic\" message: " - "Class: 0x")); - _debugSerial->print(packetBuf.cls, HEX); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(packetBuf.id, HEX); - } -#endif - } - } else { - // This is not an ACK and we do not have a class and ID - // match so we should keep diverting data into packetBuf and - // ignore the payload - ignoreThisPayload = true; - } - } else { - // This is an ACK so it is to early to do anything with it - // We need to wait until we have received the length and data - // bytes So we should keep diverting data into packetBuf - } - } else if (ubxFrameCounter == 4) // Length LSB - { - // We should save the length in packetBuf even if activePacketBuffer - // == SFE_UBLOX_PACKET_PACKETCFG - packetBuf.len = incoming; // (Duplication) - } else if (ubxFrameCounter == 5) // Length MSB - { - // We should save the length in packetBuf even if activePacketBuffer - // == SFE_UBLOX_PACKET_PACKETCFG - packetBuf.len |= incoming << 8; // (Duplication) - } else if (ubxFrameCounter == 6) // This should be the first byte of - // the payload unless .len is zero - { - if (packetBuf.len == - 0) // Check if length is zero (hopefully this is impossible!) - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print( - F("process: ZERO LENGTH packet received: Class: 0x")); - _debugSerial->print(packetBuf.cls, HEX); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(packetBuf.id, HEX); - } -#endif - // If length is zero (!) this will be the first byte of the - // checksum so record it - packetBuf.checksumA = incoming; - } else { - // The length is not zero so record this byte in the payload - packetBuf.payload[0] = incoming; - } - } else if (ubxFrameCounter == - 7) // This should be the second byte of the payload unless - // .len is zero or one - { - if (packetBuf.len == - 0) // Check if length is zero (hopefully this is impossible!) - { - // If length is zero (!) this will be the second byte of the - // checksum so record it - packetBuf.checksumB = incoming; - } else if (packetBuf.len == 1) // Check if length is one - { - // The length is one so this is the first byte of the checksum - packetBuf.checksumA = incoming; - } else // Length is >= 2 so this must be a payload byte - { - packetBuf.payload[1] = incoming; - } - // Now that we have received two payload bytes, we can check for a - // matching ACK/NACK - if ((activePacketBuffer == - SFE_UBLOX_PACKET_PACKETBUF) // If we are not already - // processing a data packet - && - (packetBuf.cls == UBX_CLASS_ACK) // and if this is an ACK/NACK - && (packetBuf.payload[0] == - requestedClass) // and if the class matches - && - (packetBuf.payload[1] == requestedID)) // and if the ID matches - { - if (packetBuf.len == 2) // Check if .len is 2 - { - // Then this is a matching ACK so copy it into packetAck - activePacketBuffer = SFE_UBLOX_PACKET_PACKETACK; - packetAck.cls = packetBuf.cls; - packetAck.id = packetBuf.id; - packetAck.len = packetBuf.len; - packetAck.counter = packetBuf.counter; - packetAck.payload[0] = packetBuf.payload[0]; - packetAck.payload[1] = packetBuf.payload[1]; - } else // Length is not 2 (hopefully this is impossible!) - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->print(F( - "process: ACK received with .len != 2: Class: 0x")); - _debugSerial->print(packetBuf.payload[0], HEX); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->print(packetBuf.payload[1], HEX); - _debugSerial->print(F(" len: ")); - _debugSerial->println(packetBuf.len); - } -#endif - } - } - } - - // Divert incoming into the correct buffer - if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETACK) - processUBX(incoming, &packetAck, requestedClass, requestedID); - else if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETCFG) - processUBX(incoming, incomingUBX, requestedClass, requestedID); - else if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETBUF) - processUBX(incoming, &packetBuf, requestedClass, requestedID); - else // if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETAUTO) - processUBX(incoming, &packetAuto, requestedClass, requestedID); - - // Finally, increment the frame counter - ubxFrameCounter++; - } else if (currentSentence == - SFE_UBLOX_SENTENCE_TYPE_NMEA) // Process incoming NMEA mesages. - // Selectively log if desired. - { - if ((nmeaByteCounter == 0) && (incoming != '$')) { - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Something went wrong. Reset. - // (Almost certainly redundant!) - } else if ((nmeaByteCounter == 1) && (incoming != 'G')) { - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Something went wrong. Reset. - } else if ((nmeaByteCounter >= 0) && (nmeaByteCounter <= 5)) { - nmeaAddressField[nmeaByteCounter] = - incoming; // Store the start character and NMEA address field - } - - if (nmeaByteCounter == 5) { - if (!_signsOfLife) // If _signsOfLife is not already true, set - // _signsOfLife to true if the NMEA header is - // valid - { - _signsOfLife = isNMEAHeaderValid(); - } - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - // Check if we have automatic storage for this message - if (isThisNMEAauto()) { - uint8_t *lengthPtr = - getNMEAWorkingLengthPtr(); // Get a pointer to the working - // copy length - uint8_t *nmeaPtr = - getNMEAWorkingNMEAPtr(); // Get a pointer to the working - // copy NMEA data - uint8_t nmeaMaxLength = getNMEAMaxLength(); - *lengthPtr = 6; // Set the working copy length - memset(nmeaPtr, 0, nmeaMaxLength); // Clear the working copy - memcpy(nmeaPtr, &nmeaAddressField[0], - 6); // Copy the start character and address field into - // the working copy - } else -#endif - { - // if ((_printDebug == true) || (_printLimitedDebug == true)) // - // This is important. Print this if doing limited debugging - // { - // _debugSerial->println(F("process: non-auto NMEA message")); - // } - } - - // We've just received the end of the address field. Check if it is - // selected for logging - if (logThisNMEA()) { - storeFileBytes(&nmeaAddressField[0], - 6); // Add start character and address field to - // the file buffer - } - // Check if it should be passed to processNMEA - if (processThisNMEA()) { - processNMEA( - nmeaAddressField[0]); // Process the start character and - // address field - processNMEA(nmeaAddressField[1]); - processNMEA(nmeaAddressField[2]); - processNMEA(nmeaAddressField[3]); - processNMEA(nmeaAddressField[4]); - processNMEA(nmeaAddressField[5]); - } - } - - if ((nmeaByteCounter > 5) || - (nmeaByteCounter < 0)) // Should we add incoming to the file buffer - // and/or pass it to processNMEA? - { -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - if (isThisNMEAauto()) { - uint8_t *lengthPtr = - getNMEAWorkingLengthPtr(); // Get a pointer to the working - // copy length - uint8_t *nmeaPtr = - getNMEAWorkingNMEAPtr(); // Get a pointer to the working - // copy NMEA data - uint8_t nmeaMaxLength = getNMEAMaxLength(); - if (*lengthPtr < nmeaMaxLength) { - *(nmeaPtr + *lengthPtr) = incoming; // Store the character - *lengthPtr = *lengthPtr + 1; // Increment the length - if (*lengthPtr == nmeaMaxLength) { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("process: NMEA buffer is full!")); - } - } - } - } -#endif - if (logThisNMEA()) - storeFileBytes(&incoming, - 1); // Add incoming to the file buffer - if (processThisNMEA()) - processNMEA(incoming); // Pass incoming to processNMEA - } - - if (incoming == '*') - nmeaByteCounter = -5; // We are expecting * plus two checksum bytes - // plus CR and LF - - nmeaByteCounter++; // Increment the byte counter - - if (nmeaByteCounter == - maxNMEAByteCount) // Check if we have processed too many bytes - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Something went wrong. Reset. - - if (nmeaByteCounter == 0) // Check if we are done - { -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - if (isThisNMEAauto()) { - uint8_t *workingLengthPtr = - getNMEAWorkingLengthPtr(); // Get a pointer to the working - // copy length - uint8_t *workingNMEAPtr = - getNMEAWorkingNMEAPtr(); // Get a pointer to the working - // copy NMEA data - uint8_t nmeaMaxLength = getNMEAMaxLength(); - - // Check the checksum: the checksum is the exclusive-OR of all - // characters between the $ and the * - uint8_t nmeaChecksum = 0; - uint8_t charsChecked = 1; // Start after the $ - uint8_t thisChar = '\0'; - while ((charsChecked < (nmeaMaxLength - 1)) && - (charsChecked < ((*workingLengthPtr) - 4)) && - (thisChar != '*')) { - thisChar = - *(workingNMEAPtr + - charsChecked); // Get a char from the working copy - if (thisChar != '*') // Ex-or the char into the checksum - - // but not if it is the '*' - nmeaChecksum ^= thisChar; - charsChecked++; // Increment the counter - } - if (thisChar == '*') // Make sure we found the * - { - uint8_t expectedChecksum1 = (nmeaChecksum >> 4) + '0'; - if (expectedChecksum1 >= ':') // Handle Hex correctly - expectedChecksum1 += 'A' - ':'; - uint8_t expectedChecksum2 = (nmeaChecksum & 0x0F) + '0'; - if (expectedChecksum2 >= ':') // Handle Hex correctly - expectedChecksum2 += 'A' - ':'; - if ((expectedChecksum1 == - *(workingNMEAPtr + charsChecked)) && - (expectedChecksum2 == - *(workingNMEAPtr + charsChecked + 1))) { - uint8_t *completeLengthPtr = - getNMEACompleteLengthPtr(); // Get a pointer to the - // complete copy length - uint8_t *completeNMEAPtr = - getNMEACompleteNMEAPtr(); // Get a pointer to the - // complete copy NMEA - // data - memset( - completeNMEAPtr, 0, - nmeaMaxLength); // Clear the previous complete copy - memcpy(completeNMEAPtr, workingNMEAPtr, - *workingLengthPtr); // Copy the working copy - // into the complete copy - *completeLengthPtr = - *workingLengthPtr; // Update the length - nmeaAutomaticFlags *flagsPtr = - getNMEAFlagsPtr(); // Get a pointer to the flags - nmeaAutomaticFlags flagsCopy = *flagsPtr; - flagsCopy.flags.bits.completeCopyValid = - 1; // Set the complete copy valid flag - flagsCopy.flags.bits.completeCopyRead = - 0; // Clear the complete copy read flag - *flagsPtr = flagsCopy; // Update the flags - // Callback - if (doesThisNMEAHaveCallback()) // Do we need to copy - // the data into the - // callback copy? - { - if (flagsCopy.flags.bits.callbackCopyValid == - 0) // Has the callback copy valid flag been - // cleared (by checkCallbacks) - { - uint8_t *callbackLengthPtr = - getNMEACallbackLengthPtr(); // Get a - // pointer to - // the callback - // copy length - uint8_t *callbackNMEAPtr = - getNMEACallbackNMEAPtr(); // Get a pointer - // to the - // callback copy - // NMEA data - memset(callbackNMEAPtr, 0, - nmeaMaxLength); // Clear the previous - // callback copy - memcpy(callbackNMEAPtr, workingNMEAPtr, - *workingLengthPtr); // Copy the working - // copy into the - // callback copy - *callbackLengthPtr = - *workingLengthPtr; // Update the length - flagsCopy.flags.bits.callbackCopyValid = - 1; // Set the callback copy valid flag - *flagsPtr = flagsCopy; // Update the flags - } - } - } else { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->print(F( - "process: NMEA checksum fail (2)! Expected ")); - _debugSerial->write(expectedChecksum1); - _debugSerial->write(expectedChecksum2); - _debugSerial->print(F(" Got ")); - _debugSerial->write( - *(workingNMEAPtr + charsChecked)); - _debugSerial->write( - *(workingNMEAPtr + charsChecked + 1)); - _debugSerial->println(); - } - } - } else { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("process: NMEA checksum fail (1)!")); - } - } - } -#endif - currentSentence = SFE_UBLOX_SENTENCE_TYPE_NONE; // All done! - } - } else if (currentSentence == SFE_UBLOX_SENTENCE_TYPE_RTCM) { - currentSentence = processRTCMframe( - incoming, &rtcmFrameCounter); // Deal with RTCM bytes - } -} - -// PRIVATE: Return true if we should add this NMEA message to the file buffer -// for logging -bool SFE_UBLOX_GNSS::logThisNMEA() { - if (_logNMEA.bits.all == 1) return (true); - if ((nmeaAddressField[3] == 'D') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'M') && (_logNMEA.bits.UBX_NMEA_DTM == 1)) - return (true); - if (nmeaAddressField[3] == 'G') { - if ((nmeaAddressField[4] == 'A') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GAQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GBQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'S') && - (_logNMEA.bits.UBX_NMEA_GBS == 1)) - return (true); - if ((nmeaAddressField[4] == 'G') && (nmeaAddressField[5] == 'A') && - (_logNMEA.bits.UBX_NMEA_GGA == 1)) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'L') && - (_logNMEA.bits.UBX_NMEA_GLL == 1)) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GLQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GNQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'S') && - (_logNMEA.bits.UBX_NMEA_GNS == 1)) - return (true); - if ((nmeaAddressField[4] == 'P') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GPQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'Q') && (nmeaAddressField[5] == 'Q') && - (_logNMEA.bits.UBX_NMEA_GQQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'R') && (nmeaAddressField[5] == 'S') && - (_logNMEA.bits.UBX_NMEA_GRS == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'A') && - (_logNMEA.bits.UBX_NMEA_GSA == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'T') && - (_logNMEA.bits.UBX_NMEA_GST == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'V') && - (_logNMEA.bits.UBX_NMEA_GSV == 1)) - return (true); - } - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'M') && (_logNMEA.bits.UBX_NMEA_RLM == 1)) - return (true); - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && - (nmeaAddressField[5] == 'C') && (_logNMEA.bits.UBX_NMEA_RMC == 1)) - return (true); - if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && - (nmeaAddressField[5] == 'T') && (_logNMEA.bits.UBX_NMEA_TXT == 1)) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'W') && (_logNMEA.bits.UBX_NMEA_VLW == 1)) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'G') && (_logNMEA.bits.UBX_NMEA_VTG == 1)) - return (true); - if ((nmeaAddressField[3] == 'Z') && (nmeaAddressField[4] == 'D') && - (nmeaAddressField[5] == 'A') && (_logNMEA.bits.UBX_NMEA_ZDA == 1)) - return (true); - return (false); -} - -// PRIVATE: Return true if the NMEA header is valid -bool SFE_UBLOX_GNSS::isNMEAHeaderValid() { - if (nmeaAddressField[0] != '*') return (false); - if (nmeaAddressField[1] != 'G') return (false); - if ((nmeaAddressField[3] == 'D') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'M')) - return (true); - if (nmeaAddressField[3] == 'G') { - if ((nmeaAddressField[4] == 'A') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'S')) - return (true); - if ((nmeaAddressField[4] == 'G') && (nmeaAddressField[5] == 'A')) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'L')) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'S')) - return (true); - if ((nmeaAddressField[4] == 'P') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'Q') && (nmeaAddressField[5] == 'Q')) - return (true); - if ((nmeaAddressField[4] == 'R') && (nmeaAddressField[5] == 'S')) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'A')) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'T')) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'V')) - return (true); - } - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'M')) - return (true); - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && - (nmeaAddressField[5] == 'C')) - return (true); - if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && - (nmeaAddressField[5] == 'T')) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'W')) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'G')) - return (true); - if ((nmeaAddressField[3] == 'Z') && (nmeaAddressField[4] == 'D') && - (nmeaAddressField[5] == 'A')) - return (true); - return (false); -} - -// PRIVATE: Return true if we should pass this NMEA message to processNMEA -bool SFE_UBLOX_GNSS::processThisNMEA() { - if (_processNMEA.bits.all == 1) return (true); - if ((nmeaAddressField[3] == 'D') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'M') && (_processNMEA.bits.UBX_NMEA_DTM == 1)) - return (true); - if (nmeaAddressField[3] == 'G') { - if ((nmeaAddressField[4] == 'A') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GAQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GBQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'S') && - (_processNMEA.bits.UBX_NMEA_GBS == 1)) - return (true); - if ((nmeaAddressField[4] == 'G') && (nmeaAddressField[5] == 'A') && - (_processNMEA.bits.UBX_NMEA_GGA == 1)) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'L') && - (_processNMEA.bits.UBX_NMEA_GLL == 1)) - return (true); - if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GLQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GNQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'S') && - (_processNMEA.bits.UBX_NMEA_GNS == 1)) - return (true); - if ((nmeaAddressField[4] == 'P') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GPQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'Q') && (nmeaAddressField[5] == 'Q') && - (_processNMEA.bits.UBX_NMEA_GQQ == 1)) - return (true); - if ((nmeaAddressField[4] == 'R') && (nmeaAddressField[5] == 'S') && - (_processNMEA.bits.UBX_NMEA_GRS == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'A') && - (_processNMEA.bits.UBX_NMEA_GSA == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'T') && - (_processNMEA.bits.UBX_NMEA_GST == 1)) - return (true); - if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'V') && - (_processNMEA.bits.UBX_NMEA_GSV == 1)) - return (true); - } - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'M') && (_processNMEA.bits.UBX_NMEA_RLM == 1)) - return (true); - if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && - (nmeaAddressField[5] == 'C') && (_processNMEA.bits.UBX_NMEA_RMC == 1)) - return (true); - if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && - (nmeaAddressField[5] == 'T') && (_processNMEA.bits.UBX_NMEA_TXT == 1)) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && - (nmeaAddressField[5] == 'W') && (_processNMEA.bits.UBX_NMEA_VLW == 1)) - return (true); - if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'T') && - (nmeaAddressField[5] == 'G') && (_processNMEA.bits.UBX_NMEA_VTG == 1)) - return (true); - if ((nmeaAddressField[3] == 'Z') && (nmeaAddressField[4] == 'D') && - (nmeaAddressField[5] == 'A') && (_processNMEA.bits.UBX_NMEA_ZDA == 1)) - return (true); - return (false); -} - -// This is the default or generic NMEA processor. We're only going to pipe the -// data to serial port so we can see it. User could overwrite this function to -// pipe characters to nmea.process(c) of tinyGPS or MicroNMEA Or user could pipe -// each character to a buffer, radio, etc. -void SFE_UBLOX_GNSS::processNMEA_v(char incoming) { - // If user has assigned an output port then pipe the characters there - if (_nmeaOutputPort != NULL) - _nmeaOutputPort->write(incoming); // Echo this byte to the serial port -} - -void SFE_UBLOX_GNSS::processNMEA(char incoming) { processNMEA_v(incoming); } - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA -// Check if the NMEA message (in nmeaAddressField) is "auto" (i.e. has RAM -// allocated for it) -bool SFE_UBLOX_GNSS::isThisNMEAauto() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPGGA != NULL) return true; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNGGA != NULL) return true; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPVTG != NULL) return true; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNVTG != NULL) return true; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPRMC != NULL) return true; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNRMC != NULL) return true; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPZDA != NULL) return true; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNZDA != NULL) return true; - } - - return false; -} - -// Do we need to copy the data into the callback copy? -bool SFE_UBLOX_GNSS::doesThisNMEAHaveCallback() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPGGA != NULL) - if (storageNMEAGPGGA->callbackCopy != NULL) - if ((storageNMEAGPGGA->callbackPointer != NULL) || - (storageNMEAGPGGA->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNGGA != NULL) - if (storageNMEAGNGGA->callbackCopy != NULL) - if ((storageNMEAGNGGA->callbackPointer != NULL) || - (storageNMEAGNGGA->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPVTG != NULL) - if (storageNMEAGPVTG->callbackCopy != NULL) - if ((storageNMEAGPVTG->callbackPointer != NULL) || - (storageNMEAGPVTG->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNVTG != NULL) - if (storageNMEAGNVTG->callbackCopy != NULL) - if ((storageNMEAGNVTG->callbackPointer != NULL) || - (storageNMEAGNVTG->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPRMC != NULL) - if (storageNMEAGPRMC->callbackCopy != NULL) - if ((storageNMEAGPRMC->callbackPointer != NULL) || - (storageNMEAGPRMC->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNRMC != NULL) - if (storageNMEAGNRMC->callbackCopy != NULL) - if ((storageNMEAGNRMC->callbackPointer != NULL) || - (storageNMEAGNRMC->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGPZDA != NULL) - if (storageNMEAGPZDA->callbackCopy != NULL) - if ((storageNMEAGPZDA->callbackPointer != NULL) || - (storageNMEAGPZDA->callbackPointerPtr != NULL)) - return true; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - if (storageNMEAGNZDA != NULL) - if (storageNMEAGNZDA->callbackCopy != NULL) - if ((storageNMEAGNZDA->callbackPointer != NULL) || - (storageNMEAGNZDA->callbackPointerPtr != NULL)) - return true; - } - - return false; -} - -// Get a pointer to the working copy length -uint8_t *SFE_UBLOX_GNSS::getNMEAWorkingLengthPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->workingCopy.length; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->workingCopy.length; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->workingCopy.length; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->workingCopy.length; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->workingCopy.length; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->workingCopy.length; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->workingCopy.length; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->workingCopy.length; - } - - return NULL; -} - -// Get a pointer to the working copy NMEA data -uint8_t *SFE_UBLOX_GNSS::getNMEAWorkingNMEAPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->workingCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->workingCopy.nmea[0]; - } - - return NULL; -} - -// Get a pointer to the complete copy length -uint8_t *SFE_UBLOX_GNSS::getNMEACompleteLengthPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->completeCopy.length; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->completeCopy.length; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->completeCopy.length; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->completeCopy.length; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->completeCopy.length; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->completeCopy.length; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->completeCopy.length; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->completeCopy.length; - } - - return NULL; -} - -// Get a pointer to the complete copy NMEA data -uint8_t *SFE_UBLOX_GNSS::getNMEACompleteNMEAPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->completeCopy.nmea[0]; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->completeCopy.nmea[0]; - } - - return NULL; -} - -// Get a pointer to the callback copy length -uint8_t *SFE_UBLOX_GNSS::getNMEACallbackLengthPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->callbackCopy->length; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->callbackCopy->length; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->callbackCopy->length; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->callbackCopy->length; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->callbackCopy->length; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->callbackCopy->length; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->callbackCopy->length; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->callbackCopy->length; - } - - return NULL; -} - -// Get a pointer to the callback copy NMEA data -uint8_t *SFE_UBLOX_GNSS::getNMEACallbackNMEAPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->callbackCopy->nmea[0]; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->callbackCopy->nmea[0]; - } - - return NULL; -} - -// Get the maximum length of this NMEA message -uint8_t SFE_UBLOX_GNSS::getNMEAMaxLength() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_GGA_MAX_LENGTH; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_GGA_MAX_LENGTH; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_VTG_MAX_LENGTH; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_VTG_MAX_LENGTH; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_RMC_MAX_LENGTH; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_RMC_MAX_LENGTH; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_ZDA_MAX_LENGTH; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return NMEA_ZDA_MAX_LENGTH; - } - - return 0; -} - -// Get a pointer to the automatic NMEA flags -nmeaAutomaticFlags *SFE_UBLOX_GNSS::getNMEAFlagsPtr() { - char thisNMEA[] = "GPGGA"; - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPGGA->automaticFlags; - } - - strcpy(thisNMEA, "GNGGA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNGGA->automaticFlags; - } - - strcpy(thisNMEA, "GPVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPVTG->automaticFlags; - } - - strcpy(thisNMEA, "GNVTG"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNVTG->automaticFlags; - } - - strcpy(thisNMEA, "GPRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPRMC->automaticFlags; - } - - strcpy(thisNMEA, "GNRMC"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNRMC->automaticFlags; - } - - strcpy(thisNMEA, "GPZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGPZDA->automaticFlags; - } - - strcpy(thisNMEA, "GNZDA"); - if (memcmp(thisNMEA, &nmeaAddressField[1], 5) == 0) { - return &storageNMEAGNZDA->automaticFlags; - } - - return NULL; -} -#endif - -// We need to be able to identify an RTCM packet and then the length -// so that we know when the RTCM message is completely received and we then -// start listening for other sentences (like NMEA or UBX) RTCM packet structure -// is very odd. I never found RTCM STANDARD 10403.2 but -// http://d1.amobbs.com/bbs_upload782111/files_39/ourdev_635123CK0HJT.pdf is -// good -// https://dspace.cvut.cz/bitstream/handle/10467/65205/F3-BP-2016-Shkalikava-Anastasiya-Prenos%20polohove%20informace%20prostrednictvim%20datove%20site.pdf?sequence=-1 -// Lead me to: -// https://forum.u-blox.com/index.php/4348/how-to-read-rtcm-messages-from-neo-m8p -// RTCM 3.2 bytes look like this: -// Byte 0: Always 0xD3 -// Byte 1: 6-bits of zero -// Byte 2: 10-bits of length of this packet including the first two-ish header -// bytes, + 6. byte 3 + 4 bits: Msg type 12 bits Example: D3 00 7C 43 F0 ... / -// 0x7C = 124+6 = 130 bytes in this packet, 0x43F = Msg type 1087 -SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe_v( - uint8_t incoming, uint16_t *rtcmFrameCounter) { - static uint16_t rtcmLen = 0; - - if (*rtcmFrameCounter == 1) { - rtcmLen = (incoming & 0x03) << 8; // Get the last two bits of this - // byte. Bits 8&9 of 10-bit length - } else if (*rtcmFrameCounter == 2) { - rtcmLen |= incoming; // Bits 0-7 of packet length - rtcmLen += 6; // There are 6 additional bytes of what we presume is - // header, msgType, CRC, and stuff - } - /*else if (rtcmFrameCounter == 3) - { - rtcmMsgType = incoming << 4; //Message Type, MS 4 bits - } - else if (rtcmFrameCounter == 4) - { - rtcmMsgType |= (incoming >> 4); //Message Type, bits 0-7 - }*/ - - *rtcmFrameCounter = *rtcmFrameCounter + 1; - - processRTCM(incoming); // Here is where we expose this byte to the user - - // Reset and start looking for next sentence type when done - return (*rtcmFrameCounter == rtcmLen) ? SFE_UBLOX_SENTENCE_TYPE_NONE - : SFE_UBLOX_SENTENCE_TYPE_RTCM; -} - -SFE_UBLOX_GNSS::sfe_ublox_sentence_types_e SFE_UBLOX_GNSS::processRTCMframe( - uint8_t incoming, uint16_t *rtcmFrameCounter) { - return processRTCMframe_v(incoming, rtcmFrameCounter); -} - -// This function is called for each byte of an RTCM frame -// Ths user can overwrite this function and process the RTCM frame as they -// please Bytes can be piped to Serial or other interface. The consumer could be -// a radio or the internet (Ntrip broadcaster) -void SFE_UBLOX_GNSS::processRTCM_v(uint8_t incoming) { - // Radio.sendReliable((String)incoming); //An example of passing this byte - // to a radio - - //_debugSerial->write(incoming); //An example of passing this byte out the - // serial port - - // Debug printing - // _debugSerial->print(F(" ")); - // if(incoming < 0x10) _debugSerial->print(F("0")); - // _debugSerial->print(incoming, HEX); - // if(rtcmFrameCounter % 16 == 0) _debugSerial->println(); - - (void)incoming; // Do something with incoming just to get rid of the pesky - // compiler warning! -} - -void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming) { processRTCM_v(incoming); } - -// Given a character, file it away into the uxb packet structure -// Set valid to VALID or NOT_VALID once sentence is completely received and -// passes or fails CRC The payload portion of the packet can be 100s of bytes -// but the max array size is packetCfgPayloadSize bytes. startingSpot can be set -// so we only record a subset of bytes within a larger packet. -void SFE_UBLOX_GNSS::processUBX(uint8_t incoming, ubxPacket *incomingUBX, - uint8_t requestedClass, uint8_t requestedID) { - // If incomingUBX is a user-defined custom packet, then the payload size - // could be different to packetCfgPayloadSize. TO DO: update this to prevent - // an overrun when receiving an automatic message - // and the incomingUBX payload size is smaller than - // packetCfgPayloadSize. - uint16_t maximum_payload_size; - if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETCFG) - maximum_payload_size = packetCfgPayloadSize; - else if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETAUTO) { - // Calculate maximum payload size once Class and ID have been received - // (This check is probably redundant as activePacketBuffer can only be - // SFE_UBLOX_PACKET_PACKETAUTO - // when ubxFrameCounter >= 3) - // if (incomingUBX->counter >= 2) - //{ - maximum_payload_size = - getMaxPayloadSize(incomingUBX->cls, incomingUBX->id); - if (maximum_payload_size == 0) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - _debugSerial->print(F( - "processUBX: getMaxPayloadSize returned ZERO!! Class: 0x")); - _debugSerial->print(incomingUBX->cls); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(incomingUBX->id); - } -#endif - } - //} - // else - // maximum_payload_size = 2; - } else - maximum_payload_size = 2; - - bool overrun = false; - - // Add all incoming bytes to the rolling checksum - // Stop at len+4 as this is the checksum bytes to that should not be added - // to the rolling checksum - if (incomingUBX->counter < incomingUBX->len + 4) addToChecksum(incoming); - - if (incomingUBX->counter == 0) { - incomingUBX->cls = incoming; - } else if (incomingUBX->counter == 1) { - incomingUBX->id = incoming; - } else if (incomingUBX->counter == 2) // Len LSB - { - incomingUBX->len = incoming; - } else if (incomingUBX->counter == 3) // Len MSB - { - incomingUBX->len |= incoming << 8; - } else if (incomingUBX->counter == incomingUBX->len + 4) // ChecksumA - { - incomingUBX->checksumA = incoming; - } else if (incomingUBX->counter == incomingUBX->len + 5) // ChecksumB - { - incomingUBX->checksumB = incoming; - - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // We're done! Reset the sentence to - // being looking for a new start char - - // Validate this sentence - if ((incomingUBX->checksumA == rollingChecksumA) && - (incomingUBX->checksumB == rollingChecksumB)) { - incomingUBX->valid = - SFE_UBLOX_PACKET_VALIDITY_VALID; // Flag the packet as valid - _signsOfLife = - true; // The checksum is valid, so set the _signsOfLife flag - - // Let's check if the class and ID match the requestedClass and - // requestedID Remember - this could be a data packet or an ACK - // packet - if ((incomingUBX->cls == requestedClass) && - (incomingUBX->id == requestedID)) { - incomingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_VALID; // If we have a match, set - // the classAndIDmatch - // flag to valid - } - - // If this is an ACK then let's check if the class and ID match the - // requestedClass and requestedID - else if ((incomingUBX->cls == UBX_CLASS_ACK) && - (incomingUBX->id == UBX_ACK_ACK) && - (incomingUBX->payload[0] == requestedClass) && - (incomingUBX->payload[1] == requestedID)) { - incomingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_VALID; // If we have a match, set - // the classAndIDmatch - // flag to valid - } - - // If this is a NACK then let's check if the class and ID match the - // requestedClass and requestedID - else if ((incomingUBX->cls == UBX_CLASS_ACK) && - (incomingUBX->id == UBX_ACK_NACK) && - (incomingUBX->payload[0] == requestedClass) && - (incomingUBX->payload[1] == requestedID)) { - incomingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_NOTACKNOWLEDGED; // If we have a match, - // set the - // classAndIDmatch flag - // to NOTACKNOWLEDGED -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("processUBX: NACK received: Requested Class: 0x")); - _debugSerial->print(incomingUBX->payload[0], HEX); - _debugSerial->print(F(" Requested ID: 0x")); - _debugSerial->println(incomingUBX->payload[1], HEX); - } -#endif - } - - // This is not an ACK and we do not have a complete class and ID - // match So let's check for an "automatic" message arriving - else if (checkAutomatic(incomingUBX->cls, incomingUBX->id)) { - // This isn't the message we are looking for... - // Let's say so and leave incomingUBX->classAndIDmatch - // _unchanged_ -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("processUBX: incoming \"automatic\" message: Class: " - "0x")); - _debugSerial->print(incomingUBX->cls, HEX); - _debugSerial->print(F(" ID: 0x")); - _debugSerial->println(incomingUBX->id, HEX); - } -#endif - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("Incoming: Size: ")); - _debugSerial->print(incomingUBX->len); - _debugSerial->print(F(" Received: ")); - printPacket(incomingUBX); - - if (incomingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID) { - _debugSerial->println(F("packetCfg now valid")); - } - if (packetAck.valid == SFE_UBLOX_PACKET_VALIDITY_VALID) { - _debugSerial->println(F("packetAck now valid")); - } - if (incomingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) { - _debugSerial->println(F("packetCfg classAndIDmatch")); - } - if (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) { - _debugSerial->println(F("packetAck classAndIDmatch")); - } - } -#endif - - // We've got a valid packet, now do something with it but only if - // ignoreThisPayload is false - if (ignoreThisPayload == false) { - processUBXpacket(incomingUBX); - } - } else // Checksum failure - { - incomingUBX->valid = SFE_UBLOX_PACKET_VALIDITY_NOT_VALID; - - // Let's check if the class and ID match the requestedClass and - // requestedID. This is potentially risky as we are saying that we - // saw the requested Class and ID but that the packet checksum - // failed. Potentially it could be the class or ID bytes that caused - // the checksum error! - if ((incomingUBX->cls == requestedClass) && - (incomingUBX->id == requestedID)) { - incomingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID; // If we have a match, - // set the - // classAndIDmatch - // flag to not valid - } - // If this is an ACK then let's check if the class and ID match the - // requestedClass and requestedID - else if ((incomingUBX->cls == UBX_CLASS_ACK) && - (incomingUBX->payload[0] == requestedClass) && - (incomingUBX->payload[1] == requestedID)) { - incomingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID; // If we have a match, - // set the - // classAndIDmatch - // flag to not valid - } - - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - // Drive an external pin to allow for easier logic analyzation - if (debugPin >= 0) { - digitalWrite((uint8_t)debugPin, LOW); - delay(10); - digitalWrite((uint8_t)debugPin, HIGH); - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - _debugSerial->print(F("Checksum failed:")); - _debugSerial->print(F(" checksumA: ")); - _debugSerial->print(incomingUBX->checksumA); - _debugSerial->print(F(" checksumB: ")); - _debugSerial->print(incomingUBX->checksumB); - - _debugSerial->print(F(" rollingChecksumA: ")); - _debugSerial->print(rollingChecksumA); - _debugSerial->print(F(" rollingChecksumB: ")); - _debugSerial->print(rollingChecksumB); - _debugSerial->println(); -#endif - } - } - - // Now that the packet is complete and has been processed, we need to - // delete the memory allocated for packetAuto - if (activePacketBuffer == SFE_UBLOX_PACKET_PACKETAUTO) { - delete[] payloadAuto; // Created with new[] - payloadAuto = NULL; // Redundant? - packetAuto.payload = payloadAuto; - } - } else // Load this byte into the payload array - { - // If an automatic packet comes in asynchronously, we need to fudge the - // startingSpot - uint16_t startingSpot = incomingUBX->startingSpot; - if (checkAutomatic(incomingUBX->cls, incomingUBX->id)) startingSpot = 0; - // Check if this is payload data which should be ignored - if (ignoreThisPayload == false) { - // Begin recording if counter goes past startingSpot - if ((incomingUBX->counter - 4) >= startingSpot) { - // Check to see if we have room for this byte - if (((incomingUBX->counter - 4) - startingSpot) < - maximum_payload_size) // If counter = 208, starting spot = - // 200, we're good to record. - { - incomingUBX - ->payload[(incomingUBX->counter - 4) - startingSpot] = - incoming; // Store this byte into payload array - } else { - overrun = true; - } - } - } - } - - // incomingUBX->counter should never reach maximum_payload_size + class + id - // + len[2] + checksum[2] - if (overrun || ((incomingUBX->counter == maximum_payload_size + 6) && - (ignoreThisPayload == false))) { - // Something has gone very wrong - currentSentence = - SFE_UBLOX_SENTENCE_TYPE_NONE; // Reset the sentence to being - // looking for a new start char -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - if (overrun) - _debugSerial->print(F("processUBX: buffer overrun detected!")); - else - _debugSerial->print( - F("processUBX: counter hit maximum_payload_size + 6!")); - _debugSerial->print(F(" activePacketBuffer: ")); - _debugSerial->print(activePacketBuffer); - _debugSerial->print(F(" maximum_payload_size: ")); - _debugSerial->println(maximum_payload_size); - } -#endif - } - - // Increment the counter - incomingUBX->counter++; -} - -// Once a packet has been received and validated, identify this packet's -// class/id and update internal flags -void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg) { - switch (msg->cls) { - case UBX_CLASS_NAV: - if (msg->id == UBX_NAV_POSECEF && msg->len == UBX_NAV_POSECEF_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVPOSECEF != NULL) { - packetUBXNAVPOSECEF->data.iTOW = extractLong(msg, 0); - packetUBXNAVPOSECEF->data.ecefX = extractSignedLong(msg, 4); - packetUBXNAVPOSECEF->data.ecefY = extractSignedLong(msg, 8); - packetUBXNAVPOSECEF->data.ecefZ = - extractSignedLong(msg, 12); - packetUBXNAVPOSECEF->data.pAcc = extractLong(msg, 16); - - // Mark all datums as fresh (not read before) - packetUBXNAVPOSECEF->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVPOSECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVPOSECEF->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVPOSECEF->callbackData->iTOW, - &packetUBXNAVPOSECEF->data.iTOW, - sizeof(UBX_NAV_POSECEF_data_t)); - packetUBXNAVPOSECEF->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVPOSECEF->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_STATUS && - msg->len == UBX_NAV_STATUS_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVSTATUS != NULL) { - packetUBXNAVSTATUS->data.iTOW = extractLong(msg, 0); - packetUBXNAVSTATUS->data.gpsFix = extractByte(msg, 4); - packetUBXNAVSTATUS->data.flags.all = extractByte(msg, 5); - packetUBXNAVSTATUS->data.fixStat.all = extractByte(msg, 6); - packetUBXNAVSTATUS->data.flags2.all = extractByte(msg, 7); - packetUBXNAVSTATUS->data.ttff = extractLong(msg, 8); - packetUBXNAVSTATUS->data.msss = extractLong(msg, 12); - - // Mark all datums as fresh (not read before) - packetUBXNAVSTATUS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVSTATUS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVSTATUS->callbackData->iTOW, - &packetUBXNAVSTATUS->data.iTOW, - sizeof(UBX_NAV_STATUS_data_t)); - packetUBXNAVSTATUS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVSTATUS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_DOP && msg->len == UBX_NAV_DOP_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVDOP != NULL) { - packetUBXNAVDOP->data.iTOW = extractLong(msg, 0); - packetUBXNAVDOP->data.gDOP = extractInt(msg, 4); - packetUBXNAVDOP->data.pDOP = extractInt(msg, 6); - packetUBXNAVDOP->data.tDOP = extractInt(msg, 8); - packetUBXNAVDOP->data.vDOP = extractInt(msg, 10); - packetUBXNAVDOP->data.hDOP = extractInt(msg, 12); - packetUBXNAVDOP->data.nDOP = extractInt(msg, 14); - packetUBXNAVDOP->data.eDOP = extractInt(msg, 16); - - // Mark all datums as fresh (not read before) - packetUBXNAVDOP->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVDOP->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVDOP->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVDOP->callbackData->iTOW, - &packetUBXNAVDOP->data.iTOW, - sizeof(UBX_NAV_DOP_data_t)); - packetUBXNAVDOP->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVDOP->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_ATT && msg->len == UBX_NAV_ATT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVATT != NULL) { - packetUBXNAVATT->data.iTOW = extractLong(msg, 0); - packetUBXNAVATT->data.version = extractByte(msg, 4); - packetUBXNAVATT->data.roll = extractSignedLong(msg, 8); - packetUBXNAVATT->data.pitch = extractSignedLong(msg, 12); - packetUBXNAVATT->data.heading = extractSignedLong(msg, 16); - packetUBXNAVATT->data.accRoll = extractLong(msg, 20); - packetUBXNAVATT->data.accPitch = extractLong(msg, 24); - packetUBXNAVATT->data.accHeading = extractLong(msg, 28); - - // Mark all datums as fresh (not read before) - packetUBXNAVATT->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVATT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVATT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVATT->callbackData->iTOW, - &packetUBXNAVATT->data.iTOW, - sizeof(UBX_NAV_ATT_data_t)); - packetUBXNAVATT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVATT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_PVT && msg->len == UBX_NAV_PVT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVPVT != NULL) { - packetUBXNAVPVT->data.iTOW = extractLong(msg, 0); - packetUBXNAVPVT->data.year = extractInt(msg, 4); - packetUBXNAVPVT->data.month = extractByte(msg, 6); - packetUBXNAVPVT->data.day = extractByte(msg, 7); - packetUBXNAVPVT->data.hour = extractByte(msg, 8); - packetUBXNAVPVT->data.min = extractByte(msg, 9); - packetUBXNAVPVT->data.sec = extractByte(msg, 10); - packetUBXNAVPVT->data.valid.all = extractByte(msg, 11); - packetUBXNAVPVT->data.tAcc = extractLong(msg, 12); - packetUBXNAVPVT->data.nano = - extractSignedLong(msg, 16); // Includes milliseconds - packetUBXNAVPVT->data.fixType = extractByte(msg, 20); - packetUBXNAVPVT->data.flags.all = extractByte(msg, 21); - packetUBXNAVPVT->data.flags2.all = extractByte(msg, 22); - packetUBXNAVPVT->data.numSV = extractByte(msg, 23); - packetUBXNAVPVT->data.lon = extractSignedLong(msg, 24); - packetUBXNAVPVT->data.lat = extractSignedLong(msg, 28); - packetUBXNAVPVT->data.height = extractSignedLong(msg, 32); - packetUBXNAVPVT->data.hMSL = extractSignedLong(msg, 36); - packetUBXNAVPVT->data.hAcc = extractLong(msg, 40); - packetUBXNAVPVT->data.vAcc = extractLong(msg, 44); - packetUBXNAVPVT->data.velN = extractSignedLong(msg, 48); - packetUBXNAVPVT->data.velE = extractSignedLong(msg, 52); - packetUBXNAVPVT->data.velD = extractSignedLong(msg, 56); - packetUBXNAVPVT->data.gSpeed = extractSignedLong(msg, 60); - packetUBXNAVPVT->data.headMot = extractSignedLong(msg, 64); - packetUBXNAVPVT->data.sAcc = extractLong(msg, 68); - packetUBXNAVPVT->data.headAcc = extractLong(msg, 72); - packetUBXNAVPVT->data.pDOP = extractInt(msg, 76); - packetUBXNAVPVT->data.flags3.all = extractByte(msg, 78); - packetUBXNAVPVT->data.headVeh = extractSignedLong(msg, 84); - packetUBXNAVPVT->data.magDec = extractSignedInt(msg, 88); - packetUBXNAVPVT->data.magAcc = extractInt(msg, 90); - - // Mark all datums as fresh (not read before) - packetUBXNAVPVT->moduleQueried.moduleQueried1.all = - 0xFFFFFFFF; - packetUBXNAVPVT->moduleQueried.moduleQueried2.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVPVT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVPVT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVPVT->callbackData->iTOW, - &packetUBXNAVPVT->data.iTOW, - sizeof(UBX_NAV_PVT_data_t)); - packetUBXNAVPVT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVPVT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_ODO && msg->len == UBX_NAV_ODO_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVODO != NULL) { - packetUBXNAVODO->data.version = extractByte(msg, 0); - packetUBXNAVODO->data.iTOW = extractLong(msg, 4); - packetUBXNAVODO->data.distance = extractLong(msg, 8); - packetUBXNAVODO->data.totalDistance = extractLong(msg, 12); - packetUBXNAVODO->data.distanceStd = extractLong(msg, 16); - - // Mark all datums as fresh (not read before) - packetUBXNAVODO->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVODO->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVODO->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVODO->callbackData->version, - &packetUBXNAVODO->data.version, - sizeof(UBX_NAV_ODO_data_t)); - packetUBXNAVODO->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVODO->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_VELECEF && - msg->len == UBX_NAV_VELECEF_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVVELECEF != NULL) { - packetUBXNAVVELECEF->data.iTOW = extractLong(msg, 0); - packetUBXNAVVELECEF->data.ecefVX = - extractSignedLong(msg, 4); - packetUBXNAVVELECEF->data.ecefVY = - extractSignedLong(msg, 8); - packetUBXNAVVELECEF->data.ecefVZ = - extractSignedLong(msg, 12); - packetUBXNAVVELECEF->data.sAcc = extractLong(msg, 16); - - // Mark all datums as fresh (not read before) - packetUBXNAVVELECEF->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVVELECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVVELECEF->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVVELECEF->callbackData->iTOW, - &packetUBXNAVVELECEF->data.iTOW, - sizeof(UBX_NAV_VELECEF_data_t)); - packetUBXNAVVELECEF->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVVELECEF->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_VELNED && - msg->len == UBX_NAV_VELNED_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVVELNED != NULL) { - packetUBXNAVVELNED->data.iTOW = extractLong(msg, 0); - packetUBXNAVVELNED->data.velN = extractSignedLong(msg, 4); - packetUBXNAVVELNED->data.velE = extractSignedLong(msg, 8); - packetUBXNAVVELNED->data.velD = extractSignedLong(msg, 12); - packetUBXNAVVELNED->data.speed = extractLong(msg, 16); - packetUBXNAVVELNED->data.gSpeed = extractLong(msg, 20); - packetUBXNAVVELNED->data.heading = - extractSignedLong(msg, 24); - packetUBXNAVVELNED->data.sAcc = extractLong(msg, 28); - packetUBXNAVVELNED->data.cAcc = extractLong(msg, 32); - - // Mark all datums as fresh (not read before) - packetUBXNAVVELNED->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVVELNED->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVVELNED->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVVELNED->callbackData->iTOW, - &packetUBXNAVVELNED->data.iTOW, - sizeof(UBX_NAV_VELNED_data_t)); - packetUBXNAVVELNED->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVVELNED->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_HPPOSECEF && - msg->len == UBX_NAV_HPPOSECEF_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVHPPOSECEF != NULL) { - packetUBXNAVHPPOSECEF->data.version = extractByte(msg, 0); - packetUBXNAVHPPOSECEF->data.iTOW = extractLong(msg, 4); - packetUBXNAVHPPOSECEF->data.ecefX = - extractSignedLong(msg, 8); - packetUBXNAVHPPOSECEF->data.ecefY = - extractSignedLong(msg, 12); - packetUBXNAVHPPOSECEF->data.ecefZ = - extractSignedLong(msg, 16); - packetUBXNAVHPPOSECEF->data.ecefXHp = - extractSignedChar(msg, 20); - packetUBXNAVHPPOSECEF->data.ecefYHp = - extractSignedChar(msg, 21); - packetUBXNAVHPPOSECEF->data.ecefZHp = - extractSignedChar(msg, 22); - packetUBXNAVHPPOSECEF->data.flags.all = - extractByte(msg, 23); - packetUBXNAVHPPOSECEF->data.pAcc = extractLong(msg, 24); - - // Mark all datums as fresh (not read before) - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVHPPOSECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVHPPOSECEF->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVHPPOSECEF->callbackData->version, - &packetUBXNAVHPPOSECEF->data.version, - sizeof(UBX_NAV_HPPOSECEF_data_t)); - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVHPPOSECEF->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_HPPOSLLH && - msg->len == UBX_NAV_HPPOSLLH_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVHPPOSLLH != NULL) { - packetUBXNAVHPPOSLLH->data.version = extractByte(msg, 0); - packetUBXNAVHPPOSLLH->data.flags.all = extractByte(msg, 3); - packetUBXNAVHPPOSLLH->data.iTOW = extractLong(msg, 4); - packetUBXNAVHPPOSLLH->data.lon = extractSignedLong(msg, 8); - packetUBXNAVHPPOSLLH->data.lat = extractSignedLong(msg, 12); - packetUBXNAVHPPOSLLH->data.height = - extractSignedLong(msg, 16); - packetUBXNAVHPPOSLLH->data.hMSL = - extractSignedLong(msg, 20); - packetUBXNAVHPPOSLLH->data.lonHp = - extractSignedChar(msg, 24); - packetUBXNAVHPPOSLLH->data.latHp = - extractSignedChar(msg, 25); - packetUBXNAVHPPOSLLH->data.heightHp = - extractSignedChar(msg, 26); - packetUBXNAVHPPOSLLH->data.hMSLHp = - extractSignedChar(msg, 27); - packetUBXNAVHPPOSLLH->data.hAcc = extractLong(msg, 28); - packetUBXNAVHPPOSLLH->data.vAcc = extractLong(msg, 32); - - // Mark all datums as fresh (not read before) - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVHPPOSLLH->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVHPPOSLLH->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVHPPOSLLH->callbackData->version, - &packetUBXNAVHPPOSLLH->data.version, - sizeof(UBX_NAV_HPPOSLLH_data_t)); - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVHPPOSLLH->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_PVAT && - msg->len == UBX_NAV_PVAT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVPVAT != NULL) { - packetUBXNAVPVAT->data.iTOW = extractLong(msg, 0); - packetUBXNAVPVAT->data.version = extractByte(msg, 4); - packetUBXNAVPVAT->data.valid.all = extractByte(msg, 5); - packetUBXNAVPVAT->data.year = extractInt(msg, 6); - packetUBXNAVPVAT->data.month = extractByte(msg, 8); - packetUBXNAVPVAT->data.day = extractByte(msg, 9); - packetUBXNAVPVAT->data.hour = extractByte(msg, 10); - packetUBXNAVPVAT->data.min = extractByte(msg, 11); - packetUBXNAVPVAT->data.sec = extractByte(msg, 12); - packetUBXNAVPVAT->data.tAcc = extractLong(msg, 16); - packetUBXNAVPVAT->data.nano = - extractSignedLong(msg, 20); // Includes milliseconds - packetUBXNAVPVAT->data.fixType = extractByte(msg, 24); - packetUBXNAVPVAT->data.flags.all = extractByte(msg, 25); - packetUBXNAVPVAT->data.flags2.all = extractByte(msg, 26); - packetUBXNAVPVAT->data.numSV = extractByte(msg, 27); - packetUBXNAVPVAT->data.lon = extractSignedLong(msg, 28); - packetUBXNAVPVAT->data.lat = extractSignedLong(msg, 32); - packetUBXNAVPVAT->data.height = extractSignedLong(msg, 36); - packetUBXNAVPVAT->data.hMSL = extractSignedLong(msg, 40); - packetUBXNAVPVAT->data.hAcc = extractLong(msg, 44); - packetUBXNAVPVAT->data.vAcc = extractLong(msg, 48); - packetUBXNAVPVAT->data.velN = extractSignedLong(msg, 52); - packetUBXNAVPVAT->data.velE = extractSignedLong(msg, 56); - packetUBXNAVPVAT->data.velD = extractSignedLong(msg, 60); - packetUBXNAVPVAT->data.gSpeed = extractSignedLong(msg, 64); - packetUBXNAVPVAT->data.sAcc = extractLong(msg, 68); - packetUBXNAVPVAT->data.vehRoll = extractSignedLong(msg, 72); - packetUBXNAVPVAT->data.vehPitch = - extractSignedLong(msg, 76); - packetUBXNAVPVAT->data.vehHeading = - extractSignedLong(msg, 80); - packetUBXNAVPVAT->data.motHeading = - extractSignedLong(msg, 84); - packetUBXNAVPVAT->data.accRoll = extractInt(msg, 88); - packetUBXNAVPVAT->data.accPitch = extractInt(msg, 90); - packetUBXNAVPVAT->data.accHeading = extractInt(msg, 92); - packetUBXNAVPVAT->data.magDec = extractSignedInt(msg, 94); - packetUBXNAVPVAT->data.magAcc = extractInt(msg, 96); - packetUBXNAVPVAT->data.errEllipseOrient = - extractInt(msg, 98); - packetUBXNAVPVAT->data.errEllipseMajor = - extractLong(msg, 100); - packetUBXNAVPVAT->data.errEllipseMinor = - extractLong(msg, 104); - - // Mark all datums as fresh (not read before) - packetUBXNAVPVAT->moduleQueried.moduleQueried1.all = - 0xFFFFFFFF; - packetUBXNAVPVAT->moduleQueried.moduleQueried2.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVPVAT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVPVAT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVPVAT->callbackData->iTOW, - &packetUBXNAVPVAT->data.iTOW, - sizeof(UBX_NAV_PVAT_data_t)); - packetUBXNAVPVAT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVPVAT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_TIMEUTC && - msg->len == UBX_NAV_TIMEUTC_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVTIMEUTC != NULL) { - packetUBXNAVTIMEUTC->data.iTOW = extractLong(msg, 0); - packetUBXNAVTIMEUTC->data.tAcc = extractLong(msg, 4); - packetUBXNAVTIMEUTC->data.nano = extractSignedLong(msg, 8); - packetUBXNAVTIMEUTC->data.year = extractInt(msg, 12); - packetUBXNAVTIMEUTC->data.month = extractByte(msg, 14); - packetUBXNAVTIMEUTC->data.day = extractByte(msg, 15); - packetUBXNAVTIMEUTC->data.hour = extractByte(msg, 16); - packetUBXNAVTIMEUTC->data.min = extractByte(msg, 17); - packetUBXNAVTIMEUTC->data.sec = extractByte(msg, 18); - packetUBXNAVTIMEUTC->data.valid.all = extractByte(msg, 19); - - // Mark all datums as fresh (not read before) - packetUBXNAVTIMEUTC->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVTIMEUTC->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVTIMEUTC->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVTIMEUTC->callbackData->iTOW, - &packetUBXNAVTIMEUTC->data.iTOW, - sizeof(UBX_NAV_TIMEUTC_data_t)); - packetUBXNAVTIMEUTC->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVTIMEUTC->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_CLOCK && - msg->len == UBX_NAV_CLOCK_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVCLOCK != NULL) { - packetUBXNAVCLOCK->data.iTOW = extractLong(msg, 0); - packetUBXNAVCLOCK->data.clkB = extractSignedLong(msg, 4); - packetUBXNAVCLOCK->data.clkD = extractSignedLong(msg, 8); - packetUBXNAVCLOCK->data.tAcc = extractLong(msg, 12); - packetUBXNAVCLOCK->data.fAcc = extractLong(msg, 16); - - // Mark all datums as fresh (not read before) - packetUBXNAVCLOCK->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVCLOCK->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVCLOCK->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVCLOCK->callbackData->iTOW, - &packetUBXNAVCLOCK->data.iTOW, - sizeof(UBX_NAV_CLOCK_data_t)); - packetUBXNAVCLOCK->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVCLOCK->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_TIMELS && - msg->len == UBX_NAV_TIMELS_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVTIMELS != NULL) { - packetUBXNAVTIMELS->data.iTOW = extractLong(msg, 0); - packetUBXNAVTIMELS->data.version = extractByte(msg, 4); - packetUBXNAVTIMELS->data.srcOfCurrLs = extractByte(msg, 8); - packetUBXNAVTIMELS->data.currLs = extractSignedChar(msg, 9); - packetUBXNAVTIMELS->data.srcOfLsChange = - extractByte(msg, 10); - packetUBXNAVTIMELS->data.lsChange = - extractSignedChar(msg, 11); - packetUBXNAVTIMELS->data.timeToLsEvent = - extractSignedLong(msg, 12); - packetUBXNAVTIMELS->data.dateOfLsGpsWn = - extractInt(msg, 16); - packetUBXNAVTIMELS->data.dateOfLsGpsDn = - extractInt(msg, 18); - packetUBXNAVTIMELS->data.valid.all = - extractSignedChar(msg, 23); - - // Mark all datums as fresh (not read before) - packetUBXNAVTIMELS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - } - } else if (msg->id == UBX_NAV_SVIN && - msg->len == UBX_NAV_SVIN_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVSVIN != NULL) { - packetUBXNAVSVIN->data.version = extractByte(msg, 0); - packetUBXNAVSVIN->data.iTOW = extractLong(msg, 4); - packetUBXNAVSVIN->data.dur = extractLong(msg, 8); - packetUBXNAVSVIN->data.meanX = extractSignedLong(msg, 12); - packetUBXNAVSVIN->data.meanY = extractSignedLong(msg, 16); - packetUBXNAVSVIN->data.meanZ = extractSignedLong(msg, 20); - packetUBXNAVSVIN->data.meanXHP = extractSignedChar(msg, 24); - packetUBXNAVSVIN->data.meanYHP = extractSignedChar(msg, 25); - packetUBXNAVSVIN->data.meanZHP = extractSignedChar(msg, 26); - packetUBXNAVSVIN->data.meanAcc = extractLong(msg, 28); - packetUBXNAVSVIN->data.obs = extractLong(msg, 32); - packetUBXNAVSVIN->data.valid = extractSignedChar(msg, 36); - packetUBXNAVSVIN->data.active = extractSignedChar(msg, 37); - - // Mark all datums as fresh (not read before) - packetUBXNAVSVIN->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVSVIN->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVSVIN->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVSVIN->callbackData->version, - &packetUBXNAVSVIN->data.version, - sizeof(UBX_NAV_SVIN_data_t)); - packetUBXNAVSVIN->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVSVIN->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_SAT) // Note: length is variable - { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVSAT != NULL) { - packetUBXNAVSAT->data.header.iTOW = extractLong(msg, 0); - packetUBXNAVSAT->data.header.version = extractByte(msg, 4); - packetUBXNAVSAT->data.header.numSvs = extractByte(msg, 5); - - // The NAV SAT message could contain data for 255 SVs max. - // (numSvs is uint8_t. UBX_NAV_SAT_MAX_BLOCKS is 255) - for (uint16_t i = 0; - (i < UBX_NAV_SAT_MAX_BLOCKS) && - (i < - ((uint16_t)packetUBXNAVSAT->data.header.numSvs)) && - ((i * 12) < (msg->len - 8)); - i++) { - uint16_t offset = (i * 12) + 8; - packetUBXNAVSAT->data.blocks[i].gnssId = - extractByte(msg, offset + 0); - packetUBXNAVSAT->data.blocks[i].svId = - extractByte(msg, offset + 1); - packetUBXNAVSAT->data.blocks[i].cno = - extractByte(msg, offset + 2); - packetUBXNAVSAT->data.blocks[i].elev = - extractSignedChar(msg, offset + 3); - packetUBXNAVSAT->data.blocks[i].azim = - extractSignedInt(msg, offset + 4); - packetUBXNAVSAT->data.blocks[i].prRes = - extractSignedInt(msg, offset + 6); - packetUBXNAVSAT->data.blocks[i].flags.all = - extractLong(msg, offset + 8); - } - - // Mark all datums as fresh (not read before) - packetUBXNAVSAT->moduleQueried = true; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVSAT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVSAT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVSAT->callbackData->header.iTOW, - &packetUBXNAVSAT->data.header.iTOW, - sizeof(UBX_NAV_SAT_data_t)); - packetUBXNAVSAT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVSAT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_RELPOSNED && - ((msg->len == UBX_NAV_RELPOSNED_LEN) || - (msg->len == UBX_NAV_RELPOSNED_LEN_F9))) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVRELPOSNED != NULL) { - // Note: - // RELPOSNED on the M8 is only 40 bytes long - // RELPOSNED on the F9 is 64 bytes long and contains much - // more information - - packetUBXNAVRELPOSNED->data.version = extractByte(msg, 0); - packetUBXNAVRELPOSNED->data.refStationId = - extractInt(msg, 2); - packetUBXNAVRELPOSNED->data.iTOW = extractLong(msg, 4); - packetUBXNAVRELPOSNED->data.relPosN = - extractSignedLong(msg, 8); - packetUBXNAVRELPOSNED->data.relPosE = - extractSignedLong(msg, 12); - packetUBXNAVRELPOSNED->data.relPosD = - extractSignedLong(msg, 16); - - if (msg->len == UBX_NAV_RELPOSNED_LEN) { - // The M8 version does not contain relPosLength or - // relPosHeading - packetUBXNAVRELPOSNED->data.relPosLength = 0; - packetUBXNAVRELPOSNED->data.relPosHeading = 0; - packetUBXNAVRELPOSNED->data.relPosHPN = - extractSignedChar(msg, 20); - packetUBXNAVRELPOSNED->data.relPosHPE = - extractSignedChar(msg, 21); - packetUBXNAVRELPOSNED->data.relPosHPD = - extractSignedChar(msg, 22); - packetUBXNAVRELPOSNED->data.relPosHPLength = - 0; // The M8 version does not contain - // relPosHPLength - packetUBXNAVRELPOSNED->data.accN = extractLong(msg, 24); - packetUBXNAVRELPOSNED->data.accE = extractLong(msg, 28); - packetUBXNAVRELPOSNED->data.accD = extractLong(msg, 32); - // The M8 version does not contain accLength or - // accHeading - packetUBXNAVRELPOSNED->data.accLength = 0; - packetUBXNAVRELPOSNED->data.accHeading = 0; - packetUBXNAVRELPOSNED->data.flags.all = - extractLong(msg, 36); - } else { - packetUBXNAVRELPOSNED->data.relPosLength = - extractSignedLong(msg, 20); - packetUBXNAVRELPOSNED->data.relPosHeading = - extractSignedLong(msg, 24); - packetUBXNAVRELPOSNED->data.relPosHPN = - extractSignedChar(msg, 32); - packetUBXNAVRELPOSNED->data.relPosHPE = - extractSignedChar(msg, 33); - packetUBXNAVRELPOSNED->data.relPosHPD = - extractSignedChar(msg, 34); - packetUBXNAVRELPOSNED->data.relPosHPLength = - extractSignedChar(msg, 35); - packetUBXNAVRELPOSNED->data.accN = extractLong(msg, 36); - packetUBXNAVRELPOSNED->data.accE = extractLong(msg, 40); - packetUBXNAVRELPOSNED->data.accD = extractLong(msg, 44); - packetUBXNAVRELPOSNED->data.accLength = - extractLong(msg, 48); - packetUBXNAVRELPOSNED->data.accHeading = - extractLong(msg, 52); - packetUBXNAVRELPOSNED->data.flags.all = - extractLong(msg, 60); - } - - // Mark all datums as fresh (not read before) - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVRELPOSNED->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVRELPOSNED->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVRELPOSNED->callbackData->version, - &packetUBXNAVRELPOSNED->data.version, - sizeof(UBX_NAV_RELPOSNED_data_t)); - packetUBXNAVRELPOSNED->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVRELPOSNED->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_AOPSTATUS && - msg->len == UBX_NAV_AOPSTATUS_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVAOPSTATUS != NULL) { - packetUBXNAVAOPSTATUS->data.iTOW = extractLong(msg, 0); - packetUBXNAVAOPSTATUS->data.aopCfg.all = - extractByte(msg, 4); - packetUBXNAVAOPSTATUS->data.status = extractByte(msg, 5); - - // Mark all datums as fresh (not read before) - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVAOPSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVAOPSTATUS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVAOPSTATUS->callbackData->iTOW, - &packetUBXNAVAOPSTATUS->data.iTOW, - sizeof(UBX_NAV_AOPSTATUS_data_t)); - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVAOPSTATUS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_NAV_EOE && msg->len == UBX_NAV_EOE_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXNAVEOE != NULL) { - packetUBXNAVEOE->data.iTOW = extractLong(msg, 0); - - // Mark all datums as fresh (not read before) - packetUBXNAVEOE->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXNAVEOE->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXNAVEOE->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXNAVEOE->callbackData->iTOW, - &packetUBXNAVEOE->data.iTOW, - sizeof(UBX_NAV_EOE_data_t)); - packetUBXNAVEOE->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXNAVEOE->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } - break; - case UBX_CLASS_RXM: - if (msg->id == UBX_RXM_PMP) - // Note: length is variable with version 0x01 - // Note: the field positions depend on the version - { - // Parse various byte fields into storage - but only if we have - // memory allocated for it. By default, new PMP data will always - // overwrite 'old' data (data which is valid but which has not - // yet been read by the callback). To prevent this, uncomment - // the line two lines below - if ((packetUBXRXMPMP != NULL) && - (packetUBXRXMPMP->callbackData != NULL) - //&& - //(packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid - //== false) // <=== Uncomment this line to prevent new data - // from overwriting 'old' - ) { - packetUBXRXMPMP->callbackData->version = - extractByte(msg, 0); - packetUBXRXMPMP->callbackData->numBytesUserData = - extractInt(msg, 2); - packetUBXRXMPMP->callbackData->timeTag = - extractLong(msg, 4); - packetUBXRXMPMP->callbackData->uniqueWord[0] = - extractLong(msg, 8); - packetUBXRXMPMP->callbackData->uniqueWord[1] = - extractLong(msg, 12); - packetUBXRXMPMP->callbackData->serviceIdentifier = - extractInt(msg, 16); - packetUBXRXMPMP->callbackData->spare = extractByte(msg, 18); - packetUBXRXMPMP->callbackData->uniqueWordBitErrors = - extractByte(msg, 19); - - if (packetUBXRXMPMP->callbackData->version == 0x00) { - packetUBXRXMPMP->callbackData->fecBits = - extractInt(msg, 524); - packetUBXRXMPMP->callbackData->ebno = - extractByte(msg, 526); - } else // if (packetUBXRXMPMP->data.version == 0x01) - { - packetUBXRXMPMP->callbackData->fecBits = - extractInt(msg, 20); - packetUBXRXMPMP->callbackData->ebno = - extractByte(msg, 22); - } - - uint16_t userDataStart = - (packetUBXRXMPMP->callbackData->version == 0x00) ? 20 - : 24; - uint16_t userDataLength = - (packetUBXRXMPMP->callbackData->version == 0x00) - ? 504 - : (packetUBXRXMPMP->callbackData->numBytesUserData); - for (uint16_t i = 0; (i < userDataLength) && (i < 504); - i++) { - packetUBXRXMPMP->callbackData->userData[i] = - extractByte(msg, i + userDataStart); - } - - packetUBXRXMPMP->automaticFlags.flags.bits - .callbackCopyValid = true; // Mark the data as valid - } - - // Full PMP message, including Class, ID and checksum - // By default, new PMP data will always overwrite 'old' data - // (data which is valid but which has not yet been read by the - // callback). To prevent this, uncomment the line two lines - // below - if ((packetUBXRXMPMPmessage != NULL) && - (packetUBXRXMPMPmessage->callbackData != NULL) - //&& - //(packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid - //== false) // <=== Uncomment this line to prevent new data - // from overwriting 'old' - ) { - packetUBXRXMPMPmessage->callbackData->sync1 = UBX_SYNCH_1; - packetUBXRXMPMPmessage->callbackData->sync2 = UBX_SYNCH_2; - packetUBXRXMPMPmessage->callbackData->cls = UBX_CLASS_RXM; - packetUBXRXMPMPmessage->callbackData->ID = UBX_RXM_PMP; - packetUBXRXMPMPmessage->callbackData->lengthLSB = - msg->len & 0xFF; - packetUBXRXMPMPmessage->callbackData->lengthMSB = - msg->len >> 8; - - memcpy(packetUBXRXMPMPmessage->callbackData->payload, - msg->payload, msg->len); - - packetUBXRXMPMPmessage->callbackData->checksumA = - msg->checksumA; - packetUBXRXMPMPmessage->callbackData->checksumB = - msg->checksumB; - - packetUBXRXMPMPmessage->automaticFlags.flags.bits - .callbackCopyValid = true; // Mark the data as valid - } - } else if (msg->id == UBX_RXM_QZSSL6) - // Note: length is variable with version 0x01 - // Note: the field positions depend on the version - { - // Full QZSSL6 message, including Class, ID and checksum - for (int ch = 0; ch < UBX_RXM_QZSSL6_NUM_CHANNELS; ch++) { - if (0 == (packetUBXRXMQZSSL6message->automaticFlags.flags - .bits.callbackCopyValid & - (1 << ch))) { - packetUBXRXMQZSSL6message->callbackData[ch].sync1 = - UBX_SYNCH_1; - packetUBXRXMQZSSL6message->callbackData[ch].sync2 = - UBX_SYNCH_2; - packetUBXRXMQZSSL6message->callbackData[ch].cls = - UBX_CLASS_RXM; - packetUBXRXMQZSSL6message->callbackData[ch].ID = - UBX_RXM_QZSSL6; - packetUBXRXMQZSSL6message->callbackData[ch].lengthLSB = - msg->len & 0xFF; - packetUBXRXMQZSSL6message->callbackData[ch].lengthMSB = - msg->len >> 8; - - memcpy( - packetUBXRXMQZSSL6message->callbackData[ch].payload, - msg->payload, msg->len); - - packetUBXRXMQZSSL6message->callbackData[ch].checksumA = - msg->checksumA; - packetUBXRXMQZSSL6message->callbackData[ch].checksumB = - msg->checksumB; - - packetUBXRXMQZSSL6message->automaticFlags.flags.bits - .callbackCopyValid |= (1 << ch); - break; // abort when added - } - } - } else if (msg->id == UBX_RXM_COR) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if ((packetUBXRXMCOR != NULL) && - (packetUBXRXMCOR->callbackData != NULL) - //&& - //(packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid - //== false) // <=== Uncomment this line to prevent new data - // from overwriting 'old' - ) { - packetUBXRXMCOR->callbackData->version = - extractByte(msg, 0); - packetUBXRXMCOR->callbackData->ebno = extractByte(msg, 1); - packetUBXRXMCOR->callbackData->statusInfo.all = - extractLong(msg, 4); - packetUBXRXMCOR->callbackData->msgType = extractInt(msg, 8); - packetUBXRXMCOR->callbackData->msgSubType = - extractInt(msg, 10); - - packetUBXRXMCOR->automaticFlags.flags.bits - .callbackCopyValid = true; // Mark the data as valid - } - } else if (msg->id == UBX_RXM_SFRBX) - // Note: length is variable - // Note: on protocol version 17: numWords is (0..16) - // on protocol version 18+: numWords is (0..10) - { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXRXMSFRBX != NULL) { - packetUBXRXMSFRBX->data.gnssId = extractByte(msg, 0); - packetUBXRXMSFRBX->data.svId = extractByte(msg, 1); - packetUBXRXMSFRBX->data.freqId = extractByte(msg, 3); - packetUBXRXMSFRBX->data.numWords = extractByte(msg, 4); - packetUBXRXMSFRBX->data.chn = extractByte(msg, 5); - packetUBXRXMSFRBX->data.version = extractByte(msg, 6); - - for (uint8_t i = 0; - (i < UBX_RXM_SFRBX_MAX_WORDS) && - (i < packetUBXRXMSFRBX->data.numWords) && - ((i * 4) < (msg->len - 8)); - i++) { - packetUBXRXMSFRBX->data.dwrd[i] = - extractLong(msg, 8 + (i * 4)); - } - - // Mark all datums as fresh (not read before) - packetUBXRXMSFRBX->moduleQueried = true; - - // Check if we need to copy the data for the callback - if ((packetUBXRXMSFRBX->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXRXMSFRBX->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXRXMSFRBX->callbackData->gnssId, - &packetUBXRXMSFRBX->data.gnssId, - sizeof(UBX_RXM_SFRBX_data_t)); - packetUBXRXMSFRBX->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXRXMSFRBX->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_RXM_RAWX) - // Note: length is variable - { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXRXMRAWX != NULL) { - for (uint8_t i = 0; i < 8; i++) { - packetUBXRXMRAWX->data.header.rcvTow[i] = - extractByte(msg, i); - } - packetUBXRXMRAWX->data.header.week = extractInt(msg, 8); - packetUBXRXMRAWX->data.header.leapS = - extractSignedChar(msg, 10); - packetUBXRXMRAWX->data.header.numMeas = - extractByte(msg, 11); - packetUBXRXMRAWX->data.header.recStat.all = - extractByte(msg, 12); - packetUBXRXMRAWX->data.header.version = - extractByte(msg, 13); - - for (uint8_t i = 0; - (i < UBX_RXM_RAWX_MAX_BLOCKS) && - (i < packetUBXRXMRAWX->data.header.numMeas) && - ((((uint16_t)i) * 32) < (msg->len - 16)); - i++) { - uint16_t offset = (((uint16_t)i) * 32) + 16; - for (uint8_t j = 0; j < 8; j++) { - packetUBXRXMRAWX->data.blocks[i].prMes[j] = - extractByte(msg, offset + j); - packetUBXRXMRAWX->data.blocks[i].cpMes[j] = - extractByte(msg, offset + 8 + j); - if (j < 4) - packetUBXRXMRAWX->data.blocks[i].doMes[j] = - extractByte(msg, offset + 16 + j); - } - packetUBXRXMRAWX->data.blocks[i].gnssId = - extractByte(msg, offset + 20); - packetUBXRXMRAWX->data.blocks[i].svId = - extractByte(msg, offset + 21); - packetUBXRXMRAWX->data.blocks[i].sigId = - extractByte(msg, offset + 22); - packetUBXRXMRAWX->data.blocks[i].freqId = - extractByte(msg, offset + 23); - packetUBXRXMRAWX->data.blocks[i].lockTime = - extractInt(msg, offset + 24); - packetUBXRXMRAWX->data.blocks[i].cno = - extractByte(msg, offset + 26); - packetUBXRXMRAWX->data.blocks[i].prStdev = - extractByte(msg, offset + 27); - packetUBXRXMRAWX->data.blocks[i].cpStdev = - extractByte(msg, offset + 28); - packetUBXRXMRAWX->data.blocks[i].doStdev = - extractByte(msg, offset + 29); - packetUBXRXMRAWX->data.blocks[i].trkStat.all = - extractByte(msg, offset + 30); - } - - // Mark all datums as fresh (not read before) - packetUBXRXMRAWX->moduleQueried = true; - - // Check if we need to copy the data for the callback - if ((packetUBXRXMRAWX->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXRXMRAWX->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy( - &packetUBXRXMRAWX->callbackData->header.rcvTow[0], - &packetUBXRXMRAWX->data.header.rcvTow[0], - sizeof(UBX_RXM_RAWX_data_t)); - packetUBXRXMRAWX->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXRXMRAWX->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } - break; - case UBX_CLASS_CFG: - if (msg->id == UBX_CFG_PRT && msg->len == UBX_CFG_PRT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXCFGPRT != NULL) { - packetUBXCFGPRT->data.portID = extractByte(msg, 0); - packetUBXCFGPRT->data.txReady.all = extractInt(msg, 2); - packetUBXCFGPRT->data.mode = extractLong(msg, 4); - packetUBXCFGPRT->data.baudRate = extractLong(msg, 8); - packetUBXCFGPRT->data.inProtoMask.all = extractInt(msg, 12); - packetUBXCFGPRT->data.outProtoMask.all = - extractInt(msg, 14); - packetUBXCFGPRT->data.flags = extractInt(msg, 16); - - // Mark data as valid - packetUBXCFGPRT->dataValid = true; - } - } else if (msg->id == UBX_CFG_RATE && - msg->len == UBX_CFG_RATE_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXCFGRATE != NULL) { - packetUBXCFGRATE->data.measRate = extractInt(msg, 0); - packetUBXCFGRATE->data.navRate = extractInt(msg, 2); - packetUBXCFGRATE->data.timeRef = extractInt(msg, 4); - - // Mark all datums as fresh (not read before) - packetUBXCFGRATE->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - } - } - break; - case UBX_CLASS_TIM: - if (msg->id == UBX_TIM_TM2 && msg->len == UBX_TIM_TM2_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXTIMTM2 != NULL) { - packetUBXTIMTM2->data.ch = extractByte(msg, 0); - packetUBXTIMTM2->data.flags.all = extractByte(msg, 1); - packetUBXTIMTM2->data.count = extractInt(msg, 2); - packetUBXTIMTM2->data.wnR = extractInt(msg, 4); - packetUBXTIMTM2->data.wnF = extractInt(msg, 6); - packetUBXTIMTM2->data.towMsR = extractLong(msg, 8); - packetUBXTIMTM2->data.towSubMsR = extractLong(msg, 12); - packetUBXTIMTM2->data.towMsF = extractLong(msg, 16); - packetUBXTIMTM2->data.towSubMsF = extractLong(msg, 20); - packetUBXTIMTM2->data.accEst = extractLong(msg, 24); - - // Mark all datums as fresh (not read before) - packetUBXTIMTM2->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXTIMTM2->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXTIMTM2->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXTIMTM2->callbackData->ch, - &packetUBXTIMTM2->data.ch, - sizeof(UBX_TIM_TM2_data_t)); - packetUBXTIMTM2->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXTIMTM2->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } - break; - case UBX_CLASS_ESF: - if (msg->id == UBX_ESF_ALG && msg->len == UBX_ESF_ALG_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXESFALG != NULL) { - packetUBXESFALG->data.iTOW = extractLong(msg, 0); - packetUBXESFALG->data.version = extractByte(msg, 4); - packetUBXESFALG->data.flags.all = extractByte(msg, 5); - packetUBXESFALG->data.error.all = extractByte(msg, 6); - packetUBXESFALG->data.yaw = extractLong(msg, 8); - packetUBXESFALG->data.pitch = extractSignedInt(msg, 12); - packetUBXESFALG->data.roll = extractSignedInt(msg, 14); - - // Mark all datums as fresh (not read before) - packetUBXESFALG->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXESFALG->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXESFALG->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXESFALG->callbackData->iTOW, - &packetUBXESFALG->data.iTOW, - sizeof(UBX_ESF_ALG_data_t)); - packetUBXESFALG->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXESFALG->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_ESF_INS && msg->len == UBX_ESF_INS_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXESFINS != NULL) { - packetUBXESFINS->data.bitfield0.all = extractLong(msg, 0); - packetUBXESFINS->data.iTOW = extractLong(msg, 8); - packetUBXESFINS->data.xAngRate = extractSignedLong(msg, 12); - packetUBXESFINS->data.yAngRate = extractSignedLong(msg, 16); - packetUBXESFINS->data.zAngRate = extractSignedLong(msg, 20); - packetUBXESFINS->data.xAccel = extractSignedLong(msg, 24); - packetUBXESFINS->data.yAccel = extractSignedLong(msg, 28); - packetUBXESFINS->data.zAccel = extractSignedLong(msg, 32); - - // Mark all datums as fresh (not read before) - packetUBXESFINS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXESFINS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXESFINS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXESFINS->callbackData->bitfield0.all, - &packetUBXESFINS->data.bitfield0.all, - sizeof(UBX_ESF_INS_data_t)); - packetUBXESFINS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXESFINS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_ESF_MEAS) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXESFMEAS != NULL) { - packetUBXESFMEAS->data.timeTag = extractLong(msg, 0); - packetUBXESFMEAS->data.flags.all = extractInt(msg, 4); - packetUBXESFMEAS->data.id = extractInt(msg, 6); - for (uint16_t i = 0; - (i < DEF_MAX_NUM_ESF_MEAS) && - (i < packetUBXESFMEAS->data.flags.bits.numMeas) && - ((i * 4) < (msg->len - 8)); - i++) { - packetUBXESFMEAS->data.data[i].data.all = - extractLong(msg, 8 + (i * 4)); - } - if ((uint16_t)msg->len > - (uint16_t)(8 + - (packetUBXESFMEAS->data.flags.bits.numMeas * - 4))) - packetUBXESFMEAS->data.calibTtag = extractLong( - msg, - 8 + (packetUBXESFMEAS->data.flags.bits.numMeas * - 4)); - - // Check if we need to copy the data for the callback - if ((packetUBXESFMEAS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXESFMEAS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXESFMEAS->callbackData->timeTag, - &packetUBXESFMEAS->data.timeTag, - sizeof(UBX_ESF_MEAS_data_t)); - packetUBXESFMEAS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXESFMEAS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_ESF_RAW) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXESFRAW != NULL) { - packetUBXESFRAW->data.numEsfRawBlocks = - (msg->len - 4) / - 8; // Record how many blocks were received. Could be 7 - // or 70 (ZED-F9R vs. NEO-M8U) - for (uint16_t i = 0; - (i < (DEF_NUM_SENS * DEF_MAX_NUM_ESF_RAW_REPEATS)) && - ((i * 8) < (msg->len - 4)); - i++) { - packetUBXESFRAW->data.data[i].data.all = - extractLong(msg, 4 + (i * 8)); - packetUBXESFRAW->data.data[i].sTag = - extractLong(msg, 8 + (i * 8)); - } - - // Check if we need to copy the data for the callback - if ((packetUBXESFRAW->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXESFRAW->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXESFRAW->callbackData->data[0].data.all, - &packetUBXESFRAW->data.data[0].data.all, - sizeof(UBX_ESF_RAW_data_t)); - packetUBXESFRAW->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXESFRAW->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_ESF_STATUS) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXESFSTATUS != NULL) { - packetUBXESFSTATUS->data.iTOW = extractLong(msg, 0); - packetUBXESFSTATUS->data.version = extractByte(msg, 4); - packetUBXESFSTATUS->data.fusionMode = extractByte(msg, 12); - packetUBXESFSTATUS->data.numSens = extractByte(msg, 15); - for (uint16_t i = 0; - (i < DEF_NUM_SENS) && - (i < packetUBXESFSTATUS->data.numSens) && - ((i * 4) < (msg->len - 16)); - i++) { - packetUBXESFSTATUS->data.status[i].sensStatus1.all = - extractByte(msg, 16 + (i * 4) + 0); - packetUBXESFSTATUS->data.status[i].sensStatus2.all = - extractByte(msg, 16 + (i * 4) + 1); - packetUBXESFSTATUS->data.status[i].freq = - extractByte(msg, 16 + (i * 4) + 2); - packetUBXESFSTATUS->data.status[i].faults.all = - extractByte(msg, 16 + (i * 4) + 3); - } - - // Mark all datums as fresh (not read before) - packetUBXESFSTATUS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXESFSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXESFSTATUS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXESFSTATUS->callbackData->iTOW, - &packetUBXESFSTATUS->data.iTOW, - sizeof(UBX_ESF_STATUS_data_t)); - packetUBXESFSTATUS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXESFSTATUS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } - break; - case UBX_CLASS_MGA: - if (msg->id == UBX_MGA_ACK_DATA0 && - msg->len == UBX_MGA_ACK_DATA0_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXMGAACK != NULL) { - // Calculate how many ACKs are already stored in the ring - // buffer - uint8_t ackBufferContains; - if (packetUBXMGAACK->head >= - packetUBXMGAACK - ->tail) // Check if wrap-around has occurred - { - // Wrap-around has not occurred so do a simple - // subtraction - ackBufferContains = - packetUBXMGAACK->head - packetUBXMGAACK->tail; - } else { - // Wrap-around has occurred so do a simple subtraction - // but add in the buffer length - // (UBX_MGA_ACK_RINGBUFFER_LEN) - ackBufferContains = - ((uint8_t)(((uint16_t)packetUBXMGAACK->head + - (uint16_t) - UBX_MGA_ACK_DATA0_RINGBUFFER_LEN) - - (uint16_t)packetUBXMGAACK->tail)); - } - // Have we got space to store this ACK? - if (ackBufferContains < - (UBX_MGA_ACK_DATA0_RINGBUFFER_LEN - 1)) { - // Yes, we have, so store it - packetUBXMGAACK->data[packetUBXMGAACK->head].type = - extractByte(msg, 0); - packetUBXMGAACK->data[packetUBXMGAACK->head].version = - extractByte(msg, 1); - packetUBXMGAACK->data[packetUBXMGAACK->head].infoCode = - extractByte(msg, 2); - packetUBXMGAACK->data[packetUBXMGAACK->head].msgId = - extractByte(msg, 3); - packetUBXMGAACK->data[packetUBXMGAACK->head] - .msgPayloadStart[0] = extractByte(msg, 4); - packetUBXMGAACK->data[packetUBXMGAACK->head] - .msgPayloadStart[1] = extractByte(msg, 5); - packetUBXMGAACK->data[packetUBXMGAACK->head] - .msgPayloadStart[2] = extractByte(msg, 6); - packetUBXMGAACK->data[packetUBXMGAACK->head] - .msgPayloadStart[3] = extractByte(msg, 7); - // Increment the head - packetUBXMGAACK->head++; - if (packetUBXMGAACK->head == - UBX_MGA_ACK_DATA0_RINGBUFFER_LEN) - packetUBXMGAACK->head = 0; - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("processUBXpacket: packetUBXMGAACK is full. " - "ACK will be lost!")); - } -#endif - } - } - } else if (msg->id == UBX_MGA_DBD && - msg->len <= - UBX_MGA_DBD_LEN) // Message length may be less than - // UBX_MGA_DBD_LEN. UBX_MGA_DBD_LEN - // is the maximum it will be. - { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXMGADBD != NULL) { - // Calculate how many DBDs are already stored in the ring - // buffer - uint8_t dbdBufferContains; - if (packetUBXMGADBD->head >= - packetUBXMGADBD - ->tail) // Check if wrap-around has occurred - { - // Wrap-around has not occurred so do a simple - // subtraction - dbdBufferContains = - packetUBXMGADBD->head - packetUBXMGADBD->tail; - } else { - // Wrap-around has occurred so do a simple subtraction - // but add in the buffer length - // (UBX_MGA_DBD_RINGBUFFER_LEN) - dbdBufferContains = - ((uint8_t)(((uint16_t)packetUBXMGADBD->head + - (uint16_t)UBX_MGA_DBD_RINGBUFFER_LEN) - - (uint16_t)packetUBXMGADBD->tail)); - } - // Have we got space to store this DBD? - if (dbdBufferContains < (UBX_MGA_DBD_RINGBUFFER_LEN - 1)) { - // Yes, we have, so store it - // We need to save the entire message - header, payload - // and checksum - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryHeader1 = UBX_SYNCH_1; - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryHeader2 = UBX_SYNCH_2; - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryClass = UBX_CLASS_MGA; - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryID = UBX_MGA_DBD; - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryLenLSB = - (uint8_t)(msg->len & - 0xFF); // We need to store the length of - // the DBD entry. The entry itself - // does not contain a length... - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryLenMSB = (uint8_t)((msg->len >> 8) & 0xFF); - for (uint16_t i = 0; i < msg->len; i++) { - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntry[i] = extractByte(msg, i); - } - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryChecksumA = msg->checksumA; - packetUBXMGADBD->data[packetUBXMGADBD->head] - .dbdEntryChecksumB = msg->checksumB; - // Increment the head - packetUBXMGADBD->head++; - if (packetUBXMGADBD->head == UBX_MGA_DBD_RINGBUFFER_LEN) - packetUBXMGADBD->head = 0; - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("processUBXpacket: packetUBXMGADBD is full. " - "DBD data will be lost!")); - } -#endif - } - } - } - break; - case UBX_CLASS_HNR: - if (msg->id == UBX_HNR_PVT && msg->len == UBX_HNR_PVT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXHNRPVT != NULL) { - packetUBXHNRPVT->data.iTOW = extractLong(msg, 0); - packetUBXHNRPVT->data.year = extractInt(msg, 4); - packetUBXHNRPVT->data.month = extractByte(msg, 6); - packetUBXHNRPVT->data.day = extractByte(msg, 7); - packetUBXHNRPVT->data.hour = extractByte(msg, 8); - packetUBXHNRPVT->data.min = extractByte(msg, 9); - packetUBXHNRPVT->data.sec = extractByte(msg, 10); - packetUBXHNRPVT->data.valid.all = extractByte(msg, 11); - packetUBXHNRPVT->data.nano = extractSignedLong(msg, 12); - packetUBXHNRPVT->data.gpsFix = extractByte(msg, 16); - packetUBXHNRPVT->data.flags.all = extractByte(msg, 17); - packetUBXHNRPVT->data.lon = extractSignedLong(msg, 20); - packetUBXHNRPVT->data.lat = extractSignedLong(msg, 24); - packetUBXHNRPVT->data.height = extractSignedLong(msg, 28); - packetUBXHNRPVT->data.hMSL = extractSignedLong(msg, 32); - packetUBXHNRPVT->data.gSpeed = extractSignedLong(msg, 36); - packetUBXHNRPVT->data.speed = extractSignedLong(msg, 40); - packetUBXHNRPVT->data.headMot = extractSignedLong(msg, 44); - packetUBXHNRPVT->data.headVeh = extractSignedLong(msg, 48); - packetUBXHNRPVT->data.hAcc = extractLong(msg, 52); - packetUBXHNRPVT->data.vAcc = extractLong(msg, 56); - packetUBXHNRPVT->data.sAcc = extractLong(msg, 60); - packetUBXHNRPVT->data.headAcc = extractLong(msg, 64); - - // Mark all datums as fresh (not read before) - packetUBXHNRPVT->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXHNRPVT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXHNRPVT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXHNRPVT->callbackData->iTOW, - &packetUBXHNRPVT->data.iTOW, - sizeof(UBX_HNR_PVT_data_t)); - packetUBXHNRPVT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXHNRPVT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_HNR_ATT && msg->len == UBX_HNR_ATT_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXHNRATT != NULL) { - packetUBXHNRATT->data.iTOW = extractLong(msg, 0); - packetUBXHNRATT->data.version = extractByte(msg, 4); - packetUBXHNRATT->data.roll = extractSignedLong(msg, 8); - packetUBXHNRATT->data.pitch = extractSignedLong(msg, 12); - packetUBXHNRATT->data.heading = extractSignedLong(msg, 16); - packetUBXHNRATT->data.accRoll = extractLong(msg, 20); - packetUBXHNRATT->data.accPitch = extractLong(msg, 24); - packetUBXHNRATT->data.accHeading = extractLong(msg, 28); - - // Mark all datums as fresh (not read before) - packetUBXHNRATT->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXHNRATT->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXHNRATT->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXHNRATT->callbackData->iTOW, - &packetUBXHNRATT->data.iTOW, - sizeof(UBX_HNR_ATT_data_t)); - packetUBXHNRATT->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXHNRATT->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } else if (msg->id == UBX_HNR_INS && msg->len == UBX_HNR_INS_LEN) { - // Parse various byte fields into storage - but only if we have - // memory allocated for it - if (packetUBXHNRINS != NULL) { - packetUBXHNRINS->data.bitfield0.all = extractLong(msg, 0); - packetUBXHNRINS->data.iTOW = extractLong(msg, 8); - packetUBXHNRINS->data.xAngRate = extractSignedLong(msg, 12); - packetUBXHNRINS->data.yAngRate = extractSignedLong(msg, 16); - packetUBXHNRINS->data.zAngRate = extractSignedLong(msg, 20); - packetUBXHNRINS->data.xAccel = extractSignedLong(msg, 24); - packetUBXHNRINS->data.yAccel = extractSignedLong(msg, 28); - packetUBXHNRINS->data.zAccel = extractSignedLong(msg, 32); - - // Mark all datums as fresh (not read before) - packetUBXHNRINS->moduleQueried.moduleQueried.all = - 0xFFFFFFFF; - - // Check if we need to copy the data for the callback - if ((packetUBXHNRINS->callbackData != - NULL) // If RAM has been allocated for the copy of the - // data - && (packetUBXHNRINS->automaticFlags.flags.bits - .callbackCopyValid == - false)) // AND the data is stale - { - memcpy(&packetUBXHNRINS->callbackData->bitfield0.all, - &packetUBXHNRINS->data.bitfield0.all, - sizeof(UBX_HNR_INS_data_t)); - packetUBXHNRINS->automaticFlags.flags.bits - .callbackCopyValid = true; - } - - // Check if we need to copy the data into the file buffer - if (packetUBXHNRINS->automaticFlags.flags.bits - .addToFileBuffer) { - storePacket(msg); - } - } - } - break; - } -} - -// Given a message, calc and store the two byte "8-Bit Fletcher" checksum over -// the entirety of the message This is called before we send a command message -void SFE_UBLOX_GNSS::calcChecksum(ubxPacket *msg) { - msg->checksumA = 0; - msg->checksumB = 0; - - msg->checksumA += msg->cls; - msg->checksumB += msg->checksumA; - - msg->checksumA += msg->id; - msg->checksumB += msg->checksumA; - - msg->checksumA += (msg->len & 0xFF); - msg->checksumB += msg->checksumA; - - msg->checksumA += (msg->len >> 8); - msg->checksumB += msg->checksumA; - - for (uint16_t i = 0; i < msg->len; i++) { - msg->checksumA += msg->payload[i]; - msg->checksumB += msg->checksumA; - } -} - -// Given a message and a byte, add to rolling "8-Bit Fletcher" checksum -// This is used when receiving messages from module -void SFE_UBLOX_GNSS::addToChecksum(uint8_t incoming) { - rollingChecksumA += incoming; - rollingChecksumB += rollingChecksumA; -} - -// Given a packet and payload, send everything including CRC bytes via I2C port -sfe_ublox_status_e SFE_UBLOX_GNSS::sendCommand(ubxPacket *outgoingUBX, - uint16_t maxWait, - bool expectACKonly) { - sfe_ublox_status_e retVal = SFE_UBLOX_STATUS_SUCCESS; - - calcChecksum(outgoingUBX); // Sets checksum A and B bytes of the packet - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("\nSending: ")); - printPacket(outgoingUBX, true); // Always print payload - } -#endif - - if (commType == COMM_TYPE_I2C) { - retVal = sendI2cCommand(outgoingUBX, maxWait); - if (retVal != SFE_UBLOX_STATUS_SUCCESS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println(F("Send I2C Command failed")); - } -#endif - return retVal; - } - } else if (commType == COMM_TYPE_SERIAL) { - sendSerialCommand(outgoingUBX); - } else if (commType == COMM_TYPE_SPI) { - sendSpiCommand(outgoingUBX); - } - - if (maxWait > 0) { - // Depending on what we just sent, either we need to look for an ACK or - // not - if ((outgoingUBX->cls == UBX_CLASS_CFG) || (expectACKonly == true)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("sendCommand: Waiting for ACK response")); - } -#endif - retVal = waitForACKResponse(outgoingUBX, outgoingUBX->cls, - outgoingUBX->id, - maxWait); // Wait for Ack response - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("sendCommand: Waiting for No ACK response")); - } -#endif - retVal = waitForNoACKResponse(outgoingUBX, outgoingUBX->cls, - outgoingUBX->id, - maxWait); // Wait for Ack response - } - } - return retVal; -} - -// Returns false if sensor fails to respond to I2C traffic -sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand(ubxPacket *outgoingUBX, - uint16_t maxWait) { - // From the integration guide: - // "The receiver does not provide any write access except for writing UBX - // and NMEA messages to the - // receiver, such as configuration or aiding data. Therefore, the register - // set mentioned in section Read Access is not writeable. Following the - // start condition from the master, the 7-bit device address and the RW bit - // (which is a logic low for write access) are clocked onto the bus by the - // master transmitter. The receiver answers with an acknowledge (logic low) - // to indicate that it is responsible for the given address. Now, the - // master can write 2 to N bytes to the receiver, generating a stop - // condition after the last byte being written. The number of data bytes - // must be at least 2 to properly distinguish from the write access to set - // the address counter in random read accesses." - // I take two things from this: - // 1) We do not need to write 0xFF to point at register 0xFF. We're already - // pointing at it. 2) We must always write at least 2 bytes, otherwise it - // looks like we are starting to do a read. Point 2 is important. It means: - // * In this function: - // if we do multiple writes (because we're trying to write more than - // i2cTransactionSize), we may need to write one byte less in the - // penultimate write to ensure we always have two bytes left for the - // final write. - // * In pushRawData: - // if there is one byte to write, or one byte left to write, we need to - // do the same thing and may need to store a single byte until - // pushRawData is called again. - // The next four lines can be commented. We do not need to point at the 0xFF - // data register - //_i2cPort->beginTransmission((uint8_t)_gpsI2Caddress); //There is no - // register to write to, we just begin writing data bytes - //_i2cPort->write(0xFF); - // if (_i2cPort->endTransmission(false) != 0) //Don't release bus - // return (SFE_UBLOX_STATUS_I2C_COMM_FAILURE); //Sensor did not ACK - - // The total number of bytes to be written is: payload len + 8 - // UBX_SYNCH_1 - // UBX_SYNCH_2 - // cls - // id - // len (MSB) - // len (LSB) - // < payload > - // checksumA - // checksumB - - // i2cTransactionSize will be at least 8. We don't need to check for smaller - // values than that. - - uint16_t bytesToSend = - outgoingUBX->len + 8; // How many bytes need to be sent - uint16_t bytesSent = 0; // How many bytes have been sent - uint16_t bytesLeftToSend = bytesToSend; // How many bytes remain to be sent - uint16_t startSpot = 0; // Payload pointer - - while (bytesLeftToSend > 0) { - uint16_t len = - bytesLeftToSend; // How many bytes should we actually write? - if (len > i2cTransactionSize) // Limit len to i2cTransactionSize - len = i2cTransactionSize; - - bytesLeftToSend -= len; // Calculate how many bytes will be left after - // we do this write - - // If bytesLeftToSend is zero, that's OK. - // If bytesLeftToSend is >= 2, that's OK. - // But if bytesLeftToSend is 1, we need to adjust len to make sure we - // write at least 2 bytes in the final write - if (bytesLeftToSend == 1) { - len -= 1; // Decrement len by 1 - bytesLeftToSend += 1; // Increment bytesLeftToSend by 1 - } - - _i2cPort->beginTransmission( - (uint8_t)_gpsI2Caddress); // Start the transmission - - if (bytesSent == - 0) // Is this the first write? If it is, write the header bytes - { - _i2cPort->write(UBX_SYNCH_1); // μ - oh ublox, you're funny. I will - // call you micro-blox from now on. - _i2cPort->write(UBX_SYNCH_2); // b - _i2cPort->write(outgoingUBX->cls); - _i2cPort->write(outgoingUBX->id); - _i2cPort->write(outgoingUBX->len & 0xFF); // LSB - _i2cPort->write(outgoingUBX->len >> 8); // MSB - - bytesSent += 6; - - uint16_t x = 0; - // Write a portion of the payload to the bus. - // Keep going until we reach the end of the payload (x == - // outgoingUBX->len) or we've sent as many bytes as we can in this - // transmission (bytesSent == len). - for (; (x < outgoingUBX->len) && (bytesSent < len); x++) { - _i2cPort->write(outgoingUBX->payload[startSpot + x]); - bytesSent++; - } - startSpot += x; - - // Can we write both checksum bytes? - // We can send both bytes now if we have exactly 2 bytes left - // to be sent in this transmission (bytesSent == (len - 2)). - if (bytesSent == (len - 2)) { - // Write checksum - _i2cPort->write(outgoingUBX->checksumA); - _i2cPort->write(outgoingUBX->checksumB); - bytesSent += 2; - } - } else // Keep writing payload bytes. Write the checksum at the right - // time. - { - uint16_t x = 0; - // Write a portion of the payload to the bus. - // Keep going until we've sent as many bytes as we can in this - // transmission (x == len) or until we reach the end of the payload - // ((startSpot + x) == (outgoingUBX->len)) - for (; (x < len) && ((startSpot + x) < (outgoingUBX->len)); x++) { - _i2cPort->write(outgoingUBX->payload[startSpot + x]); - bytesSent++; - } - startSpot += x; - - // Can we write both checksum bytes? - // We can send both bytes if we have exactly 2 bytes left to be sent - // (bytesSent == (bytesToSend - 2)) and if there is room for 2 bytes - // in this transmission - if ((bytesSent == (bytesToSend - 2)) && (x == (len - 2))) { - // Write checksum - _i2cPort->write(outgoingUBX->checksumA); - _i2cPort->write(outgoingUBX->checksumB); - bytesSent += 2; - } - } - - if (bytesSent < bytesToSend) // Do we need to go round the loop again? - { - if (_i2cPort->endTransmission(_i2cStopRestart) != - 0) // Don't release bus unless we have to - return ( - SFE_UBLOX_STATUS_I2C_COMM_FAILURE); // Sensor did not ACK - } - } - - // All done transmitting bytes. Release bus. - if (_i2cPort->endTransmission() != 0) - return (SFE_UBLOX_STATUS_I2C_COMM_FAILURE); // Sensor did not ACK - - (void)maxWait; // Do something with maxWait just to avoid the pesky - // compiler warnings! - - return (SFE_UBLOX_STATUS_SUCCESS); -} - -// Given a packet and payload, send everything including CRC bytesA via Serial -// port -void SFE_UBLOX_GNSS::sendSerialCommand(ubxPacket *outgoingUBX) { - // Write header bytes - _serialPort->write(UBX_SYNCH_1); // μ - oh ublox, you're funny. I will call - // you micro-blox from now on. - _serialPort->write(UBX_SYNCH_2); // b - _serialPort->write(outgoingUBX->cls); - _serialPort->write(outgoingUBX->id); - _serialPort->write(outgoingUBX->len & 0xFF); // LSB - _serialPort->write(outgoingUBX->len >> 8); // MSB - - // Write payload. - for (uint16_t i = 0; i < outgoingUBX->len; i++) { - _serialPort->write(outgoingUBX->payload[i]); - } - - // Write checksum - _serialPort->write(outgoingUBX->checksumA); - _serialPort->write(outgoingUBX->checksumB); -} - -// Transfer a byte to SPI. Also capture any bytes received from the UBLOX device -// during sending and capture them in a small buffer so that they can be -// processed later with process -void SFE_UBLOX_GNSS::spiTransfer(uint8_t byteToTransfer) { - uint8_t returnedByte = _spiPort->transfer(byteToTransfer); - if ((spiBufferIndex < getSpiTransactionSize()) && - (returnedByte != 0xFF || - currentSentence != SFE_UBLOX_SENTENCE_TYPE_NONE)) { - spiBuffer[spiBufferIndex] = returnedByte; - spiBufferIndex++; - } -} - -// Send a command via SPI -void SFE_UBLOX_GNSS::sendSpiCommand(ubxPacket *outgoingUBX) { - if (spiBuffer == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->print( - F("sendSpiCommand: no memory allocation for SPI Buffer!")); - } -#endif - return; - } - - // Start at the beginning of the SPI buffer - spiBufferIndex = 0; - - _spiPort->beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - digitalWrite(_csPin, LOW); - // Write header bytes - spiTransfer(UBX_SYNCH_1); // μ - oh ublox, you're funny. I will call you - // micro-blox from now on. - spiTransfer(UBX_SYNCH_2); // b - - spiTransfer(outgoingUBX->cls); - spiTransfer(outgoingUBX->id); - spiTransfer(outgoingUBX->len & 0xFF); // LSB - spiTransfer(outgoingUBX->len >> 8); - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug) { - _debugSerial->print(F("sendSpiCommand: ")); - _debugSerial->print(UBX_SYNCH_1, HEX); - _debugSerial->print(F(" ")); - _debugSerial->print(UBX_SYNCH_2, HEX); - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->cls, HEX); - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->id, HEX); - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->len & 0xFF, HEX); - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->len >> 8, HEX); - } -#endif - - // Write payload. - for (uint16_t i = 0; i < outgoingUBX->len; i++) { - spiTransfer(outgoingUBX->payload[i]); -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug) { - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->payload[i], HEX); - } -#endif - } - - // Write checksum - spiTransfer(outgoingUBX->checksumA); - spiTransfer(outgoingUBX->checksumB); - digitalWrite(_csPin, HIGH); - _spiPort->endTransaction(); - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug) { - _debugSerial->print(F(" ")); - _debugSerial->print(outgoingUBX->checksumA, HEX); - _debugSerial->print(F(" ")); - _debugSerial->println(outgoingUBX->checksumB, HEX); - } -#endif -} - -// Pretty prints the current ubxPacket -void SFE_UBLOX_GNSS::printPacket(ubxPacket *packet, bool alwaysPrintPayload) { - // Only print the payload is ignoreThisPayload is false otherwise - // we could be printing gibberish from beyond the end of packetBuf - // (These two lines get rid of a pesky compiler warning) - bool printPayload = (ignoreThisPayload == false); - printPayload |= (alwaysPrintPayload == true); - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("CLS:")); - if (packet->cls == UBX_CLASS_NAV) // 1 - _debugSerial->print(F("NAV")); - else if (packet->cls == UBX_CLASS_ACK) // 5 - _debugSerial->print(F("ACK")); - else if (packet->cls == UBX_CLASS_CFG) // 6 - _debugSerial->print(F("CFG")); - else if (packet->cls == UBX_CLASS_MON) // 0x0A - _debugSerial->print(F("MON")); - else { - _debugSerial->print(F("0x")); - _debugSerial->print(packet->cls, HEX); - } - - _debugSerial->print(F(" ID:")); - if (packet->cls == UBX_CLASS_NAV && packet->id == UBX_NAV_PVT) - _debugSerial->print(F("PVT")); - else if (packet->cls == UBX_CLASS_CFG && packet->id == UBX_CFG_RATE) - _debugSerial->print(F("RATE")); - else if (packet->cls == UBX_CLASS_CFG && packet->id == UBX_CFG_CFG) - _debugSerial->print(F("SAVE")); - else { - _debugSerial->print(F("0x")); - _debugSerial->print(packet->id, HEX); - } - - _debugSerial->print(F(" Len: 0x")); - _debugSerial->print(packet->len, HEX); - - if (printPayload) { - _debugSerial->print(F(" Payload:")); - - for (uint16_t x = 0; x < packet->len; x++) { - _debugSerial->print(F(" ")); - _debugSerial->print(packet->payload[x], HEX); - } - } else { - _debugSerial->print(F(" Payload: IGNORED")); - } - _debugSerial->println(); - } -#else - if (_printDebug == true) { - _debugSerial->print(F("Len: 0x")); - _debugSerial->print(packet->len, HEX); - } -#endif -} - -// When messages from the class CFG are sent to the receiver, the receiver will -// send an "acknowledge"(UBX - ACK - ACK) or a -//"not acknowledge"(UBX-ACK-NAK) message back to the sender, depending on -// whether or not the message was processed correctly. -// Some messages from other classes also use the same acknowledgement mechanism. - -// When we poll or get a setting, we will receive _both_ a config packet and an -// ACK If the poll or get request is not valid, we will receive _only_ a NACK - -// If we are trying to get or poll a setting, then packetCfg.len will be 0 or 1 -// when the packetCfg is _sent_. If we poll the setting for a particular port -// using UBX-CFG-PRT then .len will be 1 initially For all other gets or polls, -// .len will be 0 initially -//(It would be possible for .len to be 2 _if_ we were using UBX-CFG-MSG to poll -// the settings for a particular message - but we don't use that (currently)) - -// If the get or poll _fails_, i.e. is NACK'd, then packetCfg.len could still be -// 0 or 1 after the NACK is received But if the get or poll is ACK'd, then -// packetCfg.len will have been updated by the incoming data and will always be -// at least 2 - -// If we are going to set the value for a setting, then packetCfg.len will be at -// least 3 when the packetCfg is _sent_. -//(UBX-CFG-MSG appears to have the shortest set length of 3 bytes) - -// We need to think carefully about how interleaved PVT packets affect things. -// It is entirely possible that our packetCfg and packetAck were received -// successfully but while we are still in the "if (checkUblox() == true)" loop a -// PVT packet is processed or _starts_ to arrive (remember that Serial data can -// arrive very slowly). - -// Returns SFE_UBLOX_STATUS_DATA_RECEIVED if we got an ACK and a valid packetCfg -// (module is responding with register content) Returns -// SFE_UBLOX_STATUS_DATA_SENT if we got an ACK and no packetCfg (no valid -// packetCfg needed, module absorbs new register data) Returns -// SFE_UBLOX_STATUS_FAIL if something very bad happens (e.g. a double checksum -// failure) Returns SFE_UBLOX_STATUS_COMMAND_NACK if the packet was -// not-acknowledged (NACK) Returns SFE_UBLOX_STATUS_CRC_FAIL if we had a -// checksum failure Returns SFE_UBLOX_STATUS_TIMEOUT if we timed out Returns -// SFE_UBLOX_STATUS_DATA_OVERWRITTEN if we got an ACK and a valid packetCfg but -// that the packetCfg has been -// or is currently being overwritten (remember that Serial data can arrive very -// slowly) -sfe_ublox_status_e SFE_UBLOX_GNSS::waitForACKResponse(ubxPacket *outgoingUBX, - uint8_t requestedClass, - uint8_t requestedID, - uint16_t maxTime) { - outgoingUBX->valid = - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; // This will go VALID (or - // NOT_VALID) when we receive a - // response to the packet we - // sent - packetAck.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetBuf.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetAuto.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - outgoingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; // This will go VALID (or - // NOT_VALID) when we receive a - // packet that matches the - // requested class and ID - packetAck.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetBuf.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetAuto.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - - unsigned long startTime = millis(); - while (millis() < (startTime + (unsigned long)maxTime)) { - if (checkUbloxInternal(outgoingUBX, requestedClass, requestedID) == - true) // See if new data is available. Process bytes as they come - // in. - { - // If both the outgoingUBX->classAndIDmatch and - // packetAck.classAndIDmatch are VALID and outgoingUBX->valid is - // _still_ VALID and the class and ID _still_ match then we can be - // confident that the data in outgoingUBX is valid - if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->cls == requestedClass) && - (outgoingUBX->id == requestedID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: valid data and valid ACK " - "received after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return ( - SFE_UBLOX_STATUS_DATA_RECEIVED); // We received valid data - // and a correct ACK! - } - - // We can be confident that the data packet (if we are going to get - // one) will always arrive before the matching ACK. So if we sent a - // config packet which only produces an ACK then - // outgoingUBX->classAndIDmatch will be NOT_DEFINED and the - // packetAck.classAndIDmatch will VALID. We should not check - // outgoingUBX->valid, outgoingUBX->cls or outgoingUBX->id as these - // may have been changed by an automatic packet. - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: no data and valid ACK after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return (SFE_UBLOX_STATUS_DATA_SENT); // We got an ACK but no - // data... - } - - // If both the outgoingUBX->classAndIDmatch and - // packetAck.classAndIDmatch are VALID but the outgoingUBX->cls or - // ID no longer match then we can be confident that we had valid - // data but it has been or is currently being overwritten by an - // automatic packet (e.g. PVT). If (e.g.) a PVT packet is _being_ - // received: outgoingUBX->valid will be NOT_DEFINED If (e.g.) a PVT - // packet _has been_ received: outgoingUBX->valid will be VALID (or - // just possibly NOT_VALID) So we cannot use outgoingUBX->valid as - // part of this check. Note: the addition of packetBuf should make - // this check redundant! - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - ((outgoingUBX->cls != requestedClass) || - (outgoingUBX->id != requestedID))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: data being OVERWRITTEN after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return ( - SFE_UBLOX_STATUS_DATA_OVERWRITTEN); // Data was valid but - // has been or is being - // overwritten - } - - // If packetAck.classAndIDmatch is VALID but both outgoingUBX->valid - // and outgoingUBX->classAndIDmatch are NOT_VALID then we can be - // confident we have had a checksum failure on the data packet - else if ((packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID) && - (outgoingUBX->valid == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: CRC failed after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return (SFE_UBLOX_STATUS_CRC_FAIL); // Checksum fail - } - - // If our packet was not-acknowledged (NACK) we do not receive a - // data packet - we only get the NACK. So you would expect - // outgoingUBX->valid and outgoingUBX->classAndIDmatch to still be - // NOT_DEFINED But if a full PVT packet arrives afterwards - // outgoingUBX->valid could be VALID (or just possibly NOT_VALID) - // but outgoingUBX->cls and outgoingUBX->id would not match... - // So I think this is telling us we need a special state for - // packetAck.classAndIDmatch to tell us the packet was definitely - // NACK'd otherwise we are possibly just guessing... Note: the - // addition of packetBuf changes the logic of this, but we'll leave - // the code as is for now. - else if (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_NOTACKNOWLEDGED) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: data was NOTACKNOWLEDGED (NACK) " - "after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return (SFE_UBLOX_STATUS_COMMAND_NACK); // We received a NACK! - } - - // If the outgoingUBX->classAndIDmatch is VALID but the - // packetAck.classAndIDmatch is NOT_VALID then the ack probably had - // a checksum error. We will take a gamble and return DATA_RECEIVED. - // If we were playing safe, we should return FAIL instead - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID) && - (outgoingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->cls == requestedClass) && - (outgoingUBX->id == requestedID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: VALID data and INVALID ACK " - "received after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return ( - SFE_UBLOX_STATUS_DATA_RECEIVED); // We received valid data - // and an invalid ACK! - } - - // If the outgoingUBX->classAndIDmatch is NOT_VALID and the - // packetAck.classAndIDmatch is NOT_VALID then we return a FAIL. - // This must be a double checksum failure? - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: INVALID data and INVALID ACK " - "received after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return (SFE_UBLOX_STATUS_FAIL); // We received invalid data and - // an invalid ACK! - } - - // If the outgoingUBX->classAndIDmatch is VALID and the - // packetAck.classAndIDmatch is NOT_DEFINED then the ACK has not yet - // been received and we should keep waiting for it - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (packetAck.classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED)) { - // if (_printDebug == true) - // { - // _debugSerial->print(F("waitForACKResponse: valid data after - // ")); _debugSerial->print(millis() - startTime); - // _debugSerial->println(F(" msec. Waiting for ACK.")); - // } - } - - } // checkUbloxInternal == true - - delay(1); // Allow an RTOS to get an elbow in (#11) - } // while (millis() < (startTime + (unsigned long)maxTime)) - - // We have timed out... - // If the outgoingUBX->classAndIDmatch is VALID then we can take a gamble - // and return DATA_RECEIVED even though we did not get an ACK - if ((outgoingUBX->classAndIDmatch == SFE_UBLOX_PACKET_VALIDITY_VALID) && - (packetAck.classAndIDmatch == SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED) && - (outgoingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->cls == requestedClass) && - (outgoingUBX->id == requestedID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForACKResponse: TIMEOUT with valid data after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec. ")); - } -#endif - return (SFE_UBLOX_STATUS_DATA_RECEIVED); // We received valid data... - // But no ACK! - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("waitForACKResponse: TIMEOUT after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec.")); - } -#endif - - return (SFE_UBLOX_STATUS_TIMEOUT); -} - -// For non-CFG queries no ACK is sent so we use this function -// Returns SFE_UBLOX_STATUS_DATA_RECEIVED if we got a config packet full of -// response data that has CLS/ID match to our query packet Returns -// SFE_UBLOX_STATUS_CRC_FAIL if we got a corrupt config packet that has CLS/ID -// match to our query packet Returns SFE_UBLOX_STATUS_TIMEOUT if we timed out -// Returns SFE_UBLOX_STATUS_DATA_OVERWRITTEN if we got an a valid packetCfg but -// that the packetCfg has been -// or is currently being overwritten (remember that Serial data can arrive very -// slowly) -sfe_ublox_status_e SFE_UBLOX_GNSS::waitForNoACKResponse(ubxPacket *outgoingUBX, - uint8_t requestedClass, - uint8_t requestedID, - uint16_t maxTime) { - outgoingUBX->valid = - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; // This will go VALID (or - // NOT_VALID) when we receive a - // response to the packet we - // sent - packetAck.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetBuf.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetAuto.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - outgoingUBX->classAndIDmatch = - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; // This will go VALID (or - // NOT_VALID) when we receive a - // packet that matches the - // requested class and ID - packetAck.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetBuf.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - packetAuto.classAndIDmatch = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; - - unsigned long startTime = millis(); - while (millis() - startTime < maxTime) { - if (checkUbloxInternal(outgoingUBX, requestedClass, requestedID) == - true) // See if new data is available. Process bytes as they come - // in. - { - // If outgoingUBX->classAndIDmatch is VALID - // and outgoingUBX->valid is _still_ VALID and the class and ID - // _still_ match then we can be confident that the data in - // outgoingUBX is valid - if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID) && - (outgoingUBX->cls == requestedClass) && - (outgoingUBX->id == requestedID)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForNoACKResponse: valid data with CLS/ID match " - "after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return ( - SFE_UBLOX_STATUS_DATA_RECEIVED); // We received valid data! - } - - // If the outgoingUBX->classAndIDmatch is VALID - // but the outgoingUBX->cls or ID no longer match then we can be - // confident that we had valid data but it has been or is currently - // being overwritten by another packet (e.g. PVT). If (e.g.) a PVT - // packet is _being_ received: outgoingUBX->valid will be - // NOT_DEFINED If (e.g.) a PVT packet _has been_ received: - // outgoingUBX->valid will be VALID (or just possibly NOT_VALID) So - // we cannot use outgoingUBX->valid as part of this check. Note: the - // addition of packetBuf should make this check redundant! - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_VALID) && - ((outgoingUBX->cls != requestedClass) || - (outgoingUBX->id != requestedID))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F( - "waitForNoACKResponse: data being OVERWRITTEN after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return ( - SFE_UBLOX_STATUS_DATA_OVERWRITTEN); // Data was valid but - // has been or is being - // overwritten - } - - // If outgoingUBX->classAndIDmatch is NOT_DEFINED - // and outgoingUBX->valid is VALID then this must be (e.g.) a PVT - // packet - else if ((outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED) && - (outgoingUBX->valid == SFE_UBLOX_PACKET_VALIDITY_VALID)) { - // if (_printDebug == true) - // { - // _debugSerial->print(F("waitForNoACKResponse: valid but - // UNWANTED data after ")); _debugSerial->print(millis() - - // startTime); _debugSerial->print(F(" msec. Class: ")); - // _debugSerial->print(outgoingUBX->cls); - // _debugSerial->print(F(" ID: ")); - // _debugSerial->print(outgoingUBX->id); - // } - } - - // If the outgoingUBX->classAndIDmatch is NOT_VALID then we return - // CRC failure - else if (outgoingUBX->classAndIDmatch == - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print( - F("waitForNoACKResponse: CLS/ID match but failed CRC " - "after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec")); - } -#endif - return (SFE_UBLOX_STATUS_CRC_FAIL); // We received invalid data - } - } - - delay(1); // Allow an RTOS to get an elbow in (#11) - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("waitForNoACKResponse: TIMEOUT after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" msec. No packet received.")); - } -#endif - - return (SFE_UBLOX_STATUS_TIMEOUT); -} - -// Check if any callbacks are waiting to be processed -void SFE_UBLOX_GNSS::checkCallbacks(void) { - if (checkCallbacksReentrant == - true) // Check for reentry (i.e. checkCallbacks has been called from - // inside a callback) - return; - - checkCallbacksReentrant = true; - - if ((packetUBXNAVPOSECEF != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVPOSECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVPOSECEF->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVPOSECEF->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV POSECEF")); - packetUBXNAVPOSECEF->callbackPointer( - *packetUBXNAVPOSECEF->callbackData); // Call the callback - } - if (packetUBXNAVPOSECEF->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV POSECEF")); - packetUBXNAVPOSECEF->callbackPointerPtr( - packetUBXNAVPOSECEF->callbackData); // Call the callback - } - packetUBXNAVPOSECEF->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVSTATUS != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVSTATUS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVSTATUS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV STATUS")); - packetUBXNAVSTATUS->callbackPointer( - *packetUBXNAVSTATUS->callbackData); // Call the callback - } - if (packetUBXNAVSTATUS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV STATUS")); - packetUBXNAVSTATUS->callbackPointerPtr( - packetUBXNAVSTATUS->callbackData); // Call the callback - } - packetUBXNAVSTATUS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVDOP != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVDOP->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVDOP->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVDOP->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV DOP")); - packetUBXNAVDOP->callbackPointer( - *packetUBXNAVDOP->callbackData); // Call the callback - } - if (packetUBXNAVDOP->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV DOP")); - packetUBXNAVDOP->callbackPointerPtr( - packetUBXNAVDOP->callbackData); // Call the callback - } - packetUBXNAVDOP->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVATT != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVATT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVATT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVATT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV ATT")); - packetUBXNAVATT->callbackPointer( - *packetUBXNAVATT->callbackData); // Call the callback - } - if (packetUBXNAVATT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV ATT")); - packetUBXNAVATT->callbackPointerPtr( - packetUBXNAVATT->callbackData); // Call the callback - } - packetUBXNAVATT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVPVT != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVPVT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVPVT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVPVT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV PVT")); - packetUBXNAVPVT->callbackPointer( - *packetUBXNAVPVT->callbackData); // Call the callback - } - if (packetUBXNAVPVT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV PVT")); - packetUBXNAVPVT->callbackPointerPtr( - packetUBXNAVPVT->callbackData); // Call the callback - } - packetUBXNAVPVT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVODO != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVODO->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVODO->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVODO->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV ODO")); - packetUBXNAVODO->callbackPointer( - *packetUBXNAVODO->callbackData); // Call the callback - } - if (packetUBXNAVODO->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV ODO")); - packetUBXNAVODO->callbackPointerPtr( - packetUBXNAVODO->callbackData); // Call the callback - } - packetUBXNAVODO->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVVELECEF != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVVELECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVVELECEF->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVVELECEF->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV VELECEF")); - packetUBXNAVVELECEF->callbackPointer( - *packetUBXNAVVELECEF->callbackData); // Call the callback - } - if (packetUBXNAVVELECEF->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV VELECEF")); - packetUBXNAVVELECEF->callbackPointerPtr( - packetUBXNAVVELECEF->callbackData); // Call the callback - } - packetUBXNAVVELECEF->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVVELNED != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVVELNED->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVVELNED->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVVELNED->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV VELNED")); - packetUBXNAVVELNED->callbackPointer( - *packetUBXNAVVELNED->callbackData); // Call the callback - } - if (packetUBXNAVVELNED->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV VELNED")); - packetUBXNAVVELNED->callbackPointerPtr( - packetUBXNAVVELNED->callbackData); // Call the callback - } - packetUBXNAVVELNED->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVHPPOSECEF != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVHPPOSECEF->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && - (packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVHPPOSECEF->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV HPPOSECEF")); - packetUBXNAVHPPOSECEF->callbackPointer( - *packetUBXNAVHPPOSECEF->callbackData); // Call the callback - } - if (packetUBXNAVHPPOSECEF->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV HPPOSECEF")); - packetUBXNAVHPPOSECEF->callbackPointerPtr( - packetUBXNAVHPPOSECEF->callbackData); // Call the callback - } - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVHPPOSLLH != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVHPPOSLLH->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVHPPOSLLH->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV HPPOSLLH")); - packetUBXNAVHPPOSLLH->callbackPointer( - *packetUBXNAVHPPOSLLH->callbackData); // Call the callback - } - if (packetUBXNAVHPPOSLLH->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV HPPOSLLH")); - packetUBXNAVHPPOSLLH->callbackPointerPtr( - packetUBXNAVHPPOSLLH->callbackData); // Call the callback - } - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVPVAT != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVPVAT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVPVAT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVPVAT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV PVAT")); - packetUBXNAVPVAT->callbackPointer( - *packetUBXNAVPVAT->callbackData); // Call the callback - } - if (packetUBXNAVPVAT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV PVAT")); - packetUBXNAVPVAT->callbackPointerPtr( - packetUBXNAVPVAT->callbackData); // Call the callback - } - packetUBXNAVPVAT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVTIMEUTC != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVTIMEUTC->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVTIMEUTC->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVTIMEUTC->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV TIMEUTC")); - packetUBXNAVTIMEUTC->callbackPointerPtr( - packetUBXNAVTIMEUTC->callbackData); // Call the callback - } - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVCLOCK != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVCLOCK->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVCLOCK->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVCLOCK->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV CLOCK")); - packetUBXNAVCLOCK->callbackPointer( - *packetUBXNAVCLOCK->callbackData); // Call the callback - } - if (packetUBXNAVCLOCK->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV CLOCK")); - packetUBXNAVCLOCK->callbackPointerPtr( - packetUBXNAVCLOCK->callbackData); // Call the callback - } - packetUBXNAVCLOCK->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVSVIN != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVSVIN->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVSVIN->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV SVIN")); - packetUBXNAVSVIN->callbackPointerPtr( - packetUBXNAVSVIN->callbackData); // Call the callback - } - packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVSAT != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVSAT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVSAT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVSAT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV SAT")); - packetUBXNAVSAT->callbackPointer( - *packetUBXNAVSAT->callbackData); // Call the callback - } - if (packetUBXNAVSAT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV SAT")); - packetUBXNAVSAT->callbackPointerPtr( - packetUBXNAVSAT->callbackData); // Call the callback - } - packetUBXNAVSAT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVRELPOSNED != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVRELPOSNED->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && - (packetUBXNAVRELPOSNED->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVRELPOSNED->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV RELPOSNED")); - packetUBXNAVRELPOSNED->callbackPointer( - *packetUBXNAVRELPOSNED->callbackData); // Call the callback - } - if (packetUBXNAVRELPOSNED->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV RELPOSNED")); - packetUBXNAVRELPOSNED->callbackPointerPtr( - packetUBXNAVRELPOSNED->callbackData); // Call the callback - } - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVAOPSTATUS != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVAOPSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && - (packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVAOPSTATUS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // NAV AOPSTATUS")); - packetUBXNAVAOPSTATUS->callbackPointer( - *packetUBXNAVAOPSTATUS->callbackData); // Call the callback - } - if (packetUBXNAVAOPSTATUS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV AOPSTATUS")); - packetUBXNAVAOPSTATUS->callbackPointerPtr( - packetUBXNAVAOPSTATUS->callbackData); // Call the callback - } - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXNAVEOE != - NULL) // If RAM has been allocated for message storage - && (packetUBXNAVEOE->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXNAVEOE->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXNAVEOE->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for NAV EOE")); - packetUBXNAVEOE->callbackPointerPtr( - packetUBXNAVEOE->callbackData); // Call the callback - } - packetUBXNAVEOE->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXRXMPMP != - NULL) // If RAM has been allocated for message storage - && (packetUBXRXMPMP->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXRXMPMP->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - && (packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr for - // RXM PMP")); - packetUBXRXMPMP->callbackPointerPtr( - packetUBXRXMPMP->callbackData); // Call the callback - packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXRXMPMPmessage != - NULL) // If RAM has been allocated for message storage - && (packetUBXRXMPMPmessage->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXRXMPMPmessage->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - && - (packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr for - // RXM PMP message")); - packetUBXRXMPMPmessage->callbackPointerPtr( - packetUBXRXMPMPmessage->callbackData); // Call the callback - packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXRXMQZSSL6message != - NULL) && // If RAM has been allocated for message storage - (packetUBXRXMQZSSL6message->callbackData != - NULL) && // If RAM has been allocated for the copy of the data - (packetUBXRXMQZSSL6message->callbackPointerPtr != - NULL)) // If the pointer to the callback has been defined - { - for (int ch = 0; ch < UBX_RXM_QZSSL6_NUM_CHANNELS; ch++) { - if (packetUBXRXMQZSSL6message->automaticFlags.flags.bits - .callbackCopyValid & - (1 << ch)) // If the copy of the data is valid - { - packetUBXRXMQZSSL6message->callbackPointerPtr( - &packetUBXRXMQZSSL6message - ->callbackData[ch]); // Call the callback - packetUBXRXMQZSSL6message->automaticFlags.flags.bits - .callbackCopyValid &= ~(1 << ch); // clear it - } - } - } - - if ((packetUBXRXMCOR != - NULL) // If RAM has been allocated for message storage - && (packetUBXRXMCOR->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXRXMCOR->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - && (packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr for - // RXM COR")); - packetUBXRXMCOR->callbackPointerPtr( - packetUBXRXMCOR->callbackData); // Call the callback - packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXRXMSFRBX != - NULL) // If RAM has been allocated for message storage - && (packetUBXRXMSFRBX->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXRXMSFRBX->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // RXM SFRBX")); - packetUBXRXMSFRBX->callbackPointer( - *packetUBXRXMSFRBX->callbackData); // Call the callback - } - if (packetUBXRXMSFRBX->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for RXM SFRBX")); - packetUBXRXMSFRBX->callbackPointerPtr( - packetUBXRXMSFRBX->callbackData); // Call the callback - } - packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXRXMRAWX != - NULL) // If RAM has been allocated for message storage - && (packetUBXRXMRAWX->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXRXMRAWX->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXRXMRAWX->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // RXM RAWX")); - packetUBXRXMRAWX->callbackPointer( - *packetUBXRXMRAWX->callbackData); // Call the callback - } - if (packetUBXRXMRAWX->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for RXM RAWX")); - packetUBXRXMRAWX->callbackPointerPtr( - packetUBXRXMRAWX->callbackData); // Call the callback - } - packetUBXRXMRAWX->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXTIMTM2 != - NULL) // If RAM has been allocated for message storage - && (packetUBXTIMTM2->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXTIMTM2->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXTIMTM2->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // TIM TM2")); - packetUBXTIMTM2->callbackPointer( - *packetUBXTIMTM2->callbackData); // Call the callback - } - if (packetUBXTIMTM2->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for TIM TM2")); - packetUBXTIMTM2->callbackPointerPtr( - packetUBXTIMTM2->callbackData); // Call the callback - } - packetUBXTIMTM2->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXESFALG != - NULL) // If RAM has been allocated for message storage - && (packetUBXESFALG->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXESFALG->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXESFALG->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // ESF ALG")); - packetUBXESFALG->callbackPointer( - *packetUBXESFALG->callbackData); // Call the callback - } - if (packetUBXESFALG->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for ESF ALG")); - packetUBXESFALG->callbackPointerPtr( - packetUBXESFALG->callbackData); // Call the callback - } - packetUBXESFALG->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXESFINS != - NULL) // If RAM has been allocated for message storage - && (packetUBXESFINS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXESFINS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXESFINS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // ESF INS")); - packetUBXESFINS->callbackPointer( - *packetUBXESFINS->callbackData); // Call the callback - } - if (packetUBXESFINS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for ESF INS")); - packetUBXESFINS->callbackPointerPtr( - packetUBXESFINS->callbackData); // Call the callback - } - packetUBXESFINS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXESFMEAS != - NULL) // If RAM has been allocated for message storage - && (packetUBXESFMEAS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXESFMEAS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXESFMEAS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // ESF MEAS")); - packetUBXESFMEAS->callbackPointer( - *packetUBXESFMEAS->callbackData); // Call the callback - } - if (packetUBXESFMEAS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for ESF MEAS")); - packetUBXESFMEAS->callbackPointerPtr( - packetUBXESFMEAS->callbackData); // Call the callback - } - packetUBXESFMEAS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXESFRAW != - NULL) // If RAM has been allocated for message storage - && (packetUBXESFRAW->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXESFRAW->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXESFRAW->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // ESF RAW")); - packetUBXESFRAW->callbackPointer( - *packetUBXESFRAW->callbackData); // Call the callback - } - if (packetUBXESFRAW->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for ESF RAW")); - packetUBXESFRAW->callbackPointerPtr( - packetUBXESFRAW->callbackData); // Call the callback - } - packetUBXESFRAW->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXESFSTATUS != - NULL) // If RAM has been allocated for message storage - && (packetUBXESFSTATUS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXESFSTATUS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXESFSTATUS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // ESF STATUS")); - packetUBXESFSTATUS->callbackPointer( - *packetUBXESFSTATUS->callbackData); // Call the callback - } - if (packetUBXESFSTATUS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for ESF STATUS")); - packetUBXESFSTATUS->callbackPointerPtr( - packetUBXESFSTATUS->callbackData); // Call the callback - } - packetUBXESFSTATUS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXHNRATT != - NULL) // If RAM has been allocated for message storage - && (packetUBXHNRATT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXHNRATT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXHNRATT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // HNR ATT")); - packetUBXHNRATT->callbackPointer( - *packetUBXHNRATT->callbackData); // Call the callback - } - if (packetUBXHNRATT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for HNR ATT")); - packetUBXHNRATT->callbackPointerPtr( - packetUBXHNRATT->callbackData); // Call the callback - } - packetUBXHNRATT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXHNRINS != - NULL) // If RAM has been allocated for message storage - && (packetUBXHNRINS->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXHNRINS->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXHNRINS->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // HNR INS")); - packetUBXHNRINS->callbackPointer( - *packetUBXHNRINS->callbackData); // Call the callback - } - if (packetUBXHNRINS->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for HNR INS")); - packetUBXHNRINS->callbackPointerPtr( - packetUBXHNRINS->callbackData); // Call the callback - } - packetUBXHNRINS->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - - if ((packetUBXHNRPVT != - NULL) // If RAM has been allocated for message storage - && (packetUBXHNRPVT->callbackData != - NULL) // If RAM has been allocated for the copy of the data - && (packetUBXHNRPVT->automaticFlags.flags.bits.callbackCopyValid == - true)) // If the copy of the data is valid - { - if (packetUBXHNRPVT->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // HNR PVT")); - packetUBXHNRPVT->callbackPointer( - *packetUBXHNRPVT->callbackData); // Call the callback - } - if (packetUBXHNRPVT->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for HNR PVT")); - packetUBXHNRPVT->callbackPointerPtr( - packetUBXHNRPVT->callbackData); // Call the callback - } - packetUBXHNRPVT->automaticFlags.flags.bits.callbackCopyValid = - false; // Mark the data as stale - } - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - if ((storageNMEAGPGGA != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGPGGA->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGPGGA->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GPGGA")); - storageNMEAGPGGA->callbackPointer( - *storageNMEAGPGGA->callbackCopy); // Call the callback - } - if (storageNMEAGPGGA->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GPGGA")); - storageNMEAGPGGA->callbackPointerPtr( - storageNMEAGPGGA->callbackCopy); // Call the callback - } - storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGNGGA != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGNGGA->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGNGGA->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGNGGA->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GNGGA")); - storageNMEAGNGGA->callbackPointer( - *storageNMEAGNGGA->callbackCopy); // Call the callback - } - if (storageNMEAGNGGA->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GNGGA")); - storageNMEAGNGGA->callbackPointerPtr( - storageNMEAGNGGA->callbackCopy); // Call the callback - } - storageNMEAGNGGA->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGPVTG != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGPVTG->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGPVTG->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGPVTG->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GPVTG")); - storageNMEAGPVTG->callbackPointer( - *storageNMEAGPVTG->callbackCopy); // Call the callback - } - if (storageNMEAGPVTG->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GPVTG")); - storageNMEAGPVTG->callbackPointerPtr( - storageNMEAGPVTG->callbackCopy); // Call the callback - } - storageNMEAGPVTG->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGNVTG != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGNVTG->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGNVTG->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGNVTG->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GNVTG")); - storageNMEAGNVTG->callbackPointer( - *storageNMEAGNVTG->callbackCopy); // Call the callback - } - if (storageNMEAGNVTG->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GNVTG")); - storageNMEAGNVTG->callbackPointerPtr( - storageNMEAGNVTG->callbackCopy); // Call the callback - } - storageNMEAGNVTG->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGPRMC != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGPRMC->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGPRMC->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGPRMC->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GPRMC")); - storageNMEAGPRMC->callbackPointer( - *storageNMEAGPRMC->callbackCopy); // Call the callback - } - if (storageNMEAGPRMC->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GPRMC")); - storageNMEAGPRMC->callbackPointerPtr( - storageNMEAGPRMC->callbackCopy); // Call the callback - } - storageNMEAGPRMC->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGNRMC != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGNRMC->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGNRMC->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGNRMC->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GNRMC")); - storageNMEAGNRMC->callbackPointer( - *storageNMEAGNRMC->callbackCopy); // Call the callback - } - if (storageNMEAGNRMC->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GNRMC")); - storageNMEAGNRMC->callbackPointerPtr( - storageNMEAGNRMC->callbackCopy); // Call the callback - } - storageNMEAGNRMC->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGPZDA != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGPZDA->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGPZDA->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGPZDA->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GPZDA")); - storageNMEAGPZDA->callbackPointer( - *storageNMEAGPZDA->callbackCopy); // Call the callback - } - if (storageNMEAGPZDA->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GPZDA")); - storageNMEAGPZDA->callbackPointerPtr( - storageNMEAGPZDA->callbackCopy); // Call the callback - } - storageNMEAGPZDA->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } - - if ((storageNMEAGNZDA != - NULL) // If RAM has been allocated for message storage - && (storageNMEAGNZDA->callbackCopy != - NULL) // If RAM has been allocated for the copy of the data - && (storageNMEAGNZDA->automaticFlags.flags.bits.callbackCopyValid == - 1)) // If the copy of the data is valid - { - if (storageNMEAGNZDA->callbackPointer != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callback for - // GNZDA")); - storageNMEAGNZDA->callbackPointer( - *storageNMEAGNZDA->callbackCopy); // Call the callback - } - if (storageNMEAGNZDA->callbackPointerPtr != - NULL) // If the pointer to the callback has been defined - { - // if (_printDebug == true) - // _debugSerial->println(F("checkCallbacks: calling callbackPtr - // for GNZDA")); - storageNMEAGNZDA->callbackPointerPtr( - storageNMEAGNZDA->callbackCopy); // Call the callback - } - storageNMEAGNZDA->automaticFlags.flags.bits.callbackCopyValid = - 0; // Mark the data as stale - } -#endif - - checkCallbacksReentrant = false; -} - -// Push (e.g.) RTCM data directly to the module -// Returns true if all numDataBytes were pushed successfully -// Warning: this function does not check that the data is valid. It is the -// user's responsibility to ensure the data is valid before pushing. Default to -// using a restart between transmissions. But processors like ESP32 seem to need -// a stop (#30). Set stop to true to use a stop instead. On processors like the -// ESP32, you can use setI2CTransactionSize to increase the size of each -// transmission - to e.g. 128 bytes -bool SFE_UBLOX_GNSS::pushRawData(uint8_t *dataBytes, size_t numDataBytes, - bool stop) { - // Return now if numDataBytes is zero - if (numDataBytes == 0) - return (false); // Indicate to the user that there was no data to push - - if (commType == COMM_TYPE_SERIAL) { - // Serial: write all the bytes in one go - size_t bytesWritten = _serialPort->write(dataBytes, numDataBytes); - return (bytesWritten == numDataBytes); - } else if (commType == COMM_TYPE_I2C) { - // We can not write a single data byte to I2C as it would look like the - // address of a random read. If numDataBytes is 1, we should probably - // just reject the data and return false. But we'll be nice and store - // the byte until the next time pushRawData is called. - if ((numDataBytes == 1) && (_pushSingleByte == false)) { - _pushThisSingleByte = *dataBytes; - _pushSingleByte = true; - return (false); // Indicate to the user that their data has not - // been pushed yet - } - - // If stop is true then always use a stop - // Else if _i2cStopRestart is true then always use a stop - // Else use a restart where needed - if (stop == true) - stop = true; // Redundant - but makes it clear what is happening - else if (_i2cStopRestart == true) - stop = true; - else - stop = false; // Use a restart - - // I2C: split the data up into packets of i2cTransactionSize - size_t bytesLeftToWrite = numDataBytes; - size_t bytesWrittenTotal = 0; - - if (_pushSingleByte == true) // Increment bytesLeftToWrite if we have a - // single byte waiting to be pushed - bytesLeftToWrite++; - - while (bytesLeftToWrite > 0) { - size_t bytesToWrite; // Limit bytesToWrite to i2cTransactionSize - if (bytesLeftToWrite > i2cTransactionSize) - bytesToWrite = i2cTransactionSize; - else - bytesToWrite = bytesLeftToWrite; - - // If there would be one byte left to be written next time, send one - // byte less now - if ((bytesLeftToWrite - bytesToWrite) == 1) bytesToWrite--; - - _i2cPort->beginTransmission(_gpsI2Caddress); - - size_t bytesWritten = 0; - - // If _pushSingleByte is true, push it now - if (_pushSingleByte == true) { - bytesWritten += _i2cPort->write( - _pushThisSingleByte); // Write the single byte - bytesWritten += _i2cPort->write( - dataBytes, - bytesToWrite - - 1); // Write the bytes - but send one byte less - dataBytes += bytesToWrite - 1; // Point to fresh data - _pushSingleByte = false; // Clear the flag - } else { - bytesWritten += _i2cPort->write( - dataBytes, bytesToWrite); // Write the bytes - dataBytes += bytesToWrite; // Point to fresh data - } - - bytesWrittenTotal += bytesWritten; // Update the totals - bytesLeftToWrite -= bytesToWrite; - - if (bytesLeftToWrite > 0) { - if (_i2cPort->endTransmission(stop) != - 0) // Send a restart or stop command - return (false); // Sensor did not ACK - } else { - if (_i2cPort->endTransmission() != - 0) // We're done. Release bus. Always use a stop here - return (false); // Sensor did not ACK - } - } - - return (bytesWrittenTotal == - numDataBytes); // Return true if the correct number of bytes - // were written - } else // SPI - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("pushRawData: SPI not currently supported")); - } -#endif - return (false); - } -} - -// Push MGA AssistNow data to the module. -// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE). -// Wait for maxWait millis after sending each packet (if mgaAck is NO). -// Return how many bytes were pushed successfully. -// If skipTime is true, any UBX-MGA-INI-TIME_UTC or UBX-MGA-INI-TIME_GNSS -// packets found in the data will be skipped, allowing the user to override with -// their own time data with setUTCTimeAssistance. -size_t SFE_UBLOX_GNSS::pushAssistNowData(const String &dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(0, false, - (const uint8_t *)dataBytes.c_str(), - numDataBytes, mgaAck, maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowData(const uint8_t *dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(0, false, dataBytes, numDataBytes, mgaAck, - maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, const String &dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(0, skipTime, - (const uint8_t *)dataBytes.c_str(), - numDataBytes, mgaAck, maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, - const uint8_t *dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(0, skipTime, dataBytes, numDataBytes, - mgaAck, maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowData(size_t offset, bool skipTime, - const String &dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(offset, skipTime, - (const uint8_t *)dataBytes.c_str(), - numDataBytes, mgaAck, maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowData(size_t offset, bool skipTime, - const uint8_t *dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - return (pushAssistNowDataInternal(offset, skipTime, dataBytes, numDataBytes, - mgaAck, maxWait)); -} -size_t SFE_UBLOX_GNSS::pushAssistNowDataInternal( - size_t offset, bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait) { - size_t dataPtr = offset; // Pointer into dataBytes - size_t packetsProcessed = - 0; // Keep count of how many packets have been processed - size_t bytesPushed = 0; // Keep count - - bool checkForAcks = - (mgaAck == SFE_UBLOX_MGA_ASSIST_ACK_YES); // If mgaAck is YES, always - // check for Acks - - // If mgaAck is ENQUIRE, we need to check UBX-CFG-NAVX5 ackAiding to - // determine if UBX-MGA-ACK's are expected - if (mgaAck == SFE_UBLOX_MGA_ASSIST_ACK_ENQUIRE) { - uint8_t ackAiding = - getAckAiding(maxWait); // Enquire if we should expect Acks - if (ackAiding == 1) checkForAcks = true; - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->print( - F("pushAssistNowData: mgaAck is ENQUIRE. getAckAiding " - "returned ")); - _debugSerial->println(ackAiding); - } -#endif - } - - // If checkForAcks is true, then we need to set up storage for the - // UBX-MGA-ACK-DATA0 messages - if (checkForAcks) { - if (packetUBXMGAACK == NULL) - initPacketUBXMGAACK(); // Check that RAM has been allocated for the - // MGA_ACK data - if (packetUBXMGAACK == NULL) // Bail if the RAM allocation failed - return (0); - } - - while (dataPtr < - (offset + - numDataBytes)) // Keep going until we have processed all the bytes - { - // Start by checking the validity of the packet being pointed to - bool dataIsOK = true; - - dataIsOK &= - (*(dataBytes + dataPtr + 0) == UBX_SYNCH_1); // Check for 0xB5 - dataIsOK &= - (*(dataBytes + dataPtr + 1) == UBX_SYNCH_2); // Check for 0x62 - dataIsOK &= (*(dataBytes + dataPtr + 2) == - UBX_CLASS_MGA); // Check for class UBX-MGA - - size_t packetLength = ((size_t) * (dataBytes + dataPtr + 4)) | - (((size_t) * (dataBytes + dataPtr + 5)) - << 8); // Extract the length - - uint8_t checksumA = 0; - uint8_t checksumB = 0; - // Calculate the checksum bytes - // Keep going until the end of the packet is reached (payloadPtr == - // (dataPtr + packetLength)) or we reach the end of the AssistNow data - // (payloadPtr == offset + numDataBytes) - for (size_t payloadPtr = dataPtr + ((size_t)2); - (payloadPtr < (dataPtr + packetLength + ((size_t)6))) && - (payloadPtr < (offset + numDataBytes)); - payloadPtr++) { - checksumA += *(dataBytes + payloadPtr); - checksumB += checksumA; - } - // Check the checksum bytes - dataIsOK &= - (checksumA == *(dataBytes + dataPtr + packetLength + ((size_t)6))); - dataIsOK &= - (checksumB == *(dataBytes + dataPtr + packetLength + ((size_t)7))); - - dataIsOK &= ((dataPtr + packetLength + ((size_t)8)) <= - (offset + numDataBytes)); // Check we haven't overrun - - // If the data is valid, push it - if (dataIsOK) { - // Check if this is time assistance data which should be skipped - if ((skipTime) && - ((*(dataBytes + dataPtr + 3) == UBX_MGA_INI_TIME_UTC) || - (*(dataBytes + dataPtr + 3) == UBX_MGA_INI_TIME_GNSS))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print( - F("pushAssistNowData: skipped INI_TIME ID 0x")); - if (*(dataBytes + dataPtr + 3) < 0x10) - _debugSerial->print(F("0")); - _debugSerial->println(*(dataBytes + dataPtr + 3), HEX); - } -#endif - } else { - bool pushResult = - pushRawData((uint8_t *)(dataBytes + dataPtr), - packetLength + ((size_t)8)); // Push the data - - if (pushResult) - bytesPushed += - packetLength + ((size_t)8); // Increment bytesPushed if - // the push was successful - - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print(F("pushAssistNowData: packet ID 0x")); - if (*(dataBytes + dataPtr + 3) < 0x10) - _debugSerial->print(F("0")); - _debugSerial->print(*(dataBytes + dataPtr + 3), HEX); - _debugSerial->print(F(" length ")); - _debugSerial->println(packetLength); - } - - if (checkForAcks) { - unsigned long startTime = millis(); - bool keepGoing = true; - while (keepGoing && - (millis() < - (startTime + maxWait))) // Keep checking for the - // ACK until we time out - { - checkUblox(); - if (packetUBXMGAACK->head != - packetUBXMGAACK - ->tail) // Does the MGA ACK ringbuffer contain - // any ACK's? - { - bool dataAckd = true; // Check if we've received - // the correct ACK - dataAckd &= - (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgId == - *(dataBytes + dataPtr + - 3)); // Check if the message ID matches - dataAckd &= - (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[0] == - *(dataBytes + dataPtr + - 6)); // Check if the first four data bytes - // match - dataAckd &= - (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[1] == - *(dataBytes + dataPtr + 7)); - dataAckd &= - (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[2] == - *(dataBytes + dataPtr + 8)); - dataAckd &= - (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[3] == - *(dataBytes + dataPtr + 9)); - - if (dataAckd) // Is this the ACK we are looking - // for? - { - if ((packetUBXMGAACK - ->data[packetUBXMGAACK->tail] - .type == (uint8_t)1) && - (packetUBXMGAACK - ->data[packetUBXMGAACK->tail] - .infoCode == - (uint8_t) - SFE_UBLOX_MGA_ACK_INFOCODE_ACCEPTED)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print - // this if doing limited - // debugging - { - _debugSerial->print( - F("pushAssistNowData: packet was " - "accepted after ")); - _debugSerial->print(millis() - - startTime); - _debugSerial->println(F(" ms")); - } -#endif - packetsProcessed++; - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print - // this if doing limited - // debugging - { - _debugSerial->print( - F("pushAssistNowData: packet was " - "_not_ accepted. infoCode is ")); - _debugSerial->println( - packetUBXMGAACK - ->data[packetUBXMGAACK->tail] - .infoCode); - } -#endif - } - keepGoing = false; - } - // Increment the tail - packetUBXMGAACK->tail++; - if (packetUBXMGAACK->tail == - UBX_MGA_ACK_DATA0_RINGBUFFER_LEN) - packetUBXMGAACK->tail = 0; - } - } - if (keepGoing) // If keepGoing is still true, we must have - // timed out - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing - // limited debugging - { - _debugSerial->println( - F("pushAssistNowData: packet ack timed out!")); - } -#endif - } - } else { - // We are not checking for Acks, so let's assume the send - // was successful? - packetsProcessed++; - // We are not checking for Acks, so delay for maxWait millis - // unless we've reached the end of the data - if ((dataPtr + packetLength + ((size_t)8)) < - (offset + numDataBytes)) { - delay(maxWait); - } - } - } - - dataPtr += packetLength + ((size_t)8); // Point to the next message - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - // The data was invalid. Send a debug message and then try to find - // the next 0xB5 - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - _debugSerial->print( - F("pushAssistNowData: bad data - ignored! dataPtr is ")); - _debugSerial->println(dataPtr); - } -#endif - - while ((dataPtr < (offset + numDataBytes)) && - (*(dataBytes + ++dataPtr) != UBX_SYNCH_1)) { - ; // Increment dataPtr until we are pointing at the next 0xB5 - - // or we reach the end of the data - } - } - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->print(F("pushAssistNowData: packetsProcessed: ")); - _debugSerial->println(packetsProcessed); - } -#endif - - return ( - bytesPushed); // Return the number of valid bytes successfully pushed -} - -// PRIVATE: Allocate RAM for packetUBXMGAACK and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXMGAACK() { - packetUBXMGAACK = - new UBX_MGA_ACK_DATA0_t; // Allocate RAM for the main struct - if (packetUBXMGAACK == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXMGAACK: RAM alloc failed!")); -#endif - return (false); - } - packetUBXMGAACK->head = 0; // Initialize the ring buffer pointers - packetUBXMGAACK->tail = 0; - return (true); -} - -// Provide initial time assistance -bool SFE_UBLOX_GNSS::setUTCTimeAssistance( - uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, - uint8_t second, uint32_t nanos, uint16_t tAccS, uint32_t tAccNs, - uint8_t source, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait) { - uint8_t iniTimeUTC[32]; // Create the UBX-MGA-INI-TIME_UTC message by hand - memset(iniTimeUTC, 0x00, - 32); // Set all unused / reserved bytes and the checksum to zero - - iniTimeUTC[0] = UBX_SYNCH_1; // Sync char 1 - iniTimeUTC[1] = UBX_SYNCH_2; // Sync char 2 - iniTimeUTC[2] = UBX_CLASS_MGA; // Class - iniTimeUTC[3] = UBX_MGA_INI_TIME_UTC; // ID - iniTimeUTC[4] = 24; // Length LSB - iniTimeUTC[5] = 0x00; // Length MSB - iniTimeUTC[6] = 0x10; // type - iniTimeUTC[7] = 0x00; // version - iniTimeUTC[8] = source; // ref (source) - iniTimeUTC[9] = 0x80; // leapSecs. Set to 0x80 = unknown - iniTimeUTC[10] = (uint8_t)(year & 0xFF); // year LSB - iniTimeUTC[11] = (uint8_t)(year >> 8); // year MSB - iniTimeUTC[12] = month; // month starting at 1 - iniTimeUTC[13] = day; // day starting at 1 - iniTimeUTC[14] = hour; // hour 0:23 - iniTimeUTC[15] = minute; // minute 0:59 - iniTimeUTC[16] = second; // seconds 0:59 - iniTimeUTC[18] = (uint8_t)(nanos & 0xFF); // nanoseconds LSB - iniTimeUTC[19] = (uint8_t)((nanos >> 8) & 0xFF); - iniTimeUTC[20] = (uint8_t)((nanos >> 16) & 0xFF); - iniTimeUTC[21] = (uint8_t)(nanos >> 24); // nanoseconds MSB - iniTimeUTC[22] = - (uint8_t)(tAccS & 0xFF); // seconds part of the accuracy LSB - iniTimeUTC[23] = (uint8_t)(tAccS >> 8); // seconds part of the accuracy MSB - iniTimeUTC[26] = - (uint8_t)(tAccNs & 0xFF); // nanoseconds part of the accuracy LSB - iniTimeUTC[27] = (uint8_t)((tAccNs >> 8) & 0xFF); - iniTimeUTC[28] = (uint8_t)((tAccNs >> 16) & 0xFF); - iniTimeUTC[29] = - (uint8_t)(tAccNs >> 24); // nanoseconds part of the accuracy MSB - - for (uint8_t i = 2; i < 30; i++) // Calculate the checksum - { - iniTimeUTC[30] += iniTimeUTC[i]; - iniTimeUTC[31] += iniTimeUTC[30]; - } - - // Return true if the one packet was pushed successfully - return (pushAssistNowDataInternal(0, false, iniTimeUTC, 32, mgaAck, - maxWait) == 32); -} - -// Provide initial position assistance -// The units for ecefX/Y/Z and posAcc (stddev) are cm. -bool SFE_UBLOX_GNSS::setPositionAssistanceXYZ(int32_t ecefX, int32_t ecefY, - int32_t ecefZ, uint32_t posAcc, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - uint8_t iniPosXYZ[28]; // Create the UBX-MGA-INI-POS_XYZ message by hand - memset(iniPosXYZ, 0x00, - 28); // Set all unused / reserved bytes and the checksum to zero - - iniPosXYZ[0] = UBX_SYNCH_1; // Sync char 1 - iniPosXYZ[1] = UBX_SYNCH_2; // Sync char 2 - iniPosXYZ[2] = UBX_CLASS_MGA; // Class - iniPosXYZ[3] = UBX_MGA_INI_POS_XYZ; // ID - iniPosXYZ[4] = 20; // Length LSB - iniPosXYZ[5] = 0x00; // Length MSB - iniPosXYZ[6] = 0x00; // type - iniPosXYZ[7] = 0x00; // version - - union // Use a union to convert from int32_t to uint32_t - { - int32_t signedLong; - uint32_t unsignedLong; - } signedUnsigned; - - signedUnsigned.signedLong = ecefX; - iniPosXYZ[10] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosXYZ[11] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosXYZ[12] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosXYZ[13] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - signedUnsigned.signedLong = ecefY; - iniPosXYZ[14] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosXYZ[15] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosXYZ[16] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosXYZ[17] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - signedUnsigned.signedLong = ecefZ; - iniPosXYZ[18] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosXYZ[19] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosXYZ[20] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosXYZ[21] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - iniPosXYZ[22] = (uint8_t)(posAcc & 0xFF); // LSB - iniPosXYZ[23] = (uint8_t)((posAcc >> 8) & 0xFF); - iniPosXYZ[24] = (uint8_t)((posAcc >> 16) & 0xFF); - iniPosXYZ[25] = (uint8_t)(posAcc >> 24); // MSB - - for (uint8_t i = 2; i < 26; i++) // Calculate the checksum - { - iniPosXYZ[26] += iniPosXYZ[i]; - iniPosXYZ[27] += iniPosXYZ[26]; - } - - // Return true if the one packet was pushed successfully - return (pushAssistNowDataInternal(0, false, iniPosXYZ, 28, mgaAck, - maxWait) == 28); -} - -// The units for lat and lon are degrees * 1e-7 (WGS84) -// The units for alt (WGS84) and posAcc (stddev) are cm. -bool SFE_UBLOX_GNSS::setPositionAssistanceLLH(int32_t lat, int32_t lon, - int32_t alt, uint32_t posAcc, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait) { - uint8_t iniPosLLH[28]; // Create the UBX-MGA-INI-POS_LLH message by hand - memset(iniPosLLH, 0x00, - 28); // Set all unused / reserved bytes and the checksum to zero - - iniPosLLH[0] = UBX_SYNCH_1; // Sync char 1 - iniPosLLH[1] = UBX_SYNCH_2; // Sync char 2 - iniPosLLH[2] = UBX_CLASS_MGA; // Class - iniPosLLH[3] = UBX_MGA_INI_POS_LLH; // ID - iniPosLLH[4] = 20; // Length LSB - iniPosLLH[5] = 0x00; // Length MSB - iniPosLLH[6] = 0x01; // type - iniPosLLH[7] = 0x00; // version - - union // Use a union to convert from int32_t to uint32_t - { - int32_t signedLong; - uint32_t unsignedLong; - } signedUnsigned; - - signedUnsigned.signedLong = lat; - iniPosLLH[10] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosLLH[11] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosLLH[12] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosLLH[13] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - signedUnsigned.signedLong = lon; - iniPosLLH[14] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosLLH[15] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosLLH[16] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosLLH[17] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - signedUnsigned.signedLong = alt; - iniPosLLH[18] = (uint8_t)(signedUnsigned.unsignedLong & 0xFF); // LSB - iniPosLLH[19] = (uint8_t)((signedUnsigned.unsignedLong >> 8) & 0xFF); - iniPosLLH[20] = (uint8_t)((signedUnsigned.unsignedLong >> 16) & 0xFF); - iniPosLLH[21] = (uint8_t)(signedUnsigned.unsignedLong >> 24); // MSB - - iniPosLLH[22] = (uint8_t)(posAcc & 0xFF); // LSB - iniPosLLH[23] = (uint8_t)((posAcc >> 8) & 0xFF); - iniPosLLH[24] = (uint8_t)((posAcc >> 16) & 0xFF); - iniPosLLH[25] = (uint8_t)(posAcc >> 24); // MSB - - for (uint8_t i = 2; i < 26; i++) // Calculate the checksum - { - iniPosLLH[26] += iniPosLLH[i]; - iniPosLLH[27] += iniPosLLH[26]; - } - - // Return true if the one packet was pushed successfully - return (pushAssistNowDataInternal(0, false, iniPosLLH, 28, mgaAck, - maxWait) == 28); -} - -// Find the start of the AssistNow Offline (UBX_MGA_ANO) data for the chosen day -// The daysIntoFture parameter makes it easy to get the data for (e.g.) tomorrow -// based on today's date Returns numDataBytes if unsuccessful TO DO: enhance -// this so it will find the nearest data for the chosen day - instead of an -// exact match -size_t SFE_UBLOX_GNSS::findMGAANOForDate(const String &dataBytes, - size_t numDataBytes, uint16_t year, - uint8_t month, uint8_t day, - uint8_t daysIntoFuture) { - return (findMGAANOForDateInternal((const uint8_t *)dataBytes.c_str(), - numDataBytes, year, month, day, - daysIntoFuture)); -} -size_t SFE_UBLOX_GNSS::findMGAANOForDate(const uint8_t *dataBytes, - size_t numDataBytes, uint16_t year, - uint8_t month, uint8_t day, - uint8_t daysIntoFuture) { - return (findMGAANOForDateInternal(dataBytes, numDataBytes, year, month, day, - daysIntoFuture)); -} -size_t SFE_UBLOX_GNSS::findMGAANOForDateInternal(const uint8_t *dataBytes, - size_t numDataBytes, - uint16_t year, uint8_t month, - uint8_t day, - uint8_t daysIntoFuture) { - size_t dataPtr = 0; // Pointer into dataBytes - bool dateFound = false; // Flag to indicate when the date has been found - - // Calculate matchDay, matchMonth and matchYear - uint8_t matchDay = day; - uint8_t matchMonth = month; - uint8_t matchYear = (uint8_t)(year - 2000); - - // Add on daysIntoFuture - uint8_t daysIntoFutureCopy = daysIntoFuture; - while (daysIntoFutureCopy > 0) { - matchDay++; - daysIntoFutureCopy--; - switch (matchMonth) { - case 1: - case 3: - case 5: - case 7: - case 8: - case 10: - case 12: - if (matchDay == 32) { - matchDay = 1; - matchMonth++; - if (matchMonth == 13) { - matchMonth = 1; - matchYear++; - } - } - break; - case 4: - case 6: - case 9: - case 11: - if (matchDay == 31) { - matchDay = 1; - matchMonth++; - } - break; - default: // February - if (((matchYear % 4) == 0) && (matchDay == 30)) { - matchDay = 1; - matchMonth++; - } else if (((matchYear % 4) > 0) && (matchDay == 29)) { - matchDay = 1; - matchMonth++; - } - break; - } - } - - while ((!dateFound) && - (dataPtr < numDataBytes)) // Keep going until we have found the date - // or processed all the bytes - { - // Start by checking the validity of the packet being pointed to - bool dataIsOK = true; - - dataIsOK &= - (*(dataBytes + dataPtr + 0) == UBX_SYNCH_1); // Check for 0xB5 - dataIsOK &= - (*(dataBytes + dataPtr + 1) == UBX_SYNCH_2); // Check for 0x62 - dataIsOK &= (*(dataBytes + dataPtr + 2) == - UBX_CLASS_MGA); // Check for class UBX-MGA - - size_t packetLength = ((size_t) * (dataBytes + dataPtr + 4)) | - (((size_t) * (dataBytes + dataPtr + 5)) - << 8); // Extract the length - - uint8_t checksumA = 0; - uint8_t checksumB = 0; - // Calculate the checksum bytes - // Keep going until the end of the packet is reached (payloadPtr == - // (dataPtr + packetLength)) or we reach the end of the AssistNow data - // (payloadPtr == numDataBytes) - for (size_t payloadPtr = dataPtr + ((size_t)2); - (payloadPtr < (dataPtr + packetLength + ((size_t)6))) && - (payloadPtr < numDataBytes); - payloadPtr++) { - checksumA += *(dataBytes + payloadPtr); - checksumB += checksumA; - } - // Check the checksum bytes - dataIsOK &= - (checksumA == *(dataBytes + dataPtr + packetLength + ((size_t)6))); - dataIsOK &= - (checksumB == *(dataBytes + dataPtr + packetLength + ((size_t)7))); - - dataIsOK &= ((dataPtr + packetLength + ((size_t)8)) <= - numDataBytes); // Check we haven't overrun - - // If the data is valid, check for a date match - if (dataIsOK) { - if ((*(dataBytes + dataPtr + 3) == UBX_MGA_ANO) && - (*(dataBytes + dataPtr + 10) == matchYear) && - (*(dataBytes + dataPtr + 11) == matchMonth) && - (*(dataBytes + dataPtr + 12) == matchDay)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print( - F("findMGAANOForDate: found date match at location ")); - _debugSerial->println(dataPtr); - } -#endif - dateFound = true; - } else { - // The data is valid, but these are not the droids we are - // looking for... - dataPtr += - packetLength + ((size_t)8); // Point to the next message - } - } else { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - // The data was invalid. Send a debug message and then try to find - // the next 0xB5 - if ((_printDebug == true) || - (_printLimitedDebug == true)) // This is important. Print this - // if doing limited debugging - { - _debugSerial->print( - F("findMGAANOForDate: bad data - ignored! dataPtr is ")); - _debugSerial->println(dataPtr); - } -#endif - - while ((dataPtr < numDataBytes) && - (*(dataBytes + ++dataPtr) != UBX_SYNCH_1)) { - ; // Increment dataPtr until we are pointing at the next 0xB5 - - // or we reach the end of the data - } - } - } - - return (dataPtr); -} - -// Read the whole navigation data base. The receiver will send all available -// data from its internal database. Data is written to dataBytes. Set -// maxNumDataBytes to the (maximum) size of dataBytes. If the database exceeds -// maxNumDataBytes, the excess bytes will be lost. The function returns the -// number of database bytes written to dataBytes. The return value will be equal -// to maxNumDataBytes if excess data was received. The function will timeout -// after maxWait milliseconds - in case the final UBX-MGA-ACK was missed. -size_t SFE_UBLOX_GNSS::readNavigationDatabase(uint8_t *dataBytes, - size_t maxNumDataBytes, - uint16_t maxWait) { - // Allocate RAM to store the MGA ACK message - if (packetUBXMGAACK == NULL) - initPacketUBXMGAACK(); // Check that RAM has been allocated for the - // MGA_ACK data - if (packetUBXMGAACK == NULL) // Bail if the RAM allocation failed - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("readNavigationDatabase: packetUBXMGAACK RAM allocation " - "failed!")); - } -#endif - return ((size_t)0); - } - if (packetUBXMGAACK->head != - packetUBXMGAACK->tail) // Does the MGA ACK ringbuffer contain any data? - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("readNavigationDatabase: packetUBXMGAACK contains " - "unprocessed data. Clearing it.")); - } -#endif - packetUBXMGAACK->tail = - packetUBXMGAACK->head; // Clear the buffer by setting the tail - // equal to the head - } - - // Allocate RAM to store the MGA DBD messages - if (packetUBXMGADBD == NULL) - initPacketUBXMGADBD(); // Check that RAM has been allocated for the - // MGA_DBD data - if (packetUBXMGADBD == NULL) // Bail if the RAM allocation failed - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("readNavigationDatabase: packetUBXMGADBD RAM allocation " - "failed!")); - } -#endif - return ((size_t)0); - } - if (packetUBXMGADBD->head != - packetUBXMGADBD->tail) // Does the MGA DBD ringbuffer contain any data? - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("readNavigationDatabase: packetUBXMGADBD contains " - "unprocessed data. Clearing it.")); - } -#endif - packetUBXMGADBD->tail = - packetUBXMGADBD->head; // Clear the buffer by setting the tail - // equal to the head - } - - // Record what ackAiding is currently set to so we can restore it - uint8_t currentAckAiding = getAckAiding(); - if (currentAckAiding == 255) - currentAckAiding = - 0; // If the get failed, disable the ACKs when returning - // Enable ackAiding - setAckAiding(1); - - // Record what i2cPollingWait is currently set to so we can restore it - uint8_t currentI2cPollingWait = i2cPollingWait; - // Set the I2C polling wait to 1ms - i2cPollingWait = 1; - - // Construct the poll message: - uint8_t pollNaviDatabase[8]; // Create the UBX-MGA-DBD message by hand - memset(pollNaviDatabase, 0x00, - 8); // Set all unused / reserved bytes and the checksum to zero - - pollNaviDatabase[0] = UBX_SYNCH_1; // Sync char 1 - pollNaviDatabase[1] = UBX_SYNCH_2; // Sync char 2 - pollNaviDatabase[2] = UBX_CLASS_MGA; // Class - pollNaviDatabase[3] = UBX_MGA_DBD; // ID - pollNaviDatabase[4] = 0x00; // Length LSB - pollNaviDatabase[5] = 0x00; // Length MSB - - for (uint8_t i = 2; i < 6; i++) // Calculate the checksum - { - pollNaviDatabase[6] += pollNaviDatabase[i]; - pollNaviDatabase[7] += pollNaviDatabase[6]; - } - - // Push the poll message to the module. - // Do not Wait for an ACK - the DBD data will start arriving immediately. - size_t pushResult = pushAssistNowDataInternal( - 0, false, pollNaviDatabase, (size_t)8, SFE_UBLOX_MGA_ASSIST_ACK_NO, 0); - - // Check pushResult == 8 - if (pushResult != 8) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("readNavigationDatabase: pushAssistNowDataInternal failed!")); - } -#endif - i2cPollingWait = currentI2cPollingWait; // Restore i2cPollingWait - setAckAiding(currentAckAiding); // Restore Ack Aiding - return ((size_t)0); - } - - // Now keep checking for the arrival of UBX-MGA-DBD packets and write them - // to dataBytes - bool keepGoing = true; - unsigned long startTime = millis(); - uint32_t databaseEntriesRX = - 0; // Keep track of how many database entries are received - size_t numBytesReceived = 0; // Keep track of how many bytes are received - - while (keepGoing && (millis() < (startTime + maxWait))) { - checkUblox(); - - while (packetUBXMGADBD->head != - packetUBXMGADBD - ->tail) // Does the MGA DBD ringbuffer contain any data? - { - // The data will be valid - process will have already checked it. So - // we can simply copy the data into dataBuffer. We do not need to - // check if there is room to store the entire database entry. - // pushAssistNowData will check the data before pushing it. - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryHeader1; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryHeader2; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail].dbdEntryClass; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail].dbdEntryID; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail].dbdEntryLenLSB; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail].dbdEntryLenMSB; - size_t msgLen = - (((size_t)packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryLenMSB) * - 256) + - ((size_t)packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryLenLSB); - for (size_t i = 0; i < msgLen; i++) { - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntry[i]; - } - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryChecksumA; - if (numBytesReceived < maxNumDataBytes) - *(dataBytes + (numBytesReceived++)) = - packetUBXMGADBD->data[packetUBXMGADBD->tail] - .dbdEntryChecksumB; - - // Increment the tail - packetUBXMGADBD->tail++; - if (packetUBXMGADBD->tail == UBX_MGA_DBD_RINGBUFFER_LEN) - packetUBXMGADBD->tail = 0; - - databaseEntriesRX++; // Increment the number of entries received - } - - // The final MGA-ACK is sent at the end of the DBD packets. So, we need - // to check the ACK buffer _after_ the DBD buffer. - while (packetUBXMGAACK->head != - packetUBXMGAACK - ->tail) // Does the MGA ACK ringbuffer contain any data? - { - // Check if we've received the correct ACK - bool idMatch = - (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgId == - UBX_MGA_DBD); // Check if the message ID matches - - bool dataAckd = true; - dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[0] == - (uint8_t)(databaseEntriesRX & - 0xFF)); // Check if the ACK contents match - // databaseEntriesRX - dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[1] == - (uint8_t)((databaseEntriesRX >> 8) & 0xFF)); - dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[2] == - (uint8_t)((databaseEntriesRX >> 16) & 0xFF)); - dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[3] == - (uint8_t)((databaseEntriesRX >> 24) & 0xFF)); - - if (idMatch && dataAckd) // Is the ACK valid? - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print( - F("readNavigationDatabase: ACK received. " - "databaseEntriesRX is ")); - _debugSerial->print(databaseEntriesRX); - _debugSerial->print(F(". numBytesReceived is ")); - _debugSerial->print(numBytesReceived); - _debugSerial->print(F(". DBD read complete after ")); - _debugSerial->print(millis() - startTime); - _debugSerial->println(F(" ms")); - } -#endif - keepGoing = false; - } else if (idMatch) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited - // debugging - { - _debugSerial->print( - F("readNavigationDatabase: unexpected ACK received. " - "databaseEntriesRX is 0x")); - _debugSerial->print(databaseEntriesRX, HEX); - _debugSerial->print(F(". msgPayloadStart is 0x")); - for (uint8_t i = 4; i > 0; i--) { - if (packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[i - 1] < 0x10) - _debugSerial->print(F("0")); - _debugSerial->print( - packetUBXMGAACK->data[packetUBXMGAACK->tail] - .msgPayloadStart[i - 1], - HEX); - } - _debugSerial->println(); - } -#endif - } - - // Increment the tail - packetUBXMGAACK->tail++; - if (packetUBXMGAACK->tail == UBX_MGA_ACK_DATA0_RINGBUFFER_LEN) - packetUBXMGAACK->tail = 0; - } - } - - if (keepGoing) // If keepGoing is still true, we must have timed out - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("readNavigationDatabase: DBD RX timed out!")); - } -#endif - } - - i2cPollingWait = currentI2cPollingWait; // Restore i2cPollingWait - setAckAiding(currentAckAiding); // Restore Ack Aiding - - return (numBytesReceived); -} - -// PRIVATE: Allocate RAM for packetUBXMGADBD and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXMGADBD() { - packetUBXMGADBD = new UBX_MGA_DBD_t; // Allocate RAM for the main struct - if (packetUBXMGADBD == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXMGADBD: RAM alloc failed!")); -#endif - return (false); - } - packetUBXMGADBD->head = 0; // Initialize the ring buffer pointers - packetUBXMGADBD->tail = 0; - return (true); -} - -// Support for data logging - -// Set the file buffer size. This must be called _before_ .begin -void SFE_UBLOX_GNSS::setFileBufferSize(uint16_t bufferSize) { - fileBufferSize = bufferSize; -} - -// Return the file buffer size -uint16_t SFE_UBLOX_GNSS::getFileBufferSize(void) { return (fileBufferSize); } - -// Extract numBytes of data from the file buffer. Copy it to destination. -// It is the user's responsibility to ensure destination is large enough. -// Returns the number of bytes extracted - which may be less than numBytes. -uint16_t SFE_UBLOX_GNSS::extractFileBufferData(uint8_t *destination, - uint16_t numBytes) { - // Check how many bytes are available in the buffer - uint16_t bytesAvailable = fileBufferSpaceUsed(); - if (numBytes > bytesAvailable) // Limit numBytes if required - numBytes = bytesAvailable; - - // Start copying at fileBufferTail. Wrap-around if required. - uint16_t bytesBeforeWrapAround = - fileBufferSize - - fileBufferTail; // How much space is available 'above' Tail? - if (bytesBeforeWrapAround > numBytes) // Will we need to wrap-around? - { - bytesBeforeWrapAround = numBytes; // We need to wrap-around - } - memcpy(destination, &ubxFileBuffer[fileBufferTail], - bytesBeforeWrapAround); // Copy the data out of the buffer - - // Is there any data leftover which we need to copy from the 'bottom' of the - // buffer? - uint16_t bytesLeftToCopy = - numBytes - - bytesBeforeWrapAround; // Calculate if there are any bytes left to copy - if (bytesLeftToCopy > 0) // If there are bytes left to copy - { - memcpy(&destination[bytesBeforeWrapAround], &ubxFileBuffer[0], - bytesLeftToCopy); // Copy the remaining data out of the buffer - fileBufferTail = bytesLeftToCopy; // Update Tail. The next byte to be - // read will be read from here. - } else { - fileBufferTail += numBytes; // Only update Tail. The next byte to be - // read will be read from here. - } - - return (numBytes); // Return the number of bytes extracted -} - -// Returns the number of bytes available in file buffer which are waiting to be -// read -uint16_t SFE_UBLOX_GNSS::fileBufferAvailable(void) { - return (fileBufferSpaceUsed()); -} - -// Returns the maximum number of bytes which the file buffer contained. -// Handy for checking the buffer is large enough to handle all the incoming -// data. -uint16_t SFE_UBLOX_GNSS::getMaxFileBufferAvail(void) { - return (fileBufferMaxAvail); -} - -// Clear the file buffer - discard all contents -void SFE_UBLOX_GNSS::clearFileBuffer(void) { - if (fileBufferSize == 0) // Bail if the user has not called - // setFileBufferSize (probably redundant) - return; - fileBufferTail = fileBufferHead; -} - -// Reset fileBufferMaxAvail -void SFE_UBLOX_GNSS::clearMaxFileBufferAvail(void) { fileBufferMaxAvail = 0; } - -// PRIVATE: Create the file buffer. Called by .begin -bool SFE_UBLOX_GNSS::createFileBuffer(void) { - if (fileBufferSize == - 0) // Bail if the user has not called setFileBufferSize - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("createFileBuffer: Warning. fileBufferSize is zero. Data " - "logging is not possible.")); - } -#endif - return (false); - } - - if (ubxFileBuffer != - NULL) // Bail if RAM has already been allocated for the file buffer - { // This will happen if you call .begin more than once - without calling - // .end first -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("createFileBuffer: Warning. File buffer already exists. " - "Skipping...")); - } -#endif - return (false); - } - - ubxFileBuffer = new uint8_t[fileBufferSize]; // Allocate RAM for the buffer - - if (ubxFileBuffer == NULL) // Check if the new (alloc) was successful - { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println(F("createFileBuffer: RAM alloc failed!")); - } - return (false); - } - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("createFileBuffer: fileBufferSize is: ")); - _debugSerial->println(fileBufferSize); - } -#endif - - fileBufferHead = 0; // Initialize head and tail - fileBufferTail = 0; - - return (true); -} - -// PRIVATE: Check how much space is available in the buffer -uint16_t SFE_UBLOX_GNSS::fileBufferSpaceAvailable(void) { - return (fileBufferSize - fileBufferSpaceUsed()); -} - -// PRIVATE: Check how much space is used in the buffer -uint16_t SFE_UBLOX_GNSS::fileBufferSpaceUsed(void) { - if (fileBufferHead >= fileBufferTail) // Check if wrap-around has occurred - { - // Wrap-around has not occurred so do a simple subtraction - return (fileBufferHead - fileBufferTail); - } else { - // Wrap-around has occurred so do a simple subtraction but add in the - // fileBufferSize - return ( - (uint16_t)(((uint32_t)fileBufferHead + (uint32_t)fileBufferSize) - - (uint32_t)fileBufferTail)); - } -} - -// PRIVATE: Add a UBX packet to the file buffer -bool SFE_UBLOX_GNSS::storePacket(ubxPacket *msg) { - // First, check that the file buffer has been created - if ((ubxFileBuffer == NULL) || (fileBufferSize == 0)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println(F("storePacket: file buffer not available!")); - } -#endif - return (false); - } - - // Now, check if there is enough space in the buffer for all of the data - uint16_t totalLength = - msg->len + 8; // Total length. Include sync chars, class, id, length - // and checksum bytes - if (totalLength > fileBufferSpaceAvailable()) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("storePacket: insufficient space available! Data will be " - "lost!")); - } -#endif - return (false); - } - - // Store the two sync chars - uint8_t sync_chars[] = {UBX_SYNCH_1, UBX_SYNCH_2}; - writeToFileBuffer(sync_chars, 2); - - // Store the Class & ID - writeToFileBuffer(&msg->cls, 1); - writeToFileBuffer(&msg->id, 1); - - // Store the length. Ensure length is little-endian - uint8_t msg_length[2]; - msg_length[0] = msg->len & 0xFF; - msg_length[1] = msg->len >> 8; - writeToFileBuffer(msg_length, 2); - - // Store the payload - writeToFileBuffer(msg->payload, msg->len); - - // Store the checksum - writeToFileBuffer(&msg->checksumA, 1); - writeToFileBuffer(&msg->checksumB, 1); - - return (true); -} - -// PRIVATE: Add theBytes to the file buffer -bool SFE_UBLOX_GNSS::storeFileBytes(uint8_t *theBytes, uint16_t numBytes) { - // First, check that the file buffer has been created - if ((ubxFileBuffer == NULL) || (fileBufferSize == 0)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println( - F("storeFileBytes: file buffer not available!")); - } -#endif - return (false); - } - - // Now, check if there is enough space in the buffer for all of the data - if (numBytes > fileBufferSpaceAvailable()) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("storeFileBytes: insufficient space available! Data will be " - "lost!")); - } -#endif - return (false); - } - - // There is room for all the data in the buffer so copy the data into the - // buffer - writeToFileBuffer(theBytes, numBytes); - - return (true); -} - -// PRIVATE: Write theBytes to the file buffer -void SFE_UBLOX_GNSS::writeToFileBuffer(uint8_t *theBytes, uint16_t numBytes) { - // Start writing at fileBufferHead. Wrap-around if required. - uint16_t bytesBeforeWrapAround = - fileBufferSize - - fileBufferHead; // How much space is available 'above' Head? - if (bytesBeforeWrapAround > - numBytes) // Is there enough room for all the data? - { - bytesBeforeWrapAround = - numBytes; // There is enough room for all the data - } - memcpy(&ubxFileBuffer[fileBufferHead], theBytes, - bytesBeforeWrapAround); // Copy the data into the buffer - - // Is there any data leftover which we need to copy to the 'bottom' of the - // buffer? - uint16_t bytesLeftToCopy = - numBytes - - bytesBeforeWrapAround; // Calculate if there are any bytes left to copy - if (bytesLeftToCopy > 0) // If there are bytes left to copy - { - memcpy(&ubxFileBuffer[0], &theBytes[bytesBeforeWrapAround], - bytesLeftToCopy); // Copy the remaining data into the buffer - fileBufferHead = bytesLeftToCopy; // Update Head. The next byte written - // will be written here. - } else { - fileBufferHead += numBytes; // Only update Head. The next byte written - // will be written here. - } - - // Update fileBufferMaxAvail if required - uint16_t bytesInBuffer = fileBufferSpaceUsed(); - if (bytesInBuffer > fileBufferMaxAvail) fileBufferMaxAvail = bytesInBuffer; -} - -//=-=-=-=-=-=-=-= Specific commands =-=-=-=-=-=-=-==-=-=-=-=-=-=-= -//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -// Loads the payloadCfg array with the current protocol bits located the -// UBX-CFG-PRT register for a given port -bool SFE_UBLOX_GNSS::getPortSettings(uint8_t portID, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 1; - packetCfg.startingSpot = 0; - - payloadCfg[0] = portID; - - return ( - (sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_RECEIVED); // We are expecting data and an ACK -} - -// Configure a given port to output UBX, NMEA, RTCM3 or a combination thereof -// Port 0=I2c, 1=UART1, 2=UART2, 3=USB, 4=SPI -// Bit:0 = UBX, :1=NMEA, :5=RTCM3 -bool SFE_UBLOX_GNSS::setPortOutput(uint8_t portID, uint8_t outStreamSettings, - uint16_t maxWait) { - // Get the current config values for this port ID - if (getPortSettings(portID, maxWait) == false) - return (false); // Something went wrong. Bail. - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[14] = - outStreamSettings; // OutProtocolMask LSB - Set outStream bits - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Configure a given port to input UBX, NMEA, RTCM3 or a combination thereof -// Port 0=I2c, 1=UART1, 2=UART2, 3=USB, 4=SPI -// Bit:0 = UBX, :1=NMEA, :5=RTCM3 -bool SFE_UBLOX_GNSS::setPortInput(uint8_t portID, uint8_t inStreamSettings, - uint16_t maxWait) { - // Get the current config values for this port ID - // This will load the payloadCfg array with current port settings - if (getPortSettings(portID, maxWait) == false) - return (false); // Something went wrong. Bail. - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[12] = - inStreamSettings; // InProtocolMask LSB - Set inStream bits - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Changes the I2C address that the u-blox module responds to -// 0x42 is the default but can be changed with this command -bool SFE_UBLOX_GNSS::setI2CAddress(uint8_t deviceAddress, uint16_t maxWait) { - // Get the current config values for the I2C port - // This will load the payloadCfg array with current port settings - if (getPortSettings(COM_PORT_I2C, maxWait) == false) - return (false); // Something went wrong. Bail. - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[4] = deviceAddress << 1; // DDC mode LSB - - if (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT) // We are only expecting an ACK - { - // Success! Now change our internal global. - _gpsI2Caddress = deviceAddress; // Store the I2C address from user - return (true); - } - return (false); -} - -// Changes the serial baud rate of the u-blox module, can't return success/fail -// 'cause ACK from modem is lost due to baud rate change -void SFE_UBLOX_GNSS::setSerialRate(uint32_t baudrate, uint8_t uartPort, - uint16_t maxWait) { - // Get the current config values for the UART port - // This will load the payloadCfg array with current port settings - if (getPortSettings(uartPort, maxWait) == false) - return; // Something went wrong. Bail. - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("Current baud rate: ")); - _debugSerial->println(((uint32_t)payloadCfg[10] << 16) | - ((uint32_t)payloadCfg[9] << 8) | payloadCfg[8]); - } -#endif - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[8] = baudrate; - payloadCfg[9] = baudrate >> 8; - payloadCfg[10] = baudrate >> 16; - payloadCfg[11] = baudrate >> 24; - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("New baud rate:")); - _debugSerial->println(((uint32_t)payloadCfg[10] << 16) | - ((uint32_t)payloadCfg[9] << 8) | payloadCfg[8]); - } -#endif - - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("setSerialRate: sendCommand returned: ")); - _debugSerial->println(statusString(retVal)); - } -#else - (void)retVal; // Get rid of a pesky compiler warning! -#endif -} - -// Configure a port to output UBX, NMEA, RTCM3 or a combination thereof -bool SFE_UBLOX_GNSS::setI2COutput(uint8_t comSettings, uint16_t maxWait) { - return (setPortOutput(COM_PORT_I2C, comSettings, maxWait)); -} -bool SFE_UBLOX_GNSS::setUART1Output(uint8_t comSettings, uint16_t maxWait) { - return (setPortOutput(COM_PORT_UART1, comSettings, maxWait)); -} -bool SFE_UBLOX_GNSS::setUART2Output(uint8_t comSettings, uint16_t maxWait) { - return (setPortOutput(COM_PORT_UART2, comSettings, maxWait)); -} -bool SFE_UBLOX_GNSS::setUSBOutput(uint8_t comSettings, uint16_t maxWait) { - return (setPortOutput(COM_PORT_USB, comSettings, maxWait)); -} -bool SFE_UBLOX_GNSS::setSPIOutput(uint8_t comSettings, uint16_t maxWait) { - return (setPortOutput(COM_PORT_SPI, comSettings, maxWait)); -} - -// Want to see the NMEA messages on the Serial port? Here's how -void SFE_UBLOX_GNSS::setNMEAOutputPort(Stream &nmeaOutputPort) { - _nmeaOutputPort = &nmeaOutputPort; // Store the port from user -} - -void SFE_UBLOX_GNSS::setOutputPort(Stream &outputPort) { - _outputPort = &outputPort; // Store the port from user -} - -// Reset to defaults - -void SFE_UBLOX_GNSS::factoryReset() { - // Copy default settings to permanent - // Note: this does not load the permanent configuration into the current - // configuration. Calling factoryDefault() will do that. - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_CFG; - packetCfg.len = 13; - packetCfg.startingSpot = 0; - for (uint8_t i = 0; i < 4; i++) { - payloadCfg[0 + i] = - 0xff; // clear mask: copy default config to permanent config - payloadCfg[4 + i] = 0x00; // save mask: don't save current to permanent - payloadCfg[8 + i] = - 0x00; // load mask: don't copy permanent config to current - } - payloadCfg[12] = 0xff; // all forms of permanent memory - sendCommand(&packetCfg, 0); // don't expect ACK - hardReset(); // cause factory default config to actually be loaded and used - // cleanly -} - -void SFE_UBLOX_GNSS::hardReset() { - // Issue hard reset - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RST; - packetCfg.len = 4; - packetCfg.startingSpot = 0; - payloadCfg[0] = 0xff; // cold start - payloadCfg[1] = 0xff; // cold start - payloadCfg[2] = 0; // 0=HW reset - payloadCfg[3] = 0; // reserved - sendCommand(&packetCfg, 0); // don't expect ACK -} - -void SFE_UBLOX_GNSS::softwareResetGNSSOnly() { - // Issue controlled software reset (GNSS only) - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RST; - packetCfg.len = 4; - packetCfg.startingSpot = 0; - payloadCfg[0] = 0; // hot start - payloadCfg[1] = 0; // hot start - payloadCfg[2] = 0x02; // 0x02 = Controlled software reset (GNSS only) - payloadCfg[3] = 0; // reserved - sendCommand(&packetCfg, 0); // don't expect ACK -} - -// Reset module to factory defaults -// This still works but it is the old way of configuring ublox modules. See -// getVal and setVal for the new methods -bool SFE_UBLOX_GNSS::factoryDefault(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_CFG; - packetCfg.len = 12; - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - packetCfg.payload[0] = - 0xFF; // Set any bit in the clearMask field to clear saved config - packetCfg.payload[1] = 0xFF; - packetCfg.payload[8] = - 0xFF; // Set any bit in the loadMask field to discard current config - // and rebuild from lower non-volatile memory layers - packetCfg.payload[9] = 0xFF; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Save configuration to BBR / Flash - -// Save current configuration to flash and BBR (battery backed RAM) -// This still works but it is the old way of configuring ublox modules. See -// getVal and setVal for the new methods -bool SFE_UBLOX_GNSS::saveConfiguration(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_CFG; - packetCfg.len = 12; - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - packetCfg.payload[4] = 0xFF; // Set any bit in the saveMask field to save - // current config to Flash and BBR - packetCfg.payload[5] = 0xFF; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Save the selected configuration sub-sections to flash and BBR (battery backed -// RAM) This still works but it is the old way of configuring ublox modules. See -// getVal and setVal for the new methods -bool SFE_UBLOX_GNSS::saveConfigSelective(uint32_t configMask, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_CFG; - packetCfg.len = 12; - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - packetCfg.payload[4] = - configMask & 0xFF; // Set the appropriate bits in the saveMask field to - // save current config to Flash and BBR - packetCfg.payload[5] = (configMask >> 8) & 0xFF; - packetCfg.payload[6] = (configMask >> 16) & 0xFF; - packetCfg.payload[7] = (configMask >> 24) & 0xFF; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Configure a given message type for a given port (UART1, I2C, SPI, etc) -bool SFE_UBLOX_GNSS::configureMessage(uint8_t msgClass, uint8_t msgID, - uint8_t portID, uint8_t sendRate, - uint16_t maxWait) { - // Poll for the current settings for a given message - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 2; - packetCfg.startingSpot = 0; - - payloadCfg[0] = msgClass; - payloadCfg[1] = msgID; - - // This will load the payloadCfg array with current settings of the given - // register - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); // If command send fails then bail - - // Now send it back with new mods - packetCfg.len = 8; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[2 + portID] = - sendRate; // Send rate is relative to the event a message is registered - // on. For example, if the rate of a navigation message is - // set to 2, the message is sent every 2nd navigation - // solution. - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Enable a given message type, default of 1 per update rate (usually 1 per -// second) -bool SFE_UBLOX_GNSS::enableMessage(uint8_t msgClass, uint8_t msgID, - uint8_t portID, uint8_t rate, - uint16_t maxWait) { - return (configureMessage(msgClass, msgID, portID, rate, maxWait)); -} -// Disable a given message type on a given port -bool SFE_UBLOX_GNSS::disableMessage(uint8_t msgClass, uint8_t msgID, - uint8_t portID, uint16_t maxWait) { - return (configureMessage(msgClass, msgID, portID, 0, maxWait)); -} - -bool SFE_UBLOX_GNSS::enableNMEAMessage(uint8_t msgID, uint8_t portID, - uint8_t rate, uint16_t maxWait) { - return (configureMessage(UBX_CLASS_NMEA, msgID, portID, rate, maxWait)); -} -bool SFE_UBLOX_GNSS::disableNMEAMessage(uint8_t msgID, uint8_t portID, - uint16_t maxWait) { - return (enableNMEAMessage(msgID, portID, 0, maxWait)); -} - -// Given a message number turns on a message ID for output over a given portID -// (UART, I2C, SPI, USB, etc) To disable a message, set secondsBetween messages -// to 0 Note: This function will return false if the message is already enabled -// For base station RTK output we need to enable various sentences - -// NEO-M8P has four: -// 1005 = 0xF5 0x05 - Stationary RTK reference ARP -// 1077 = 0xF5 0x4D - GPS MSM7 -// 1087 = 0xF5 0x57 - GLONASS MSM7 -// 1230 = 0xF5 0xE6 - GLONASS code-phase biases, set to once every 10 seconds - -// ZED-F9P has six: -// 1005, 1074, 1084, 1094, 1124, 1230 - -// Much of this configuration is not documented and instead discerned from -// u-center binary console -bool SFE_UBLOX_GNSS::enableRTCMmessage(uint8_t messageNumber, uint8_t portID, - uint8_t sendRate, uint16_t maxWait) { - return (configureMessage(UBX_RTCM_MSB, messageNumber, portID, sendRate, - maxWait)); -} - -// Disable a given message on a given port by setting secondsBetweenMessages to -// zero -bool SFE_UBLOX_GNSS::disableRTCMmessage(uint8_t messageNumber, uint8_t portID, - uint16_t maxWait) { - return (enableRTCMmessage(messageNumber, portID, 0, maxWait)); -} - -// Functions used for RTK and base station setup - -// Get the current TimeMode3 settings - these contain survey in statuses -bool SFE_UBLOX_GNSS::getSurveyMode(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TMODE3; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - return ( - (sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_RECEIVED); // We are expecting data and an ACK -} - -// Get the current TimeMode3 settings - these contain survey in statuses -bool SFE_UBLOX_GNSS::getSurveyMode(UBX_CFG_TMODE3_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TMODE3; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->version = extractByte(&packetCfg, 0); - data->flags.all = extractInt(&packetCfg, 2); - data->ecefXOrLat = extractSignedLong(&packetCfg, 4); - data->ecefYOrLon = extractSignedLong(&packetCfg, 8); - data->ecefZOrAlt = extractSignedLong(&packetCfg, 12); - data->ecefXOrLatHP = extractSignedChar(&packetCfg, 16); - data->ecefYOrLonHP = extractSignedChar(&packetCfg, 17); - data->ecefZOrAltHP = extractSignedChar(&packetCfg, 18); - data->fixedPosAcc = extractLong(&packetCfg, 20); - data->svinMinDur = extractLong(&packetCfg, 24); - data->svinAccLimit = extractLong(&packetCfg, 28); - - return (true); -} - -// Control Survey-In for NEO-M8P -bool SFE_UBLOX_GNSS::setSurveyMode(uint8_t mode, uint16_t observationTime, - float requiredAccuracy, uint16_t maxWait) { - return (setSurveyModeFull(mode, (uint32_t)observationTime, requiredAccuracy, - maxWait)); -} -bool SFE_UBLOX_GNSS::setSurveyModeFull(uint8_t mode, uint32_t observationTime, - float requiredAccuracy, - uint16_t maxWait) { - if (getSurveyMode(maxWait) == - false) // Ask module for the current TimeMode3 settings. Loads into - // payloadCfg. - return (false); - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TMODE3; - packetCfg.len = 40; - packetCfg.startingSpot = 0; - - // payloadCfg should be loaded with poll response. Now modify only the bits - // we care about - payloadCfg[2] = mode; // Set mode. Survey-In and Disabled are most common. - // Use ECEF (not LAT/LON/ALT). - - // svinMinDur is U4 (uint32_t) in seconds - payloadCfg[24] = observationTime & 0xFF; // svinMinDur in seconds - payloadCfg[25] = (observationTime >> 8) & 0xFF; - payloadCfg[26] = (observationTime >> 16) & 0xFF; - payloadCfg[27] = (observationTime >> 24) & 0xFF; - - // svinAccLimit is U4 (uint32_t) in 0.1mm. - uint32_t svinAccLimit = - (uint32_t)(requiredAccuracy * 10000.0); // Convert m to 0.1mm - payloadCfg[28] = svinAccLimit & 0xFF; // svinAccLimit in 0.1mm increments - payloadCfg[29] = (svinAccLimit >> 8) & 0xFF; - payloadCfg[30] = (svinAccLimit >> 16) & 0xFF; - payloadCfg[31] = (svinAccLimit >> 24) & 0xFF; - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Begin Survey-In for NEO-M8P -bool SFE_UBLOX_GNSS::enableSurveyMode(uint16_t observationTime, - float requiredAccuracy, - uint16_t maxWait) { - return (setSurveyModeFull(SVIN_MODE_ENABLE, (uint32_t)observationTime, - requiredAccuracy, maxWait)); -} -bool SFE_UBLOX_GNSS::enableSurveyModeFull(uint32_t observationTime, - float requiredAccuracy, - uint16_t maxWait) { - return (setSurveyModeFull(SVIN_MODE_ENABLE, observationTime, - requiredAccuracy, maxWait)); -} - -// Stop Survey-In for NEO-M8P -bool SFE_UBLOX_GNSS::disableSurveyMode(uint16_t maxWait) { - return (setSurveyMode(SVIN_MODE_DISABLE, 0, 0, maxWait)); -} - -// Set the ECEF or Lat/Long coordinates of a receiver -// This imediately puts the receiver in TIME mode (fixed) and will begin -// outputting RTCM sentences if enabled This is helpful once an antenna's -// position has been established. See this tutorial: -// https://learn.sparkfun.com/tutorials/how-to-build-a-diy-gnss-reference-station#gather-raw-gnss-data -// For ECEF the units are: cm, 0.1mm, cm, 0.1mm, cm, 0.1mm -// For Lat/Lon/Alt the units are: degrees^-7, degrees^-9, degrees^-7, -// degrees^-9, cm, 0.1mm -bool SFE_UBLOX_GNSS::setStaticPosition(int32_t ecefXOrLat, int8_t ecefXOrLatHP, - int32_t ecefYOrLon, int8_t ecefYOrLonHP, - int32_t ecefZOrAlt, int8_t ecefZOrAltHP, - bool latLong, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TMODE3; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current TimeMode3 settings. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (false); - - packetCfg.len = 40; - - // customCfg should be loaded with poll response. Now modify only the bits - // we care about - payloadCfg[2] = 2; // Set mode to fixed. Use ECEF (not LAT/LON/ALT). - - if (latLong == true) - payloadCfg[3] = - (uint8_t)(1 << 0); // Set mode to fixed. Use LAT/LON/ALT. - - // Set ECEF X or Lat - payloadCfg[4] = (ecefXOrLat >> 8 * 0) & 0xFF; // LSB - payloadCfg[5] = (ecefXOrLat >> 8 * 1) & 0xFF; - payloadCfg[6] = (ecefXOrLat >> 8 * 2) & 0xFF; - payloadCfg[7] = (ecefXOrLat >> 8 * 3) & 0xFF; // MSB - - // Set ECEF Y or Long - payloadCfg[8] = (ecefYOrLon >> 8 * 0) & 0xFF; // LSB - payloadCfg[9] = (ecefYOrLon >> 8 * 1) & 0xFF; - payloadCfg[10] = (ecefYOrLon >> 8 * 2) & 0xFF; - payloadCfg[11] = (ecefYOrLon >> 8 * 3) & 0xFF; // MSB - - // Set ECEF Z or Altitude - payloadCfg[12] = (ecefZOrAlt >> 8 * 0) & 0xFF; // LSB - payloadCfg[13] = (ecefZOrAlt >> 8 * 1) & 0xFF; - payloadCfg[14] = (ecefZOrAlt >> 8 * 2) & 0xFF; - payloadCfg[15] = (ecefZOrAlt >> 8 * 3) & 0xFF; // MSB - - // Set high precision parts - payloadCfg[16] = ecefXOrLatHP; - payloadCfg[17] = ecefYOrLonHP; - payloadCfg[18] = ecefZOrAltHP; - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -bool SFE_UBLOX_GNSS::setStaticPosition(int32_t ecefXOrLat, int32_t ecefYOrLon, - int32_t ecefZOrAlt, bool latlong, - uint16_t maxWait) { - return (setStaticPosition(ecefXOrLat, 0, ecefYOrLon, 0, ecefZOrAlt, 0, - latlong, maxWait)); -} - -// Set the DGNSS differential mode -bool SFE_UBLOX_GNSS::setDGNSSConfiguration(sfe_ublox_dgnss_mode_e dgnssMode, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_DGNSS; - packetCfg.len = 4; - packetCfg.startingSpot = 0; - - payloadCfg[0] = (uint8_t)dgnssMode; - payloadCfg[1] = 0; // reserved0 - payloadCfg[2] = 0; - payloadCfg[3] = 0; - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Module Protocol Version - -// Get the current protocol version of the u-blox module we're communicating -// with This is helpful when deciding if we should call the high-precision -// Lat/Long (HPPOSLLH) or the regular (POSLLH) -uint8_t SFE_UBLOX_GNSS::getProtocolVersionHigh(uint16_t maxWait) { - if (moduleSWVersion == NULL) - initModuleSWVersion(); // Check that RAM has been allocated for the SW - // version - if (moduleSWVersion == NULL) // Bail if the RAM allocation failed - return (false); - - if (moduleSWVersion->moduleQueried == false) getProtocolVersion(maxWait); - return (moduleSWVersion->versionHigh); -} - -// Get the current protocol version of the u-blox module we're communicating -// with This is helpful when deciding if we should call the high-precision -// Lat/Long (HPPOSLLH) or the regular (POSLLH) -uint8_t SFE_UBLOX_GNSS::getProtocolVersionLow(uint16_t maxWait) { - if (moduleSWVersion == NULL) - initModuleSWVersion(); // Check that RAM has been allocated for the SW - // version - if (moduleSWVersion == NULL) // Bail if the RAM allocation failed - return (false); - - if (moduleSWVersion->moduleQueried == false) getProtocolVersion(maxWait); - return (moduleSWVersion->versionLow); -} - -// Get the current protocol version of the u-blox module we're communicating -// with This is helpful when deciding if we should call the high-precision -// Lat/Long (HPPOSLLH) or the regular (POSLLH) -bool SFE_UBLOX_GNSS::getProtocolVersion(uint16_t maxWait) { - if (moduleSWVersion == NULL) - initModuleSWVersion(); // Check that RAM has been allocated for the SW - // version - if (moduleSWVersion == NULL) // Bail if the RAM allocation failed - return (false); - - // Send packet with only CLS and ID, length of zero. This will cause the - // module to respond with the contents of that CLS/ID. - packetCfg.cls = UBX_CLASS_MON; - packetCfg.id = UBX_MON_VER; - - packetCfg.len = 0; - packetCfg.startingSpot = - 40; // Start at first "extended software information" string - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are only expecting data (no ACK) - return (false); // If command send fails then bail - - // Payload should now contain ~220 characters (depends on module type) - - // if (_printDebug == true) - // { - // _debugSerial->print(F("MON VER Payload:")); - // for (int location = 0; location < packetCfg.len; location++) - // { - // if (location % 30 == 0) - // _debugSerial->println(); - // _debugSerial->write(payloadCfg[location]); - // } - // _debugSerial->println(); - // } - - // We will step through the payload looking at each extension field of 30 - // bytes - for (uint8_t extensionNumber = 0; extensionNumber < 10; extensionNumber++) { - // Now we need to find "PROTVER=18.00" in the incoming byte stream - if ((payloadCfg[(30 * extensionNumber) + 0] == 'P') && - (payloadCfg[(30 * extensionNumber) + 6] == 'R')) { - moduleSWVersion->versionHigh = - (payloadCfg[(30 * extensionNumber) + 8] - '0') * 10 + - (payloadCfg[(30 * extensionNumber) + 9] - - '0'); // Convert '18' to 18 - moduleSWVersion->versionLow = - (payloadCfg[(30 * extensionNumber) + 11] - '0') * 10 + - (payloadCfg[(30 * extensionNumber) + 12] - - '0'); // Convert '00' to 00 - moduleSWVersion->moduleQueried = true; // Mark this data as new - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("Protocol version: ")); - _debugSerial->print(moduleSWVersion->versionHigh); - _debugSerial->print(F(".")); - _debugSerial->println(moduleSWVersion->versionLow); - } -#endif - return (true); // Success! - } - } - - return (false); // We failed -} - -// PRIVATE: Allocate RAM for moduleSWVersion and initialize it -bool SFE_UBLOX_GNSS::initModuleSWVersion() { - moduleSWVersion = - new moduleSWVersion_t; // Allocate RAM for the main struct - if (moduleSWVersion == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initModuleSWVersion: RAM alloc failed!")); -#endif - return (false); - } - moduleSWVersion->versionHigh = 0; - moduleSWVersion->versionLow = 0; - moduleSWVersion->moduleQueried = false; - return (true); -} - -// Geofences - -// Add a new geofence using UBX-CFG-GEOFENCE -bool SFE_UBLOX_GNSS::addGeofence(int32_t latitude, int32_t longitude, - uint32_t radius, byte confidence, - byte pinPolarity, byte pin, uint16_t maxWait) { - if (currentGeofenceParams == NULL) - initGeofenceParams(); // Check if RAM has been allocated for - // currentGeofenceParams - if (currentGeofenceParams == NULL) // Abort if the RAM allocation failed - return (false); - - if (currentGeofenceParams->numFences >= 4) - return (false); // Quit if we already have four geofences defined - - // Store the new geofence parameters - currentGeofenceParams->lats[currentGeofenceParams->numFences] = latitude; - currentGeofenceParams->longs[currentGeofenceParams->numFences] = longitude; - currentGeofenceParams->rads[currentGeofenceParams->numFences] = radius; - currentGeofenceParams->numFences = - currentGeofenceParams->numFences + 1; // Increment the number of fences - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_GEOFENCE; - packetCfg.len = (currentGeofenceParams->numFences * 12) + 8; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0; // Message version = 0x00 - payloadCfg[1] = currentGeofenceParams->numFences; // numFences - payloadCfg[2] = confidence; // confLvl = Confidence level 0-4 (none, 68%, - // 95%, 99.7%, 99.99%) - payloadCfg[3] = 0; // reserved1 - if (pin > 0) { - payloadCfg[4] = 1; // enable PIO combined fence state - } else { - payloadCfg[4] = 0; // disable PIO combined fence state - } - payloadCfg[5] = pinPolarity; // PIO pin polarity (0 = low means inside, 1 = - // low means outside (or unknown)) - payloadCfg[6] = pin; // PIO pin - payloadCfg[7] = 0; // reserved2 - payloadCfg[8] = currentGeofenceParams->lats[0] & 0xFF; - payloadCfg[9] = currentGeofenceParams->lats[0] >> 8; - payloadCfg[10] = currentGeofenceParams->lats[0] >> 16; - payloadCfg[11] = currentGeofenceParams->lats[0] >> 24; - payloadCfg[12] = currentGeofenceParams->longs[0] & 0xFF; - payloadCfg[13] = currentGeofenceParams->longs[0] >> 8; - payloadCfg[14] = currentGeofenceParams->longs[0] >> 16; - payloadCfg[15] = currentGeofenceParams->longs[0] >> 24; - payloadCfg[16] = currentGeofenceParams->rads[0] & 0xFF; - payloadCfg[17] = currentGeofenceParams->rads[0] >> 8; - payloadCfg[18] = currentGeofenceParams->rads[0] >> 16; - payloadCfg[19] = currentGeofenceParams->rads[0] >> 24; - if (currentGeofenceParams->numFences >= 2) { - payloadCfg[20] = currentGeofenceParams->lats[1] & 0xFF; - payloadCfg[21] = currentGeofenceParams->lats[1] >> 8; - payloadCfg[22] = currentGeofenceParams->lats[1] >> 16; - payloadCfg[23] = currentGeofenceParams->lats[1] >> 24; - payloadCfg[24] = currentGeofenceParams->longs[1] & 0xFF; - payloadCfg[25] = currentGeofenceParams->longs[1] >> 8; - payloadCfg[26] = currentGeofenceParams->longs[1] >> 16; - payloadCfg[27] = currentGeofenceParams->longs[1] >> 24; - payloadCfg[28] = currentGeofenceParams->rads[1] & 0xFF; - payloadCfg[29] = currentGeofenceParams->rads[1] >> 8; - payloadCfg[30] = currentGeofenceParams->rads[1] >> 16; - payloadCfg[31] = currentGeofenceParams->rads[1] >> 24; - } - if (currentGeofenceParams->numFences >= 3) { - payloadCfg[32] = currentGeofenceParams->lats[2] & 0xFF; - payloadCfg[33] = currentGeofenceParams->lats[2] >> 8; - payloadCfg[34] = currentGeofenceParams->lats[2] >> 16; - payloadCfg[35] = currentGeofenceParams->lats[2] >> 24; - payloadCfg[36] = currentGeofenceParams->longs[2] & 0xFF; - payloadCfg[37] = currentGeofenceParams->longs[2] >> 8; - payloadCfg[38] = currentGeofenceParams->longs[2] >> 16; - payloadCfg[39] = currentGeofenceParams->longs[2] >> 24; - payloadCfg[40] = currentGeofenceParams->rads[2] & 0xFF; - payloadCfg[41] = currentGeofenceParams->rads[2] >> 8; - payloadCfg[42] = currentGeofenceParams->rads[2] >> 16; - payloadCfg[43] = currentGeofenceParams->rads[2] >> 24; - } - if (currentGeofenceParams->numFences >= 4) { - payloadCfg[44] = currentGeofenceParams->lats[3] & 0xFF; - payloadCfg[45] = currentGeofenceParams->lats[3] >> 8; - payloadCfg[46] = currentGeofenceParams->lats[3] >> 16; - payloadCfg[47] = currentGeofenceParams->lats[3] >> 24; - payloadCfg[48] = currentGeofenceParams->longs[3] & 0xFF; - payloadCfg[49] = currentGeofenceParams->longs[3] >> 8; - payloadCfg[50] = currentGeofenceParams->longs[3] >> 16; - payloadCfg[51] = currentGeofenceParams->longs[3] >> 24; - payloadCfg[52] = currentGeofenceParams->rads[3] & 0xFF; - payloadCfg[53] = currentGeofenceParams->rads[3] >> 8; - payloadCfg[54] = currentGeofenceParams->rads[3] >> 16; - payloadCfg[55] = currentGeofenceParams->rads[3] >> 24; - } - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Clear all geofences using UBX-CFG-GEOFENCE -bool SFE_UBLOX_GNSS::clearGeofences(uint16_t maxWait) { - if (currentGeofenceParams == NULL) - initGeofenceParams(); // Check if RAM has been allocated for - // currentGeofenceParams - if (currentGeofenceParams == NULL) // Abort if the RAM allocation failed - return (false); - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_GEOFENCE; - packetCfg.len = 8; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0; // Message version = 0x00 - payloadCfg[1] = 0; // numFences - payloadCfg[2] = 0; // confLvl - payloadCfg[3] = 0; // reserved1 - payloadCfg[4] = 0; // disable PIO combined fence state - payloadCfg[5] = 0; // PIO pin polarity (0 = low means inside, 1 = low means - // outside (or unknown)) - payloadCfg[6] = 0; // PIO pin - payloadCfg[7] = 0; // reserved2 - - currentGeofenceParams->numFences = - 0; // Zero the number of geofences currently in use - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Clear the antenna control settings using UBX-CFG-ANT -// This function is hopefully redundant but may be needed to release -// any PIO pins pre-allocated for antenna functions -bool SFE_UBLOX_GNSS::clearAntPIO(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ANT; - packetCfg.len = 4; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0x10; // Antenna flag mask: set the recovery bit - payloadCfg[1] = 0; - payloadCfg[2] = - 0xFF; // Antenna pin configuration: set pinSwitch and pinSCD to 31 - payloadCfg[3] = - 0xFF; // Antenna pin configuration: set pinOCD to 31, set reconfig bit - - return ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Returns the combined geofence state using UBX-NAV-GEOFENCE -bool SFE_UBLOX_GNSS::getGeofenceState(geofenceState ¤tGeofenceState, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_GEOFENCE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the geofence status. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - currentGeofenceState.status = payloadCfg[5]; // Extract the status - currentGeofenceState.numFences = - payloadCfg[6]; // Extract the number of geofences - currentGeofenceState.combState = - payloadCfg[7]; // Extract the combined state of all geofences - if (currentGeofenceState.numFences > 0) - currentGeofenceState.states[0] = - payloadCfg[8]; // Extract geofence 1 state - if (currentGeofenceState.numFences > 1) - currentGeofenceState.states[1] = - payloadCfg[10]; // Extract geofence 2 state - if (currentGeofenceState.numFences > 2) - currentGeofenceState.states[2] = - payloadCfg[12]; // Extract geofence 3 state - if (currentGeofenceState.numFences > 3) - currentGeofenceState.states[3] = - payloadCfg[14]; // Extract geofence 4 state - - return (true); -} - -// PRIVATE: Allocate RAM for currentGeofenceParams and initialize it -bool SFE_UBLOX_GNSS::initGeofenceParams() { - currentGeofenceParams = - new geofenceParams_t; // Allocate RAM for the main struct - if (currentGeofenceParams == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initGeofenceParams: RAM alloc failed!")); -#endif - return (false); - } - currentGeofenceParams->numFences = 0; - return (true); -} - -// Power Save Mode -// Enables/Disables Low Power Mode using UBX-CFG-RXM -bool SFE_UBLOX_GNSS::powerSaveMode(bool power_save, uint16_t maxWait) { - // Let's begin by checking the Protocol Version as UBX_CFG_RXM is not - // supported on the ZED (protocol >= 27) - uint8_t protVer = getProtocolVersionHigh(maxWait); - /* - if (_printDebug == true) - { - _debugSerial->print(F("Protocol version is ")); - _debugSerial->println(protVer); - } - */ - if (protVer >= 27) { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("powerSaveMode (UBX-CFG-RXM) is not supported by this " - "protocol version")); - } - return (false); - } - - // Now let's change the power setting using UBX-CFG-RXM - return setupPowerMode( - power_save ? SFE_UBLOX_CFG_RXM_POWERSAVE : SFE_UBLOX_CFG_RXM_CONTINUOUS, - maxWait); -} - -// Get Power Save Mode -// Returns the current Low Power Mode using UBX-CFG-RXM -// Returns 255 if the sendCommand fails -uint8_t SFE_UBLOX_GNSS::getPowerSaveMode(uint16_t maxWait) { - // Let's begin by checking the Protocol Version as UBX_CFG_RXM is not - // supported on the ZED (protocol >= 27) - uint8_t protVer = getProtocolVersionHigh(maxWait); - /* - if (_printDebug == true) - { - _debugSerial->print(F("Protocol version is ")); - _debugSerial->println(protVer); - } - */ - if (protVer >= 27) { - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - { - _debugSerial->println( - F("powerSaveMode (UBX-CFG-RXM) is not supported by this " - "protocol version")); - } - return (255); - } - - // Now let's read the power setting using UBX-CFG-RXM - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RXM; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current power management settings. Loads into - // payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (255); - - return (payloadCfg[1]); // Return the low power mode -} - -// Powers off the GPS device for a given duration to reduce power consumption. -// NOTE: Querying the device before the duration is complete, for example by -// "getLatitude()" will wake it up! Returns true if command has not been not -// acknowledged. Returns false if command has not been acknowledged or maxWait = -// 0. -bool SFE_UBLOX_GNSS::powerOff(uint32_t durationInMs, uint16_t maxWait) { - // use durationInMs = 0 for infinite duration -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("Powering off for ")); - _debugSerial->print(durationInMs); - _debugSerial->println(" ms"); - } -#endif - - // Power off device using UBX-RXM-PMREQ - packetCfg.cls = UBX_CLASS_RXM; // 0x02 - packetCfg.id = UBX_RXM_PMREQ; // 0x41 - packetCfg.len = 8; - packetCfg.startingSpot = 0; - - // duration - // big endian to little endian, switch byte order - payloadCfg[0] = (durationInMs >> (8 * 0)) & 0xff; - payloadCfg[1] = (durationInMs >> (8 * 1)) & 0xff; - payloadCfg[2] = (durationInMs >> (8 * 2)) & 0xff; - payloadCfg[3] = (durationInMs >> (8 * 3)) & 0xff; - - payloadCfg[4] = 0x02; // Flags : set the backup bit - payloadCfg[5] = 0x00; // Flags - payloadCfg[6] = 0x00; // Flags - payloadCfg[7] = 0x00; // Flags - - if (maxWait != 0) { - // check for "not acknowledged" command - return (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_COMMAND_NACK); - } else { - sendCommand(&packetCfg, maxWait); - return false; // can't tell if command not acknowledged if maxWait = 0 - } -} - -// Powers off the GPS device for a given duration to reduce power consumption. -// While powered off it can be woken up by creating a falling or rising voltage -// edge on the specified pin. NOTE: The GPS seems to be sensitve to signals on -// the pins while powered off. Works best when Microcontroller is in deepsleep. -// NOTE: Querying the device before the duration is complete, for example by -// "getLatitude()" will wake it up! Returns true if command has not been not -// acknowledged. Returns false if command has not been acknowledged or maxWait = -// 0. -bool SFE_UBLOX_GNSS::powerOffWithInterrupt(uint32_t durationInMs, - uint32_t wakeupSources, - bool forceWhileUsb, - uint16_t maxWait) { - // use durationInMs = 0 for infinite duration -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("Powering off for ")); - _debugSerial->print(durationInMs); - _debugSerial->println(" ms"); - } -#endif - - // Power off device using UBX-RXM-PMREQ - packetCfg.cls = UBX_CLASS_RXM; // 0x02 - packetCfg.id = UBX_RXM_PMREQ; // 0x41 - packetCfg.len = 16; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0x00; // message version - - // bytes 1-3 are reserved - and must be set to zero - payloadCfg[1] = 0x00; - payloadCfg[2] = 0x00; - payloadCfg[3] = 0x00; - - // duration - // big endian to little endian, switch byte order - payloadCfg[4] = (durationInMs >> (8 * 0)) & 0xff; - payloadCfg[5] = (durationInMs >> (8 * 1)) & 0xff; - payloadCfg[6] = (durationInMs >> (8 * 2)) & 0xff; - payloadCfg[7] = (durationInMs >> (8 * 3)) & 0xff; - - // flags - - // disables USB interface when powering off, defaults to true - if (forceWhileUsb) { - payloadCfg[8] = 0x06; // force | backup - } else { - payloadCfg[8] = 0x02; // backup only (leave the force bit clear - - // module will stay on if USB is connected) - } - - payloadCfg[9] = 0x00; - payloadCfg[10] = 0x00; - payloadCfg[11] = 0x00; - - // wakeUpSources - - // wakeupPin mapping, defaults to VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 - - // Possible values are: - // VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX - // VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 - // VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 - // VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS - - payloadCfg[12] = (wakeupSources >> (8 * 0)) & 0xff; - payloadCfg[13] = (wakeupSources >> (8 * 1)) & 0xff; - payloadCfg[14] = (wakeupSources >> (8 * 2)) & 0xff; - payloadCfg[15] = (wakeupSources >> (8 * 3)) & 0xff; - - if (maxWait != 0) { - // check for "not acknowledged" command - return (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_COMMAND_NACK); - } else { - sendCommand(&packetCfg, maxWait); - return false; // can't tell if command not acknowledged if maxWait = 0 - } -} - -bool SFE_UBLOX_GNSS::setPowerManagement(sfe_ublox_pms_mode_e mode, - uint16_t period, uint16_t onTime, - uint16_t maxWait) { - // INVALID only valid in response - if (mode == SFE_UBLOX_PMS_MODE_INVALID) return false; - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PMS; - packetCfg.len = 8; - packetCfg.startingSpot = 0; - - packetCfg.payload[0] = 0x0; // message version - packetCfg.payload[1] = mode; - // only valid if mode==SFE_UBLOX_PMS_MODE_INTERVAL - if (mode == SFE_UBLOX_PMS_MODE_INTERVAL) { - packetCfg.payload[2] = period >> 8; - packetCfg.payload[3] = period & 0xff; - packetCfg.payload[4] = onTime >> 8; - packetCfg.payload[5] = onTime & 0xff; - } else { - packetCfg.payload[2] = 0; - packetCfg.payload[3] = 0; - packetCfg.payload[4] = 0; - packetCfg.payload[5] = 0; - } - packetCfg.payload[6] = 0x0; // reserved - packetCfg.payload[7] = 0x0; // reserved - return sendCommand(&packetCfg, maxWait); -} - -bool SFE_UBLOX_GNSS::setupPowerMode(sfe_ublox_rxm_mode_e mode, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RXM; - packetCfg.len = 2; - packetCfg.startingSpot = 0; - - packetCfg.payload[0] = 0x0; // reserved - packetCfg.payload[1] = mode; // low power mode - - return sendCommand(&packetCfg, maxWait); -} - -// Dynamic Platform Model - -// Change the dynamic platform model using UBX-CFG-NAV5 -// Possible values are: -// PORTABLE,STATIONARY,PEDESTRIAN,AUTOMOTIVE,SEA, -// AIRBORNE1g,AIRBORNE2g,AIRBORNE4g,WRIST,BIKE -// WRIST is not supported in protocol versions less than 18 -// BIKE is supported in protocol versions 19.2 -bool SFE_UBLOX_GNSS::setDynamicModel(dynModel newDynamicModel, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAV5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current navigation model settings. Loads into - // payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - payloadCfg[0] = 0x01; // mask: set only the dyn bit (0) - payloadCfg[1] = 0x00; // mask - payloadCfg[2] = newDynamicModel; // dynModel - - packetCfg.len = 36; - packetCfg.startingSpot = 0; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Get the dynamic platform model using UBX-CFG-NAV5 -// Returns DYN_MODEL_UNKNOWN (255) if the sendCommand fails -uint8_t SFE_UBLOX_GNSS::getDynamicModel(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAV5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current navigation model settings. Loads into - // payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (DYN_MODEL_UNKNOWN); - - return (payloadCfg[2]); // Return the dynamic model -} - -// Reset the odometer -bool SFE_UBLOX_GNSS::resetOdometer(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_RESETODO; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // This is a special case as we are only expecting an ACK but this is not a - // CFG message - return (sendCommand(&packetCfg, maxWait, true) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Enable / disable the odometer -bool SFE_UBLOX_GNSS::enableOdometer(bool enable, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ODO; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current odometer configuration. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - if (enable) - payloadCfg[4] = payloadCfg[4] | UBX_CFG_ODO_USE_ODO; - else - payloadCfg[4] = payloadCfg[4] & ~UBX_CFG_ODO_USE_ODO; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Read the odometer configuration -bool SFE_UBLOX_GNSS::getOdometerConfig(uint8_t *flags, uint8_t *odoCfg, - uint8_t *cogMaxSpeed, - uint8_t *cogMaxPosAcc, - uint8_t *velLpGain, uint8_t *cogLpGain, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ODO; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current odometer configuration. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - *flags = payloadCfg[4]; - *odoCfg = payloadCfg[5]; - *cogMaxSpeed = payloadCfg[12]; - *cogMaxPosAcc = payloadCfg[13]; - *velLpGain = payloadCfg[16]; - *cogLpGain = payloadCfg[17]; - - return true; -} - -// Configure the odometer -bool SFE_UBLOX_GNSS::setOdometerConfig(uint8_t flags, uint8_t odoCfg, - uint8_t cogMaxSpeed, - uint8_t cogMaxPosAcc, uint8_t velLpGain, - uint8_t cogLpGain, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ODO; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current odometer configuration. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - payloadCfg[4] = flags; - payloadCfg[5] = odoCfg; - payloadCfg[12] = cogMaxSpeed; - payloadCfg[13] = cogMaxPosAcc; - payloadCfg[16] = velLpGain; - payloadCfg[17] = cogLpGain; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Enable/Disable individual GNSS systems using UBX-CFG-GNSS -bool SFE_UBLOX_GNSS::enableGNSS(bool enable, sfe_ublox_gnss_ids_e id, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_GNSS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - uint8_t numConfigBlocks = payloadCfg[3]; // Extract the numConfigBlocks - - for (uint8_t block = 0; block < numConfigBlocks; - block++) // Check each configuration block - { - if (payloadCfg[(block * 8) + 4] == - (uint8_t) - id) // Check the gnssId for this block. Do we have a match? - { - // We have a match so set/clear the enable bit in flags - if (enable) - payloadCfg[(block * 8) + 4 + 4] |= - 0x01; // Set the enable bit in flags (Little Endian) - else - payloadCfg[(block * 8) + 4 + 4] &= - 0xFE; // Clear the enable bit in flags (Little Endian) - break; - } - } - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Check if an individual GNSS system is enabled -bool SFE_UBLOX_GNSS::isGNSSenabled(sfe_ublox_gnss_ids_e id, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_GNSS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - uint8_t numConfigBlocks = payloadCfg[3]; // Extract the numConfigBlocks - - for (uint8_t block = 0; block < numConfigBlocks; - block++) // Check each configuration block - { - if (payloadCfg[(block * 8) + 4] == - (uint8_t) - id) // Check the gnssId for this block. Do we have a match? - { - // We have a match so check the enable bit in flags - if ((payloadCfg[(block * 8) + 4 + 4] & 0x01) > - 0) // Check the enable bit in flags (Little Endian) - return true; - } - } - - return false; -} - -// Reset ESF automatic IMU-mount alignment -bool SFE_UBLOX_GNSS::resetIMUalignment(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_ESF; - packetCfg.id = UBX_ESF_RESETALG; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // This is a special case as we are only expecting an ACK but this is not a - // CFG message - return (sendCommand(&packetCfg, maxWait, true) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// UBX-CFG-ESFALG is not documented. This was found using u-center. -// Returns the state of the UBX-CFG-ESFALG 'Automatic IMU-mount Alignment' flag -bool SFE_UBLOX_GNSS::getESFAutoAlignment(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ESFALG; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println(F("getESFAutoAlignment failed")); - } -#endif - - return (false); // If command send fails then bail - } - - return (payloadCfg[1] & 0b1); // Return Bit 0 -} - -// Set the state of the UBX-CFG-ESFALG 'Automatic IMU-mount Alignment' flag -bool SFE_UBLOX_GNSS::setESFAutoAlignment(bool enable, uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ESFALG; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println(F("getESFAutoAlignment failed")); - } -#endif - - return (false); // If command send fails then bail - } - - // payloadCfg is now filled - - if (enable) - payloadCfg[1] |= 0b1; - else - payloadCfg[1] &= ~(0b1); - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_SENT) // This time we are only expecting an ACK - { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->println(F("setESFAutoAlignment failed")); - } -#endif - return (false); - } - - return (true); -} - -// Get the time pulse parameters using UBX_CFG_TP5 -bool SFE_UBLOX_GNSS::getTimePulseParameters(UBX_CFG_TP5_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TP5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->tpIdx = extractByte(&packetCfg, 0); - data->version = extractByte(&packetCfg, 1); - data->antCableDelay = extractSignedInt(&packetCfg, 4); - data->rfGroupDelay = extractSignedInt(&packetCfg, 6); - data->freqPeriod = extractLong(&packetCfg, 8); - data->freqPeriodLock = extractLong(&packetCfg, 12); - data->pulseLenRatio = extractLong(&packetCfg, 16); - data->pulseLenRatioLock = extractLong(&packetCfg, 20); - data->userConfigDelay = extractSignedLong(&packetCfg, 24); - data->flags.all = extractLong(&packetCfg, 28); - - return (true); -} - -// Set the time pulse parameters using UBX_CFG_TP5 -bool SFE_UBLOX_GNSS::setTimePulseParameters(UBX_CFG_TP5_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_TP5; - packetCfg.len = UBX_CFG_TP5_LEN; - packetCfg.startingSpot = 0; - - // Insert the data - payloadCfg[0] = data->tpIdx; - payloadCfg[1] = data->version; - payloadCfg[4] = data->antCableDelay & 0xFF; // Little Endian - payloadCfg[5] = data->antCableDelay >> 8; - payloadCfg[6] = data->rfGroupDelay & 0xFF; // Little Endian - payloadCfg[7] = data->rfGroupDelay >> 8; - payloadCfg[8] = data->freqPeriod & 0xFF; // Little Endian - payloadCfg[9] = (data->freqPeriod >> 8) & 0xFF; - payloadCfg[10] = (data->freqPeriod >> 16) & 0xFF; - payloadCfg[11] = (data->freqPeriod >> 24) & 0xFF; - payloadCfg[12] = data->freqPeriodLock & 0xFF; // Little Endian - payloadCfg[13] = (data->freqPeriodLock >> 8) & 0xFF; - payloadCfg[14] = (data->freqPeriodLock >> 16) & 0xFF; - payloadCfg[15] = (data->freqPeriodLock >> 24) & 0xFF; - payloadCfg[16] = data->pulseLenRatio & 0xFF; // Little Endian - payloadCfg[17] = (data->pulseLenRatio >> 8) & 0xFF; - payloadCfg[18] = (data->pulseLenRatio >> 16) & 0xFF; - payloadCfg[19] = (data->pulseLenRatio >> 24) & 0xFF; - payloadCfg[20] = data->pulseLenRatioLock & 0xFF; // Little Endian - payloadCfg[21] = (data->pulseLenRatioLock >> 8) & 0xFF; - payloadCfg[22] = (data->pulseLenRatioLock >> 16) & 0xFF; - payloadCfg[23] = (data->pulseLenRatioLock >> 24) & 0xFF; - payloadCfg[24] = data->userConfigDelay & 0xFF; // Little Endian - payloadCfg[25] = (data->userConfigDelay >> 8) & 0xFF; - payloadCfg[26] = (data->userConfigDelay >> 16) & 0xFF; - payloadCfg[27] = (data->userConfigDelay >> 24) & 0xFF; - payloadCfg[28] = data->flags.all & 0xFF; // Little Endian - payloadCfg[29] = (data->flags.all >> 8) & 0xFF; - payloadCfg[30] = (data->flags.all >> 16) & 0xFF; - payloadCfg[31] = (data->flags.all >> 24) & 0xFF; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Get the jamming/interference monitor configuration using UBX_CFG_ITFM -bool SFE_UBLOX_GNSS::getJammingConfiguration(UBX_CFG_ITFM_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ITFM; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->config.all = extractLong(&packetCfg, 0); - data->config2.all = extractLong(&packetCfg, 4); - - return (true); -} - -// Set the jamming/interference monitor configuration using UBX_CFG_ITFM -bool SFE_UBLOX_GNSS::setJammingConfiguration(UBX_CFG_ITFM_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_ITFM; - packetCfg.len = UBX_CFG_ITFM_LEN; - packetCfg.startingSpot = 0; - - payloadCfg[0] = data->config.all & 0xFF; // Little Endian - payloadCfg[1] = (data->config.all >> 8) & 0xFF; - payloadCfg[2] = (data->config.all >> 16) & 0xFF; - payloadCfg[3] = (data->config.all >> 24) & 0xFF; - payloadCfg[4] = data->config2.all & 0xFF; // Little Endian - payloadCfg[5] = (data->config2.all >> 8) & 0xFF; - payloadCfg[6] = (data->config2.all >> 16) & 0xFF; - payloadCfg[7] = (data->config2.all >> 24) & 0xFF; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Get the RF information using UBX_MON_RF -bool SFE_UBLOX_GNSS::getRFinformation(UBX_MON_RF_data_t *data, - uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_MON; - packetCfg.id = UBX_MON_RF; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->header.version = extractByte(&packetCfg, 0); - data->header.nBlocks = extractByte(&packetCfg, 1); - - // Extract the RF information blocks - for (uint8_t block = 0; - (block < data->header.nBlocks) && (block < UBX_MON_RF_MAX_BLOCKS); - block++) { - data->blocks[block].blockId = extractByte(&packetCfg, 4 + (block * 24)); - data->blocks[block].flags.all = - extractByte(&packetCfg, 5 + (block * 24)); - data->blocks[block].antStatus = - extractByte(&packetCfg, 6 + (block * 24)); - data->blocks[block].antPower = - extractByte(&packetCfg, 7 + (block * 24)); - data->blocks[block].postStatus = - extractLong(&packetCfg, 8 + (block * 24)); - data->blocks[block].noisePerMS = - extractInt(&packetCfg, 16 + (block * 24)); - data->blocks[block].agcCnt = extractInt(&packetCfg, 18 + (block * 24)); - data->blocks[block].jamInd = extractByte(&packetCfg, 20 + (block * 24)); - data->blocks[block].ofsI = - extractSignedChar(&packetCfg, 21 + (block * 24)); - data->blocks[block].magI = extractByte(&packetCfg, 22 + (block * 24)); - data->blocks[block].ofsQ = - extractSignedChar(&packetCfg, 23 + (block * 24)); - data->blocks[block].magQ = extractByte(&packetCfg, 24 + (block * 24)); - } - - return (true); -} - -// Get the hardware status (including jamming) using UBX_MON_HW -bool SFE_UBLOX_GNSS::getHWstatus(UBX_MON_HW_data_t *data, uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_MON; - packetCfg.id = UBX_MON_HW; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->pinSel = extractLong(&packetCfg, 0); - data->pinBank = extractLong(&packetCfg, 4); - data->pinDir = extractLong(&packetCfg, 8); - data->pinVal = extractLong(&packetCfg, 12); - data->noisePerMS = extractInt(&packetCfg, 16); - data->agcCnt = extractInt(&packetCfg, 18); - data->aStatus = extractByte(&packetCfg, 20); - data->aPower = extractByte(&packetCfg, 21); - data->flags.all = extractByte(&packetCfg, 22); - data->usedMask = extractLong(&packetCfg, 24); - for (uint8_t pin = 0; pin < 17; pin++) { - data->VP[pin] = extractByte(&packetCfg, 28 + pin); - } - data->jamInd = extractByte(&packetCfg, 45); - data->pinIrq = extractLong(&packetCfg, 48); - data->pullH = extractLong(&packetCfg, 52); - data->pullL = extractLong(&packetCfg, 56); - - return (true); -} - -// Get the extended hardware status using UBX_MON_HW2 -bool SFE_UBLOX_GNSS::getHW2status(UBX_MON_HW2_data_t *data, uint16_t maxWait) { - if (data == NULL) // Check if the user forgot to include the data pointer - return (false); // Bail - - packetCfg.cls = UBX_CLASS_MON; - packetCfg.id = UBX_MON_HW2; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Extract the data - data->ofsI = extractSignedChar(&packetCfg, 0); - data->magI = extractByte(&packetCfg, 1); - data->ofsQ = extractSignedChar(&packetCfg, 2); - data->magQ = extractByte(&packetCfg, 3); - data->cfgSource = extractByte(&packetCfg, 4); - data->lowLevCfg = - extractLong(&packetCfg, 8); // Low-level configuration (obsolete for - // protocol versions greater than 15.00) - data->postStatus = extractLong(&packetCfg, 20); - - return (true); -} - -// UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, UBX-MGA-ACK -// messages will be sent by the module to acknowledge the MGA data -uint8_t SFE_UBLOX_GNSS::getAckAiding( - uint16_t maxWait) // Get the ackAiding byte - returns 255 if the - // sendCommand fails -{ - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAVX5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (255); - - // Extract the ackAiding byte - // There are three versions of UBX-CFG-NAVX5 but ackAiding is always in byte - // 17 - return (extractByte(&packetCfg, 17)); -} -bool SFE_UBLOX_GNSS::setAckAiding(uint8_t ackAiding, - uint16_t maxWait) // Set the ackAiding byte -{ - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAVX5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Set the ackAiding byte - // There are three versions of UBX-CFG-NAVX5 but ackAiding is always in byte - // 17 - payloadCfg[17] = ackAiding; - - // There are three versions of UBX-CFG-NAVX5 but the ackAid flag is always - // in bit 10 of mask1 - payloadCfg[2] = 0x00; // Clear the LS byte of mask1 - payloadCfg[3] = 0x04; // Set _only_ the ackAid flag = bit 10 of mask1 = bit - // 2 of the MS byte - payloadCfg[4] = 0x00; // Clear the LS byte of mask2, just in case - payloadCfg[5] = 0x00; // Clear the LS byte of mask2, just in case - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// AssistNow Autonomous support -// UBX-CFG-NAVX5 - get the AssistNow Autonomous configuration (aopCfg) - returns -// 255 if the sendCommand fails -uint8_t SFE_UBLOX_GNSS::getAopCfg(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAVX5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (255); - - // Extract the aopCfg byte - // There are three versions of UBX-CFG-NAVX5 but aopCfg is always in byte 27 - return (extractByte(&packetCfg, 27)); -} -// Set the aopCfg byte and the aopOrdMaxErr word -bool SFE_UBLOX_GNSS::setAopCfg(uint8_t aopCfg, uint16_t aopOrbMaxErr, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NAVX5; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - // Set the aopCfg byte - // There are three versions of UBX-CFG-NAVX5 but aopCfg is always in byte 27 - // and aopOrbMaxErr is always in bytes 30 & 31 - payloadCfg[27] = aopCfg; - payloadCfg[30] = (uint8_t)(aopOrbMaxErr & 0xFF); // aopOrbMaxErr LSB - payloadCfg[31] = (uint8_t)(aopOrbMaxErr >> 8); // aopOrbMaxErr MSB - - // There are three versions of UBX-CFG-NAVX5 but the aop flag is always in - // bit 14 of mask1 - payloadCfg[2] = 0x00; // Clear the LS byte of mask1 - payloadCfg[3] = 0x40; // Set _only_ the aop flag = bit 14 of mask1 = bit 6 - // of the MS byte - payloadCfg[4] = 0x00; // Clear the LS byte of mask2, just in case - payloadCfg[5] = 0x00; // Clear the LS byte of mask2, just in case - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// SPARTN dynamic keys -//"When the receiver boots, the host should send 'current' and 'next' keys in -// one message." - Use setDynamicSPARTNKeys for this. "Every time the 'current' -// key is expired, 'next' takes its place." "Therefore the host should then -// retrieve the new 'next' key and send only that." - Use setDynamicSPARTNKey -// for this. -// The key can be provided in binary (uint8_t) format or in ASCII Hex (char) -// format, but in both cases keyLengthBytes _must_ represent the binary key -// length in bytes. -bool SFE_UBLOX_GNSS::setDynamicSPARTNKey(uint8_t keyLengthBytes, - uint16_t validFromWno, - uint32_t validFromTow, - const char *key) { - uint8_t *binaryKey = - new uint8_t[keyLengthBytes]; // Allocate memory to store the binaryKey - - if (binaryKey == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) - _debugSerial->println( - F("setDynamicSPARTNKey: binaryKey RAM allocation failed!")); -#endif - return (false); - } - - bool ok = true; - - // Convert the ASCII Hex const char to binary uint8_t - for (uint16_t i = 0; i < ((uint16_t)keyLengthBytes * 2); i += 2) { - if ((key[i] >= '0') && (key[i] <= '9')) { - binaryKey[i >> 1] = (key[i] - '0') << 4; - } else if ((key[i] >= 'a') && (key[i] <= 'f')) { - binaryKey[i >> 1] = (key[i] + 10 - 'a') << 4; - } else if ((key[i] >= 'A') && (key[i] <= 'F')) { - binaryKey[i >> 1] = (key[i] + 10 - 'A') << 4; - } else { - ok = false; - } - - if ((key[i + 1] >= '0') && (key[i + 1] <= '9')) { - binaryKey[i >> 1] |= key[i + 1] - '0'; - } else if ((key[i + 1] >= 'a') && (key[i + 1] <= 'f')) { - binaryKey[i >> 1] |= key[i + 1] + 10 - 'a'; - } else if ((key[i + 1] >= 'A') && (key[i + 1] <= 'F')) { - binaryKey[i >> 1] |= key[i + 1] + 10 - 'A'; - } else { - ok = false; - } - } - - if (ok) - ok = setDynamicSPARTNKey(keyLengthBytes, validFromWno, validFromTow, - (const uint8_t *)binaryKey); - - delete[] binaryKey; // Free the memory allocated for binaryKey - - return (ok); -} - -bool SFE_UBLOX_GNSS::setDynamicSPARTNKey(uint8_t keyLengthBytes, - uint16_t validFromWno, - uint32_t validFromTow, - const uint8_t *key) { - // Check if there is room for the key in packetCfg. Resize the buffer if - // not. - size_t payloadLength = (size_t)keyLengthBytes + 12; - if (packetCfgPayloadSize < payloadLength) { - if (!setPacketCfgPayloadSize( - payloadLength)) // Check if the resize was successful - { - return (false); - } - } - - // Copy the key etc. into packetCfg - packetCfg.cls = UBX_CLASS_RXM; - packetCfg.id = UBX_RXM_SPARTNKEY; - packetCfg.len = payloadLength; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0x01; // version - payloadCfg[1] = 0x01; // numKeys - payloadCfg[2] = 0x00; // reserved0 - payloadCfg[3] = 0x00; // reserved0 - payloadCfg[4] = 0x00; // reserved1 - payloadCfg[5] = keyLengthBytes; - payloadCfg[6] = validFromWno & 0xFF; // validFromWno little-endian - payloadCfg[7] = validFromWno >> 8; - payloadCfg[8] = validFromTow & 0xFF; // validFromTow little-endian - payloadCfg[9] = (validFromTow >> 8) & 0xFF; - payloadCfg[10] = (validFromTow >> 16) & 0xFF; - payloadCfg[11] = (validFromTow >> 24) & 0xFF; - - memcpy(&payloadCfg[12], key, keyLengthBytes); - - return (sendCommand(&packetCfg, 0) == - SFE_UBLOX_STATUS_SUCCESS); // UBX-RXM-SPARTNKEY is silent. It does - // not ACK (or NACK) -} - -bool SFE_UBLOX_GNSS::setDynamicSPARTNKeys( - uint8_t keyLengthBytes1, uint16_t validFromWno1, uint32_t validFromTow1, - const char *key1, uint8_t keyLengthBytes2, uint16_t validFromWno2, - uint32_t validFromTow2, const char *key2) { - uint8_t *binaryKey1 = - new uint8_t[keyLengthBytes1]; // Allocate memory to store binaryKey1 - - if (binaryKey1 == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) - _debugSerial->println( - F("setDynamicSPARTNKeys: binaryKey1 RAM allocation failed!")); -#endif - return (false); - } - - uint8_t *binaryKey2 = - new uint8_t[keyLengthBytes2]; // Allocate memory to store binaryKey2 - - if (binaryKey2 == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) - _debugSerial->println( - F("setDynamicSPARTNKeys: binaryKey2 RAM allocation failed!")); -#endif - delete[] binaryKey1; - return (false); - } - - bool ok = true; - - // Convert the ASCII Hex const char to binary uint8_t - for (uint16_t i = 0; i < ((uint16_t)keyLengthBytes1 * 2); i += 2) { - if ((key1[i] >= '0') && (key1[i] <= '9')) { - binaryKey1[i >> 1] = (key1[i] - '0') << 4; - } else if ((key1[i] >= 'a') && (key1[i] <= 'f')) { - binaryKey1[i >> 1] = (key1[i] + 10 - 'a') << 4; - } else if ((key1[i] >= 'A') && (key1[i] <= 'F')) { - binaryKey1[i >> 1] = (key1[i] + 10 - 'A') << 4; - } else { - ok = false; - } - - if ((key1[i + 1] >= '0') && (key1[i + 1] <= '9')) { - binaryKey1[i >> 1] |= key1[i + 1] - '0'; - } else if ((key1[i + 1] >= 'a') && (key1[i + 1] <= 'f')) { - binaryKey1[i >> 1] |= key1[i + 1] + 10 - 'a'; - } else if ((key1[i + 1] >= 'A') && (key1[i + 1] <= 'F')) { - binaryKey1[i >> 1] |= key1[i + 1] + 10 - 'A'; - } else { - ok = false; - } - } - - // Convert the ASCII Hex const char to binary uint8_t - for (uint16_t i = 0; i < ((uint16_t)keyLengthBytes2 * 2); i += 2) { - if ((key2[i] >= '0') && (key2[i] <= '9')) { - binaryKey2[i >> 1] = (key2[i] - '0') << 4; - } else if ((key2[i] >= 'a') && (key2[i] <= 'f')) { - binaryKey2[i >> 1] = (key2[i] + 10 - 'a') << 4; - } else if ((key2[i] >= 'A') && (key2[i] <= 'F')) { - binaryKey2[i >> 1] = (key2[i] + 10 - 'A') << 4; - } else { - ok = false; - } - - if ((key2[i + 1] >= '0') && (key2[i + 1] <= '9')) { - binaryKey2[i >> 1] |= key2[i + 1] - '0'; - } else if ((key2[i + 1] >= 'a') && (key2[i + 1] <= 'f')) { - binaryKey2[i >> 1] |= key2[i + 1] + 10 - 'a'; - } else if ((key2[i + 1] >= 'A') && (key2[i + 1] <= 'F')) { - binaryKey2[i >> 1] |= key2[i + 1] + 10 - 'A'; - } else { - ok = false; - } - } - - if (ok) - ok = setDynamicSPARTNKeys(keyLengthBytes1, validFromWno1, validFromTow1, - (const uint8_t *)binaryKey1, keyLengthBytes2, - validFromWno2, validFromTow2, - (const uint8_t *)binaryKey2); - - delete[] binaryKey1; // Free the memory allocated for binaryKey1 - delete[] binaryKey2; // Free the memory allocated for binaryKey2 - - return (ok); -} - -bool SFE_UBLOX_GNSS::setDynamicSPARTNKeys( - uint8_t keyLengthBytes1, uint16_t validFromWno1, uint32_t validFromTow1, - const uint8_t *key1, uint8_t keyLengthBytes2, uint16_t validFromWno2, - uint32_t validFromTow2, const uint8_t *key2) { - // Check if there is room for the key in packetCfg. Resize the buffer if - // not. - size_t payloadLength = - (size_t)keyLengthBytes1 + (size_t)keyLengthBytes2 + 20; - if (packetCfgPayloadSize < payloadLength) { - if (!setPacketCfgPayloadSize( - payloadLength)) // Check if the resize was successful - { - return (false); - } - } - - // Copy the key etc. into packetCfg - packetCfg.cls = UBX_CLASS_RXM; - packetCfg.id = UBX_RXM_SPARTNKEY; - packetCfg.len = payloadLength; - packetCfg.startingSpot = 0; - - payloadCfg[0] = 0x01; // version - payloadCfg[1] = 0x02; // numKeys - payloadCfg[2] = 0x00; // reserved0 - payloadCfg[3] = 0x00; // reserved0 - payloadCfg[4] = 0x00; // reserved1 - payloadCfg[5] = keyLengthBytes1; - payloadCfg[6] = validFromWno1 & 0xFF; // validFromWno little-endian - payloadCfg[7] = validFromWno1 >> 8; - payloadCfg[8] = validFromTow1 & 0xFF; // validFromTow little-endian - payloadCfg[9] = (validFromTow1 >> 8) & 0xFF; - payloadCfg[10] = (validFromTow1 >> 16) & 0xFF; - payloadCfg[11] = (validFromTow1 >> 24) & 0xFF; - payloadCfg[12] = 0x00; // reserved1 - payloadCfg[13] = keyLengthBytes2; - payloadCfg[14] = validFromWno2 & 0xFF; // validFromWno little-endian - payloadCfg[15] = validFromWno2 >> 8; - payloadCfg[16] = validFromTow2 & 0xFF; // validFromTow little-endian - payloadCfg[17] = (validFromTow2 >> 8) & 0xFF; - payloadCfg[18] = (validFromTow2 >> 16) & 0xFF; - payloadCfg[19] = (validFromTow2 >> 24) & 0xFF; - - memcpy(&payloadCfg[20], key1, keyLengthBytes1); - memcpy(&payloadCfg[20 + keyLengthBytes1], key2, keyLengthBytes2); - - return (sendCommand(&packetCfg, 0) == - SFE_UBLOX_STATUS_SUCCESS); // UBX-RXM-SPARTNKEY is silent. It does - // not ACK (or NACK) -} - -// CONFIGURATION INTERFACE (protocol v27 and above) - -// Form 32-bit key from group/id/size -uint32_t SFE_UBLOX_GNSS::createKey(uint16_t group, uint16_t id, uint8_t size) { - uint32_t key = 0; - key |= (uint32_t)id; - key |= (uint32_t)group << 16; - key |= (uint32_t)size << 28; - return (key); -} - -// Given a key, load the payload with data that can then be extracted to 8, 16, -// or 32 bits This function takes a full 32-bit key Default layer is RAM -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -sfe_ublox_status_e SFE_UBLOX_GNSS::getVal(uint32_t key, uint8_t layer, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALGET; - packetCfg.len = 4 + 4 * 1; // While multiple keys are allowed, we will send - // only one key at a time - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - // VALGET uses different memory layer definitions to VALSET - // because it can only return the value for one layer. - // So we need to fiddle the layer here. - // And just to complicate things further, the ZED-F9P only responds - // correctly to layer 0 (RAM) and layer 7 (Default)! - uint8_t getLayer = 7; // 7 is the "Default Layer" - if ((layer & VAL_LAYER_RAM) == - VAL_LAYER_RAM) // Did the user request the RAM layer? - { - getLayer = 0; // Layer 0 is RAM - } - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = getLayer; // Layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("key: 0x")); - _debugSerial->print(key, HEX); - _debugSerial->println(); - } -#endif - - // Send VALGET command with this key - - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if (_printDebug == true) { - _debugSerial->print(F("getVal: sendCommand returned: ")); - _debugSerial->println(statusString(retVal)); - } -#endif - - // Verify the response is the correct length as compared to what the user - // called (did the module respond with 8-bits but the user called getVal32?) - // Response is 8 bytes plus cfg data - // if(packet->len > 8+1) - - // The response is now sitting in payload, ready for extraction - return (retVal); -} - -// Given a key, return its value -// This function takes a full 32-bit key -// Default layer is RAM -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::getVal8(uint32_t key, uint8_t layer, uint16_t maxWait) { - if (getVal(key, layer, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (0); - - return (extractByte(&packetCfg, 8)); -} -uint16_t SFE_UBLOX_GNSS::getVal16(uint32_t key, uint8_t layer, - uint16_t maxWait) { - if (getVal(key, layer, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (0); - - return (extractInt(&packetCfg, 8)); -} -uint32_t SFE_UBLOX_GNSS::getVal32(uint32_t key, uint8_t layer, - uint16_t maxWait) { - if (getVal(key, layer, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (0); - - return (extractLong(&packetCfg, 8)); -} -uint64_t SFE_UBLOX_GNSS::getVal64(uint32_t key, uint8_t layer, - uint16_t maxWait) { - if (getVal(key, layer, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (0); - - return (extractLongLong(&packetCfg, 8)); -} - -// Given a group, ID and size, return the value of this config spot -// The 32-bit key is put together from group/ID/size. See other getVal to send -// key directly. Configuration of modern u-blox modules is now done via -// getVal/setVal/delVal, ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::getVal8(uint16_t group, uint16_t id, uint8_t size, - uint8_t layer, uint16_t maxWait) { - uint32_t key = createKey(group, id, size); - return getVal8(key, layer, maxWait); -} -uint16_t SFE_UBLOX_GNSS::getVal16(uint16_t group, uint16_t id, uint8_t size, - uint8_t layer, uint16_t maxWait) { - uint32_t key = createKey(group, id, size); - return getVal16(key, layer, maxWait); -} -uint32_t SFE_UBLOX_GNSS::getVal32(uint16_t group, uint16_t id, uint8_t size, - uint8_t layer, uint16_t maxWait) { - uint32_t key = createKey(group, id, size); - return getVal32(key, layer, maxWait); -} -uint64_t SFE_UBLOX_GNSS::getVal64(uint16_t group, uint16_t id, uint8_t size, - uint8_t layer, uint16_t maxWait) { - uint32_t key = createKey(group, id, size); - return getVal64(key, layer, maxWait); -} - -// Given a key, set a 16-bit value -// This function takes a full 32-bit key -// Default layer is all: RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::setVal(uint32_t key, uint16_t value, uint8_t layer, - uint16_t maxWait) { - return setVal16(key, value, layer, maxWait); -} - -// Given a key, set a 16-bit value -// This function takes a full 32-bit key -// Default layer is all: RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::setVal16(uint32_t key, uint16_t value, uint8_t layer, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 2; // 4 byte header, 4 byte key ID, 2 bytes of value - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Given a key, set an 8-bit value -// This function takes a full 32-bit key -// Default layer is all: RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::setVal8(uint32_t key, uint8_t value, uint8_t layer, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = 4 + 4 + 1; // 4 byte header, 4 byte key ID, 1 byte value - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value; // Value - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Given a key, set a 32-bit value -// This function takes a full 32-bit key -// Default layer is all: RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::setVal32(uint32_t key, uint32_t value, uint8_t layer, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 4; // 4 byte header, 4 byte key ID, 4 bytes of value - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - payloadCfg[10] = value >> 8 * 2; - payloadCfg[11] = value >> 8 * 3; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Given a key, set a 64-bit value -// This function takes a full 32-bit key -// Default layer is all: RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::setVal64(uint32_t key, uint64_t value, uint8_t layer, - uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 8; // 4 byte header, 4 byte key ID, 8 bytes of value - packetCfg.startingSpot = 0; - - // Clear packet payload - memset(payloadCfg, 0, packetCfg.len); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - payloadCfg[10] = value >> 8 * 2; - payloadCfg[11] = value >> 8 * 3; - payloadCfg[12] = value >> 8 * 4; - payloadCfg[13] = value >> 8 * 5; - payloadCfg[14] = value >> 8 * 6; - payloadCfg[15] = value >> 8 * 7; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Start defining a new UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 64-bit value -// Default layer is RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::newCfgValset64(uint32_t key, uint64_t value, - uint8_t layer) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 8; // 4 byte header, 4 byte key ID, 8 bytes of value - packetCfg.startingSpot = 0; - - _numCfgKeyIDs = 1; - - // Clear all of packet payload - memset(payloadCfg, 0, packetCfgPayloadSize); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - payloadCfg[10] = value >> 8 * 2; - payloadCfg[11] = value >> 8 * 3; - payloadCfg[12] = value >> 8 * 4; - payloadCfg[13] = value >> 8 * 5; - payloadCfg[14] = value >> 8 * 6; - payloadCfg[15] = value >> 8 * 7; - - // All done - return (true); -} - -// Start defining a new UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 32-bit value -// Default layer is RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::newCfgValset32(uint32_t key, uint32_t value, - uint8_t layer) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 4; // 4 byte header, 4 byte key ID, 4 bytes of value - packetCfg.startingSpot = 0; - - _numCfgKeyIDs = 1; - - // Clear all of packet payload - memset(payloadCfg, 0, packetCfgPayloadSize); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - payloadCfg[10] = value >> 8 * 2; - payloadCfg[11] = value >> 8 * 3; - - // All done - return (true); -} - -// Start defining a new UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 16-bit value -// Default layer is RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::newCfgValset16(uint32_t key, uint16_t value, - uint8_t layer) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = - 4 + 4 + 2; // 4 byte header, 4 byte key ID, 2 bytes of value - packetCfg.startingSpot = 0; - - _numCfgKeyIDs = 1; - - // Clear all of packet payload - memset(payloadCfg, 0, packetCfgPayloadSize); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value >> 8 * 0; // Value LSB - payloadCfg[9] = value >> 8 * 1; - - // All done - return (true); -} - -// Start defining a new UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 8-bit value -// Default layer is RAM+BBR+Flash -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::newCfgValset8(uint32_t key, uint8_t value, - uint8_t layer) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = 4 + 4 + 1; // 4 byte header, 4 byte key ID, 1 byte value - packetCfg.startingSpot = 0; - - _numCfgKeyIDs = 1; - - // Clear all of packet payload - memset(payloadCfg, 0, packetCfgPayloadSize); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // Load key into outgoing payload - payloadCfg[4] = key >> 8 * 0; // Key LSB - payloadCfg[5] = key >> 8 * 1; - payloadCfg[6] = key >> 8 * 2; - payloadCfg[7] = key >> 8 * 3; - - // Load user's value - payloadCfg[8] = value; // Value - - // All done - return (true); -} - -// Start defining a new (empty) UBX-CFG-VALSET ubxPacket -// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, -// ie protocol v27 and above found on ZED-F9P -uint8_t SFE_UBLOX_GNSS::newCfgValset(uint8_t layer) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_VALSET; - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - - _numCfgKeyIDs = 0; - - // Clear all of packet payload - memset(payloadCfg, 0, packetCfgPayloadSize); - - payloadCfg[0] = 0; // Message Version - set to 0 - payloadCfg[1] = layer; // By default we ask for the BBR layer - - // All done - return (true); -} - -// Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 64-bit value -uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset64: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 12)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("addCfgValset64: packetCfgPayloadSize reached!")); -#endif - return false; - } - - if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset64: key limit reached!")); -#endif - return false; - } - - // Load key into outgoing payload - payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB - payloadCfg[packetCfg.len + 1] = key >> 8 * 1; - payloadCfg[packetCfg.len + 2] = key >> 8 * 2; - payloadCfg[packetCfg.len + 3] = key >> 8 * 3; - - // Load user's value - payloadCfg[packetCfg.len + 4] = value >> 8 * 0; // Value LSB - payloadCfg[packetCfg.len + 5] = value >> 8 * 1; - payloadCfg[packetCfg.len + 6] = value >> 8 * 2; - payloadCfg[packetCfg.len + 7] = value >> 8 * 3; - payloadCfg[packetCfg.len + 8] = value >> 8 * 4; - payloadCfg[packetCfg.len + 9] = value >> 8 * 5; - payloadCfg[packetCfg.len + 10] = value >> 8 * 6; - payloadCfg[packetCfg.len + 11] = value >> 8 * 7; - - // Update packet length: 4 byte key ID, 8 bytes of value - packetCfg.len = packetCfg.len + 4 + 8; - - _numCfgKeyIDs++; - - // All done - return (true); -} - -// Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 32-bit value -uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset32: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 8)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("addCfgValset32: packetCfgPayloadSize reached!")); -#endif - return false; - } - - if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset32: key limit reached!")); -#endif - return false; - } - - // Load key into outgoing payload - payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB - payloadCfg[packetCfg.len + 1] = key >> 8 * 1; - payloadCfg[packetCfg.len + 2] = key >> 8 * 2; - payloadCfg[packetCfg.len + 3] = key >> 8 * 3; - - // Load user's value - payloadCfg[packetCfg.len + 4] = value >> 8 * 0; // Value LSB - payloadCfg[packetCfg.len + 5] = value >> 8 * 1; - payloadCfg[packetCfg.len + 6] = value >> 8 * 2; - payloadCfg[packetCfg.len + 7] = value >> 8 * 3; - - // Update packet length: 4 byte key ID, 4 bytes of value - packetCfg.len = packetCfg.len + 4 + 4; - - _numCfgKeyIDs++; - - // All done - return (true); -} - -// Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 16-bit value -uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset16: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 6)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("addCfgValset16: packetCfgPayloadSize reached!")); -#endif - return false; - } - - if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset16: key limit reached!")); -#endif - return false; - } - - // Load key into outgoing payload - payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB - payloadCfg[packetCfg.len + 1] = key >> 8 * 1; - payloadCfg[packetCfg.len + 2] = key >> 8 * 2; - payloadCfg[packetCfg.len + 3] = key >> 8 * 3; - - // Load user's value - payloadCfg[packetCfg.len + 4] = value >> 8 * 0; // Value LSB - payloadCfg[packetCfg.len + 5] = value >> 8 * 1; - - // Update packet length: 4 byte key ID, 2 bytes of value - packetCfg.len = packetCfg.len + 4 + 2; - - _numCfgKeyIDs++; - - // All done - return (true); -} - -// Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket -// This function takes a full 32-bit key and 8-bit value -uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset8: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 5)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("addCfgValset8: packetCfgPayloadSize reached!")); -#endif - return false; - } - - if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("addCfgValset8: key limit reached!")); -#endif - return false; - } - - // Load key into outgoing payload - payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB - payloadCfg[packetCfg.len + 1] = key >> 8 * 1; - payloadCfg[packetCfg.len + 2] = key >> 8 * 2; - payloadCfg[packetCfg.len + 3] = key >> 8 * 3; - - // Load user's value - payloadCfg[packetCfg.len + 4] = value; // Value - - // Update packet length: 4 byte key ID, 1 byte value - packetCfg.len = packetCfg.len + 4 + 1; - - _numCfgKeyIDs++; - - // All done - return (true); -} - -// Add a final keyID and value to an existing UBX-CFG-VALSET ubxPacket and send -// it This function takes a full 32-bit key and 64-bit value -uint8_t SFE_UBLOX_GNSS::sendCfgValset64(uint32_t key, uint64_t value, - uint16_t maxWait) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset64: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 12)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("sendCfgValset64: packetCfgPayloadSize reached!")); -#endif - } else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset64: key limit reached!")); -#endif - } else - // Load keyID and value into outgoing payload - addCfgValset64(key, value); - - _numCfgKeyIDs = 0; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Add a final keyID and value to an existing UBX-CFG-VALSET ubxPacket and send -// it This function takes a full 32-bit key and 32-bit value -uint8_t SFE_UBLOX_GNSS::sendCfgValset32(uint32_t key, uint32_t value, - uint16_t maxWait) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset32: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 8)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("sendCfgValset32: packetCfgPayloadSize reached!")); -#endif - } else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset32: key limit reached!")); -#endif - } else - // Load keyID and value into outgoing payload - addCfgValset32(key, value); - - _numCfgKeyIDs = 0; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Add a final keyID and value to an existing UBX-CFG-VALSET ubxPacket and send -// it This function takes a full 32-bit key and 16-bit value -uint8_t SFE_UBLOX_GNSS::sendCfgValset16(uint32_t key, uint16_t value, - uint16_t maxWait) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset16: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 6)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("sendCfgValset16: packetCfgPayloadSize reached!")); -#endif - } else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset16: key limit reached!")); -#endif - } else - // Load keyID and value into outgoing payload - addCfgValset16(key, value); - - _numCfgKeyIDs = 0; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Add a final keyID and value to an existing UBX-CFG-VALSET ubxPacket and send -// it This function takes a full 32-bit key and 8-bit value -uint8_t SFE_UBLOX_GNSS::sendCfgValset8(uint32_t key, uint8_t value, - uint16_t maxWait) { - if ((_autoSendAtSpaceRemaining > 0) && - (packetCfg.len >= (packetCfgPayloadSize - _autoSendAtSpaceRemaining))) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset8: autosend")); -#endif - sendCommand(&packetCfg); - packetCfg.len = 4; // 4 byte header - packetCfg.startingSpot = 0; - _numCfgKeyIDs = 0; - memset(&payloadCfg[4], 0, packetCfgPayloadSize - 4); - } - - if (packetCfg.len >= (packetCfgPayloadSize - 5)) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("sendCfgValset8: packetCfgPayloadSize reached!")); -#endif - } else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("sendCfgValset8: key limit reached!")); -#endif - } else - // Load keyID and value into outgoing payload - addCfgValset8(key, value); - - _numCfgKeyIDs = 0; - - // Send VALSET command with this key and value - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Send the UBX-CFG-VALSET ubxPacket -uint8_t SFE_UBLOX_GNSS::sendCfgValset(uint16_t maxWait) { - if (_numCfgKeyIDs == 0) return true; // Nothing to send... - - // Send VALSET command with this key and value - bool success = sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT; // We are only expecting an ACK - - if (success) _numCfgKeyIDs = 0; - - return success; -} - -// Return the number of keys in the CfgValset -uint8_t SFE_UBLOX_GNSS::getCfgValsetLen() { return _numCfgKeyIDs; } - -// Return the number of free bytes remaining in packetCfgPayload -size_t SFE_UBLOX_GNSS::getCfgValsetSpaceRemaining() { - return getPacketCfgSpaceRemaining(); -} - -//=-=-=-=-=-=-=-= "Automatic" Messages =-=-=-=-=-=-=-==-=-=-=-=-=-=-= -//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -// ***** NAV POSECEF automatic support - -bool SFE_UBLOX_GNSS::getNAVPOSECEF(uint16_t maxWait) { - if (packetUBXNAVPOSECEF == NULL) - initPacketUBXNAVPOSECEF(); // Check that RAM has been allocated for the - // POSECEF data - if (packetUBXNAVPOSECEF == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic && - packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_POSECEF); - return packetUBXNAVPOSECEF->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic && - !packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_POSECEF; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVPOSECEF(bool enable, uint16_t maxWait) { - return setAutoNAVPOSECEFrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVPOSECEF(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVPOSECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVPOSECEFrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVPOSECEF == NULL) - initPacketUBXNAVPOSECEF(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVPOSECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_POSECEF; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVPOSECEF->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVPOSECEFcallback( - void (*callbackPointer)(UBX_NAV_POSECEF_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVPOSECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVPOSECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPOSECEF->callbackData = - new UBX_NAV_POSECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPOSECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVPOSECEFcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPOSECEF->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVPOSECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_POSECEF_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVPOSECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVPOSECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPOSECEF->callbackData = - new UBX_NAV_POSECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPOSECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVPOSECEFcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPOSECEF->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and POSECEF is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVPOSECEF(bool enabled, bool implicitUpdate) { - if (packetUBXNAVPOSECEF == NULL) - initPacketUBXNAVPOSECEF(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVPOSECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVPOSECEF and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVPOSECEF() { - packetUBXNAVPOSECEF = - new UBX_NAV_POSECEF_t; // Allocate RAM for the main struct - if (packetUBXNAVPOSECEF == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVPOSECEF: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVPOSECEF->automaticFlags.flags.all = 0; - packetUBXNAVPOSECEF->callbackPointer = NULL; - packetUBXNAVPOSECEF->callbackPointerPtr = NULL; - packetUBXNAVPOSECEF->callbackData = NULL; - packetUBXNAVPOSECEF->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale. This is handy to get data alignment after -// CRC failure or if there are no helper functions and the user wants to request -// fresh data -void SFE_UBLOX_GNSS::flushNAVPOSECEF() { - if (packetUBXNAVPOSECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPOSECEF->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVPOSECEF(bool enabled) { - if (packetUBXNAVPOSECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPOSECEF->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV STATUS automatic support - -bool SFE_UBLOX_GNSS::getNAVSTATUS(uint16_t maxWait) { - if (packetUBXNAVSTATUS == NULL) - initPacketUBXNAVSTATUS(); // Check that RAM has been allocated for the - // STATUS data - if (packetUBXNAVSTATUS == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic && - packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_STATUS); - return packetUBXNAVSTATUS->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic && - !packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_STATUS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getNAVSTATUS works. -bool SFE_UBLOX_GNSS::setAutoNAVSTATUS(bool enable, uint16_t maxWait) { - return setAutoNAVSTATUSrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getNAVSTATUS works. -bool SFE_UBLOX_GNSS::setAutoNAVSTATUS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVSTATUSrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getNAVSTATUS works. -bool SFE_UBLOX_GNSS::setAutoNAVSTATUSrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVSTATUS == NULL) - initPacketUBXNAVSTATUS(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_STATUS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVSTATUS->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVSTATUScallback( - void (*callbackPointer)(UBX_NAV_STATUS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVSTATUS->callbackData = - new UBX_NAV_STATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVSTATUScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVSTATUS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_STATUS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVSTATUS->callbackData = - new UBX_NAV_STATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVSTATUScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVSTATUS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and STATUS is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVSTATUS(bool enabled, bool implicitUpdate) { - if (packetUBXNAVSTATUS == NULL) - initPacketUBXNAVSTATUS(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVSTATUS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVSTATUS() { - packetUBXNAVSTATUS = - new UBX_NAV_STATUS_t; // Allocate RAM for the main struct - if (packetUBXNAVSTATUS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVSTATUS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVSTATUS->automaticFlags.flags.all = 0; - packetUBXNAVSTATUS->callbackPointer = NULL; - packetUBXNAVSTATUS->callbackPointerPtr = NULL; - packetUBXNAVSTATUS->callbackData = NULL; - packetUBXNAVSTATUS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale. This is handy to get data alignment after -// CRC failure or if there are no helper functions and the user wants to request -// fresh data -void SFE_UBLOX_GNSS::flushNAVSTATUS() { - if (packetUBXNAVSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSTATUS->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVSTATUS(bool enabled) { - if (packetUBXNAVSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSTATUS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** DOP automatic support - -bool SFE_UBLOX_GNSS::getDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVDOP->automaticFlags.flags.bits.automatic && - packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getDOP: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_DOP); - return packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVDOP->automaticFlags.flags.bits.automatic && - !packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getDOP: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getDOP: Polling")); - // } - - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_DOP; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getDOP: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getDOP retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getDOP works. -bool SFE_UBLOX_GNSS::setAutoDOP(bool enable, uint16_t maxWait) { - return setAutoDOPrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getDOP works. -bool SFE_UBLOX_GNSS::setAutoDOP(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoDOPrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getDOP works. -bool SFE_UBLOX_GNSS::setAutoDOPrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVDOP == - NULL) // Only attempt this if RAM allocation was successful - return false; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_DOP; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVDOP->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoDOPcallback( - void (*callbackPointer)(UBX_NAV_DOP_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoDOP(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVDOP->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVDOP->callbackData = - new UBX_NAV_DOP_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVDOP->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setAutoDOPcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVDOP->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoDOPcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_DOP_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoDOP(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVDOP->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVDOP->callbackData = - new UBX_NAV_DOP_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVDOP->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoDOPcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVDOP->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and DOP is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoDOP(bool enabled, bool implicitUpdate) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVDOP == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVDOP->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVDOP->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVDOP and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVDOP() { - packetUBXNAVDOP = new UBX_NAV_DOP_t; // Allocate RAM for the main struct - if (packetUBXNAVDOP == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVDOP: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVDOP->automaticFlags.flags.all = 0; - packetUBXNAVDOP->callbackPointer = NULL; - packetUBXNAVDOP->callbackPointerPtr = NULL; - packetUBXNAVDOP->callbackData = NULL; - packetUBXNAVDOP->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the DOP data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushDOP() { - if (packetUBXNAVDOP == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVDOP->moduleQueried.moduleQueried.all = - 0; // Mark all DOPs as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVDOP(bool enabled) { - if (packetUBXNAVDOP == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVDOP->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** EOE automatic support - -bool SFE_UBLOX_GNSS::getNAVEOE(uint16_t maxWait) { - if (packetUBXNAVEOE == NULL) - initPacketUBXNAVEOE(); // Check that RAM has been allocated for the EOE - // data - if (packetUBXNAVEOE == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVEOE->automaticFlags.flags.bits.automatic && - packetUBXNAVEOE->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEOE: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_EOE); - return packetUBXNAVEOE->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVEOE->automaticFlags.flags.bits.automatic && - !packetUBXNAVEOE->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEOE: Exit immediately")); - // } - return (false); - } else { - // Note to self: NAV-EOE is "Periodic" (only). Not sure if it can be - // polled? - - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_EOE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getEOE works. -bool SFE_UBLOX_GNSS::setAutoNAVEOE(bool enable, uint16_t maxWait) { - return setAutoNAVEOErate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getEOE works. -bool SFE_UBLOX_GNSS::setAutoNAVEOE(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVEOErate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getEOE works. -bool SFE_UBLOX_GNSS::setAutoNAVEOErate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVEOE == NULL) - initPacketUBXNAVEOE(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVEOE == - NULL) // Only attempt this if RAM allocation was successful - return false; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_EOE; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVEOE->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVEOE->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVEOE->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVEOEcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_EOE_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVEOE(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVEOE->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVEOE->callbackData = - new UBX_NAV_EOE_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVEOE->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVEOEcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVEOE->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and EOE is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVEOE(bool enabled, bool implicitUpdate) { - if (packetUBXNAVEOE == NULL) - initPacketUBXNAVEOE(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVEOE == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVEOE->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVEOE->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVEOE->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVEOE->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVEOE and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVEOE() { - packetUBXNAVEOE = new UBX_NAV_EOE_t; // Allocate RAM for the main struct - if (packetUBXNAVEOE == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVEOE: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVEOE->automaticFlags.flags.all = 0; - packetUBXNAVEOE->callbackPointerPtr = NULL; - packetUBXNAVEOE->callbackData = NULL; - packetUBXNAVEOE->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the EOE data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushNAVEOE() { - if (packetUBXNAVEOE == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVEOE->moduleQueried.moduleQueried.all = - 0; // Mark all EOEs as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVEOE(bool enabled) { - if (packetUBXNAVEOE == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVEOE->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** VEH ATT automatic support - -bool SFE_UBLOX_GNSS::getVehAtt(uint16_t maxWait) { - return (getNAVATT(maxWait)); -} - -bool SFE_UBLOX_GNSS::getNAVATT(uint16_t maxWait) { - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the NAV - // ATT data - if (packetUBXNAVATT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXNAVATT->automaticFlags.flags.bits.automatic && - packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_ATT); - return packetUBXNAVATT->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVATT->automaticFlags.flags.bits.automatic && - !packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting HNR PVT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_ATT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic NAV ATT message generation by the GNSS. This -// changes the way getVehAtt works. -bool SFE_UBLOX_GNSS::setAutoNAVATT(bool enable, uint16_t maxWait) { - return setAutoNAVATTrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic NAV ATT message generation by the GNSS. This -// changes the way getVehAtt works. -bool SFE_UBLOX_GNSS::setAutoNAVATT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVATTrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic NAV ATT attitude message generation by the GNSS. -// This changes the way getVehAtt works. -bool SFE_UBLOX_GNSS::setAutoNAVATTrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVATT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_ATT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVATT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVATT->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVATTcallback( - void (*callbackPointer)(UBX_NAV_ATT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVATT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVATT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVATT->callbackData = - new UBX_NAV_ATT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVATT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVATTcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVATT->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVATTcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_ATT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVATT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVATT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVATT->callbackData = - new UBX_NAV_ATT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVATT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVATTcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVATT->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and NAV ATT attitude is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVATT(bool enabled, bool implicitUpdate) { - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the NAV - // ATT data - if (packetUBXNAVATT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVATT->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVATT->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVATT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVATT() { - packetUBXNAVATT = new UBX_NAV_ATT_t; // Allocate RAM for the main struct - if (packetUBXNAVATT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVATT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVATT->automaticFlags.flags.all = 0; - packetUBXNAVATT->callbackPointer = NULL; - packetUBXNAVATT->callbackPointerPtr = NULL; - packetUBXNAVATT->callbackData = NULL; - packetUBXNAVATT->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the ATT data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushNAVATT() { - if (packetUBXNAVATT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVATT->moduleQueried.moduleQueried.all = - 0; // Mark all ATT data as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVATT(bool enabled) { - if (packetUBXNAVATT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVATT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** PVT automatic support - -// Get the latest Position/Velocity/Time solution and fill all global variables -bool SFE_UBLOX_GNSS::getPVT(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->automaticFlags.flags.bits.automatic && - packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getPVT: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_PVT); - return packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all; - } else if (packetUBXNAVPVT->automaticFlags.flags.bits.automatic && - !packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getPVT: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getPVT: Polling")); - // } - - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_PVT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - // packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can - // record up to 20+packetCfgPayloadSize = 84 bytes Note:now hard-coded - // in processUBX - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getPVT: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getPVT retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVT works. -bool SFE_UBLOX_GNSS::setAutoPVT(bool enable, uint16_t maxWait) { - return setAutoPVTrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVT works. -bool SFE_UBLOX_GNSS::setAutoPVT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoPVTrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVT works. -bool SFE_UBLOX_GNSS::setAutoPVTrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_PVT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVPVT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. This changes the -// way getPVT works. -bool SFE_UBLOX_GNSS::setAutoPVTcallback( - void (*callbackPointer)(UBX_NAV_PVT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoPVT(true, false, maxWait); - if (!result) return (result); // Bail if setAutoPVT failed - - if (packetUBXNAVPVT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPVT->callbackData = - new UBX_NAV_PVT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPVT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setAutoPVTcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPVT->callbackPointer = - callbackPointer; // RAM has been allocated so now update the pointer - - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoPVTcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_PVT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoPVT(true, false, maxWait); - if (!result) return (result); // Bail if setAutoPVT failed - - if (packetUBXNAVPVT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPVT->callbackData = - new UBX_NAV_PVT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPVT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoPVTcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPVT->callbackPointerPtr = - callbackPointerPtr; // RAM has been allocated so now update the pointer - - return (true); -} - -// In case no config access to the GNSS is possible and PVT is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoPVT(bool enabled, bool implicitUpdate) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVPVT->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVPVT->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVPVT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVPVT() { - packetUBXNAVPVT = new UBX_NAV_PVT_t; // Allocate RAM for the main struct - if (packetUBXNAVPVT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVPVT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVPVT->automaticFlags.flags.all = 0; - packetUBXNAVPVT->callbackPointer = NULL; - packetUBXNAVPVT->callbackPointerPtr = NULL; - packetUBXNAVPVT->callbackData = NULL; - packetUBXNAVPVT->moduleQueried.moduleQueried1.all = 0; - packetUBXNAVPVT->moduleQueried.moduleQueried2.all = 0; - return (true); -} - -// Mark all the PVT data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushPVT() { - if (packetUBXNAVPVT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPVT->moduleQueried.moduleQueried1.all = - 0; // Mark all datums as stale (read before) - packetUBXNAVPVT->moduleQueried.moduleQueried2.all = 0; -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVPVT(bool enabled) { - if (packetUBXNAVPVT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPVT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV ODO automatic support - -bool SFE_UBLOX_GNSS::getNAVODO(uint16_t maxWait) { - if (packetUBXNAVODO == NULL) - initPacketUBXNAVODO(); // Check that RAM has been allocated for the ODO - // data - if (packetUBXNAVODO == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVODO->automaticFlags.flags.bits.automatic && - packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_ODO); - return packetUBXNAVODO->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVODO->automaticFlags.flags.bits.automatic && - !packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_ODO; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getODO works. -bool SFE_UBLOX_GNSS::setAutoNAVODO(bool enable, uint16_t maxWait) { - return setAutoNAVODOrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getODO works. -bool SFE_UBLOX_GNSS::setAutoNAVODO(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVODOrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getODO works. -bool SFE_UBLOX_GNSS::setAutoNAVODOrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVODO == NULL) - initPacketUBXNAVODO(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVODO == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_ODO; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVODO->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVODO->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVODOcallback( - void (*callbackPointer)(UBX_NAV_ODO_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVODO(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVODO->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVODO->callbackData = - new UBX_NAV_ODO_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVODO->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVODOcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVODO->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVODOcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_ODO_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVODO(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVODO->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVODO->callbackData = - new UBX_NAV_ODO_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVODO->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVODOcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVODO->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ODO is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVODO(bool enabled, bool implicitUpdate) { - if (packetUBXNAVODO == NULL) - initPacketUBXNAVODO(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVODO == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVODO->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVODO->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVODO and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVODO() { - packetUBXNAVODO = new UBX_NAV_ODO_t; // Allocate RAM for the main struct - if (packetUBXNAVODO == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVODO: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVODO->automaticFlags.flags.all = 0; - packetUBXNAVODO->callbackPointer = NULL; - packetUBXNAVODO->callbackPointerPtr = NULL; - packetUBXNAVODO->callbackData = NULL; - packetUBXNAVODO->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVODO() { - if (packetUBXNAVODO == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVODO->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVODO(bool enabled) { - if (packetUBXNAVODO == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVODO->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV VELECEF automatic support - -bool SFE_UBLOX_GNSS::getNAVVELECEF(uint16_t maxWait) { - if (packetUBXNAVVELECEF == NULL) - initPacketUBXNAVVELECEF(); // Check that RAM has been allocated for the - // VELECEF data - if (packetUBXNAVVELECEF == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic && - packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_VELECEF); - return packetUBXNAVVELECEF->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic && - !packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_VELECEF; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVVELECEF(bool enable, uint16_t maxWait) { - return setAutoNAVVELECEFrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVVELECEF(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVVELECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVVELECEFrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVVELECEF == NULL) - initPacketUBXNAVVELECEF(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVVELECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_VELECEF; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVVELECEF->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVVELECEFcallback( - void (*callbackPointer)(UBX_NAV_VELECEF_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVVELECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVVELECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVVELECEF->callbackData = - new UBX_NAV_VELECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVVELECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVVELECEFcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVVELECEF->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVVELECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_VELECEF_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVVELECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVVELECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVVELECEF->callbackData = - new UBX_NAV_VELECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVVELECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVVELECEFcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVVELECEF->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and VELECEF is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVVELECEF(bool enabled, bool implicitUpdate) { - if (packetUBXNAVVELECEF == NULL) - initPacketUBXNAVVELECEF(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVVELECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVVELECEF and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVVELECEF() { - packetUBXNAVVELECEF = - new UBX_NAV_VELECEF_t; // Allocate RAM for the main struct - if (packetUBXNAVVELECEF == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVVELECEF: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVVELECEF->automaticFlags.flags.all = 0; - packetUBXNAVVELECEF->callbackPointer = NULL; - packetUBXNAVVELECEF->callbackPointerPtr = NULL; - packetUBXNAVVELECEF->callbackData = NULL; - packetUBXNAVVELECEF->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVVELECEF() { - if (packetUBXNAVVELECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVVELECEF->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVVELECEF(bool enabled) { - if (packetUBXNAVVELECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVVELECEF->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV VELNED automatic support - -bool SFE_UBLOX_GNSS::getNAVVELNED(uint16_t maxWait) { - if (packetUBXNAVVELNED == NULL) - initPacketUBXNAVVELNED(); // Check that RAM has been allocated for the - // VELNED data - if (packetUBXNAVVELNED == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVVELNED->automaticFlags.flags.bits.automatic && - packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_VELNED); - return packetUBXNAVVELNED->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVVELNED->automaticFlags.flags.bits.automatic && - !packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_VELNED; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELNED works. -bool SFE_UBLOX_GNSS::setAutoNAVVELNED(bool enable, uint16_t maxWait) { - return setAutoNAVVELNEDrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELNED works. -bool SFE_UBLOX_GNSS::setAutoNAVVELNED(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVVELNEDrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getVELNED works. -bool SFE_UBLOX_GNSS::setAutoNAVVELNEDrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVVELNED == NULL) - initPacketUBXNAVVELNED(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVVELNED == - NULL) // Only attempt this if RAM allocation was successful - return false; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_VELNED; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVVELNED->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVVELNED->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVVELNEDcallback( - void (*callbackPointer)(UBX_NAV_VELNED_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVVELNED(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVVELNED->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVVELNED->callbackData = - new UBX_NAV_VELNED_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVVELNED->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVVELNEDcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVVELNED->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVVELNEDcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_VELNED_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVVELNED(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVVELNED->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVVELNED->callbackData = - new UBX_NAV_VELNED_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVVELNED->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVVELNEDcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVVELNED->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and VELNED is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVVELNED(bool enabled, bool implicitUpdate) { - if (packetUBXNAVVELNED == NULL) - initPacketUBXNAVVELNED(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVVELNED == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVVELNED->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVVELNED->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVVELNED and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVVELNED() { - packetUBXNAVVELNED = - new UBX_NAV_VELNED_t; // Allocate RAM for the main struct - if (packetUBXNAVVELNED == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVVELNED: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVVELNED->automaticFlags.flags.all = 0; - packetUBXNAVVELNED->callbackPointer = NULL; - packetUBXNAVVELNED->callbackPointerPtr = NULL; - packetUBXNAVVELNED->callbackData = NULL; - packetUBXNAVVELNED->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVVELNED() { - if (packetUBXNAVVELNED == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere! - packetUBXNAVVELNED->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVVELNED(bool enabled) { - if (packetUBXNAVVELNED == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVVELNED->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV HPPOSECEF automatic support - -bool SFE_UBLOX_GNSS::getNAVHPPOSECEF(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic && - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_HPPOSECEF); - return packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic && - !packetUBXNAVHPPOSECEF->automaticFlags.flags.bits - .implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_HPPOSECEF; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVHPPOSECEF(bool enable, uint16_t maxWait) { - return setAutoNAVHPPOSECEFrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVHPPOSECEF(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVHPPOSECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSECEF works. -bool SFE_UBLOX_GNSS::setAutoNAVHPPOSECEFrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVHPPOSECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_HPPOSECEF; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVHPPOSECEFcallback( - void (*callbackPointer)(UBX_NAV_HPPOSECEF_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVHPPOSECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVHPPOSECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVHPPOSECEF->callbackData = - new UBX_NAV_HPPOSECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVHPPOSECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVHPPOSECEFcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVHPPOSECEF->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVHPPOSECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_HPPOSECEF_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVHPPOSECEF(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVHPPOSECEF->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVHPPOSECEF->callbackData = - new UBX_NAV_HPPOSECEF_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVHPPOSECEF->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVHPPOSECEFcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVHPPOSECEF->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and HPPOSECEF is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVHPPOSECEF(bool enabled, bool implicitUpdate) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVHPPOSECEF == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVHPPOSECEF and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVHPPOSECEF() { - packetUBXNAVHPPOSECEF = - new UBX_NAV_HPPOSECEF_t; // Allocate RAM for the main struct - if (packetUBXNAVHPPOSECEF == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVHPPOSECEF: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVHPPOSECEF->automaticFlags.flags.all = 0; - packetUBXNAVHPPOSECEF->callbackPointer = NULL; - packetUBXNAVHPPOSECEF->callbackPointerPtr = NULL; - packetUBXNAVHPPOSECEF->callbackData = NULL; - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVHPPOSECEF() { - if (packetUBXNAVHPPOSECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVHPPOSECEF(bool enabled) { - if (packetUBXNAVHPPOSECEF == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV HPPOSLLH automatic support - -bool SFE_UBLOX_GNSS::getHPPOSLLH(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic && - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHPPOSLLH: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_HPPOSLLH); - return packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic && - !packetUBXNAVHPPOSLLH->automaticFlags.flags.bits - .implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHPPOSLLH: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHPPOSLLH: Polling")); - // } - - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_HPPOSLLH; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHPPOSLLH: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getHPPOSLLH retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSLLH works. -bool SFE_UBLOX_GNSS::setAutoHPPOSLLH(bool enable, uint16_t maxWait) { - return setAutoHPPOSLLHrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSLLH works. -bool SFE_UBLOX_GNSS::setAutoHPPOSLLH(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoHPPOSLLHrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getHPPOSLLH works. -bool SFE_UBLOX_GNSS::setAutoHPPOSLLHrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVHPPOSLLH == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_HPPOSLLH; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoHPPOSLLHcallback( - void (*callbackPointer)(UBX_NAV_HPPOSLLH_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHPPOSLLH(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVHPPOSLLH->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVHPPOSLLH->callbackData = - new UBX_NAV_HPPOSLLH_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVHPPOSLLH->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHPPOSLLHcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVHPPOSLLH->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoHPPOSLLHcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_HPPOSLLH_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHPPOSLLH(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVHPPOSLLH->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVHPPOSLLH->callbackData = - new UBX_NAV_HPPOSLLH_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVHPPOSLLH->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHPPOSLLHcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVHPPOSLLH->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and HPPOSLLH is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoHPPOSLLH(bool enabled, bool implicitUpdate) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVHPPOSLLH == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVHPPOSLLH and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVHPPOSLLH() { - packetUBXNAVHPPOSLLH = - new UBX_NAV_HPPOSLLH_t; // Allocate RAM for the main struct - if (packetUBXNAVHPPOSLLH == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVHPPOSLLH: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVHPPOSLLH->automaticFlags.flags.all = 0; - packetUBXNAVHPPOSLLH->callbackPointer = NULL; - packetUBXNAVHPPOSLLH->callbackPointerPtr = NULL; - packetUBXNAVHPPOSLLH->callbackData = NULL; - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the HPPOSLLH data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushHPPOSLLH() { - if (packetUBXNAVHPPOSLLH == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere! - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVHPPOSLLH(bool enabled) { - if (packetUBXNAVHPPOSLLH == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** PVAT automatic support - -// Get the latest Position/Velocity/Time solution and fill all global variables -bool SFE_UBLOX_GNSS::getNAVPVAT(uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVAT->automaticFlags.flags.bits.automatic && - packetUBXNAVPVAT->automaticFlags.flags.bits.implicitUpdate) { - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_PVAT); - return packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all; - } else if (packetUBXNAVPVAT->automaticFlags.flags.bits.automatic && - !packetUBXNAVPVAT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_PVAT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVAT works. -bool SFE_UBLOX_GNSS::setAutoNAVPVAT(bool enable, uint16_t maxWait) { - return setAutoNAVPVATrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVAT works. -bool SFE_UBLOX_GNSS::setAutoNAVPVAT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVPVATrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getPVAT works. -bool SFE_UBLOX_GNSS::setAutoNAVPVATrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_PVAT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVPVAT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVPVAT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. This changes the -// way getPVAT works. -bool SFE_UBLOX_GNSS::setAutoNAVPVATcallback( - void (*callbackPointer)(UBX_NAV_PVAT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVPVAT(true, false, maxWait); - if (!result) return (result); // Bail if setAutoPVAT failed - - if (packetUBXNAVPVAT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPVAT->callbackData = - new UBX_NAV_PVAT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPVAT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVPVATcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPVAT->callbackPointer = - callbackPointer; // RAM has been allocated so now update the pointer - - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVPVATcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_PVAT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVPVAT(true, false, maxWait); - if (!result) return (result); // Bail if setAutoPVAT failed - - if (packetUBXNAVPVAT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVPVAT->callbackData = - new UBX_NAV_PVAT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVPVAT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVPVATcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVPVAT->callbackPointerPtr = - callbackPointerPtr; // RAM has been allocated so now update the pointer - - return (true); -} - -// In case no config access to the GNSS is possible and PVAT is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVPVAT(bool enabled, bool implicitUpdate) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVPVAT->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVPVAT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVPVAT->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVPVAT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVPVAT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVPVAT() { - packetUBXNAVPVAT = new UBX_NAV_PVAT_t; // Allocate RAM for the main struct - if (packetUBXNAVPVAT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVPVAT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVPVAT->automaticFlags.flags.all = 0; - packetUBXNAVPVAT->callbackPointer = NULL; - packetUBXNAVPVAT->callbackPointerPtr = NULL; - packetUBXNAVPVAT->callbackData = NULL; - packetUBXNAVPVAT->moduleQueried.moduleQueried1.all = 0; - packetUBXNAVPVAT->moduleQueried.moduleQueried2.all = 0; - return (true); -} - -// Mark all the PVAT data as read/stale. This is handy to get data alignment -// after CRC failure -void SFE_UBLOX_GNSS::flushNAVPVAT() { - if (packetUBXNAVPVAT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPVAT->moduleQueried.moduleQueried1.all = - 0; // Mark all datums as stale (read before) - packetUBXNAVPVAT->moduleQueried.moduleQueried2.all = 0; -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVPVAT(bool enabled) { - if (packetUBXNAVPVAT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVPVAT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV TIMEUTC automatic support - -bool SFE_UBLOX_GNSS::getNAVTIMEUTC(uint16_t maxWait) { - if (packetUBXNAVTIMEUTC == NULL) - initPacketUBXNAVTIMEUTC(); // Check that RAM has been allocated for the - // TIMEUTC data - if (packetUBXNAVTIMEUTC == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVTIMEUTC->automaticFlags.flags.bits.automatic && - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_TIMEUTC); - return packetUBXNAVTIMEUTC->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVTIMEUTC->automaticFlags.flags.bits.automatic && - !packetUBXNAVTIMEUTC->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_TIMEUTC; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMEUTC works. -bool SFE_UBLOX_GNSS::setAutoNAVTIMEUTC(bool enable, uint16_t maxWait) { - return setAutoNAVTIMEUTCrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMEUTC works. -bool SFE_UBLOX_GNSS::setAutoNAVTIMEUTC(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVTIMEUTCrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMEUTC works. -bool SFE_UBLOX_GNSS::setAutoNAVTIMEUTCrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVTIMEUTC == NULL) - initPacketUBXNAVTIMEUTC(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVTIMEUTC == - NULL) // Only attempt this if RAM allocation was successful - return false; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_TIMEUTC; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVTIMEUTC->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVTIMEUTCcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_TIMEUTC_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVTIMEUTC(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVTIMEUTC->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVTIMEUTC->callbackData = - new UBX_NAV_TIMEUTC_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVTIMEUTC->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVTIMEUTCcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVTIMEUTC->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and TIMEUTC is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVTIMEUTC(bool enabled, bool implicitUpdate) { - if (packetUBXNAVTIMEUTC == NULL) - initPacketUBXNAVTIMEUTC(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVTIMEUTC == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVTIMEUTC and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVTIMEUTC() { - packetUBXNAVTIMEUTC = - new UBX_NAV_TIMEUTC_t; // Allocate RAM for the main struct - if (packetUBXNAVTIMEUTC == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVTIMEUTC: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVTIMEUTC->automaticFlags.flags.all = 0; - packetUBXNAVTIMEUTC->callbackPointerPtr = NULL; - packetUBXNAVTIMEUTC->callbackData = NULL; - packetUBXNAVTIMEUTC->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVTIMEUTC() { - if (packetUBXNAVTIMEUTC == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVTIMEUTC->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVTIMEUTC(bool enabled) { - if (packetUBXNAVTIMEUTC == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVTIMEUTC->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV CLOCK automatic support - -bool SFE_UBLOX_GNSS::getNAVCLOCK(uint16_t maxWait) { - if (packetUBXNAVCLOCK == NULL) - initPacketUBXNAVCLOCK(); // Check that RAM has been allocated for the - // CLOCK data - if (packetUBXNAVCLOCK == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic && - packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_CLOCK); - return packetUBXNAVCLOCK->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic && - !packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting CLOCK so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_CLOCK; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic CLOCK message generation by the GNSS. This -// changes the way getNAVCLOCK works. -bool SFE_UBLOX_GNSS::setAutoNAVCLOCK(bool enable, uint16_t maxWait) { - return setAutoNAVCLOCKrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic CLOCK message generation by the GNSS. This -// changes the way getNAVCLOCK works. -bool SFE_UBLOX_GNSS::setAutoNAVCLOCK(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVCLOCKrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic CLOCK message generation by the GNSS. This -// changes the way getNAVCLOCK works. -bool SFE_UBLOX_GNSS::setAutoNAVCLOCKrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVCLOCK == NULL) - initPacketUBXNAVCLOCK(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVCLOCK == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_CLOCK; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVCLOCK->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVCLOCKcallback( - void (*callbackPointer)(UBX_NAV_CLOCK_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVCLOCK(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVCLOCK->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVCLOCK->callbackData = - new UBX_NAV_CLOCK_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVCLOCK->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVCLOCKcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVCLOCK->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVCLOCKcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_CLOCK_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVCLOCK(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVCLOCK->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVCLOCK->callbackData = - new UBX_NAV_CLOCK_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVCLOCK->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVCLOCKcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVCLOCK->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and NAV CLOCK is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVCLOCK(bool enabled, bool implicitUpdate) { - if (packetUBXNAVCLOCK == NULL) - initPacketUBXNAVCLOCK(); // Check that RAM has been allocated for the - // CLOCK data - if (packetUBXNAVCLOCK == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVCLOCK and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVCLOCK() { - packetUBXNAVCLOCK = - new UBX_NAV_CLOCK_t; // Allocate RAM for the main struct - if (packetUBXNAVCLOCK == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVCLOCK: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVCLOCK->automaticFlags.flags.all = 0; - packetUBXNAVCLOCK->callbackPointer = NULL; - packetUBXNAVCLOCK->callbackPointerPtr = NULL; - packetUBXNAVCLOCK->callbackData = NULL; - packetUBXNAVCLOCK->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVCLOCK() { - if (packetUBXNAVCLOCK == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVCLOCK->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVCLOCK(bool enabled) { - if (packetUBXNAVCLOCK == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVCLOCK->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV TIMELS automatic support - -// Reads leap second event information and sets the global variables -// for future leap second change and number of leap seconds since GPS epoch -// Returns true if commands was successful -bool SFE_UBLOX_GNSS::getLeapSecondEvent(uint16_t maxWait) { - if (packetUBXNAVTIMELS == NULL) - initPacketUBXNAVTIMELS(); // Check that RAM has been allocated for the - // TIMELS data - if (packetUBXNAVTIMELS == NULL) // Abort if the RAM allocation failed - return (false); - - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_TIMELS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); -} - -// PRIVATE: Allocate RAM for packetUBXNAVTIMELS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVTIMELS() { - packetUBXNAVTIMELS = - new UBX_NAV_TIMELS_t; // Allocate RAM for the main struct - if (packetUBXNAVTIMELS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVTIMELS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVTIMELS->automaticFlags.flags.all = 0; - packetUBXNAVTIMELS->callbackPointer = NULL; - packetUBXNAVTIMELS->callbackPointerPtr = NULL; - packetUBXNAVTIMELS->callbackData = NULL; - packetUBXNAVTIMELS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// ***** NAV SVIN automatic support - -// Reads survey in status and sets the global variables -// for status, position valid, observation time, and mean 3D StdDev -// Returns true if commands was successful -bool SFE_UBLOX_GNSS::getSurveyStatus(uint16_t maxWait) { - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Abort if the RAM allocation failed - return (false); - - if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && - packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_SVIN); - return packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && - !packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting SVIN so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_SVIN; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic SVIN message generation by the GNSS. This changes -// the way getSurveyStatus works. -bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, uint16_t maxWait) { - return setAutoNAVSVINrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic SVIN message generation by the GNSS. This changes -// the way getSurveyStatus works. -bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVSVINrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic SVIN message generation by the GNSS. This changes -// the way getSurveyStatus works. -bool SFE_UBLOX_GNSS::setAutoNAVSVINrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVSVIN == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_SVIN; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVSVINcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVSVIN(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVSVIN->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVSVIN->callbackData = - new UBX_NAV_SVIN_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVSVIN->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVSVINcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVSVIN->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and SVIN is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVSVIN(bool enabled, bool implicitUpdate) { - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXNAVSVIN->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVSVIN and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVSVIN() { - packetUBXNAVSVIN = new UBX_NAV_SVIN_t; // Allocate RAM for the main struct - if (packetUBXNAVSVIN == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVSVIN: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVSVIN->automaticFlags.flags.all = 0; - packetUBXNAVSVIN->callbackPointerPtr = NULL; - packetUBXNAVSVIN->callbackData = NULL; - packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVSVIN() { - if (packetUBXNAVSVIN == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSVIN->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVSVIN(bool enabled) { - if (packetUBXNAVSVIN == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSVIN->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV SAT automatic support - -// Signal information -// Returns true if commands was successful -bool SFE_UBLOX_GNSS::getNAVSAT(uint16_t maxWait) { - if (packetUBXNAVSAT == NULL) - initPacketUBXNAVSAT(); // Check that RAM has been allocated for the - // NAVSAT data - if (packetUBXNAVSAT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVSAT->automaticFlags.flags.bits.automatic && - packetUBXNAVSAT->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_SAT); - return packetUBXNAVSAT->moduleQueried; - } else if (packetUBXNAVSAT->automaticFlags.flags.bits.automatic && - !packetUBXNAVSAT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting NAVSAT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_SAT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic NAVSAT message generation by the GNSS. This -// changes the way getNAVSAT works. -bool SFE_UBLOX_GNSS::setAutoNAVSAT(bool enable, uint16_t maxWait) { - return setAutoNAVSATrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic NAVSAT message generation by the GNSS. This -// changes the way getNAVSAT works. -bool SFE_UBLOX_GNSS::setAutoNAVSAT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoNAVSATrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic NAV SAT message generation by the GNSS. This -// changes the way getNAVSAT works. -bool SFE_UBLOX_GNSS::setAutoNAVSATrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVSAT == NULL) - initPacketUBXNAVSAT(); // Check that RAM has been allocated for the - // data - if (packetUBXNAVSAT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_SAT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVSAT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVSAT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVSAT->moduleQueried = false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoNAVSATcallback( - void (*callbackPointer)(UBX_NAV_SAT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVSAT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVSAT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVSAT->callbackData = - new UBX_NAV_SAT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVSAT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVSATcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVSAT->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoNAVSATcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_SAT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoNAVSAT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVSAT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVSAT->callbackData = - new UBX_NAV_SAT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVSAT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoNAVSATcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVSAT->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and NAV SAT is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoNAVSAT(bool enabled, bool implicitUpdate) { - if (packetUBXNAVSAT == NULL) - initPacketUBXNAVSAT(); // Check that RAM has been allocated for the - // NAVSAT data - if (packetUBXNAVSAT == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXNAVSAT->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVSAT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVSAT->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVSAT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVSAT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVSAT() { - packetUBXNAVSAT = new UBX_NAV_SAT_t; // Allocate RAM for the main struct - if (packetUBXNAVSAT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVSAT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVSAT->automaticFlags.flags.all = 0; - packetUBXNAVSAT->callbackPointer = NULL; - packetUBXNAVSAT->callbackPointerPtr = NULL; - packetUBXNAVSAT->callbackData = NULL; - packetUBXNAVSAT->moduleQueried = false; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVSAT() { - if (packetUBXNAVSAT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSAT->moduleQueried = - false; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVSAT(bool enabled) { - if (packetUBXNAVSAT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVSAT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** NAV RELPOSNED automatic support - -// Relative Positioning Information in NED frame -// Returns true if commands was successful -// Note: -// RELPOSNED on the M8 is only 40 bytes long -// RELPOSNED on the F9 is 64 bytes long and contains much more information -bool SFE_UBLOX_GNSS::getRELPOSNED(uint16_t maxWait) { - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic && - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_RELPOSNED); - return packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic && - !packetUBXNAVRELPOSNED->automaticFlags.flags.bits - .implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting RELPOSNED so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_RELPOSNED; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic RELPOSNED message generation by the GNSS. This -// changes the way getRELPOSNED works. -bool SFE_UBLOX_GNSS::setAutoRELPOSNED(bool enable, uint16_t maxWait) { - return setAutoRELPOSNEDrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic RELPOSNED message generation by the GNSS. This -// changes the way getRELPOSNED works. -bool SFE_UBLOX_GNSS::setAutoRELPOSNED(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoRELPOSNEDrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic RELPOSNED message generation by the GNSS. This -// changes the way getRELPOSNED works. -bool SFE_UBLOX_GNSS::setAutoRELPOSNEDrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVRELPOSNED == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_RELPOSNED; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoRELPOSNEDcallback( - void (*callbackPointer)(UBX_NAV_RELPOSNED_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRELPOSNED(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVRELPOSNED->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVRELPOSNED->callbackData = - new UBX_NAV_RELPOSNED_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVRELPOSNED->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRELPOSNEDcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVRELPOSNED->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoRELPOSNEDcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_RELPOSNED_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRELPOSNED(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVRELPOSNED->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVRELPOSNED->callbackData = - new UBX_NAV_RELPOSNED_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVRELPOSNED->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRELPOSNEDcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVRELPOSNED->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and RELPOSNED is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoRELPOSNED(bool enabled, bool implicitUpdate) { - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVRELPOSNED and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVRELPOSNED() { - packetUBXNAVRELPOSNED = - new UBX_NAV_RELPOSNED_t; // Allocate RAM for the main struct - if (packetUBXNAVRELPOSNED == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVRELPOSNED: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVRELPOSNED->automaticFlags.flags.all = 0; - packetUBXNAVRELPOSNED->callbackPointer = NULL; - packetUBXNAVRELPOSNED->callbackPointerPtr = NULL; - packetUBXNAVRELPOSNED->callbackData = NULL; - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushNAVRELPOSNED() { - if (packetUBXNAVRELPOSNED == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logNAVRELPOSNED(bool enabled) { - if (packetUBXNAVRELPOSNED == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** AOPSTATUS automatic support - -bool SFE_UBLOX_GNSS::getAOPSTATUS(uint16_t maxWait) { - if (packetUBXNAVAOPSTATUS == NULL) - initPacketUBXNAVAOPSTATUS(); // Check that RAM has been allocated for - // the AOPSTATUS data - if (packetUBXNAVAOPSTATUS == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.automatic && - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getAOPSTATUS: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_AOPSTATUS); - return packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.automatic && - !packetUBXNAVAOPSTATUS->automaticFlags.flags.bits - .implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getAOPSTATUS: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getAOPSTATUS: Polling")); - // } - - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_NAV; - packetCfg.id = UBX_NAV_AOPSTATUS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getAOPSTATUS: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getAOPSTATUS retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getAOPSTATUS works. -bool SFE_UBLOX_GNSS::setAutoAOPSTATUS(bool enable, uint16_t maxWait) { - return setAutoAOPSTATUSrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getAOPSTATUS works. -bool SFE_UBLOX_GNSS::setAutoAOPSTATUS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoAOPSTATUSrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getAOPSTATUS works. -bool SFE_UBLOX_GNSS::setAutoAOPSTATUSrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXNAVAOPSTATUS == NULL) - initPacketUBXNAVAOPSTATUS(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVAOPSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_NAV; - payloadCfg[1] = UBX_NAV_AOPSTATUS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoAOPSTATUScallback( - void (*callbackPointer)(UBX_NAV_AOPSTATUS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoAOPSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVAOPSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVAOPSTATUS->callbackData = - new UBX_NAV_AOPSTATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVAOPSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoAOPSTATUScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVAOPSTATUS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoAOPSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_AOPSTATUS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoAOPSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXNAVAOPSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXNAVAOPSTATUS->callbackData = - new UBX_NAV_AOPSTATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXNAVAOPSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoAOPSTATUScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXNAVAOPSTATUS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and AOPSTATUS is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoAOPSTATUS(bool enabled, bool implicitUpdate) { - if (packetUBXNAVAOPSTATUS == NULL) - initPacketUBXNAVAOPSTATUS(); // Check that RAM has been allocated for - // the data - if (packetUBXNAVAOPSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.automatic != enabled || - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.automatic = enabled; - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXNAVAOPSTATUS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXNAVAOPSTATUS() { - packetUBXNAVAOPSTATUS = - new UBX_NAV_AOPSTATUS_t; // Allocate RAM for the main struct - if (packetUBXNAVAOPSTATUS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXNAVAOPSTATUS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXNAVAOPSTATUS->automaticFlags.flags.all = 0; - packetUBXNAVAOPSTATUS->callbackPointer = NULL; - packetUBXNAVAOPSTATUS->callbackPointerPtr = NULL; - packetUBXNAVAOPSTATUS->callbackData = NULL; - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the AOPSTATUS data as read/stale. This is handy to get data -// alignment after CRC failure -void SFE_UBLOX_GNSS::flushAOPSTATUS() { - if (packetUBXNAVAOPSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.all = - 0; // Mark all AOPSTATUSs as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logAOPSTATUS(bool enabled) { - if (packetUBXNAVAOPSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXNAVAOPSTATUS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** RXM PMP automatic support - -// Callback receives a pointer to the data, instead of _all_ the data. Much -// kinder on the stack! -bool SFE_UBLOX_GNSS::setRXMPMPcallbackPtr( - void (*callbackPointer)(UBX_RXM_PMP_data_t *)) { - if (packetUBXRXMPMP == NULL) - initPacketUBXRXMPMP(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMPMP == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXRXMPMP->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMPMP->callbackData = - new UBX_RXM_PMP_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMPMP->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMPMPcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMPMP->callbackPointerPtr = callbackPointer; - return (true); -} - -// PRIVATE: Allocate RAM for packetUBXRXMPMP and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMPMP() { - packetUBXRXMPMP = new UBX_RXM_PMP_t; // Allocate RAM for the main struct - if (packetUBXRXMPMP == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXRXMPMP: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMPMP->automaticFlags.flags.all = 0; - packetUBXRXMPMP->callbackPointerPtr = NULL; - packetUBXRXMPMP->callbackData = NULL; - return (true); -} - -// Callback receives a pointer to the data, instead of _all_ the data. Much -// kinder on the stack! -bool SFE_UBLOX_GNSS::setRXMPMPmessageCallbackPtr( - void (*callbackPointer)(UBX_RXM_PMP_message_data_t *)) { - if (packetUBXRXMPMPmessage == NULL) - initPacketUBXRXMPMPmessage(); // Check that RAM has been allocated for - // the data - if (packetUBXRXMPMPmessage == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXRXMPMPmessage->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMPMPmessage->callbackData = - new UBX_RXM_PMP_message_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMPMPmessage->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMPMPmessagecallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMPMPmessage->callbackPointerPtr = callbackPointer; - return (true); -} - -// PRIVATE: Allocate RAM for packetUBXRXMPMPmessage and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMPMPmessage() { - packetUBXRXMPMPmessage = - new UBX_RXM_PMP_message_t; // Allocate RAM for the main struct - if (packetUBXRXMPMPmessage == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXRXMPMPmessage: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMPMPmessage->automaticFlags.flags.all = 0; - packetUBXRXMPMPmessage->callbackPointerPtr = NULL; - packetUBXRXMPMPmessage->callbackData = NULL; - return (true); -} - -// ***** RXM QZSSL6 automatic support - -// Callback receives a pointer to the data, instead of _all_ the data. Much -// kinder on the stack! -bool SFE_UBLOX_GNSS::setRXMQZSSL6messageCallbackPtr( - void (*callbackPointer)(UBX_RXM_QZSSL6_message_data_t *)) { - if (packetUBXRXMQZSSL6message == NULL) - initPacketUBXRXMQZSSL6message(); // Check that RAM has been allocated - // for the data - if (packetUBXRXMQZSSL6message == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXRXMQZSSL6message->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMQZSSL6message - ->callbackData = new UBX_RXM_QZSSL6_message_data_t - [UBX_RXM_QZSSL6_NUM_CHANNELS]; // Allocate RAM for the main struct - } - - if (packetUBXRXMQZSSL6message->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMQZSSL6messagecallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMQZSSL6message->callbackPointerPtr = callbackPointer; - return (true); -} - -// PRIVATE: Allocate RAM for packetUBXRXMQZSSL6message and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMQZSSL6message() { - packetUBXRXMQZSSL6message = - new UBX_RXM_QZSSL6_message_t; // Allocate RAM for the main struct - if (packetUBXRXMQZSSL6message == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXRXMQZSSL6message: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMQZSSL6message->automaticFlags.flags.all = 0; - packetUBXRXMQZSSL6message->callbackPointerPtr = NULL; - packetUBXRXMQZSSL6message->callbackData = NULL; - return (true); -} - -bool SFE_UBLOX_GNSS::setRXMCORcallbackPtr( - void (*callbackPointer)(UBX_RXM_COR_data_t *)) { - if (packetUBXRXMCOR == NULL) - initPacketUBXRXMCOR(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMCOR == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXRXMCOR->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMCOR->callbackData = - new UBX_RXM_COR_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMCOR->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMCORcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMCOR->callbackPointerPtr = callbackPointer; - return (true); -} - -// PRIVATE: Allocate RAM for packetUBXRXMCOR and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMCOR() { - packetUBXRXMCOR = new UBX_RXM_COR_t; // Allocate RAM for the main struct - if (packetUBXRXMCOR == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXRXMCOR: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMCOR->automaticFlags.flags.all = 0; - packetUBXRXMCOR->callbackPointerPtr = NULL; - packetUBXRXMCOR->callbackData = NULL; - return (true); -} - -// ***** RXM SFRBX automatic support - -bool SFE_UBLOX_GNSS::getRXMSFRBX(uint16_t maxWait) { - if (packetUBXRXMSFRBX == NULL) - initPacketUBXRXMSFRBX(); // Check that RAM has been allocated for the - // SFRBX data - if (packetUBXRXMSFRBX == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic && - packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_RXM, UBX_RXM_SFRBX); - return packetUBXRXMSFRBX->moduleQueried; - } else if (packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic && - !packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // SFRBX is output-only. It cannot be polled... - // Strictly, getRXMSFRBX should be deprecated. But, to keep the library - // backward compatible, return(false) here. See issue #167 for details - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMSFRBX works. -bool SFE_UBLOX_GNSS::setAutoRXMSFRBX(bool enable, uint16_t maxWait) { - return setAutoRXMSFRBXrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMSFRBX works. -bool SFE_UBLOX_GNSS::setAutoRXMSFRBX(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoRXMSFRBXrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMSFRBX works. -bool SFE_UBLOX_GNSS::setAutoRXMSFRBXrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXRXMSFRBX == NULL) - initPacketUBXRXMSFRBX(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMSFRBX == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_RXM; - payloadCfg[1] = UBX_RXM_SFRBX; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXRXMSFRBX->moduleQueried = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoRXMSFRBXcallback( - void (*callbackPointer)(UBX_RXM_SFRBX_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRXMSFRBX(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXRXMSFRBX->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMSFRBX->callbackData = - new UBX_RXM_SFRBX_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMSFRBX->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMSFRBXcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMSFRBX->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoRXMSFRBXcallbackPtr( - void (*callbackPointerPtr)(UBX_RXM_SFRBX_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRXMSFRBX(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXRXMSFRBX->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMSFRBX->callbackData = - new UBX_RXM_SFRBX_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMSFRBX->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMSFRBXcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMSFRBX->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and SFRBX is send cyclically -// already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoRXMSFRBX(bool enabled, bool implicitUpdate) { - if (packetUBXRXMSFRBX == NULL) - initPacketUBXRXMSFRBX(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMSFRBX == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic != enabled || - packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic = enabled; - packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXRXMSFRBX and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMSFRBX() { - packetUBXRXMSFRBX = - new UBX_RXM_SFRBX_t; // Allocate RAM for the main struct - if (packetUBXRXMSFRBX == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXRXMSFRBX: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMSFRBX->automaticFlags.flags.all = 0; - packetUBXRXMSFRBX->callbackPointer = NULL; - packetUBXRXMSFRBX->callbackPointerPtr = NULL; - packetUBXRXMSFRBX->callbackData = NULL; - packetUBXRXMSFRBX->moduleQueried = false; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushRXMSFRBX() { - if (packetUBXRXMSFRBX == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXRXMSFRBX->moduleQueried = - false; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logRXMSFRBX(bool enabled) { - if (packetUBXRXMSFRBX == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXRXMSFRBX->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** RXM RAWX automatic support - -bool SFE_UBLOX_GNSS::getRXMRAWX(uint16_t maxWait) { - if (packetUBXRXMRAWX == NULL) - initPacketUBXRXMRAWX(); // Check that RAM has been allocated for the - // RAWX data - if (packetUBXRXMRAWX == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXRXMRAWX->automaticFlags.flags.bits.automatic && - packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_RXM, UBX_RXM_RAWX); - return packetUBXRXMRAWX->moduleQueried; - } else if (packetUBXRXMRAWX->automaticFlags.flags.bits.automatic && - !packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_RXM; - packetCfg.id = UBX_RXM_RAWX; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMRAWX works. -bool SFE_UBLOX_GNSS::setAutoRXMRAWX(bool enable, uint16_t maxWait) { - return setAutoRXMRAWXrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMRAWX works. -bool SFE_UBLOX_GNSS::setAutoRXMRAWX(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoRXMRAWXrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getRXMRAWX works. -bool SFE_UBLOX_GNSS::setAutoRXMRAWXrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXRXMRAWX == NULL) - initPacketUBXRXMRAWX(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMRAWX == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_RXM; - payloadCfg[1] = UBX_RXM_RAWX; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXRXMRAWX->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXRXMRAWX->moduleQueried = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoRXMRAWXcallback( - void (*callbackPointer)(UBX_RXM_RAWX_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRXMRAWX(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXRXMRAWX->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMRAWX->callbackData = - new UBX_RXM_RAWX_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMRAWX->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMRAWXcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMRAWX->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoRXMRAWXcallbackPtr( - void (*callbackPointerPtr)(UBX_RXM_RAWX_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoRXMRAWX(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXRXMRAWX->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXRXMRAWX->callbackData = - new UBX_RXM_RAWX_data_t; // Allocate RAM for the main struct - } - - if (packetUBXRXMRAWX->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoRXMRAWXcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXRXMRAWX->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and VELNED is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoRXMRAWX(bool enabled, bool implicitUpdate) { - if (packetUBXRXMRAWX == NULL) - initPacketUBXRXMRAWX(); // Check that RAM has been allocated for the - // data - if (packetUBXRXMRAWX == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXRXMRAWX->automaticFlags.flags.bits.automatic != enabled || - packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXRXMRAWX->automaticFlags.flags.bits.automatic = enabled; - packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXRXMRAWX and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXRXMRAWX() { - packetUBXRXMRAWX = new UBX_RXM_RAWX_t; // Allocate RAM for the main struct - if (packetUBXRXMRAWX == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXRXMRAWX: RAM alloc failed!")); -#endif - return (false); - } - packetUBXRXMRAWX->automaticFlags.flags.all = 0; - packetUBXRXMRAWX->callbackPointer = NULL; - packetUBXRXMRAWX->callbackPointerPtr = NULL; - packetUBXRXMRAWX->callbackData = NULL; - packetUBXRXMRAWX->moduleQueried = false; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushRXMRAWX() { - if (packetUBXRXMRAWX == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXRXMRAWX->moduleQueried = - false; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logRXMRAWX(bool enabled) { - if (packetUBXRXMRAWX == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXRXMRAWX->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** CFG automatic support - -// Get the latest CFG PRT - as used by isConnected -// Here's the dilemma: -// The NEO-D9S doesn't support NAV-RATE so, if we want to include the D9 -// without creating a special class for it, we need to use something else as -// the 'isConnected' test. The D9 does support CFG-PRT so we'll use that. BUT -// many users could already be using getPortSettings and expecting the settings -// to be returned in packetCfg. So, for isConnected ONLY, we need to enable -// auto support for CFG-PRT and then disable it afterwards so the settings go -// back to being returned in packetCfg... What a tangled web we weave...! -bool SFE_UBLOX_GNSS::getPortSettingsInternal(uint8_t portID, uint16_t maxWait) { - if (packetUBXCFGPRT == NULL) - initPacketUBXCFGPRT(); // Check that RAM has been allocated for the - // data - if (packetUBXCFGPRT == NULL) // Bail if the RAM allocation failed - return (false); - - // The CFG PRT message will never be produced automatically - that would be - // pointless. There is no setAutoCFGPRT function. We always need to poll - // explicitly. - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_PRT; - packetCfg.len = 1; - packetCfg.startingSpot = 0; - - payloadCfg[0] = portID; - - // The data is parsed as part of processing the response - sfe_ublox_status_e result = sendCommand(&packetCfg, maxWait); - bool retVal = false; - - if (result == SFE_UBLOX_STATUS_DATA_RECEIVED) retVal = true; - - if (result == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) retVal = true; - - // Now disable automatic support for CFG-PRT (see above) - delete packetUBXCFGPRT; - packetUBXCFGPRT = NULL; - - return (retVal); -} - -// PRIVATE: Allocate RAM for packetUBXCFGPRT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXCFGPRT() { - packetUBXCFGPRT = new UBX_CFG_PRT_t; // Allocate RAM for the main struct - if (packetUBXCFGPRT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXCFGPRT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXCFGPRT->dataValid = false; - return (true); -} - -// Get the latest CFG RATE -bool SFE_UBLOX_GNSS::getNavigationFrequencyInternal(uint16_t maxWait) { - if (packetUBXCFGRATE == NULL) - initPacketUBXCFGRATE(); // Check that RAM has been allocated for the - // data - if (packetUBXCFGRATE == NULL) // Bail if the RAM allocation failed - return (false); - - // The CFG RATE message will never be produced automatically - that would be - // pointless. There is no setAutoCFGRATE function. We always need to poll - // explicitly. - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RATE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) return (true); - - return (false); -} - -// PRIVATE: Allocate RAM for packetUBXCFGRATE and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXCFGRATE() { - packetUBXCFGRATE = new UBX_CFG_RATE_t; // Allocate RAM for the main struct - if (packetUBXCFGRATE == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXCFGRATE: RAM alloc failed!")); -#endif - return (false); - } - packetUBXCFGRATE->automaticFlags.flags.all = 0; // Redundant - packetUBXCFGRATE->moduleQueried.moduleQueried.all = - 0; // Mark all data as stale/read - return (true); -} - -// ***** TIM TM2 automatic support - -bool SFE_UBLOX_GNSS::getTIMTM2(uint16_t maxWait) { - if (packetUBXTIMTM2 == NULL) - initPacketUBXTIMTM2(); // Check that RAM has been allocated for the TM2 - // data - if (packetUBXTIMTM2 == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXTIMTM2->automaticFlags.flags.bits.automatic && - packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - checkUbloxInternal(&packetCfg, UBX_CLASS_TIM, UBX_TIM_TM2); - return packetUBXTIMTM2->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXTIMTM2->automaticFlags.flags.bits.automatic && - !packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - return (false); - } else { - // The GPS is not automatically reporting navigation position so we have - // to poll explicitly - packetCfg.cls = UBX_CLASS_TIM; - packetCfg.id = UBX_TIM_TM2; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - return (true); - } - - return (false); - } -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMTM2 works. -bool SFE_UBLOX_GNSS::setAutoTIMTM2(bool enable, uint16_t maxWait) { - return setAutoTIMTM2rate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMTM2 works. -bool SFE_UBLOX_GNSS::setAutoTIMTM2(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoTIMTM2rate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic navigation message generation by the GNSS. This -// changes the way getTIMTM2 works. -bool SFE_UBLOX_GNSS::setAutoTIMTM2rate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXTIMTM2 == NULL) - initPacketUBXTIMTM2(); // Check that RAM has been allocated for the - // data - if (packetUBXTIMTM2 == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_TIM; - payloadCfg[1] = UBX_TIM_TM2; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXTIMTM2->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXTIMTM2->moduleQueried.moduleQueried.bits.all = false; - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoTIMTM2callback( - void (*callbackPointer)(UBX_TIM_TM2_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoTIMTM2(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXTIMTM2->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXTIMTM2->callbackData = - new UBX_TIM_TM2_data_t; // Allocate RAM for the main struct - } - - if (packetUBXTIMTM2->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoTIMTM2callback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXTIMTM2->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoTIMTM2callbackPtr( - void (*callbackPointerPtr)(UBX_TIM_TM2_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoTIMTM2(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXTIMTM2->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXTIMTM2->callbackData = - new UBX_TIM_TM2_data_t; // Allocate RAM for the main struct - } - - if (packetUBXTIMTM2->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoTIMTM2callbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXTIMTM2->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and VELNED is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoTIMTM2(bool enabled, bool implicitUpdate) { - if (packetUBXTIMTM2 == NULL) - initPacketUBXTIMTM2(); // Check that RAM has been allocated for the - // data - if (packetUBXTIMTM2 == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXTIMTM2->automaticFlags.flags.bits.automatic != enabled || - packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXTIMTM2->automaticFlags.flags.bits.automatic = enabled; - packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXTIMTM2 and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXTIMTM2() { - packetUBXTIMTM2 = new UBX_TIM_TM2_t; // Allocate RAM for the main struct - if (packetUBXTIMTM2 == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXTIMTM2: RAM alloc failed!")); -#endif - return (false); - } - packetUBXTIMTM2->automaticFlags.flags.all = 0; - packetUBXTIMTM2->callbackPointer = NULL; - packetUBXTIMTM2->callbackPointerPtr = NULL; - packetUBXTIMTM2->callbackData = NULL; - packetUBXTIMTM2->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushTIMTM2() { - if (packetUBXTIMTM2 == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXTIMTM2->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logTIMTM2(bool enabled) { - if (packetUBXTIMTM2 == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXTIMTM2->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** ESF ALG automatic support - -bool SFE_UBLOX_GNSS::getEsfAlignment(uint16_t maxWait) { - return (getESFALG(maxWait)); -} - -bool SFE_UBLOX_GNSS::getESFALG(uint16_t maxWait) { - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the ESF - // alignment data - if (packetUBXESFALG == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXESFALG->automaticFlags.flags.bits.automatic && - packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfAlignment: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_ESF, UBX_ESF_ALG); - return packetUBXESFALG->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXESFALG->automaticFlags.flags.bits.automatic && - !packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfAlignment: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfAlignment: Polling")); - // } - - // The GPS is not automatically reporting HNR PVT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_ESF; - packetCfg.id = UBX_ESF_ALG; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfAlignment: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getEsfAlignment retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic ESF ALG message generation by the GNSS. This -// changes the way getEsfAlignment works. -bool SFE_UBLOX_GNSS::setAutoESFALG(bool enable, uint16_t maxWait) { - return setAutoESFALGrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic ESF ALG message generation by the GNSS. This -// changes the way getEsfAlignment works. -bool SFE_UBLOX_GNSS::setAutoESFALG(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoESFALGrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic ESF ALG message generation by the GNSS. This -// changes the way getEsfAlignment works. -bool SFE_UBLOX_GNSS::setAutoESFALGrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the - // data - if (packetUBXESFALG == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_ESF; - payloadCfg[1] = UBX_ESF_ALG; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXESFALG->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXESFALG->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFALGcallback( - void (*callbackPointer)(UBX_ESF_ALG_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFALG(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFALG->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFALG->callbackData = - new UBX_ESF_ALG_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFALG->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFALGcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFALG->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoESFALGcallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_ALG_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFALG(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFALG->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFALG->callbackData = - new UBX_ESF_ALG_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFALG->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFALGcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFALG->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ESF ALG is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoESFALG(bool enabled, bool implicitUpdate) { - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the ESF - // alignment data - if (packetUBXESFALG == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXESFALG->automaticFlags.flags.bits.automatic != enabled || - packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXESFALG->automaticFlags.flags.bits.automatic = enabled; - packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXESFALG and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXESFALG() { - packetUBXESFALG = new UBX_ESF_ALG_t; // Allocate RAM for the main struct - if (packetUBXESFALG == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFALG: RAM alloc failed!")); -#endif - return (false); - } - packetUBXESFALG->automaticFlags.flags.all = 0; - packetUBXESFALG->callbackPointer = NULL; - packetUBXESFALG->callbackPointerPtr = NULL; - packetUBXESFALG->callbackData = NULL; - packetUBXESFALG->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushESFALG() { - if (packetUBXESFALG == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFALG->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logESFALG(bool enabled) { - if (packetUBXESFALG == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFALG->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** ESF STATUS automatic support - -bool SFE_UBLOX_GNSS::getEsfInfo(uint16_t maxWait) { - return (getESFSTATUS(maxWait)); -} - -bool SFE_UBLOX_GNSS::getESFSTATUS(uint16_t maxWait) { - if (packetUBXESFSTATUS == NULL) - initPacketUBXESFSTATUS(); // Check that RAM has been allocated for the - // ESF status data - if (packetUBXESFSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXESFSTATUS->automaticFlags.flags.bits.automatic && - packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfInfo: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_ESF, UBX_ESF_STATUS); - return packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXESFSTATUS->automaticFlags.flags.bits.automatic && - !packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfInfo: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfInfo: Polling")); - // } - - // The GPS is not automatically reporting HNR PVT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_ESF; - packetCfg.id = UBX_ESF_STATUS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfInfo: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getEsfInfo retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic ESF STATUS message generation by the GNSS. This -// changes the way getESFInfo works. -bool SFE_UBLOX_GNSS::setAutoESFSTATUS(bool enable, uint16_t maxWait) { - return setAutoESFSTATUSrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic ESF STATUS message generation by the GNSS. This -// changes the way getESFInfo works. -bool SFE_UBLOX_GNSS::setAutoESFSTATUS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoESFSTATUSrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic ESF STATUS message generation by the GNSS. This -// changes the way getESFInfo works. -bool SFE_UBLOX_GNSS::setAutoESFSTATUSrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXESFSTATUS == NULL) - initPacketUBXESFSTATUS(); // Check that RAM has been allocated for the - // data - if (packetUBXESFSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_ESF; - payloadCfg[1] = UBX_ESF_STATUS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXESFSTATUS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFSTATUScallback( - void (*callbackPointer)(UBX_ESF_STATUS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFSTATUS->callbackData = - new UBX_ESF_STATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFSTATUScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFSTATUS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoESFSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_STATUS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFSTATUS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFSTATUS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFSTATUS->callbackData = - new UBX_ESF_STATUS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFSTATUS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFSTATUScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFSTATUS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ESF STATUS is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoESFSTATUS(bool enabled, bool implicitUpdate) { - if (packetUBXESFSTATUS == NULL) - initPacketUBXESFSTATUS(); // Check that RAM has been allocated for the - // ESF status data - if (packetUBXESFSTATUS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXESFSTATUS->automaticFlags.flags.bits.automatic != enabled || - packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXESFSTATUS->automaticFlags.flags.bits.automatic = enabled; - packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXESFSTATUS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXESFSTATUS() { - packetUBXESFSTATUS = - new UBX_ESF_STATUS_t; // Allocate RAM for the main struct - - if (packetUBXESFSTATUS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("initPacketUBXESFSTATUS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXESFSTATUS->automaticFlags.flags.all = 0; - packetUBXESFSTATUS->callbackPointer = NULL; - packetUBXESFSTATUS->callbackPointerPtr = NULL; - packetUBXESFSTATUS->callbackData = NULL; - packetUBXESFSTATUS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushESFSTATUS() { - if (packetUBXESFSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFSTATUS->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logESFSTATUS(bool enabled) { - if (packetUBXESFSTATUS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFSTATUS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** ESF INS automatic support - -bool SFE_UBLOX_GNSS::getEsfIns(uint16_t maxWait) { - return (getESFINS(maxWait)); -} - -bool SFE_UBLOX_GNSS::getESFINS(uint16_t maxWait) { - if (packetUBXESFINS == NULL) - initPacketUBXESFINS(); // Check that RAM has been allocated for the ESF - // INS data - if (packetUBXESFINS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXESFINS->automaticFlags.flags.bits.automatic && - packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfIns: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_ESF, UBX_ESF_INS); - return packetUBXESFINS->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXESFINS->automaticFlags.flags.bits.automatic && - !packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfIns: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfIns: Polling")); - // } - - // The GPS is not automatically reporting HNR PVT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_ESF; - packetCfg.id = UBX_ESF_INS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getEsfIns: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getEsfIns retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic ESF INS message generation by the GNSS. This -// changes the way getESFIns works. -bool SFE_UBLOX_GNSS::setAutoESFINS(bool enable, uint16_t maxWait) { - return setAutoESFINSrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic ESF INS message generation by the GNSS. This -// changes the way getESFIns works. -bool SFE_UBLOX_GNSS::setAutoESFINS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoESFINSrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic ESF INS message generation by the GNSS. This -// changes the way getESFIns works. -bool SFE_UBLOX_GNSS::setAutoESFINSrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXESFINS == NULL) - initPacketUBXESFINS(); // Check that RAM has been allocated for the - // data - if (packetUBXESFINS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_ESF; - payloadCfg[1] = UBX_ESF_INS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXESFINS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXESFINS->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFINScallback( - void (*callbackPointer)(UBX_ESF_INS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFINS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFINS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFINS->callbackData = - new UBX_ESF_INS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFINS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFINScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFINS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoESFINScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_INS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFINS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFINS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFINS->callbackData = - new UBX_ESF_INS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFINS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFINScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFINS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ESF INS is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoESFINS(bool enabled, bool implicitUpdate) { - if (packetUBXESFINS == NULL) - initPacketUBXESFINS(); // Check that RAM has been allocated for the ESF - // INS data - if (packetUBXESFINS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXESFINS->automaticFlags.flags.bits.automatic != enabled || - packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXESFINS->automaticFlags.flags.bits.automatic = enabled; - packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXESFINS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXESFINS() { - packetUBXESFINS = new UBX_ESF_INS_t; // Allocate RAM for the main struct - if (packetUBXESFINS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFINS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXESFINS->automaticFlags.flags.all = 0; - packetUBXESFINS->callbackPointer = NULL; - packetUBXESFINS->callbackPointerPtr = NULL; - packetUBXESFINS->callbackData = NULL; - packetUBXESFINS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushESFINS() { - if (packetUBXESFINS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFINS->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logESFINS(bool enabled) { - if (packetUBXESFINS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFINS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** ESF MEAS automatic support - -// Enable or disable automatic ESF MEAS message generation by the GNSS -bool SFE_UBLOX_GNSS::setAutoESFMEAS(bool enable, uint16_t maxWait) { - return setAutoESFMEASrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic ESF MEAS message generation by the GNSS -bool SFE_UBLOX_GNSS::setAutoESFMEAS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoESFMEASrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic ESF MEAS message generation by the GNSS -bool SFE_UBLOX_GNSS::setAutoESFMEASrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXESFMEAS == NULL) - initPacketUBXESFMEAS(); // Check that RAM has been allocated for the - // data - if (packetUBXESFMEAS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_ESF; - payloadCfg[1] = UBX_ESF_MEAS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXESFMEAS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXESFMEAS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFMEAScallback( - void (*callbackPointer)(UBX_ESF_MEAS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFMEAS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFMEAS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFMEAS->callbackData = - new UBX_ESF_MEAS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFMEAS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFMEAScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFMEAS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoESFMEAScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_MEAS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFMEAS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFMEAS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFMEAS->callbackData = - new UBX_ESF_MEAS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFMEAS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFMEAScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFMEAS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ESF MEAS is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoESFMEAS(bool enabled, bool implicitUpdate) { - if (packetUBXESFMEAS == NULL) - initPacketUBXESFMEAS(); // Check that RAM has been allocated for the - // ESF MEAS data - if (packetUBXESFMEAS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXESFMEAS->automaticFlags.flags.bits.automatic != enabled || - packetUBXESFMEAS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXESFMEAS->automaticFlags.flags.bits.automatic = enabled; - packetUBXESFMEAS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXESFMEAS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXESFMEAS() { - packetUBXESFMEAS = new UBX_ESF_MEAS_t; // Allocate RAM for the main struct - if (packetUBXESFMEAS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFMEAS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXESFMEAS->automaticFlags.flags.all = 0; - packetUBXESFMEAS->callbackPointer = NULL; - packetUBXESFMEAS->callbackPointerPtr = NULL; - packetUBXESFMEAS->callbackData = NULL; - return (true); -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logESFMEAS(bool enabled) { - if (packetUBXESFMEAS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFMEAS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** ESF RAW automatic support - -// ESF RAW messages are output only. They cannot be polled. - -// Enable or disable automatic ESF RAW message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFRAW(bool enable, uint16_t maxWait) { - return setAutoESFRAWrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic ESF RAW message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFRAW(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoESFRAWrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic ESF RAW message generation by the GNSS. -// Note: this function can only be used to enable or disable the messages. A -// rate of zero disables the messages. A rate of 1 or more causes the messages -// to be generated at the full 100Hz. -bool SFE_UBLOX_GNSS::setAutoESFRAWrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXESFRAW == NULL) - initPacketUBXESFRAW(); // Check that RAM has been allocated for the - // data - if (packetUBXESFRAW == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_ESF; - payloadCfg[1] = UBX_ESF_RAW; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXESFRAW->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXESFRAW->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return ok; -} - -// Enable automatic message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoESFRAWcallback( - void (*callbackPointer)(UBX_ESF_RAW_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFRAW(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFRAW->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFRAW->callbackData = - new UBX_ESF_RAW_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFRAW->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFRAWcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFRAW->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoESFRAWcallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_RAW_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoESFRAW(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXESFRAW->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXESFRAW->callbackData = - new UBX_ESF_RAW_data_t; // Allocate RAM for the main struct - } - - if (packetUBXESFRAW->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoESFRAWcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXESFRAW->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and ESF RAW is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoESFRAW(bool enabled, bool implicitUpdate) { - if (packetUBXESFRAW == NULL) - initPacketUBXESFRAW(); // Check that RAM has been allocated for the ESF - // RAW data - if (packetUBXESFRAW == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXESFRAW->automaticFlags.flags.bits.automatic != enabled || - packetUBXESFRAW->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXESFRAW->automaticFlags.flags.bits.automatic = enabled; - packetUBXESFRAW->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXESFRAW and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXESFRAW() { - packetUBXESFRAW = new UBX_ESF_RAW_t; // Allocate RAM for the main struct - if (packetUBXESFRAW == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFRAW: RAM alloc failed!")); -#endif - return (false); - } - packetUBXESFRAW->automaticFlags.flags.all = 0; - packetUBXESFRAW->callbackPointer = NULL; - packetUBXESFRAW->callbackPointerPtr = NULL; - packetUBXESFRAW->callbackData = NULL; - return (true); -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logESFRAW(bool enabled) { - if (packetUBXESFRAW == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXESFRAW->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** HNR ATT automatic support - -bool SFE_UBLOX_GNSS::getHNRAtt(uint16_t maxWait) { - return (getHNRATT(maxWait)); -} - -// Get the HNR Attitude data -// Returns true if the get HNR attitude is successful. Data is returned in -// hnrAtt Note: if hnrAttQueried is true, it gets set to false by this function -// since we assume -// that the user will read hnrAtt immediately after this. I.e. this -// function will only return true _once_ after each auto HNR Att is -// processed -bool SFE_UBLOX_GNSS::getHNRATT(uint16_t maxWait) { - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRATT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXHNRATT->automaticFlags.flags.bits.automatic && - packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRAtt: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_HNR, UBX_HNR_ATT); - return packetUBXHNRATT->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXHNRATT->automaticFlags.flags.bits.automatic && - !packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRAtt: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRAtt: Polling")); - // } - - // The GPS is not automatically reporting HNR attitude so we have to - // poll explicitly - packetCfg.cls = UBX_CLASS_HNR; - packetCfg.id = UBX_HNR_ATT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRAtt: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getHNRAtt retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic HNR attitude message generation by the GNSS. This -// changes the way getHNRAtt works. -bool SFE_UBLOX_GNSS::setAutoHNRATT(bool enable, uint16_t maxWait) { - return setAutoHNRATTrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic HNR attitude message generation by the GNSS. This -// changes the way getHNRAtt works. -bool SFE_UBLOX_GNSS::setAutoHNRATT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoHNRATTrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic HNR attitude message generation by the GNSS. This -// changes the way getHNRAtt works. -bool SFE_UBLOX_GNSS::setAutoHNRATTrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRATT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_HNR; - payloadCfg[1] = UBX_HNR_ATT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXHNRATT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXHNRATT->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoHNRATTcallback( - void (*callbackPointer)(UBX_HNR_ATT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRATT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRATT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRATT->callbackData = - new UBX_HNR_ATT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRATT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRAttcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRATT->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoHNRATTcallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_ATT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRATT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRATT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRATT->callbackData = - new UBX_HNR_ATT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRATT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRAttcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRATT->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and HNR attitude is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoHNRATT(bool enabled, bool implicitUpdate) { - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRATT == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXHNRATT->automaticFlags.flags.bits.automatic != enabled || - packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXHNRATT->automaticFlags.flags.bits.automatic = enabled; - packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXHNRATT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXHNRATT() { - packetUBXHNRATT = new UBX_HNR_ATT_t; // Allocate RAM for the main struct - if (packetUBXHNRATT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRATT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXHNRATT->automaticFlags.flags.all = 0; - packetUBXHNRATT->callbackPointer = NULL; - packetUBXHNRATT->callbackPointerPtr = NULL; - packetUBXHNRATT->callbackData = NULL; - packetUBXHNRATT->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushHNRATT() { - if (packetUBXHNRATT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRATT->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logHNRATT(bool enabled) { - if (packetUBXHNRATT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRATT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** HNR DYN automatic support - -bool SFE_UBLOX_GNSS::getHNRDyn(uint16_t maxWait) { - return (getHNRINS(maxWait)); -} - -// Get the HNR vehicle dynamics data -// Returns true if the get HNR vehicle dynamics is successful. Data is returned -// in hnrVehDyn Note: if hnrDynQueried is true, it gets set to false by this -// function since we assume -// that the user will read hnrVehDyn immediately after this. I.e. this -// function will only return true _once_ after each auto HNR Dyn is -// processed -bool SFE_UBLOX_GNSS::getHNRINS(uint16_t maxWait) { - if (packetUBXHNRINS == NULL) - initPacketUBXHNRINS(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRINS == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXHNRINS->automaticFlags.flags.bits.automatic && - packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRINS: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_HNR, UBX_HNR_INS); - return packetUBXHNRINS->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXHNRINS->automaticFlags.flags.bits.automatic && - !packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRINS: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRINS: Polling")); - // } - - // The GPS is not automatically reporting HNR vehicle dynamics so we - // have to poll explicitly - packetCfg.cls = UBX_CLASS_HNR; - packetCfg.id = UBX_HNR_INS; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRINS: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getHNRINS retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic HNR vehicle dynamics message generation by the -// GNSS. This changes the way getHNRINS works. -bool SFE_UBLOX_GNSS::setAutoHNRINS(bool enable, uint16_t maxWait) { - return setAutoHNRINSrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic HNR vehicle dynamics message generation by the -// GNSS. This changes the way getHNRINS works. -bool SFE_UBLOX_GNSS::setAutoHNRINS(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoHNRINSrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic HNR vehicle dynamics message generation by the -// GNSS. This changes the way getHNRINS works. -bool SFE_UBLOX_GNSS::setAutoHNRINSrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXHNRINS == NULL) - initPacketUBXHNRINS(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRINS == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_HNR; - payloadCfg[1] = UBX_HNR_INS; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXHNRINS->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXHNRINS->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoHNRINScallback( - void (*callbackPointer)(UBX_HNR_INS_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRINS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRINS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRINS->callbackData = - new UBX_HNR_INS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRINS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRINScallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRINS->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoHNRINScallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_INS_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRINS(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRINS->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRINS->callbackData = - new UBX_HNR_INS_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRINS->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRINScallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRINS->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and HNR vehicle dynamics is -// send cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoHNRINS(bool enabled, bool implicitUpdate) { - if (packetUBXHNRINS == NULL) - initPacketUBXHNRINS(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRINS == NULL) // Bail if the RAM allocation failed - return (false); - - bool changes = - packetUBXHNRINS->automaticFlags.flags.bits.automatic != enabled || - packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXHNRINS->automaticFlags.flags.bits.automatic = enabled; - packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXHNRINS and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXHNRINS() { - packetUBXHNRINS = new UBX_HNR_INS_t; // Allocate RAM for the main struct - if (packetUBXHNRINS == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRINS: RAM alloc failed!")); -#endif - return (false); - } - packetUBXHNRINS->automaticFlags.flags.all = 0; - packetUBXHNRINS->callbackPointer = NULL; - packetUBXHNRINS->callbackPointerPtr = NULL; - packetUBXHNRINS->callbackData = NULL; - packetUBXHNRINS->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushHNRINS() { - if (packetUBXHNRINS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRINS->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logHNRINS(bool enabled) { - if (packetUBXHNRINS == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRINS->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** HNR PVT automatic support - -// Get the HNR PVT data -// Returns true if the get HNR PVT is successful. Data is returned in hnrPVT -// Note: if hnrPVTQueried is true, it gets set to false by this function since -// we assume -// that the user will read hnrPVT immediately after this. I.e. this -// function will only return true _once_ after each auto HNR PVT is -// processed -bool SFE_UBLOX_GNSS::getHNRPVT(uint16_t maxWait) { - if (packetUBXHNRPVT == NULL) - initPacketUBXHNRPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXHNRPVT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (packetUBXHNRPVT->automaticFlags.flags.bits.automatic && - packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate) { - // The GPS is automatically reporting, we just check whether we got - // unread data - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRPVT: Autoreporting")); - // } - checkUbloxInternal(&packetCfg, UBX_CLASS_HNR, UBX_HNR_PVT); - return packetUBXHNRPVT->moduleQueried.moduleQueried.bits.all; - } else if (packetUBXHNRPVT->automaticFlags.flags.bits.automatic && - !packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate) { - // Someone else has to call checkUblox for us... - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRPVT: Exit immediately")); - // } - return (false); - } else { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRPVT: Polling")); - // } - - // The GPS is not automatically reporting HNR PVT so we have to poll - // explicitly - packetCfg.cls = UBX_CLASS_HNR; - packetCfg.id = UBX_HNR_PVT; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // The data is parsed as part of processing the response - sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); - - if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) return (true); - - if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) { - // if (_printDebug == true) - // { - // _debugSerial->println(F("getHNRPVT: data in packetCfg was - // OVERWRITTEN by another message (but that's OK)")); - // } - return (true); - } - - // if (_printDebug == true) - // { - // _debugSerial->print(F("getHNRPVT retVal: ")); - // _debugSerial->println(statusString(retVal)); - // } - return (false); - } - - return (false); // Trap. We should never get here... -} - -// Enable or disable automatic HNR PVT message generation by the GNSS. This -// changes the way getHNRPVT works. -bool SFE_UBLOX_GNSS::setAutoHNRPVT(bool enable, uint16_t maxWait) { - return setAutoHNRPVTrate(enable ? 1 : 0, true, maxWait); -} - -// Enable or disable automatic HNR PVT message generation by the GNSS. This -// changes the way getHNRPVT works. -bool SFE_UBLOX_GNSS::setAutoHNRPVT(bool enable, bool implicitUpdate, - uint16_t maxWait) { - return setAutoHNRPVTrate(enable ? 1 : 0, implicitUpdate, maxWait); -} - -// Enable or disable automatic HNR PVT message generation by the GNSS. This -// changes the way getHNRPVT works. -bool SFE_UBLOX_GNSS::setAutoHNRPVTrate(uint8_t rate, bool implicitUpdate, - uint16_t maxWait) { - if (packetUBXHNRPVT == NULL) - initPacketUBXHNRPVT(); // Check that RAM has been allocated for the - // data - if (packetUBXHNRPVT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - if (rate > 127) rate = 127; - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_MSG; - packetCfg.len = 3; - packetCfg.startingSpot = 0; - payloadCfg[0] = UBX_CLASS_HNR; - payloadCfg[1] = UBX_HNR_PVT; - payloadCfg[2] = rate; // rate relative to navigation freq. - - bool ok = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - if (ok) { - packetUBXHNRPVT->automaticFlags.flags.bits.automatic = (rate > 0); - packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - packetUBXHNRPVT->moduleQueried.moduleQueried.bits.all = - false; // Mark data as stale - return ok; -} - -// Enable automatic navigation message generation by the GNSS. -bool SFE_UBLOX_GNSS::setAutoHNRPVTcallback( - void (*callbackPointer)(UBX_HNR_PVT_data_t), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRPVT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRPVT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRPVT->callbackData = - new UBX_HNR_PVT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRPVT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRPVTcallback: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRPVT->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setAutoHNRPVTcallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_PVT_data_t *), uint16_t maxWait) { - // Enable auto messages. Set implicitUpdate to false as we expect the user - // to call checkUblox manually. - bool result = setAutoHNRPVT(true, false, maxWait); - if (!result) return (result); // Bail if setAuto failed - - if (packetUBXHNRPVT->callbackData == - NULL) // Check if RAM has been allocated for the callback copy - { - packetUBXHNRPVT->callbackData = - new UBX_HNR_PVT_data_t; // Allocate RAM for the main struct - } - - if (packetUBXHNRPVT->callbackData == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setAutoHNRPVTcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - packetUBXHNRPVT->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// In case no config access to the GNSS is possible and HNR PVT is send -// cyclically already set config to suitable parameters -bool SFE_UBLOX_GNSS::assumeAutoHNRPVT(bool enabled, bool implicitUpdate) { - if (packetUBXHNRPVT == NULL) - initPacketUBXHNRPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXHNRPVT == - NULL) // Only attempt this if RAM allocation was successful - return false; - - bool changes = - packetUBXHNRPVT->automaticFlags.flags.bits.automatic != enabled || - packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate != - implicitUpdate; - if (changes) { - packetUBXHNRPVT->automaticFlags.flags.bits.automatic = enabled; - packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate = - implicitUpdate; - } - return changes; -} - -// PRIVATE: Allocate RAM for packetUBXHNRPVT and initialize it -bool SFE_UBLOX_GNSS::initPacketUBXHNRPVT() { - packetUBXHNRPVT = new UBX_HNR_PVT_t; // Allocate RAM for the main struct - if (packetUBXHNRPVT == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRPVT: RAM alloc failed!")); -#endif - return (false); - } - packetUBXHNRPVT->automaticFlags.flags.all = 0; - packetUBXHNRPVT->callbackPointer = NULL; - packetUBXHNRPVT->callbackPointerPtr = NULL; - packetUBXHNRPVT->callbackData = NULL; - packetUBXHNRPVT->moduleQueried.moduleQueried.all = 0; - return (true); -} - -// Mark all the data as read/stale -void SFE_UBLOX_GNSS::flushHNRPVT() { - if (packetUBXHNRPVT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRPVT->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// Log this data in file buffer -void SFE_UBLOX_GNSS::logHNRPVT(bool enabled) { - if (packetUBXHNRPVT == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXHNRPVT->automaticFlags.flags.bits.addToFileBuffer = - (uint8_t)enabled; -} - -// ***** Helper Functions for NMEA Logging / Processing - -// Set the mainTalkerId used by NMEA messages - allows all NMEA messages except -// GSV to be prefixed with GP instead of GN -bool SFE_UBLOX_GNSS::setMainTalkerID(sfe_ublox_talker_ids_e id, - uint16_t maxWait) { - // Get the current extended NMEA protocol configuration (V1) - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NMEA; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current settings. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - payloadCfg[9] = (uint8_t)id; - - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Enable/Disable NMEA High Precision Mode - include extra decimal places in the -// Lat and Lon -bool SFE_UBLOX_GNSS::setHighPrecisionMode(bool enable, uint16_t maxWait) { - // Get the current extended NMEA protocol configuration (V1) - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_NMEA; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current settings. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); - - if (enable) { - payloadCfg[3] |= (1 << 3); // Set the highPrec flag - payloadCfg[3] &= - ~((1 << 0) | (1 << 2)); // Clear the compat and limit82 flags - } else - payloadCfg[3] &= ~(1 << 3); // Clear the highPrec flag - - packetCfg.len = 20; - packetCfg.startingSpot = 0; - - return (sendCommand(&packetCfg, maxWait) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK -} - -// Log selected NMEA messages to file buffer - if the messages are enabled and -// if the file buffer exists User needs to call setFileBufferSize before .begin -void SFE_UBLOX_GNSS::setNMEALoggingMask(uint32_t messages) { - _logNMEA.all = messages; -} -uint32_t SFE_UBLOX_GNSS::getNMEALoggingMask() { return (_logNMEA.all); } - -// Pass selected NMEA messages to processNMEA -void SFE_UBLOX_GNSS::setProcessNMEAMask(uint32_t messages) { - _processNMEA.all = messages; -} -uint32_t SFE_UBLOX_GNSS::getProcessNMEAMask() { return (_processNMEA.all); } - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA -// Initiate automatic storage of NMEA GPGGA messages - -// Get the most recent GPGGA message -// Return 0 if the message has not been received from the module -// Return 1 if the data is valid but has been read before -// Return 2 if the data is valid and is fresh/unread -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGPGGA(NMEA_GGA_data_t *data) { - if (storageNMEAGPGGA == NULL) - initStorageNMEAGPGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPGGA == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGPGGA->completeCopy, - sizeof(NMEA_GGA_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGPGGA->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGPGGA->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGPGGA->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -// Enable a callback on the arrival of a GPGGA message -bool SFE_UBLOX_GNSS::setNMEAGPGGAcallback( - void (*callbackPointer)(NMEA_GGA_data_t)) { - if (storageNMEAGPGGA == NULL) - initStorageNMEAGPGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPGGA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPGGA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPGGA->callbackCopy = new NMEA_GGA_data_t; - } - - if (storageNMEAGPGGA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGPGGAcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPGGA->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGPGGAcallbackPtr( - void (*callbackPointerPtr)(NMEA_GGA_data_t *)) { - if (storageNMEAGPGGA == NULL) - initStorageNMEAGPGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPGGA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPGGA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPGGA->callbackCopy = new NMEA_GGA_data_t; - } - - if (storageNMEAGPGGA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGPGGAcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPGGA->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GPGGA messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGPGGA() { - storageNMEAGPGGA = new NMEA_GPGGA_t; // Allocate RAM for the main struct - if (storageNMEAGPGGA == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGPGGA: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPGGA->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGPGGA->workingCopy.nmea, 0, - NMEA_GGA_MAX_LENGTH); // Clear the nmea storage - storageNMEAGPGGA->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGPGGA->completeCopy.nmea, 0, - NMEA_GGA_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGPGGA->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGPGGA->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGPGGA->callbackCopy = NULL; - - storageNMEAGPGGA->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGNGGA(NMEA_GGA_data_t *data) { - if (storageNMEAGNGGA == NULL) - initStorageNMEAGNGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNGGA == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGNGGA->completeCopy, - sizeof(NMEA_GGA_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGNGGA->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGNGGA->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGNGGA->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -bool SFE_UBLOX_GNSS::setNMEAGNGGAcallback( - void (*callbackPointer)(NMEA_GGA_data_t)) { - if (storageNMEAGNGGA == NULL) - initStorageNMEAGNGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNGGA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNGGA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNGGA->callbackCopy = new NMEA_GGA_data_t; - } - - if (storageNMEAGNGGA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGNGGAcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNGGA->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGNGGAcallbackPtr( - void (*callbackPointerPtr)(NMEA_GGA_data_t *)) { - if (storageNMEAGNGGA == NULL) - initStorageNMEAGNGGA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNGGA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNGGA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNGGA->callbackCopy = new NMEA_GGA_data_t; - } - - if (storageNMEAGNGGA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGNGGAcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNGGA->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GNGGA messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGNGGA() { - storageNMEAGNGGA = new NMEA_GNGGA_t; // Allocate RAM for the main struct - if (storageNMEAGNGGA == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGNGGA: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNGGA->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGNGGA->workingCopy.nmea, 0, - NMEA_GGA_MAX_LENGTH); // Clear the nmea storage - storageNMEAGNGGA->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGNGGA->completeCopy.nmea, 0, - NMEA_GGA_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGNGGA->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGNGGA->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGNGGA->callbackCopy = NULL; - - storageNMEAGNGGA->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -// Initiate automatic storage of NMEA GPVTG messages - -// Get the most recent GPVTG message -// Return 0 if the message has not been received from the module -// Return 1 if the data is valid but has been read before -// Return 2 if the data is valid and is fresh/unread -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGPVTG(NMEA_VTG_data_t *data) { - if (storageNMEAGPVTG == NULL) - initStorageNMEAGPVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPVTG == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGPVTG->completeCopy, - sizeof(NMEA_VTG_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGPVTG->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGPVTG->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGPVTG->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -// Enable a callback on the arrival of a GPVTG message -bool SFE_UBLOX_GNSS::setNMEAGPVTGcallback( - void (*callbackPointer)(NMEA_VTG_data_t)) { - if (storageNMEAGPVTG == NULL) - initStorageNMEAGPVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPVTG == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPVTG->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPVTG->callbackCopy = new NMEA_VTG_data_t; - } - - if (storageNMEAGPVTG->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGPVTGcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPVTG->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGPVTGcallbackPtr( - void (*callbackPointerPtr)(NMEA_VTG_data_t *)) { - if (storageNMEAGPVTG == NULL) - initStorageNMEAGPVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPVTG == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPVTG->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPVTG->callbackCopy = new NMEA_VTG_data_t; - } - - if (storageNMEAGPVTG->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGPVTGcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPVTG->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GPVTG messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGPVTG() { - storageNMEAGPVTG = new NMEA_GPVTG_t; // Allocate RAM for the main struct - if (storageNMEAGPVTG == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGPVTG: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPVTG->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGPVTG->workingCopy.nmea, 0, - NMEA_VTG_MAX_LENGTH); // Clear the nmea storage - storageNMEAGPVTG->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGPVTG->completeCopy.nmea, 0, - NMEA_VTG_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGPVTG->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGPVTG->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGPVTG->callbackCopy = NULL; - - storageNMEAGPVTG->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGNVTG(NMEA_VTG_data_t *data) { - if (storageNMEAGNVTG == NULL) - initStorageNMEAGNVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNVTG == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGNVTG->completeCopy, - sizeof(NMEA_VTG_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGNVTG->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGNVTG->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGNVTG->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -bool SFE_UBLOX_GNSS::setNMEAGNVTGcallback( - void (*callbackPointer)(NMEA_VTG_data_t)) { - if (storageNMEAGNVTG == NULL) - initStorageNMEAGNVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNVTG == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNVTG->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNVTG->callbackCopy = new NMEA_VTG_data_t; - } - - if (storageNMEAGNVTG->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGNVTGcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNVTG->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGNVTGcallbackPtr( - void (*callbackPointerPtr)(NMEA_VTG_data_t *)) { - if (storageNMEAGNVTG == NULL) - initStorageNMEAGNVTG(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNVTG == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNVTG->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNVTG->callbackCopy = new NMEA_VTG_data_t; - } - - if (storageNMEAGNVTG->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGNVTGcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNVTG->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GNVTG messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGNVTG() { - storageNMEAGNVTG = new NMEA_GNVTG_t; // Allocate RAM for the main struct - if (storageNMEAGNVTG == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGNVTG: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNVTG->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGNVTG->workingCopy.nmea, 0, - NMEA_VTG_MAX_LENGTH); // Clear the nmea storage - storageNMEAGNVTG->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGNVTG->completeCopy.nmea, 0, - NMEA_VTG_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGNVTG->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGNVTG->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGNVTG->callbackCopy = NULL; - - storageNMEAGNVTG->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -// Initiate automatic storage of NMEA GPRMC messages - -// Get the most recent GPRMC message -// Return 0 if the message has not been received from the module -// Return 1 if the data is valid but has been read before -// Return 2 if the data is valid and is fresh/unread -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGPRMC(NMEA_RMC_data_t *data) { - if (storageNMEAGPRMC == NULL) - initStorageNMEAGPRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPRMC == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGPRMC->completeCopy, - sizeof(NMEA_RMC_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGPRMC->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGPRMC->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGPRMC->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -// Enable a callback on the arrival of a GPRMC message -bool SFE_UBLOX_GNSS::setNMEAGPRMCcallback( - void (*callbackPointer)(NMEA_RMC_data_t)) { - if (storageNMEAGPRMC == NULL) - initStorageNMEAGPRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPRMC == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPRMC->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPRMC->callbackCopy = new NMEA_RMC_data_t; - } - - if (storageNMEAGPRMC->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGPRMCcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPRMC->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGPRMCcallbackPtr( - void (*callbackPointerPtr)(NMEA_RMC_data_t *)) { - if (storageNMEAGPRMC == NULL) - initStorageNMEAGPRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPRMC == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPRMC->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPRMC->callbackCopy = new NMEA_RMC_data_t; - } - - if (storageNMEAGPRMC->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGPRMCcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPRMC->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GPRMC messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGPRMC() { - storageNMEAGPRMC = new NMEA_GPRMC_t; // Allocate RAM for the main struct - if (storageNMEAGPRMC == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGPRMC: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPRMC->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGPRMC->workingCopy.nmea, 0, - NMEA_RMC_MAX_LENGTH); // Clear the nmea storage - storageNMEAGPRMC->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGPRMC->completeCopy.nmea, 0, - NMEA_RMC_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGPRMC->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGPRMC->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGPRMC->callbackCopy = NULL; - - storageNMEAGPRMC->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGNRMC(NMEA_RMC_data_t *data) { - if (storageNMEAGNRMC == NULL) - initStorageNMEAGNRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNRMC == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGNRMC->completeCopy, - sizeof(NMEA_RMC_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGNRMC->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGNRMC->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGNRMC->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -bool SFE_UBLOX_GNSS::setNMEAGNRMCcallback( - void (*callbackPointer)(NMEA_RMC_data_t)) { - if (storageNMEAGNRMC == NULL) - initStorageNMEAGNRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNRMC == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNRMC->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNRMC->callbackCopy = new NMEA_RMC_data_t; - } - - if (storageNMEAGNRMC->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGNRMCcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNRMC->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGNRMCcallbackPtr( - void (*callbackPointerPtr)(NMEA_RMC_data_t *)) { - if (storageNMEAGNRMC == NULL) - initStorageNMEAGNRMC(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNRMC == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNRMC->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNRMC->callbackCopy = new NMEA_RMC_data_t; - } - - if (storageNMEAGNRMC->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGNRMCcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNRMC->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GNRMC messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGNRMC() { - storageNMEAGNRMC = new NMEA_GNRMC_t; // Allocate RAM for the main struct - if (storageNMEAGNRMC == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGNRMC: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNRMC->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGNRMC->workingCopy.nmea, 0, - NMEA_RMC_MAX_LENGTH); // Clear the nmea storage - storageNMEAGNRMC->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGNRMC->completeCopy.nmea, 0, - NMEA_RMC_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGNRMC->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGNRMC->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGNRMC->callbackCopy = NULL; - - storageNMEAGNRMC->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -// Initiate automatic storage of NMEA GPZDA messages - -// Get the most recent GPZDA message -// Return 0 if the message has not been received from the module -// Return 1 if the data is valid but has been read before -// Return 2 if the data is valid and is fresh/unread -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGPZDA(NMEA_ZDA_data_t *data) { - if (storageNMEAGPZDA == NULL) - initStorageNMEAGPZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPZDA == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGPZDA->completeCopy, - sizeof(NMEA_ZDA_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGPZDA->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGPZDA->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGPZDA->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -// Enable a callback on the arrival of a GPZDA message -bool SFE_UBLOX_GNSS::setNMEAGPZDAcallback( - void (*callbackPointer)(NMEA_ZDA_data_t)) { - if (storageNMEAGPZDA == NULL) - initStorageNMEAGPZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPZDA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPZDA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPZDA->callbackCopy = new NMEA_ZDA_data_t; - } - - if (storageNMEAGPZDA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGPZDAcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPZDA->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGPZDAcallbackPtr( - void (*callbackPointerPtr)(NMEA_ZDA_data_t *)) { - if (storageNMEAGPZDA == NULL) - initStorageNMEAGPZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGPZDA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGPZDA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGPZDA->callbackCopy = new NMEA_ZDA_data_t; - } - - if (storageNMEAGPZDA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGPZDAcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPZDA->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GPZDA messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGPZDA() { - storageNMEAGPZDA = new NMEA_GPZDA_t; // Allocate RAM for the main struct - if (storageNMEAGPZDA == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGPZDA: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGPZDA->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGPZDA->workingCopy.nmea, 0, - NMEA_ZDA_MAX_LENGTH); // Clear the nmea storage - storageNMEAGPZDA->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGPZDA->completeCopy.nmea, 0, - NMEA_ZDA_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGPZDA->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGPZDA->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGPZDA->callbackCopy = NULL; - - storageNMEAGPZDA->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} - -uint8_t SFE_UBLOX_GNSS::getLatestNMEAGNZDA(NMEA_ZDA_data_t *data) { - if (storageNMEAGNZDA == NULL) - initStorageNMEAGNZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNZDA == NULL) // Bail if the RAM allocation failed - return (false); - - checkUbloxInternal(&packetCfg, 0, - 0); // Call checkUbloxInternal to parse any incoming - // data. Use a fake UBX class and ID. - - memcpy(data, &storageNMEAGNZDA->completeCopy, - sizeof(NMEA_ZDA_data_t)); // Copy the complete copy - - uint8_t result = 0; - if (storageNMEAGNZDA->automaticFlags.flags.bits.completeCopyValid == - 1) // Is the complete copy valid? - { - result = 1; - if (storageNMEAGNZDA->automaticFlags.flags.bits.completeCopyRead == - 0) // Has the data already been read? - { - result = 2; - storageNMEAGNZDA->automaticFlags.flags.bits.completeCopyRead = - 1; // Mark the data as read - } - } - - return (result); -} - -bool SFE_UBLOX_GNSS::setNMEAGNZDAcallback( - void (*callbackPointer)(NMEA_ZDA_data_t)) { - if (storageNMEAGNZDA == NULL) - initStorageNMEAGNZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNZDA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNZDA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNZDA->callbackCopy = new NMEA_ZDA_data_t; - } - - if (storageNMEAGNZDA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setNMEAGNZDAcallback: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNZDA->callbackPointer = callbackPointer; - return (true); -} - -bool SFE_UBLOX_GNSS::setNMEAGNZDAcallbackPtr( - void (*callbackPointerPtr)(NMEA_ZDA_data_t *)) { - if (storageNMEAGNZDA == NULL) - initStorageNMEAGNZDA(); // Check that RAM has been allocated for the - // message - if (storageNMEAGNZDA == NULL) // Bail if the RAM allocation failed - return (false); - - if (storageNMEAGNZDA->callbackCopy == - NULL) // Check if RAM has been allocated for the callback copy - { - storageNMEAGNZDA->callbackCopy = new NMEA_ZDA_data_t; - } - - if (storageNMEAGNZDA->callbackCopy == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println( - F("setNMEAGNZDAcallbackPtr: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNZDA->callbackPointerPtr = callbackPointerPtr; - return (true); -} - -// Private: allocate RAM for incoming NMEA GNZDA messages and initialize it -bool SFE_UBLOX_GNSS::initStorageNMEAGNZDA() { - storageNMEAGNZDA = new NMEA_GNZDA_t; // Allocate RAM for the main struct - if (storageNMEAGNZDA == NULL) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initStorageNMEAGNZDA: RAM alloc failed!")); -#endif - return (false); - } - - storageNMEAGNZDA->workingCopy.length = 0; // Clear the data length - memset(storageNMEAGNZDA->workingCopy.nmea, 0, - NMEA_ZDA_MAX_LENGTH); // Clear the nmea storage - storageNMEAGNZDA->completeCopy.length = 0; // Clear the data length - memset(storageNMEAGNZDA->completeCopy.nmea, 0, - NMEA_ZDA_MAX_LENGTH); // Clear the nmea storage - - storageNMEAGNZDA->callbackPointer = NULL; // Clear the callback pointers - storageNMEAGNZDA->callbackPointerPtr = NULL; // Clear the callback pointers - storageNMEAGNZDA->callbackCopy = NULL; - - storageNMEAGNZDA->automaticFlags.flags.all = - 0; // Mark the data as invalid/stale and unread - - return (true); -} -#endif - -// ***** CFG RATE Helper Functions - -// Set the rate at which the module will give us an updated navigation solution -// Expects a number that is the updates per second. For example 1 = 1Hz, 2 = -// 2Hz, etc. Max is 40Hz(?!) -bool SFE_UBLOX_GNSS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait) { - if (navFreq == 0) // Return now if navFreq is zero - return (false); - - if (navFreq > 40) - navFreq = - 40; // Limit navFreq to 40Hz so i2cPollingWait is set correctly - - // Adjust the I2C polling timeout based on update rate - // Do this even if the sendCommand fails - i2cPollingWaitNAV = - 1000 / - (((int)navFreq) * 4); // This is the number of ms to wait between - // checks for new I2C data. Max is 250. Min is 6. - i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR - ? i2cPollingWaitNAV - : i2cPollingWaitHNR; // Set i2cPollingWait to the - // lower of NAV and HNR - - // Query the module - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RATE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // This will load the payloadCfg array with current settings of the given - // register - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); // If command send fails then bail - - uint16_t measurementRate = 1000 / navFreq; - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[0] = measurementRate & 0xFF; // measRate LSB - payloadCfg[1] = measurementRate >> 8; // measRate MSB - - bool result = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - - flushCFGRATE(); // Mark the polled measurement and navigation rate data as - // stale - - return (result); -} - -// Get the rate at which the module is outputting nav solutions -uint8_t SFE_UBLOX_GNSS::getNavigationFrequency(uint16_t maxWait) { - if (packetUBXCFGRATE == NULL) - initPacketUBXCFGRATE(); // Check that RAM has been allocated for the - // RATE data - if (packetUBXCFGRATE == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXCFGRATE->moduleQueried.moduleQueried.bits.measRate == false) - getNavigationFrequencyInternal(maxWait); - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.measRate = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.all = false; - - uint16_t measurementRate = packetUBXCFGRATE->data.measRate; - - if (measurementRate == 0) { -#ifndef SFE_UBLOX_REDUCED_PROG_MEM - if ((_printDebug == true) || - (_printLimitedDebug == - true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("getNavigationFrequency: zero measRate!")); -#endif - return (0); // Avoid divide-by-zero error - } - - measurementRate = - 1000 / measurementRate; // This may return an int when it's a float, - // but I'd rather not return 4 bytes - return (measurementRate); -} - -// Set the elapsed time between GNSS measurements in milliseconds, which defines -// the rate -bool SFE_UBLOX_GNSS::setMeasurementRate(uint16_t rate, uint16_t maxWait) { - if (rate < - 25) // "Measurement rate should be greater than or equal to 25 ms." - rate = 25; - - // Adjust the I2C polling timeout based on update rate - if (rate >= 1000) - i2cPollingWaitNAV = 250; - else - i2cPollingWaitNAV = rate / 4; // This is the number of ms to wait - // between checks for new I2C data - i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR - ? i2cPollingWaitNAV - : i2cPollingWaitHNR; // Set i2cPollingWait to the - // lower of NAV and HNR - - // Query the module - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RATE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // This will load the payloadCfg array with current settings of the given - // register - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); // If command send fails then bail - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[0] = rate & 0xFF; // measRate LSB - payloadCfg[1] = rate >> 8; // measRate MSB - - bool result = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - - flushCFGRATE(); // Mark the polled measurement and navigation rate data as - // stale - - return (result); -} - -// Return the elapsed time between GNSS measurements in milliseconds, which -// defines the rate -uint16_t SFE_UBLOX_GNSS::getMeasurementRate(uint16_t maxWait) { - if (packetUBXCFGRATE == NULL) - initPacketUBXCFGRATE(); // Check that RAM has been allocated for the - // RATE data - if (packetUBXCFGRATE == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXCFGRATE->moduleQueried.moduleQueried.bits.measRate == false) - getNavigationFrequencyInternal(maxWait); - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.measRate = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXCFGRATE->data.measRate); -} - -// Set the ratio between the number of measurements and the number of navigation -// solutions. Unit is cycles. Max is 127. -bool SFE_UBLOX_GNSS::setNavigationRate(uint16_t rate, uint16_t maxWait) { - // Query the module - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_RATE; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // This will load the payloadCfg array with current settings of the given - // register - if (sendCommand(&packetCfg, maxWait) != - SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK - return (false); // If command send fails then bail - - // payloadCfg is now loaded with current bytes. Change only the ones we need - // to - payloadCfg[2] = rate & 0xFF; // navRate LSB - payloadCfg[3] = rate >> 8; // navRate MSB - - bool result = ((sendCommand(&packetCfg, maxWait)) == - SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK - - flushCFGRATE(); // Mark the polled measurement and navigation rate data as - // stale - - return (result); -} - -// Return the ratio between the number of measurements and the number of -// navigation solutions. Unit is cycles -uint16_t SFE_UBLOX_GNSS::getNavigationRate(uint16_t maxWait) { - if (packetUBXCFGRATE == NULL) - initPacketUBXCFGRATE(); // Check that RAM has been allocated for the - // RATE data - if (packetUBXCFGRATE == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXCFGRATE->moduleQueried.moduleQueried.bits.navRate == false) - getNavigationFrequencyInternal(maxWait); - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.navRate = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXCFGRATE->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXCFGRATE->data.navRate); -} - -// Mark the CFG RATE data as read/stale -void SFE_UBLOX_GNSS::flushCFGRATE() { - if (packetUBXCFGRATE == NULL) - return; // Bail if RAM has not been allocated (otherwise we could be - // writing anywhere!) - packetUBXCFGRATE->moduleQueried.moduleQueried.all = - 0; // Mark all datums as stale (read before) -} - -// ***** DOP Helper Functions - -uint16_t SFE_UBLOX_GNSS::getGeometricDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.gDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.gDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.gDOP); -} - -uint16_t SFE_UBLOX_GNSS::getPositionDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.pDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.pDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.pDOP); -} - -uint16_t SFE_UBLOX_GNSS::getTimeDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.tDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.tDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.tDOP); -} - -uint16_t SFE_UBLOX_GNSS::getVerticalDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.vDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.vDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.vDOP); -} - -uint16_t SFE_UBLOX_GNSS::getHorizontalDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.hDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.hDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.hDOP); -} - -uint16_t SFE_UBLOX_GNSS::getNorthingDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.nDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.nDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.nDOP); -} - -uint16_t SFE_UBLOX_GNSS::getEastingDOP(uint16_t maxWait) { - if (packetUBXNAVDOP == NULL) - initPacketUBXNAVDOP(); // Check that RAM has been allocated for the DOP - // data - if (packetUBXNAVDOP == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVDOP->moduleQueried.moduleQueried.bits.eDOP == false) - getDOP(maxWait); - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.eDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVDOP->data.eDOP); -} - -// ***** ATT Helper Functions - -float SFE_UBLOX_GNSS::getATTroll(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the NAV - // ATT data - if (packetUBXNAVATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXNAVATT->moduleQueried.moduleQueried.bits.roll == false) - getNAVATT(maxWait); - packetUBXNAVATT->moduleQueried.moduleQueried.bits.roll = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVATT->data.roll) / - 100000.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getATTpitch(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the NAV - // ATT data - if (packetUBXNAVATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXNAVATT->moduleQueried.moduleQueried.bits.pitch == false) - getNAVATT(maxWait); - packetUBXNAVATT->moduleQueried.moduleQueried.bits.pitch = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVATT->data.pitch) / - 100000.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getATTheading(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXNAVATT == NULL) - initPacketUBXNAVATT(); // Check that RAM has been allocated for the NAV - // ATT data - if (packetUBXNAVATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXNAVATT->moduleQueried.moduleQueried.bits.heading == false) - getNAVATT(maxWait); - packetUBXNAVATT->moduleQueried.moduleQueried.bits.heading = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVATT->data.heading) / - 100000.0); // Convert to degrees -} - -// ***** PVT Helper Functions - -uint32_t SFE_UBLOX_GNSS::getTimeOfWeek(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.iTOW == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.iTOW = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.iTOW); -} - -// Get the current year -uint16_t SFE_UBLOX_GNSS::getYear(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.year); -} - -// Get the current month -uint8_t SFE_UBLOX_GNSS::getMonth(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.month); -} - -// Get the current day -uint8_t SFE_UBLOX_GNSS::getDay(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.day); -} - -// Get the current hour -uint8_t SFE_UBLOX_GNSS::getHour(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hour == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hour = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.hour); -} - -// Get the current minute -uint8_t SFE_UBLOX_GNSS::getMinute(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.min); -} - -// Get the current second -uint8_t SFE_UBLOX_GNSS::getSecond(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.sec); -} - -// Get the current millisecond -uint16_t SFE_UBLOX_GNSS::getMillisecond(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.iTOW == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.iTOW = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.iTOW % 1000); -} - -// Get the current nanoseconds - includes milliseconds -int32_t SFE_UBLOX_GNSS::getNanosecond(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.nano); -} - -// Get the current Unix epoch time rounded to the nearest second -uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hour = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from - // Jan 1st 1970 - t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - - 2020]; // Add on the number of - // days since 2020 - t += (uint32_t) - SFE_UBLOX_DAYS_SINCE_MONTH[packetUBXNAVPVT->data.year % 4 == 0 ? 0 : 1] - [packetUBXNAVPVT->data.month - - 1]; // Add on the number of days since Jan - // 1st - t += (uint32_t)packetUBXNAVPVT->data.day - - 1; // Add on the number of days since the 1st of the month - t *= 24; // Convert to hours - t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour - t *= 60; // Convert to minutes - t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute - t *= 60; // Convert to seconds - t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second - return t; -} - -// Get the current Unix epoch including microseconds -uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint32_t µsecond, uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hour = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano = false; - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from - // Jan 1st 1970 - t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - - 2020]; // Add on the number of - // days since 2020 - t += (uint32_t) - SFE_UBLOX_DAYS_SINCE_MONTH[packetUBXNAVPVT->data.year % 4 == 0 ? 0 : 1] - [packetUBXNAVPVT->data.month - - 1]; // Add on the number of days since Jan - // 1st - t += (uint32_t)packetUBXNAVPVT->data.day - - 1; // Add on the number of days since the 1st of the month - t *= 24; // Convert to hours - t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour - t *= 60; // Convert to minutes - t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute - t *= 60; // Convert to seconds - t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second - int32_t us = packetUBXNAVPVT->data.nano / 1000; // Convert nanos to micros - microsecond = (uint32_t)us; // Could be -ve! - // Adjust t if nano is negative - if (us < 0) { - microsecond = (uint32_t)(us + 1000000); // Make nano +ve - t--; // Decrement t by 1 second - } - return t; -} - -// Get the current date validity -bool SFE_UBLOX_GNSS::getDateValid(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.validDate == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.validDate = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.valid.bits.validDate); -} - -// Get the current time validity -bool SFE_UBLOX_GNSS::getTimeValid(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.validTime == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.validTime = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.valid.bits.validTime); -} - -// Check to see if the UTC time has been fully resolved -bool SFE_UBLOX_GNSS::getTimeFullyResolved(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.fullyResolved == - false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.fullyResolved = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.valid.bits.fullyResolved); -} - -// Get the confirmed date validity -bool SFE_UBLOX_GNSS::getConfirmedDate(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedDate == - false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedDate = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.flags2.bits.confirmedDate); -} - -// Get the confirmed time validity -bool SFE_UBLOX_GNSS::getConfirmedTime(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedTime == - false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedTime = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.flags2.bits.confirmedTime); -} - -// Get the current fix type -// 0=no fix, 1=dead reckoning, 2=2D, 3=3D, 4=GNSS, 5=Time fix -uint8_t SFE_UBLOX_GNSS::getFixType(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.fixType == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.fixType = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.fixType); -} - -// Get whether we have a valid fix (i.e within DOP & accuracy masks) -bool SFE_UBLOX_GNSS::getGnssFixOk(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.gnssFixOK == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.gnssFixOK = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.flags.bits.gnssFixOK); -} - -// Get whether differential corrections were applied -bool SFE_UBLOX_GNSS::getDiffSoln(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.diffSoln == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.diffSoln = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.flags.bits.diffSoln); -} - -// Get power save mode from NAV-PVT -bool SFE_UBLOX_GNSS::getNAVPVTPSMMode(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.psmState == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.psmState = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.flags.bits.psmState); -} - -// Get whether head vehicle valid or not -bool SFE_UBLOX_GNSS::getHeadVehValid(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.headVehValid == - false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.headVehValid = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.flags.bits.headVehValid); -} - -// Get the carrier phase range solution status -// Useful when querying module to see if it has high-precision RTK fix -// 0=No solution, 1=Float solution, 2=Fixed solution -uint8_t SFE_UBLOX_GNSS::getCarrierSolutionType(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.carrSoln == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.carrSoln = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.flags.bits.carrSoln); -} - -// Get the number of satellites used in fix -uint8_t SFE_UBLOX_GNSS::getSIV(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.numSV == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.numSV = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.numSV); -} - -// Get the current longitude in degrees -// Returns a long representing the number of degrees *10^-7 -int32_t SFE_UBLOX_GNSS::getLongitude(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.lon == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.lon = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.lon); -} - -// Get the current latitude in degrees -// Returns a long representing the number of degrees *10^-7 -int32_t SFE_UBLOX_GNSS::getLatitude(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.lat == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.lat = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.lat); -} - -// Get the current altitude in mm according to ellipsoid model -int32_t SFE_UBLOX_GNSS::getAltitude(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.height == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.height = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.height); -} - -// Get the current altitude in mm according to mean sea level -// Ellipsoid model: https://www.esri.com/news/arcuser/0703/geoid1of3.html -// Difference between Ellipsoid Model and Mean Sea Level: -// https://eos-gnss.com/elevation-for-beginners/ Also see: -// https://portal.u-blox.com/s/question/0D52p00008HKDSkCAP/what-geoid-model-is-used-and-where-is-this-calculated -// and: https://cddis.nasa.gov/926/egm96/egm96.html on 10x10 degree grid -int32_t SFE_UBLOX_GNSS::getAltitudeMSL(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hMSL == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hMSL = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.hMSL); -} - -int32_t SFE_UBLOX_GNSS::getHorizontalAccEst(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hAcc == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.hAcc); -} - -int32_t SFE_UBLOX_GNSS::getVerticalAccEst(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.vAcc == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.vAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.vAcc); -} - -int32_t SFE_UBLOX_GNSS::getNedNorthVel(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.velN == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.velN = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.velN); -} - -int32_t SFE_UBLOX_GNSS::getNedEastVel(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.velE == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.velE = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.velE); -} - -int32_t SFE_UBLOX_GNSS::getNedDownVel(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.velD == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.velD = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.velD); -} - -// Get the ground speed in mm/s -int32_t SFE_UBLOX_GNSS::getGroundSpeed(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.gSpeed == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.gSpeed = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.gSpeed); -} - -// Get the heading of motion (as opposed to heading of car) in degrees * 10^-5 -int32_t SFE_UBLOX_GNSS::getHeading(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headMot == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headMot = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.headMot); -} - -uint32_t SFE_UBLOX_GNSS::getSpeedAccEst(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.sAcc == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.sAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.sAcc); -} - -uint32_t SFE_UBLOX_GNSS::getHeadingAccEst(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headAcc == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.headAcc); -} - -// Get the positional dillution of precision * 10^-2 (dimensionless) -uint16_t SFE_UBLOX_GNSS::getPDOP(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.pDOP == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.pDOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.pDOP); -} - -bool SFE_UBLOX_GNSS::getInvalidLlh(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return (false); - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.invalidLlh == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.invalidLlh = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return ((bool)packetUBXNAVPVT->data.flags3.bits.invalidLlh); -} - -int32_t SFE_UBLOX_GNSS::getHeadVeh(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headVeh == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.headVeh = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.headVeh); -} - -int16_t SFE_UBLOX_GNSS::getMagDec(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.magDec == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.magDec = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.magDec); -} - -uint16_t SFE_UBLOX_GNSS::getMagAcc(uint16_t maxWait) { - if (packetUBXNAVPVT == NULL) - initPacketUBXNAVPVT(); // Check that RAM has been allocated for the PVT - // data - if (packetUBXNAVPVT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.magAcc == false) - getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried2.bits.magAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVT->data.magAcc); -} - -// getGeoidSeparation is currently redundant. The geoid separation seems to only -// be provided in NMEA GGA and GNS messages. -int32_t SFE_UBLOX_GNSS::getGeoidSeparation(uint16_t maxWait) { - (void)maxWait; // Do something with maxWait just to get rid of the pesky - // compiler warning - - return (0); -} - -// ***** HPPOSECEF Helper Functions - -// Get the current 3D high precision positional accuracy - a fun thing to watch -// Returns a long representing the 3D accuracy in millimeters -uint32_t SFE_UBLOX_GNSS::getPositionAccuracy(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.pAcc == false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.pAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - uint32_t tempAccuracy = packetUBXNAVHPPOSECEF->data.pAcc; - - if ((tempAccuracy % 10) >= 5) - tempAccuracy += 5; // Round fraction of mm up to next mm if .5 or above - tempAccuracy /= 10; // Convert 0.1mm units to mm - - return (tempAccuracy); -} - -// Get the current 3D high precision X coordinate -// Returns a long representing the coordinate in cm -int32_t SFE_UBLOX_GNSS::getHighResECEFX(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefX == false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefX = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefX); -} - -// Get the current 3D high precision Y coordinate -// Returns a long representing the coordinate in cm -int32_t SFE_UBLOX_GNSS::getHighResECEFY(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefY == false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefY = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefY); -} - -// Get the current 3D high precision Z coordinate -// Returns a long representing the coordinate in cm -int32_t SFE_UBLOX_GNSS::getHighResECEFZ(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZ == false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZ = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefZ); -} - -// Get the high precision component of the ECEF X coordinate -// Returns a signed byte representing the component as 0.1*mm -int8_t SFE_UBLOX_GNSS::getHighResECEFXHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefXHp == - false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefXHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefXHp); -} - -// Get the high precision component of the ECEF Y coordinate -// Returns a signed byte representing the component as 0.1*mm -int8_t SFE_UBLOX_GNSS::getHighResECEFYHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefYHp == - false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefYHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefYHp); -} - -// Get the high precision component of the ECEF Z coordinate -// Returns a signed byte representing the component as 0.1*mm -int8_t SFE_UBLOX_GNSS::getHighResECEFZHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSECEF == NULL) - initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for - // the HPPOSECEF data - if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZHp == - false) - getNAVHPPOSECEF(maxWait); - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVHPPOSECEF->data.ecefZHp); -} - -// ***** HPPOSLLH Helper Functions - -uint32_t SFE_UBLOX_GNSS::getTimeOfWeekFromHPPOSLLH(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.iTOW == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.iTOW = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.iTOW); -} - -int32_t SFE_UBLOX_GNSS::getHighResLongitude(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lon == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lon = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.lon); -} - -int32_t SFE_UBLOX_GNSS::getHighResLatitude(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lat == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lat = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.lat); -} - -int32_t SFE_UBLOX_GNSS::getElipsoid(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.height == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.height = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.height); -} - -int32_t SFE_UBLOX_GNSS::getMeanSeaLevel(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hMSL == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hMSL = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.hMSL); -} - -int8_t SFE_UBLOX_GNSS::getHighResLongitudeHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lonHp == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.lonHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.lonHp); -} - -int8_t SFE_UBLOX_GNSS::getHighResLatitudeHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.latHp == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.latHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.latHp); -} - -int8_t SFE_UBLOX_GNSS::getElipsoidHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.heightHp == - false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.heightHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.heightHp); -} - -int8_t SFE_UBLOX_GNSS::getMeanSeaLevelHp(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hMSLHp == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hMSLHp = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.hMSLHp); -} - -uint32_t SFE_UBLOX_GNSS::getHorizontalAccuracy(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hAcc == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.hAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.hAcc); -} - -uint32_t SFE_UBLOX_GNSS::getVerticalAccuracy(uint16_t maxWait) { - if (packetUBXNAVHPPOSLLH == NULL) - initPacketUBXNAVHPPOSLLH(); // Check that RAM has been allocated for - // the HPPOSLLH data - if (packetUBXNAVHPPOSLLH == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.vAcc == false) - getHPPOSLLH(maxWait); - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.vAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVHPPOSLLH->data.vAcc); -} - -// ***** PVAT Helper Functions - -int32_t SFE_UBLOX_GNSS::getVehicleRoll(uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehRoll == false) - getNAVPVAT(maxWait); - packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehRoll = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVAT->data.vehRoll); -} - -int32_t SFE_UBLOX_GNSS::getVehiclePitch(uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehPitch == false) - getNAVPVAT(maxWait); - packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehPitch = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVAT->data.vehPitch); -} - -int32_t SFE_UBLOX_GNSS::getVehicleHeading(uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehHeading == false) - getNAVPVAT(maxWait); - packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.vehHeading = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVAT->data.vehHeading); -} - -int32_t SFE_UBLOX_GNSS::getMotionHeading(uint16_t maxWait) { - if (packetUBXNAVPVAT == NULL) - initPacketUBXNAVPVAT(); // Check that RAM has been allocated for the - // PVAT data - if (packetUBXNAVPVAT == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.motHeading == false) - getNAVPVAT(maxWait); - packetUBXNAVPVAT->moduleQueried.moduleQueried2.bits.motHeading = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVPVAT->moduleQueried.moduleQueried1.bits.all = false; - return (packetUBXNAVPVAT->data.motHeading); -} - -// ***** SVIN Helper Functions - -bool SFE_UBLOX_GNSS::getSurveyInActive(uint16_t maxWait) { - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed - return false; - - if (packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.active == false) - getSurveyStatus(maxWait); - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.active = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; - return ((bool)packetUBXNAVSVIN->data.active); -} - -bool SFE_UBLOX_GNSS::getSurveyInValid(uint16_t maxWait) { - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed - return false; - - if (packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.valid == false) - getSurveyStatus(maxWait); - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.valid = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; - return ((bool)packetUBXNAVSVIN->data.valid); -} - -uint32_t SFE_UBLOX_GNSS::getSurveyInObservationTimeFull( - uint16_t maxWait) // Return the full uint32_t -{ - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.dur == false) - getSurveyStatus(maxWait); - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.dur = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; - - return (packetUBXNAVSVIN->data.dur); -} - -uint16_t SFE_UBLOX_GNSS::getSurveyInObservationTime( - uint16_t maxWait) // Truncated to 65535 seconds -{ - // dur (Passed survey-in observation time) is U4 (uint32_t) seconds. Here we - // truncate to 16 bits - uint32_t tmpObsTime = getSurveyInObservationTimeFull(maxWait); - if (tmpObsTime <= 0xFFFF) { - return ((uint16_t)tmpObsTime); - } else { - return (0xFFFF); - } -} - -float SFE_UBLOX_GNSS::getSurveyInMeanAccuracy( - uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVSVIN == NULL) - initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the - // SVIN data - if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.meanAcc == false) - getSurveyStatus(maxWait); - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.meanAcc = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; - - // meanAcc is U4 (uint32_t) in 0.1mm. We convert this to float. - uint32_t tempFloat = packetUBXNAVSVIN->data.meanAcc; - return (((float)tempFloat) / 10000.0); // Convert 0.1mm to m -} - -// ***** TIMELS Helper Functions - -uint8_t SFE_UBLOX_GNSS::getLeapIndicator(int32_t &timeToLsEvent, - uint16_t maxWait) { - if (packetUBXNAVTIMELS == NULL) - initPacketUBXNAVTIMELS(); // Check that RAM has been allocated for the - // TIMELS data - if (packetUBXNAVTIMELS == NULL) // Bail if the RAM allocation failed - return 3; - - if (packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits - .validTimeToLsEvent == false) - getLeapSecondEvent(maxWait); - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validTimeToLsEvent = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.lsChange = false; - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.timeToLsEvent = false; - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.all = false; - timeToLsEvent = packetUBXNAVTIMELS->data.timeToLsEvent; - // returns NTP Leap Indicator - // 0 -no warning - // 1 -last minute of the day has 61 seconds - // 2 -last minute of the day has 59 seconds - // 3 -unknown (clock unsynchronized) - return ((bool)packetUBXNAVTIMELS->data.valid.bits.validTimeToLsEvent - ? (uint8_t)(packetUBXNAVTIMELS->data.lsChange == -1 - ? 2 - : packetUBXNAVTIMELS->data.lsChange) - : 3); -} - -int8_t SFE_UBLOX_GNSS::getCurrentLeapSeconds(sfe_ublox_ls_src_e &source, - uint16_t maxWait) { - if (packetUBXNAVTIMELS == NULL) - initPacketUBXNAVTIMELS(); // Check that RAM has been allocated for the - // TIMELS data - if (packetUBXNAVTIMELS == NULL) // Bail if the RAM allocation failed - return false; - - if (packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validCurrLs == - false) - getLeapSecondEvent(maxWait); - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validCurrLs = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.srcOfCurrLs = false; - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.currLs = false; - packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.all = false; - source = ((sfe_ublox_ls_src_e)packetUBXNAVTIMELS->data.srcOfCurrLs); - return ((int8_t)packetUBXNAVTIMELS->data.currLs); -} - -// ***** RELPOSNED Helper Functions and automatic support - -float SFE_UBLOX_GNSS::getRelPosN(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosN == - false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosN = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.relPosN) / - 100.0); // Convert to m -} - -float SFE_UBLOX_GNSS::getRelPosE(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosE == - false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosE = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.relPosE) / - 100.0); // Convert to m -} - -float SFE_UBLOX_GNSS::getRelPosD(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosD == - false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.relPosD = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.relPosD) / - 100.0); // Convert to m -} - -float SFE_UBLOX_GNSS::getRelPosAccN(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accN == false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accN = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.accN) / - 10000.0); // Convert to m -} - -float SFE_UBLOX_GNSS::getRelPosAccE(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accE == false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accE = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.accE) / - 10000.0); // Convert to m -} - -float SFE_UBLOX_GNSS::getRelPosAccD(uint16_t maxWait) // Returned as m -{ - if (packetUBXNAVRELPOSNED == NULL) - initPacketUBXNAVRELPOSNED(); // Check that RAM has been allocated for - // the RELPOSNED data - if (packetUBXNAVRELPOSNED == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accD == false) - getRELPOSNED(maxWait); - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.accD = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXNAVRELPOSNED->data.accD) / - 10000.0); // Convert to m -} - -// ***** AOPSTATUS Helper Functions - -uint8_t SFE_UBLOX_GNSS::getAOPSTATUSuseAOP(uint16_t maxWait) { - if (packetUBXNAVAOPSTATUS == NULL) - initPacketUBXNAVAOPSTATUS(); // Check that RAM has been allocated for - // the AOPSTATUS data - if (packetUBXNAVAOPSTATUS == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.useAOP == false) - getAOPSTATUS(maxWait); - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.useAOP = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVAOPSTATUS->data.aopCfg.bits.useAOP); -} - -uint8_t SFE_UBLOX_GNSS::getAOPSTATUSstatus(uint16_t maxWait) { - if (packetUBXNAVAOPSTATUS == NULL) - initPacketUBXNAVAOPSTATUS(); // Check that RAM has been allocated for - // the AOPSTATUS data - if (packetUBXNAVAOPSTATUS == NULL) // Bail if the RAM allocation failed - return 0; - - if (packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.status == false) - getAOPSTATUS(maxWait); - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.status = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXNAVAOPSTATUS->moduleQueried.moduleQueried.bits.all = false; - return (packetUBXNAVAOPSTATUS->data.status); -} - -// ***** ESF Helper Functions - -float SFE_UBLOX_GNSS::getESFroll(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the ESF - // ALG data - if (packetUBXESFALG == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXESFALG->moduleQueried.moduleQueried.bits.roll == false) - getESFALG(maxWait); - packetUBXESFALG->moduleQueried.moduleQueried.bits.roll = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXESFALG->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXESFALG->data.roll) / 100.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getESFpitch(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the ESF - // ALG data - if (packetUBXESFALG == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXESFALG->moduleQueried.moduleQueried.bits.pitch == false) - getESFALG(maxWait); - packetUBXESFALG->moduleQueried.moduleQueried.bits.pitch = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXESFALG->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXESFALG->data.pitch) / - 100.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getESFyaw(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXESFALG == NULL) - initPacketUBXESFALG(); // Check that RAM has been allocated for the ESF - // ALG data - if (packetUBXESFALG == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXESFALG->moduleQueried.moduleQueried.bits.yaw == false) - getESFALG(maxWait); - packetUBXESFALG->moduleQueried.moduleQueried.bits.yaw = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXESFALG->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXESFALG->data.yaw) / 100.0); // Convert to degrees -} - -bool SFE_UBLOX_GNSS::getSensorFusionMeasurement( - UBX_ESF_MEAS_sensorData_t *sensorData, UBX_ESF_MEAS_data_t ubxDataStruct, - uint8_t sensor) { - sensorData->data.all = ubxDataStruct.data[sensor].data.all; - return (true); -} - -bool SFE_UBLOX_GNSS::getRawSensorMeasurement( - UBX_ESF_RAW_sensorData_t *sensorData, UBX_ESF_RAW_data_t ubxDataStruct, - uint8_t sensor) { - sensorData->data.all = ubxDataStruct.data[sensor].data.all; - sensorData->sTag = ubxDataStruct.data[sensor].sTag; - return (true); -} - -bool SFE_UBLOX_GNSS::getSensorFusionStatus( - UBX_ESF_STATUS_sensorStatus_t *sensorStatus, uint8_t sensor, - uint16_t maxWait) { - if (packetUBXESFSTATUS == NULL) - initPacketUBXESFSTATUS(); // Check that RAM has been allocated for the - // ESF STATUS data - if (packetUBXESFSTATUS == NULL) // Bail if the RAM allocation failed - return (false); - - if ((packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.status & - (1 << sensor)) == 0) - getESFSTATUS(maxWait); - packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.status &= - ~(1 << sensor); // Since we are about to give this to user, mark this - // data as stale - packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.all = false; - sensorStatus->sensStatus1.all = - packetUBXESFSTATUS->data.status[sensor].sensStatus1.all; - sensorStatus->sensStatus2.all = - packetUBXESFSTATUS->data.status[sensor].sensStatus2.all; - sensorStatus->freq = packetUBXESFSTATUS->data.status[sensor].freq; - sensorStatus->faults.all = - packetUBXESFSTATUS->data.status[sensor].faults.all; - return (true); -} - -bool SFE_UBLOX_GNSS::getSensorFusionStatus( - UBX_ESF_STATUS_sensorStatus_t *sensorStatus, - UBX_ESF_STATUS_data_t ubxDataStruct, uint8_t sensor) { - sensorStatus->sensStatus1.all = - ubxDataStruct.status[sensor].sensStatus1.all; - sensorStatus->sensStatus2.all = - ubxDataStruct.status[sensor].sensStatus2.all; - sensorStatus->freq = ubxDataStruct.status[sensor].freq; - sensorStatus->faults.all = ubxDataStruct.status[sensor].faults.all; - return (true); -} - -// ***** HNR Helper Functions - -// Set the High Navigation Rate -// Returns true if the setHNRNavigationRate is successful -bool SFE_UBLOX_GNSS::setHNRNavigationRate(uint8_t rate, uint16_t maxWait) { - if (rate == 0) // Return now if rate is zero - return (false); - - if (rate > 40) - rate = 40; // Limit rate to 40Hz so i2cPollingWait is set correctly - - // Adjust the I2C polling timeout based on update rate - // Do this even if the sendCommand is not ACK'd - i2cPollingWaitHNR = - 1000 / (((int)rate) * 4); // This is the number of ms to wait between - // checks for new I2C data. Max 250. Min 6. - i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR - ? i2cPollingWaitNAV - : i2cPollingWaitHNR; // Set i2cPollingWait to the - // lower of NAV and HNR - - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_HNR; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current HNR settings. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (false); - - // Load the new navigation rate into payloadCfg - payloadCfg[0] = rate; - - // Update the navigation rate - sfe_ublox_status_e result = - sendCommand(&packetCfg, maxWait); // We are only expecting an ACK - - return (result == SFE_UBLOX_STATUS_DATA_SENT); -} - -// Get the High Navigation Rate -// Returns 0 if the getHNRNavigationRate fails -uint8_t SFE_UBLOX_GNSS::getHNRNavigationRate(uint16_t maxWait) { - packetCfg.cls = UBX_CLASS_CFG; - packetCfg.id = UBX_CFG_HNR; - packetCfg.len = 0; - packetCfg.startingSpot = 0; - - // Ask module for the current HNR settings. Loads into payloadCfg. - if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) - return (0); - - // Return the navigation rate - return (payloadCfg[0]); -} - -float SFE_UBLOX_GNSS::getHNRroll(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the HNR - // ATT data - if (packetUBXHNRATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXHNRATT->moduleQueried.moduleQueried.bits.roll == false) - getHNRATT(maxWait); - packetUBXHNRATT->moduleQueried.moduleQueried.bits.roll = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXHNRATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXHNRATT->data.roll) / - 100000.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getHNRpitch(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the HNR - // ATT data - if (packetUBXHNRATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXHNRATT->moduleQueried.moduleQueried.bits.pitch == false) - getHNRATT(maxWait); - packetUBXHNRATT->moduleQueried.moduleQueried.bits.pitch = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXHNRATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXHNRATT->data.pitch) / - 100000.0); // Convert to degrees -} - -float SFE_UBLOX_GNSS::getHNRheading(uint16_t maxWait) // Returned as degrees -{ - if (packetUBXHNRATT == NULL) - initPacketUBXHNRATT(); // Check that RAM has been allocated for the HNR - // ATT data - if (packetUBXHNRATT == NULL) // Bail if the RAM allocation failed - return (0); - - if (packetUBXHNRATT->moduleQueried.moduleQueried.bits.heading == false) - getHNRATT(maxWait); - packetUBXHNRATT->moduleQueried.moduleQueried.bits.heading = - false; // Since we are about to give this to user, mark this data as - // stale - packetUBXHNRATT->moduleQueried.moduleQueried.bits.all = false; - return (((float)packetUBXHNRATT->data.heading) / - 100000.0); // Convert to degrees -} - -// Functions to extract signed and unsigned 8/16/32-bit data from a ubxPacket -// From v2.0: These are public. The user can call these to extract data from -// custom packets - -// Given a spot in the payload array, extract eight bytes and build a uint64_t -uint64_t SFE_UBLOX_GNSS::extractLongLong(ubxPacket *msg, uint16_t spotToStart) { - uint64_t val = 0; - val |= (uint64_t)msg->payload[spotToStart + 0] << 8 * 0; - val |= (uint64_t)msg->payload[spotToStart + 1] << 8 * 1; - val |= (uint64_t)msg->payload[spotToStart + 2] << 8 * 2; - val |= (uint64_t)msg->payload[spotToStart + 3] << 8 * 3; - val |= (uint64_t)msg->payload[spotToStart + 4] << 8 * 4; - val |= (uint64_t)msg->payload[spotToStart + 5] << 8 * 5; - val |= (uint64_t)msg->payload[spotToStart + 6] << 8 * 6; - val |= (uint64_t)msg->payload[spotToStart + 7] << 8 * 7; - return (val); -} - -// Given a spot in the payload array, extract four bytes and build a long -uint32_t SFE_UBLOX_GNSS::extractLong(ubxPacket *msg, uint16_t spotToStart) { - uint32_t val = 0; - val |= (uint32_t)msg->payload[spotToStart + 0] << 8 * 0; - val |= (uint32_t)msg->payload[spotToStart + 1] << 8 * 1; - val |= (uint32_t)msg->payload[spotToStart + 2] << 8 * 2; - val |= (uint32_t)msg->payload[spotToStart + 3] << 8 * 3; - return (val); -} - -// Just so there is no ambiguity about whether a uint32_t will cast to a int32_t -// correctly... -int32_t SFE_UBLOX_GNSS::extractSignedLong(ubxPacket *msg, - uint16_t spotToStart) { - union // Use a union to convert from uint32_t to int32_t - { - uint32_t unsignedLong; - int32_t signedLong; - } unsignedSigned; - - unsignedSigned.unsignedLong = extractLong(msg, spotToStart); - return (unsignedSigned.signedLong); -} - -// Given a spot in the payload array, extract two bytes and build an int -uint16_t SFE_UBLOX_GNSS::extractInt(ubxPacket *msg, uint16_t spotToStart) { - uint16_t val = 0; - val |= (uint16_t)msg->payload[spotToStart + 0] << 8 * 0; - val |= (uint16_t)msg->payload[spotToStart + 1] << 8 * 1; - return (val); -} - -// Just so there is no ambiguity about whether a uint16_t will cast to a int16_t -// correctly... -int16_t SFE_UBLOX_GNSS::extractSignedInt(ubxPacket *msg, uint16_t spotToStart) { - union // Use a union to convert from uint16_t to int16_t - { - uint16_t unsignedInt; - int16_t signedInt; - } stSignedInt; - - stSignedInt.unsignedInt = extractInt(msg, spotToStart); - return (stSignedInt.signedInt); -} - -// Given a spot, extract a byte from the payload -uint8_t SFE_UBLOX_GNSS::extractByte(ubxPacket *msg, uint16_t spotToStart) { - return (msg->payload[spotToStart]); -} - -// Given a spot, extract a signed 8-bit value from the payload -int8_t SFE_UBLOX_GNSS::extractSignedChar(ubxPacket *msg, uint16_t spotToStart) { - union // Use a union to convert from uint8_t to int8_t - { - uint8_t unsignedByte; - int8_t signedByte; - } stSignedByte; - - stSignedByte.unsignedByte = extractByte(msg, spotToStart); - return (stSignedByte.signedByte); -} diff --git a/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.h b/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.h deleted file mode 100644 index 39c13c40..00000000 --- a/Code/BITS/BITSv5/test/SparkFun_u-blox_GNSS_Arduino_Library.h +++ /dev/null @@ -1,3731 +0,0 @@ -/* - This is a library written for the u-blox ZED-F9P and NEO-M8P-2 - SparkFun sells these at its website: www.sparkfun.com - Do you like this library? Help support SparkFun. Buy a board! - https://www.sparkfun.com/products/16481 - https://www.sparkfun.com/products/15136 - https://www.sparkfun.com/products/15005 - https://www.sparkfun.com/products/15733 - https://www.sparkfun.com/products/15193 - https://www.sparkfun.com/products/15210 - - Original version by Nathan Seidle @ SparkFun Electronics, September 6th, 2018 - v2.0 rework by Paul Clark @ SparkFun Electronics, December 31st, 2020 - - This library handles configuring and handling the responses - from a u-blox GPS module. Works with most modules from u-blox including - the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others. - - https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library - - Development environment specifics: - Arduino IDE 1.8.13 - - SparkFun code, firmware, and software is released under the MIT - License(http://opensource.org/licenses/MIT). The MIT License (MIT) Copyright - (c) 2016 SparkFun Electronics Permission is hereby granted, free of charge, to - any person obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to permit - persons to whom the Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef SPARKFUN_UBLOX_ARDUINO_LIBRARY_H -#define SPARKFUN_UBLOX_ARDUINO_LIBRARY_H - -#include "hardware/i2c.h" -#include "hardware/spi.h" -#include "u-blox_config_keys.h" -#include "u-blox_structs.h" - -// Uncomment the next line (or add SFE_UBLOX_REDUCED_PROG_MEM as a compiler -// directive) to reduce the amount of program memory used by the library -// #define SFE_UBLOX_REDUCED_PROG_MEM // Uncommenting this line will delete the -// minor debug messages to save memory - -// Uncomment the next line (or add SFE_UBLOX_DISABLE_AUTO_NMEA as a compiler -// directive) to reduce the amount of program memory used by the library -// #define SFE_UBLOX_DISABLE_AUTO_NMEA // Uncommenting this line will disable -// auto-NMEA support to save memory - -// The code exceeds the program memory on the ATmega328P (Arduino Uno), so let's -// delete the minor debug messages and disable auto-NMEA support anyway However, -// the ATmega2560 and ATmega1280 _do_ have enough memory, so let's exclude those -#if !defined(SFE_UBLOX_REDUCED_PROG_MEM) && defined(ARDUINO_ARCH_AVR) && \ - !defined(ARDUINO_AVR_MEGA2560) && !defined(ARDUINO_AVR_MEGA) && \ - !defined(ARDUINO_AVR_ADK) -#define SFE_UBLOX_REDUCED_PROG_MEM -#endif -#if !defined(SFE_UBLOX_DISABLE_AUTO_NMEA) && defined(ARDUINO_ARCH_AVR) && \ - !defined(ARDUINO_AVR_MEGA2560) && !defined(ARDUINO_AVR_MEGA) && \ - !defined(ARDUINO_AVR_ADK) -#define SFE_UBLOX_DISABLE_AUTO_NMEA -#endif - -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -// Define a digital pin to aid debugging -// Leave set to -1 if not needed -const int debugPin = -1; - -// Global Status Returns -typedef enum { - SFE_UBLOX_STATUS_SUCCESS, - SFE_UBLOX_STATUS_FAIL, - SFE_UBLOX_STATUS_CRC_FAIL, - SFE_UBLOX_STATUS_TIMEOUT, - SFE_UBLOX_STATUS_COMMAND_NACK, // Indicates that the command was - // unrecognised, invalid or that the module - // is too busy to respond - SFE_UBLOX_STATUS_OUT_OF_RANGE, - SFE_UBLOX_STATUS_INVALID_ARG, - SFE_UBLOX_STATUS_INVALID_OPERATION, - SFE_UBLOX_STATUS_MEM_ERR, - SFE_UBLOX_STATUS_HW_ERR, - SFE_UBLOX_STATUS_DATA_SENT, // This indicates that a 'set' was successful - SFE_UBLOX_STATUS_DATA_RECEIVED, // This indicates that a 'get' (poll) was - // successful - SFE_UBLOX_STATUS_I2C_COMM_FAILURE, - SFE_UBLOX_STATUS_DATA_OVERWRITTEN // This is an error - the data was valid - // but has been or _is being_ overwritten - // by another packet -} sfe_ublox_status_e; - -// ubxPacket validity -typedef enum { - SFE_UBLOX_PACKET_VALIDITY_NOT_VALID, - SFE_UBLOX_PACKET_VALIDITY_VALID, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, - SFE_UBLOX_PACKET_NOTACKNOWLEDGED // This indicates that we received a NACK -} sfe_ublox_packet_validity_e; - -// Identify which packet buffer is in use: -// packetCfg (or a custom packet), packetAck or packetBuf -// packetAuto is used to store expected "automatic" messages -typedef enum { - SFE_UBLOX_PACKET_PACKETCFG, - SFE_UBLOX_PACKET_PACKETACK, - SFE_UBLOX_PACKET_PACKETBUF, - SFE_UBLOX_PACKET_PACKETAUTO -} sfe_ublox_packet_buffer_e; - -// Define a struct to allow selective logging / processing of NMEA messages -// Set the individual bits to pass the NMEA messages to the file buffer and/or -// processNMEA Setting bits.all will pass all messages to the file buffer and -// processNMEA -typedef struct { - union { - uint32_t all; - struct { - uint32_t all : 1; - uint32_t UBX_NMEA_DTM : 1; - uint32_t UBX_NMEA_GAQ : 1; - uint32_t UBX_NMEA_GBQ : 1; - uint32_t UBX_NMEA_GBS : 1; - uint32_t UBX_NMEA_GGA : 1; - uint32_t UBX_NMEA_GLL : 1; - uint32_t UBX_NMEA_GLQ : 1; - uint32_t UBX_NMEA_GNQ : 1; - uint32_t UBX_NMEA_GNS : 1; - uint32_t UBX_NMEA_GPQ : 1; - uint32_t UBX_NMEA_GQQ : 1; - uint32_t UBX_NMEA_GRS : 1; - uint32_t UBX_NMEA_GSA : 1; - uint32_t UBX_NMEA_GST : 1; - uint32_t UBX_NMEA_GSV : 1; - uint32_t UBX_NMEA_RLM : 1; - uint32_t UBX_NMEA_RMC : 1; - uint32_t UBX_NMEA_TXT : 1; - uint32_t UBX_NMEA_VLW : 1; - uint32_t UBX_NMEA_VTG : 1; - uint32_t UBX_NMEA_ZDA : 1; - } bits; - }; -} sfe_ublox_nmea_filtering_t; - -// Define an enum to make it easy to enable/disable selected NMEA messages for -// logging / processing -typedef enum { - SFE_UBLOX_FILTER_NMEA_ALL = 0x00000001, - SFE_UBLOX_FILTER_NMEA_DTM = 0x00000002, - SFE_UBLOX_FILTER_NMEA_GAQ = 0x00000004, - SFE_UBLOX_FILTER_NMEA_GBQ = 0x00000008, - SFE_UBLOX_FILTER_NMEA_GBS = 0x00000010, - SFE_UBLOX_FILTER_NMEA_GGA = 0x00000020, - SFE_UBLOX_FILTER_NMEA_GLL = 0x00000040, - SFE_UBLOX_FILTER_NMEA_GLQ = 0x00000080, - SFE_UBLOX_FILTER_NMEA_GNQ = 0x00000100, - SFE_UBLOX_FILTER_NMEA_GNS = 0x00000200, - SFE_UBLOX_FILTER_NMEA_GPQ = 0x00000400, - SFE_UBLOX_FILTER_NMEA_GQQ = 0x00000800, - SFE_UBLOX_FILTER_NMEA_GRS = 0x00001000, - SFE_UBLOX_FILTER_NMEA_GSA = 0x00002000, - SFE_UBLOX_FILTER_NMEA_GST = 0x00004000, - SFE_UBLOX_FILTER_NMEA_GSV = 0x00008000, - SFE_UBLOX_FILTER_NMEA_RLM = 0x00010000, - SFE_UBLOX_FILTER_NMEA_RMC = 0x00020000, - SFE_UBLOX_FILTER_NMEA_TXT = 0x00040000, - SFE_UBLOX_FILTER_NMEA_VLW = 0x00080000, - SFE_UBLOX_FILTER_NMEA_VTG = 0x00100000, - SFE_UBLOX_FILTER_NMEA_ZDA = 0x00200000 -} sfe_ublox_nmea_filtering_e; - -// Registers -const uint8_t UBX_SYNCH_1 = 0xB5; -const uint8_t UBX_SYNCH_2 = 0x62; - -// The following are UBX Class IDs. Descriptions taken from ZED-F9P Interface -// Description Document page 32, NEO-M8P Interface Description page 145 -const uint8_t UBX_CLASS_NAV = - 0x01; // Navigation Results Messages: Position, Speed, Time, Acceleration, - // Heading, DOP, SVs used -const uint8_t UBX_CLASS_RXM = - 0x02; // Receiver Manager Messages: Satellite Status, RTC Status -const uint8_t UBX_CLASS_INF = - 0x04; // Information Messages: Printf-Style Messages, with IDs such as - // Error, Warning, Notice -const uint8_t UBX_CLASS_ACK = 0x05; // Ack/Nak Messages: Acknowledge or Reject - // messages to UBX-CFG input messages -const uint8_t UBX_CLASS_CFG = - 0x06; // Configuration Input Messages: Configure the receiver. -const uint8_t UBX_CLASS_UPD = - 0x09; // Firmware Update Messages: Memory/Flash erase/write, Reboot, Flash - // identification, etc. -const uint8_t UBX_CLASS_MON = - 0x0A; // Monitoring Messages: Communication Status, CPU Load, Stack Usage, - // Task Status -const uint8_t UBX_CLASS_AID = - 0x0B; //(NEO-M8P ONLY!!!) AssistNow Aiding Messages: Ephemeris, Almanac, - //other A-GPS data input -const uint8_t UBX_CLASS_TIM = - 0x0D; // Timing Messages: Time Pulse Output, Time Mark Results -const uint8_t UBX_CLASS_ESF = - 0x10; //(NEO-M8P ONLY!!!) External Sensor Fusion Messages: External Sensor - //Measurements and Status Information -const uint8_t UBX_CLASS_MGA = 0x13; // Multiple GNSS Assistance Messages: - // Assistance data for various GNSS -const uint8_t UBX_CLASS_LOG = - 0x21; // Logging Messages: Log creation, deletion, info and retrieval -const uint8_t UBX_CLASS_SEC = 0x27; // Security Feature Messages -const uint8_t UBX_CLASS_HNR = - 0x28; //(NEO-M8P ONLY!!!) High Rate Navigation Results Messages: High rate - //time, position speed, heading -const uint8_t UBX_CLASS_NMEA = 0xF0; // NMEA Strings: standard NMEA strings -const uint8_t UBX_CLASS_PUBX = - 0xF1; // Proprietary NMEA-format messages defined by u-blox - -// Class: CFG -// The following are used for configuration. Descriptions are from the ZED-F9P -// Interface Description pg 33-34 and NEO-M9N Interface Description pg 47-48 -const uint8_t UBX_CFG_ANT = 0x13; // Antenna Control Settings. Used to - // configure the antenna control settings -const uint8_t UBX_CFG_BATCH = 0x93; // Get/set data batching configuration. -const uint8_t UBX_CFG_CFG = 0x09; // Clear, Save, and Load Configurations. Used - // to save current configuration -const uint8_t UBX_CFG_DAT = - 0x06; // Set User-defined Datum or The currently defined Datum -const uint8_t UBX_CFG_DGNSS = 0x70; // DGNSS configuration -const uint8_t UBX_CFG_ESFALG = 0x56; // ESF alignment -const uint8_t UBX_CFG_ESFA = 0x4C; // ESF accelerometer -const uint8_t UBX_CFG_ESFG = 0x4D; // ESF gyro -const uint8_t UBX_CFG_GEOFENCE = - 0x69; // Geofencing configuration. Used to configure a geofence -const uint8_t UBX_CFG_GNSS = 0x3E; // GNSS system configuration -const uint8_t UBX_CFG_HNR = 0x5C; // High Navigation Rate -const uint8_t UBX_CFG_INF = - 0x02; // Depending on packet length, either: poll configuration for one - // protocol, or information message configuration -const uint8_t UBX_CFG_ITFM = - 0x39; // Jamming/Interference Monitor configuration -const uint8_t UBX_CFG_LOGFILTER = 0x47; // Data Logger Configuration -const uint8_t UBX_CFG_MSG = 0x01; // Poll a message configuration, or Set - // Message Rate(s), or Set Message Rate -const uint8_t UBX_CFG_NAV5 = - 0x24; // Navigation Engine Settings. Used to configure the navigation - // engine including the dynamic model. -const uint8_t UBX_CFG_NAVX5 = 0x23; // Navigation Engine Expert Settings -const uint8_t UBX_CFG_NMEA = 0x17; // Extended NMEA protocol configuration V1 -const uint8_t UBX_CFG_ODO = 0x1E; // Odometer, Low-speed COG Engine Settings -const uint8_t UBX_CFG_PM2 = 0x3B; // Extended power management configuration -const uint8_t UBX_CFG_PMS = 0x86; // Power mode setup -const uint8_t UBX_CFG_PRT = - 0x00; // Used to configure port specifics. Polls the configuration for one - // I/O Port, or Port configuration for UART ports, or Port - // configuration for USB port, or Port configuration for SPI port, or - // Port configuration for DDC port -const uint8_t UBX_CFG_PWR = 0x57; // Put receiver in a defined power state -const uint8_t UBX_CFG_RATE = - 0x08; // Navigation/Measurement Rate Settings. Used to set port baud rates. -const uint8_t UBX_CFG_RINV = 0x34; // Contents of Remote Inventory -const uint8_t UBX_CFG_RST = 0x04; // Reset Receiver / Clear Backup Data - // Structures. Used to reset device. -const uint8_t UBX_CFG_RXM = 0x11; // RXM configuration -const uint8_t UBX_CFG_SBAS = 0x16; // SBAS configuration -const uint8_t UBX_CFG_TMODE3 = - 0x71; // Time Mode Settings 3. Used to enable Survey In Mode -const uint8_t UBX_CFG_TP5 = 0x31; // Time Pulse Parameters -const uint8_t UBX_CFG_USB = 0x1B; // USB Configuration -const uint8_t UBX_CFG_VALDEL = - 0x8C; // Used for config of higher version u-blox modules (ie protocol v27 - // and above). Deletes values corresponding to provided keys/ - // provided keys with a transaction -const uint8_t UBX_CFG_VALGET = - 0x8B; // Used for config of higher version u-blox modules (ie protocol v27 - // and above). Configuration Items -const uint8_t UBX_CFG_VALSET = - 0x8A; // Used for config of higher version u-blox modules (ie protocol v27 - // and above). Sets values corresponding to provided key-value pairs/ - // provided key-value pairs within a transaction. - -// Class: NMEA -// The following are used to enable NMEA messages. Descriptions come from the -// NMEA messages overview in the ZED-F9P Interface Description -const uint8_t UBX_NMEA_MSB = - 0xF0; // All NMEA enable commands have 0xF0 as MSB. Equal to UBX_CLASS_NMEA -const uint8_t UBX_NMEA_DTM = 0x0A; // GxDTM (datum reference) -const uint8_t UBX_NMEA_GAQ = - 0x45; // GxGAQ (poll a standard message (if the current talker ID is GA)) -const uint8_t UBX_NMEA_GBQ = - 0x44; // GxGBQ (poll a standard message (if the current Talker ID is GB)) -const uint8_t UBX_NMEA_GBS = 0x09; // GxGBS (GNSS satellite fault detection) -const uint8_t UBX_NMEA_GGA = - 0x00; // GxGGA (Global positioning system fix data) -const uint8_t UBX_NMEA_GLL = - 0x01; // GxGLL (latitude and long, whith time of position fix and status) -const uint8_t UBX_NMEA_GLQ = - 0x43; // GxGLQ (poll a standard message (if the current Talker ID is GL)) -const uint8_t UBX_NMEA_GNQ = - 0x42; // GxGNQ (poll a standard message (if the current Talker ID is GN)) -const uint8_t UBX_NMEA_GNS = 0x0D; // GxGNS (GNSS fix data) -const uint8_t UBX_NMEA_GPQ = - 0x40; // GxGPQ (poll a standard message (if the current Talker ID is GP)) -const uint8_t UBX_NMEA_GQQ = - 0x47; // GxGQQ (poll a standard message (if the current Talker ID is GQ)) -const uint8_t UBX_NMEA_GRS = 0x06; // GxGRS (GNSS range residuals) -const uint8_t UBX_NMEA_GSA = 0x02; // GxGSA (GNSS DOP and Active satellites) -const uint8_t UBX_NMEA_GST = - 0x07; // GxGST (GNSS Pseudo Range Error Statistics) -const uint8_t UBX_NMEA_GSV = 0x03; // GxGSV (GNSS satellites in view) -const uint8_t UBX_NMEA_RLM = 0x0B; // GxRMC (Return link message (RLM)) -const uint8_t UBX_NMEA_RMC = 0x04; // GxRMC (Recommended minimum data) -const uint8_t UBX_NMEA_TXT = 0x41; // GxTXT (text transmission) -const uint8_t UBX_NMEA_VLW = 0x0F; // GxVLW (dual ground/water distance) -const uint8_t UBX_NMEA_VTG = - 0x05; // GxVTG (course over ground and Ground speed) -const uint8_t UBX_NMEA_ZDA = 0x08; // GxZDA (Time and Date) - -// The following are used to configure the NMEA protocol main talker ID and GSV -// talker ID -const uint8_t UBX_NMEA_MAINTALKERID_NOTOVERRIDDEN = - 0x00; // main talker ID is system dependent -const uint8_t UBX_NMEA_MAINTALKERID_GP = 0x01; // main talker ID is GPS -const uint8_t UBX_NMEA_MAINTALKERID_GL = 0x02; // main talker ID is GLONASS -const uint8_t UBX_NMEA_MAINTALKERID_GN = - 0x03; // main talker ID is combined receiver -const uint8_t UBX_NMEA_MAINTALKERID_GA = 0x04; // main talker ID is Galileo -const uint8_t UBX_NMEA_MAINTALKERID_GB = 0x05; // main talker ID is BeiDou -const uint8_t UBX_NMEA_GSVTALKERID_GNSS = - 0x00; // GNSS specific Talker ID (as defined by NMEA) -const uint8_t UBX_NMEA_GSVTALKERID_MAIN = 0x01; // use the main Talker ID - -// Class: PUBX -// The following are used to enable PUBX messages with configureMessage -// See the M8 receiver description & protocol specification for more details -const uint8_t UBX_PUBX_CONFIG = 0x41; // Set protocols and baud rate -const uint8_t UBX_PUBX_POSITION = 0x00; // Lat/Long position data -const uint8_t UBX_PUBX_RATE = 0x40; // Set/get NMEA message output rate -const uint8_t UBX_PUBX_SVSTATUS = 0x03; // Satellite status -const uint8_t UBX_PUBX_TIME = 0x04; // Time of day and clock information - -// Class: HNR -// The following are used to configure the HNR message rates -const uint8_t UBX_HNR_ATT = 0x01; // HNR Attitude -const uint8_t UBX_HNR_INS = 0x02; // HNR Vehicle Dynamics -const uint8_t UBX_HNR_PVT = 0x00; // HNR PVT - -// Class: INF -// The following are used to configure INF UBX messages (information messages). -// Descriptions from UBX messages overview (ZED_F9P Interface Description -// Document page 34) -const uint8_t UBX_INF_CLASS = 0x04; // All INF messages have 0x04 as the class -const uint8_t UBX_INF_DEBUG = 0x04; // ASCII output with debug contents -const uint8_t UBX_INF_ERROR = 0x00; // ASCII output with error contents -const uint8_t UBX_INF_NOTICE = - 0x02; // ASCII output with informational contents -const uint8_t UBX_INF_TEST = 0x03; // ASCII output with test contents -const uint8_t UBX_INF_WARNING = 0x01; // ASCII output with warning contents - -// Class: LOG -// The following are used to configure LOG UBX messages (loggings messages). -// Descriptions from UBX messages overview (ZED_F9P Interface Description -// Document page 34) -const uint8_t UBX_LOG_CREATE = 0x07; // Create Log File -const uint8_t UBX_LOG_ERASE = 0x03; // Erase Logged Data -const uint8_t UBX_LOG_FINDTIME = - 0x0E; // Find index of a log entry based on a given time, or response to - // FINDTIME requested -const uint8_t UBX_LOG_INFO = - 0x08; // Poll for log information, or Log information -const uint8_t UBX_LOG_RETRIEVEPOSEXTRA = 0x0F; // Odometer log entry -const uint8_t UBX_LOG_RETRIEVEPOS = 0x0B; // Position fix log entry -const uint8_t UBX_LOG_RETRIEVESTRING = 0x0D; // Byte string log entry -const uint8_t UBX_LOG_RETRIEVE = 0x09; // Request log data -const uint8_t UBX_LOG_STRING = - 0x04; // Store arbitrary string on on-board flash - -// Class: MGA -// The following are used to configure MGA UBX messages (Multiple GNSS -// Assistance Messages). Descriptions from UBX messages overview (ZED_F9P -// Interface Description Document page 34) -const uint8_t UBX_MGA_ACK_DATA0 = 0x60; // Multiple GNSS Acknowledge message -const uint8_t UBX_MGA_ANO = - 0x20; // Multiple GNSS AssistNow Offline assistance - NOT SUPPORTED BY THE - // ZED-F9P! "The ZED-F9P supports AssistNow Online only." -const uint8_t UBX_MGA_BDS_EPH = 0x03; // BDS Ephemeris Assistance -const uint8_t UBX_MGA_BDS_ALM = 0x03; // BDS Almanac Assistance -const uint8_t UBX_MGA_BDS_HEALTH = 0x03; // BDS Health Assistance -const uint8_t UBX_MGA_BDS_UTC = 0x03; // BDS UTC Assistance -const uint8_t UBX_MGA_BDS_IONO = 0x03; // BDS Ionospheric Assistance -const uint8_t UBX_MGA_DBD = 0x80; // Either: Poll the Navigation Database, or - // Navigation Database Dump Entry -const uint8_t UBX_MGA_GAL_EPH = 0x02; // Galileo Ephemeris Assistance -const uint8_t UBX_MGA_GAL_ALM = 0x02; // Galileo Almanac Assitance -const uint8_t UBX_MGA_GAL_TIMOFFSET = - 0x02; // Galileo GPS time offset assistance -const uint8_t UBX_MGA_GAL_UTC = 0x02; // Galileo UTC Assistance -const uint8_t UBX_MGA_GLO_EPH = 0x06; // GLONASS Ephemeris Assistance -const uint8_t UBX_MGA_GLO_ALM = 0x06; // GLONASS Almanac Assistance -const uint8_t UBX_MGA_GLO_TIMEOFFSET = - 0x06; // GLONASS Auxiliary Time Offset Assistance -const uint8_t UBX_MGA_GPS_EPH = 0x00; // GPS Ephemeris Assistance -const uint8_t UBX_MGA_GPS_ALM = 0x00; // GPS Almanac Assistance -const uint8_t UBX_MGA_GPS_HEALTH = 0x00; // GPS Health Assistance -const uint8_t UBX_MGA_GPS_UTC = 0x00; // GPS UTC Assistance -const uint8_t UBX_MGA_GPS_IONO = 0x00; // GPS Ionosphere Assistance -const uint8_t UBX_MGA_INI_POS_XYZ = 0x40; // Initial Position Assistance -const uint8_t UBX_MGA_INI_POS_LLH = 0x40; // Initial Position Assitance -const uint8_t UBX_MGA_INI_TIME_UTC = 0x40; // Initial Time Assistance -const uint8_t UBX_MGA_INI_TIME_GNSS = 0x40; // Initial Time Assistance -const uint8_t UBX_MGA_INI_CLKD = 0x40; // Initial Clock Drift Assitance -const uint8_t UBX_MGA_INI_FREQ = 0x40; // Initial Frequency Assistance -const uint8_t UBX_MGA_INI_EOP = - 0x40; // Earth Orientation Parameters Assistance -const uint8_t UBX_MGA_QZSS_EPH = 0x05; // QZSS Ephemeris Assistance -const uint8_t UBX_MGA_QZSS_ALM = 0x05; // QZSS Almanac Assistance -const uint8_t UBX_MGA_QZAA_HEALTH = 0x05; // QZSS Health Assistance - -// Class: MON -// The following are used to configure the MON UBX messages (monitoring -// messages). Descriptions from UBX messages overview (ZED_F9P Interface -// Description Document page 35) -const uint8_t UBX_MON_COMMS = 0x36; // Comm port information -const uint8_t UBX_MON_GNSS = 0x28; // Information message major GNSS selection -const uint8_t UBX_MON_HW2 = 0x0B; // Extended Hardware Status -const uint8_t UBX_MON_HW3 = 0x37; // HW I/O pin information -const uint8_t UBX_MON_HW = 0x09; // Hardware Status -const uint8_t UBX_MON_IO = 0x02; // I/O Subsystem Status -const uint8_t UBX_MON_MSGPP = 0x06; // Message Parse and Process Status -const uint8_t UBX_MON_PATCH = - 0x27; // Output information about installed patches -const uint8_t UBX_MON_RF = 0x38; // RF information -const uint8_t UBX_MON_RXBUF = 0x07; // Receiver Buffer Status -const uint8_t UBX_MON_RXR = 0x21; // Receiver Status Information -const uint8_t UBX_MON_SPAN = 0x31; // Signal characteristics -const uint8_t UBX_MON_SYS = 0x39; // Current system performance information -const uint8_t UBX_MON_TXBUF = - 0x08; // Transmitter Buffer Status. Used for query tx buffer size/state. -const uint8_t UBX_MON_VER = - 0x04; // Receiver/Software Version. Used for obtaining Protocol Version. - -// Class: NAV -// The following are used to configure the NAV UBX messages (navigation results -// messages). Descriptions from UBX messages overview (ZED_F9P Interface -// Description Document page 35-36) -const uint8_t UBX_NAV_ATT = 0x05; // Vehicle "Attitude" Solution -const uint8_t UBX_NAV_CLOCK = 0x22; // Clock Solution -const uint8_t UBX_NAV_DOP = 0x04; // Dilution of precision -const uint8_t UBX_NAV_EOE = 0x61; // End of Epoch -const uint8_t UBX_NAV_GEOFENCE = - 0x39; // Geofencing status. Used to poll the geofence status -const uint8_t UBX_NAV_HPPOSECEF = - 0x13; // High Precision Position Solution in ECEF. Used to find our - // positional accuracy (high precision). -const uint8_t UBX_NAV_HPPOSLLH = - 0x14; // High Precision Geodetic Position Solution. Used for obtaining - // lat/long/alt in high precision -const uint8_t UBX_NAV_ODO = 0x09; // Odometer Solution -const uint8_t UBX_NAV_ORB = 0x34; // GNSS Orbit Database Info -const uint8_t UBX_NAV_PL = 0x62; // Protection Level Information -const uint8_t UBX_NAV_POSECEF = 0x01; // Position Solution in ECEF -const uint8_t UBX_NAV_POSLLH = 0x02; // Geodetic Position Solution -const uint8_t UBX_NAV_PVT = - 0x07; // All the things! Position, velocity, time, PDOP, height, h/v - // accuracies, number of satellites. Navigation Position Velocity - // Time Solution. -const uint8_t UBX_NAV_PVAT = - 0x17; // Navigation position velocity attitude time solution (ZED-F9R only) -const uint8_t UBX_NAV_RELPOSNED = - 0x3C; // Relative Positioning Information in NED frame -const uint8_t UBX_NAV_RESETODO = 0x10; // Reset odometer -const uint8_t UBX_NAV_SAT = 0x35; // Satellite Information -const uint8_t UBX_NAV_SIG = 0x43; // Signal Information -const uint8_t UBX_NAV_STATUS = 0x03; // Receiver Navigation Status -const uint8_t UBX_NAV_SVIN = - 0x3B; // Survey-in data. Used for checking Survey In status -const uint8_t UBX_NAV_TIMEBDS = 0x24; // BDS Time Solution -const uint8_t UBX_NAV_TIMEGAL = 0x25; // Galileo Time Solution -const uint8_t UBX_NAV_TIMEGLO = 0x23; // GLO Time Solution -const uint8_t UBX_NAV_TIMEGPS = 0x20; // GPS Time Solution -const uint8_t UBX_NAV_TIMELS = 0x26; // Leap second event information -const uint8_t UBX_NAV_TIMEUTC = 0x21; // UTC Time Solution -const uint8_t UBX_NAV_VELECEF = 0x11; // Velocity Solution in ECEF -const uint8_t UBX_NAV_VELNED = 0x12; // Velocity Solution in NED -const uint8_t UBX_NAV_AOPSTATUS = 0x60; // AssistNow Autonomous status - -// Class: RXM -// The following are used to configure the RXM UBX messages (receiver manager -// messages). Descriptions from UBX messages overview (ZED_F9P Interface -// Description Document page 36) -const uint8_t UBX_RXM_COR = 0x34; // Differential correction input status -const uint8_t UBX_RXM_MEASX = 0x14; // Satellite Measurements for RRLP -const uint8_t UBX_RXM_PMP = - 0x72; // PMP raw data (NEO-D9S) (two different versions) (packet size for - // version 0x01 is variable) -const uint8_t UBX_RXM_QZSSL6 = 0x73; // QZSSL6 data (NEO-D9C) -const uint8_t UBX_RXM_PMREQ = - 0x41; // Requests a Power Management task (two different packet sizes) -const uint8_t UBX_RXM_RAWX = 0x15; // Multi-GNSS Raw Measurement Data -const uint8_t UBX_RXM_RLM = - 0x59; // Galileo SAR Short-RLM report (two different packet sizes) -const uint8_t UBX_RXM_RTCM = 0x32; // RTCM input status -const uint8_t UBX_RXM_SFRBX = 0x13; // Broadcast Navigation Data Subframe -const uint8_t UBX_RXM_SPARTN = 0x33; // SPARTN input status -const uint8_t UBX_RXM_SPARTNKEY = 0x36; // Poll/transfer dynamic SPARTN keys - -// Class: SEC -// The following are used to configure the SEC UBX messages (security feature -// messages). Descriptions from UBX messages overview (ZED_F9P Interface -// Description Document page 36) -const uint8_t UBX_SEC_UNIQID = 0x03; // Unique chip ID - -// Class: TIM -// The following are used to configure the TIM UBX messages (timing messages). -// Descriptions from UBX messages overview (ZED_F9P Interface Description -// Document page 36) -const uint8_t UBX_TIM_TM2 = 0x03; // Time mark data -const uint8_t UBX_TIM_TP = 0x01; // Time Pulse Timedata -const uint8_t UBX_TIM_VRFY = 0x06; // Sourced Time Verification - -// Class: UPD -// The following are used to configure the UPD UBX messages (firmware update -// messages). Descriptions from UBX messages overview (ZED-F9P Interface -// Description Document page 36) -const uint8_t UBX_UPD_SOS = - 0x14; // Poll Backup Fil Restore Status, Create Backup File in Flash, Clear - // Backup File in Flash, Backup File Creation Acknowledge, System - // Restored from Backup - -// The following are used to enable RTCM messages -const uint8_t UBX_RTCM_MSB = 0xF5; // All RTCM enable commands have 0xF5 as MSB -const uint8_t UBX_RTCM_1005 = 0x05; // Stationary RTK reference ARP -const uint8_t UBX_RTCM_1074 = 0x4A; // GPS MSM4 -const uint8_t UBX_RTCM_1077 = 0x4D; // GPS MSM7 -const uint8_t UBX_RTCM_1084 = 0x54; // GLONASS MSM4 -const uint8_t UBX_RTCM_1087 = 0x57; // GLONASS MSM7 -const uint8_t UBX_RTCM_1094 = 0x5E; // Galileo MSM4 -const uint8_t UBX_RTCM_1097 = 0x61; // Galileo MSM7 -const uint8_t UBX_RTCM_1124 = 0x7C; // BeiDou MSM4 -const uint8_t UBX_RTCM_1127 = 0x7F; // BeiDou MSM7 -const uint8_t UBX_RTCM_1230 = - 0xE6; // GLONASS code-phase biases, set to once every 10 seconds -const uint8_t UBX_RTCM_4072_0 = - 0xFE; // Reference station PVT (ublox proprietary RTCM message) -const uint8_t UBX_RTCM_4072_1 = - 0xFD; // Additional reference station information (ublox proprietary RTCM - // message) - -// Class: ACK -const uint8_t UBX_ACK_NACK = 0x00; -const uint8_t UBX_ACK_ACK = 0x01; -const uint8_t UBX_ACK_NONE = 0x02; // Not a real value - -// Class: ESF -// The following constants are used to get External Sensor Measurements and -// Status Information. -const uint8_t UBX_ESF_MEAS = 0x02; -const uint8_t UBX_ESF_RAW = 0x03; -const uint8_t UBX_ESF_STATUS = 0x10; -const uint8_t UBX_ESF_RESETALG = 0x13; -const uint8_t UBX_ESF_ALG = 0x14; -const uint8_t UBX_ESF_INS = 0x15; // 36 bytes - -const uint8_t SVIN_MODE_DISABLE = 0x00; -const uint8_t SVIN_MODE_ENABLE = 0x01; - -// The following consts are used to configure the various ports and streams for -// those ports. See -CFG-PRT. -const uint8_t COM_PORT_I2C = 0; -const uint8_t COM_PORT_UART1 = 1; -const uint8_t COM_PORT_UART2 = 2; -const uint8_t COM_PORT_USB = 3; -const uint8_t COM_PORT_SPI = 4; - -const uint8_t COM_TYPE_UBX = (1 << 0); -const uint8_t COM_TYPE_NMEA = (1 << 1); -const uint8_t COM_TYPE_RTCM3 = (1 << 5); -const uint8_t COM_TYPE_SPARTN = (1 << 6); - -// Odometer configuration - flags -const uint8_t UBX_CFG_ODO_USE_ODO = (1 << 0); -const uint8_t UBX_CFG_ODO_USE_COG = (1 << 1); -const uint8_t UBX_CFG_ODO_OUT_LP_VEL = (1 << 2); -const uint8_t UBX_CFG_ODO_OUT_LP_COG = (1 << 3); - -// Odometer configuration - odoCfg -enum odoCfg_e { - UBX_CFG_ODO_RUN = 0, - UBX_CFG_ODO_CYCLE, - UBX_CFG_ODO_SWIM, - UBX_CFG_ODO_CAR, - UBX_CFG_ODO_CUSTOM, -}; - -// Configuration Sub-Section mask definitions for saveConfigSelective -// (UBX-CFG-CFG) -const uint32_t VAL_CFG_SUBSEC_IOPORT = - 0x00000001; // ioPort - communications port settings (causes IO system - // reset!) -const uint32_t VAL_CFG_SUBSEC_MSGCONF = - 0x00000002; // msgConf - message configuration -const uint32_t VAL_CFG_SUBSEC_INFMSG = - 0x00000004; // infMsg - INF message configuration -const uint32_t VAL_CFG_SUBSEC_NAVCONF = - 0x00000008; // navConf - navigation configuration -const uint32_t VAL_CFG_SUBSEC_RXMCONF = - 0x00000010; // rxmConf - receiver manager configuration -const uint32_t VAL_CFG_SUBSEC_SENCONF = - 0x00000100; // senConf - sensor interface configuration (requires protocol - // 19+) -const uint32_t VAL_CFG_SUBSEC_RINVCONF = - 0x00000200; // rinvConf - remove inventory configuration -const uint32_t VAL_CFG_SUBSEC_ANTCONF = - 0x00000400; // antConf - antenna configuration -const uint32_t VAL_CFG_SUBSEC_LOGCONF = - 0x00000800; // logConf - logging configuration -const uint32_t VAL_CFG_SUBSEC_FTSCONF = - 0x00001000; // ftsConf - FTS configuration (FTS products only) - -// Bitfield wakeupSources for UBX_RXM_PMREQ -const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = 0x00000008; // uartrx -const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = 0x00000020; // extint0 -const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = 0x00000040; // extint1 -const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = 0x00000080; // spics - -enum dynModel // Possible values for the dynamic platform model, which provide - // more accuract position output for the situation. Description - // extracted from ZED-F9P Integration Manual -{ - DYN_MODEL_PORTABLE = 0, // Applications with low acceleration, e.g. - // portable devices. Suitable for most situations. - // 1 is not defined - DYN_MODEL_STATIONARY = - 2, // Used in timing applications (antenna must be stationary) or other - // stationary applications. Velocity restricted to 0 m/s. Zero - // dynamics assumed. - DYN_MODEL_PEDESTRIAN, // Applications with low acceleration and speed, e.g. - // how a pedestrian would move. Low acceleration - // assumed. - DYN_MODEL_AUTOMOTIVE, // Used for applications with equivalent dynamics to - // those of a passenger car. Low vertical - // acceleration assumed - DYN_MODEL_SEA, // Recommended for applications at sea, with zero vertical - // velocity. Zero vertical velocity assumed. Sea level - // assumed. - DYN_MODEL_AIRBORNE1g, // Airborne <1g acceleration. Used for applications - // with a higher dynamic range and greater vertical - // acceleration than a passenger car. No 2D position - // fixes supported. - DYN_MODEL_AIRBORNE2g, // Airborne <2g acceleration. Recommended for typical - // airborne environments. No 2D position fixes - // supported. - DYN_MODEL_AIRBORNE4g, // Airborne <4g acceleration. Only recommended for - // extremely dynamic environments. No 2D position - // fixes supported. - DYN_MODEL_WRIST, // Not supported in protocol versions less than 18. Only - // recommended for wrist worn applications. Receiver will - // filter out arm motion. - DYN_MODEL_BIKE, // Supported in protocol versions 19.2. (not available in - // all products) - DYN_MODEL_MOWER, // Added in HPS 1.21 (not available in all products) - DYN_MODEL_ESCOOTER, // Added in HPS 1.21 (not available in all products) - DYN_MODEL_UNKNOWN = - 255 // getDynamicModel will return 255 if sendCommand fails -}; - -// The GNSS identifiers - used by UBX-CFG-GNSS (0x06 0x3E) GNSS system -// configuration -enum sfe_ublox_gnss_ids_e { - SFE_UBLOX_GNSS_ID_GPS, - SFE_UBLOX_GNSS_ID_SBAS, - SFE_UBLOX_GNSS_ID_GALILEO, - SFE_UBLOX_GNSS_ID_BEIDOU, - SFE_UBLOX_GNSS_ID_IMES, - SFE_UBLOX_GNSS_ID_QZSS, - SFE_UBLOX_GNSS_ID_GLONASS -}; - -// The GNSS identifiers of leap second event info source - used by -// UBX-NAV-TIMELS -enum sfe_ublox_ls_src_e { - SFE_UBLOX_LS_SRC_DEFAULT, - SFE_UBLOX_LS_SRC_GLONASS, - SFE_UBLOX_LS_SRC_GPS, - SFE_UBLOX_LS_SRC_SBAS, - SFE_UBLOX_LS_SRC_BEIDOU, - SFE_UBLOX_LS_SRC_GALILEO, - SFE_UBLOX_LS_SRC_AIDED, - SFE_UBLOX_LS_SRC_CONFIGURED, - SFE_UBLOX_LS_SRC_UNKNOWN = 255 -}; - -typedef enum { - SFE_UBLOX_MGA_ASSIST_ACK_NO, // Do not expect UBX-MGA-ACK's. If the module - // outputs them, they will be ignored - SFE_UBLOX_MGA_ASSIST_ACK_YES, // Expect and check for UBX-MGA-ACK's - SFE_UBLOX_MGA_ASSIST_ACK_ENQUIRE // Check UBX-CFG-NAVX5 ackAiding to - // determine if UBX-MGA-ACK's are expected -} sfe_ublox_mga_assist_ack_e; - -// The infoCode byte included in UBX-MGA-ACK-DATA0 -enum sfe_ublox_mga_ack_infocode_e { - SFE_UBLOX_MGA_ACK_INFOCODE_ACCEPTED, - SFE_UBLOX_MGA_ACK_INFOCODE_NO_TIME, - SFE_UBLOX_MGA_ACK_INFOCODE_NOT_SUPPORTED, - SFE_UBLOX_MGA_ACK_INFOCODE_SIZE_MISMATCH, - SFE_UBLOX_MGA_ACK_INFOCODE_NOT_STORED, - SFE_UBLOX_MGA_ACK_INFOCODE_NOT_READY, - SFE_UBLOX_MGA_ACK_INFOCODE_TYPE_UNKNOWN -}; - -// The mainTalkerId, set by UBX-CFG-NMEA setMainTalkerID -enum sfe_ublox_talker_ids_e { - SFE_UBLOX_MAIN_TALKER_ID_DEFAULT, - SFE_UBLOX_MAIN_TALKER_ID_GP, - SFE_UBLOX_MAIN_TALKER_ID_GL, - SFE_UBLOX_MAIN_TALKER_ID_GN, - SFE_UBLOX_MAIN_TALKER_ID_GA, - SFE_UBLOX_MAIN_TALKER_ID_GB, - SFE_UBLOX_MAIN_TALKER_ID_GQ -}; - -// The DGNSS differential mode -enum sfe_ublox_dgnss_mode_e { - SFE_UBLOX_DGNSS_MODE_FLOAT = 2, // No attempts are made to fix ambiguities - SFE_UBLOX_DGNSS_MODE_FIXED // Ambiguities are fixed whenever possible -}; - -// Values for UBX-CFG-PMS -enum sfe_ublox_pms_mode_e { - SFE_UBLOX_PMS_MODE_FULLPOWER = 0, - SFE_UBLOX_PMS_MODE_BALANCED, - SFE_UBLOX_PMS_MODE_INTERVAL, - SFE_UBLOX_PMS_MODE_AGGRESSIVE_1HZ, - SFE_UBLOX_PMS_MODE_AGGRESSIVE_2HZ, - SFE_UBLOX_PMS_MODE_AGGRESSIVE_4HZ, - SFE_UBLOX_PMS_MODE_INVALID = 0xff -}; - -// Values for UBX-CFG-RXM -enum sfe_ublox_rxm_mode_e { - SFE_UBLOX_CFG_RXM_CONTINUOUS = 0, - SFE_UBLOX_CFG_RXM_POWERSAVE = 1 -}; - -//-=-=-=-=- - -#ifndef MAX_PAYLOAD_SIZE -// v2.0: keep this for backwards-compatibility, but this is largely superseded -// by setPacketCfgPayloadSize -#define MAX_PAYLOAD_SIZE \ - 256 // We need ~220 bytes for getProtocolVersion on most ublox modules -// #define MAX_PAYLOAD_SIZE 768 //Worst case: UBX_CFG_VALSET packet with 64 -// keyIDs each with 64 bit values -#endif - -// For storing SPI bytes received during sendSpiCommand -#define SFE_UBLOX_SPI_BUFFER_SIZE 128 - -// Default maximum NMEA byte count -// maxNMEAByteCount was set to 82: -// https://en.wikipedia.org/wiki/NMEA_0183#Message_structure but the u-blox HP -// (RTK) GGA messages are 88 bytes long The user can adjust maxNMEAByteCount by -// calling setMaxNMEAByteCount -#define SFE_UBLOX_MAX_NMEA_BYTE_COUNT 88 - -//-=-=-=-=- UBX binary specific variables -struct ubxPacket { - uint8_t cls; - uint8_t id; - uint16_t len; // Length of the payload. Does not include cls, id, or - // checksum bytes - uint16_t counter; // Keeps track of number of overall bytes received. Some - // responses are larger than 255 bytes. - uint16_t startingSpot; // The counter value needed to go past before we - // begin recording into payload array - uint8_t *payload; // We will allocate RAM for the payload if/when needed. - uint8_t checksumA; // Given to us from module. Checked against the rolling - // calculated A/B checksums. - uint8_t checksumB; - sfe_ublox_packet_validity_e valid; // Goes from NOT_DEFINED to VALID or - // NOT_VALID when checksum is checked - sfe_ublox_packet_validity_e - classAndIDmatch; // Goes from NOT_DEFINED to VALID or NOT_VALID when - // the Class and ID match the requestedClass and - // requestedID -}; - -// Struct to hold the results returned by getGeofenceState (returned by -// UBX-NAV-GEOFENCE) -typedef struct { - uint8_t status; // Geofencing status: 0 - Geofencing not available or not - // reliable; 1 - Geofencing active - uint8_t numFences; // Number of geofences - uint8_t combState; // Combined (logical OR) state of all geofences: 0 - - // Unknown; 1 - Inside; 2 - Outside - uint8_t states[4]; // Geofence states: 0 - Unknown; 1 - Inside; 2 - Outside -} geofenceState; - -// Struct to hold the current geofence parameters -typedef struct { - uint8_t numFences; // Number of active geofences - int32_t lats[4]; // Latitudes of geofences (in degrees * 10^-7) - int32_t longs[4]; // Longitudes of geofences (in degrees * 10^-7) - uint32_t rads[4]; // Radii of geofences (in m * 10^-2) -} geofenceParams_t; - -// Struct to hold the module software version -typedef struct { - uint8_t versionLow; // Loaded from getProtocolVersion(). - uint8_t versionHigh; - bool moduleQueried; -} moduleSWVersion_t; - -const uint32_t SFE_UBLOX_DAYS_FROM_1970_TO_2020 = - 18262; // Jan 1st 2020 Epoch = 1577836800 seconds -const uint16_t SFE_UBLOX_DAYS_SINCE_2020[80] = { - 0, 366, 731, 1096, 1461, 1827, 2192, 2557, 2922, 3288, - 3653, 4018, 4383, 4749, 5114, 5479, 5844, 6210, 6575, 6940, - 7305, 7671, 8036, 8401, 8766, 9132, 9497, 9862, 10227, 10593, - 10958, 11323, 11688, 12054, 12419, 12784, 13149, 13515, 13880, 14245, - 14610, 14976, 15341, 15706, 16071, 16437, 16802, 17167, 17532, 17898, - 18263, 18628, 18993, 19359, 19724, 20089, 20454, 20820, 21185, 21550, - 21915, 22281, 22646, 23011, 23376, 23742, 24107, 24472, 24837, 25203, - 25568, 25933, 26298, 26664, 27029, 27394, 27759, 28125, 28490, 28855}; -const uint16_t SFE_UBLOX_DAYS_SINCE_MONTH[2][12] = { - {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, - 335}, // Leap Year (Year % 4 == 0) - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334} // Normal Year -}; - -class SFE_UBLOX_GNSS { - public: - SFE_UBLOX_GNSS(void); - virtual ~SFE_UBLOX_GNSS(void); - - // Depending on the sentence type the processor will load characters into - // different arrays - enum sfe_ublox_sentence_types_e { - SFE_UBLOX_SENTENCE_TYPE_NONE = 0, - SFE_UBLOX_SENTENCE_TYPE_NMEA, - SFE_UBLOX_SENTENCE_TYPE_UBX, - SFE_UBLOX_SENTENCE_TYPE_RTCM - } currentSentence = SFE_UBLOX_SENTENCE_TYPE_NONE; - -// A default of 250ms for maxWait seems fine for I2C but is not enough for -// SerialUSB. If you know you are only going to be using I2C / Qwiic -// communication, you can safely reduce defaultMaxWait to 250. -#ifndef defaultMaxWait // Let's allow the user to define their own value if - // they want to -#define defaultMaxWait 1100 -#endif - - // New in v2.0: allow the payload size for packetCfg to be changed - bool setPacketCfgPayloadSize( - size_t payloadSize); // Set packetCfgPayloadSize - size_t getPacketCfgSpaceRemaining(); // Returns the number of free bytes - // remaining in packetCfgPayload - - // Begin communication with the GNSS. Advanced users can assume success if - // required. Useful if the port is already outputting messages at high - // navigation rate. Begin will then return true if "signs of life" have been - // seen: reception of _any_ valid UBX packet or _any_ valid NMEA header. By - // default use the default I2C address, and use Wire port - bool begin( - TwoWire &wirePort = Wire, uint8_t deviceAddress = 0x42, - uint16_t maxWait = defaultMaxWait, - bool assumeSuccess = false); // Returns true if module is detected - // serialPort needs to be perviously initialized to correct baud rate - bool begin( - Stream &serialPort, uint16_t maxWait = defaultMaxWait, - bool assumeSuccess = false); // Returns true if module is detected - // SPI - supply instance of SPIClass, chip select pin and SPI speed (in Hz) - bool begin(SPIClass &spiPort, uint8_t csPin, uint32_t spiSpeed, - uint16_t maxWait = defaultMaxWait, bool assumeSuccess = false); - - void end(void); // Stop all automatic message processing. Free all used RAM - - void setI2CpollingWait( - uint8_t newPollingWait_ms); // Allow the user to change the I2C polling - // wait if required - void setSPIpollingWait( - uint8_t newPollingWait_ms); // Allow the user to change the SPI polling - // wait if required - - // Set the max number of bytes set in a given I2C transaction - uint8_t i2cTransactionSize = 32; // Default to ATmega328 limit - - // Control the size of the internal I2C transaction amount - void setI2CTransactionSize(uint8_t bufferSize); - uint8_t getI2CTransactionSize(void); - - // Support for platforms like ESP32 which do not support multiple I2C - // restarts If _i2cStopRestart is true, endTransmission will always use a - // stop. If false, a restart will be used where needed. The default value - // for _i2cStopRestart is set in the class instantiation code. - void setI2cStopRestart(bool stop) { _i2cStopRestart = stop; }; - bool getI2cStopRestart(void) { return (_i2cStopRestart); }; - - // Control the size of the spi buffer. If the buffer isn't big enough, we'll - // start to lose bytes That we receive if the buffer is full! - void setSpiTransactionSize(uint8_t bufferSize); - uint8_t getSpiTransactionSize(void); - - // Control the size of maxNMEAByteCount - void setMaxNMEAByteCount(int8_t newMax); - int8_t getMaxNMEAByteCount(void); - - // Returns true if device answers on _gpsI2Caddress address or via Serial - bool isConnected(uint16_t maxWait = defaultMaxWait); - -// Enable debug messages using the chosen Serial port (Stream) -// Boards like the RedBoard Turbo use SerialUSB (not Serial). -// But other boards like the SAMD51 Thing Plus use Serial (not SerialUSB). -// These lines let the code compile cleanly on as many SAMD boards as possible. -#if defined(ARDUINO_ARCH_SAMD) // Is this a SAMD board? -#if defined(USB_VID) // Is the USB Vendor ID defined? -#if (USB_VID == 0x1B4F) // Is this a SparkFun board? -#if !defined(ARDUINO_SAMD51_THING_PLUS) & \ - !defined(ARDUINO_SAMD51_MICROMOD) // If it is not a SAMD51 Thing Plus or - // SAMD51 MicroMod - void enableDebugging(Stream &debugPort = SerialUSB, - bool printLimitedDebug = - false); // Given a port to print to, enable debug - // messages. Default to all, not limited. -#else - void enableDebugging(Stream &debugPort = Serial, - bool printLimitedDebug = - false); // Given a port to print to, enable debug - // messages. Default to all, not limited. -#endif -#else - void enableDebugging(Stream &debugPort = Serial, - bool printLimitedDebug = - false); // Given a port to print to, enable debug - // messages. Default to all, not limited. -#endif -#else - void enableDebugging(Stream &debugPort = Serial, - bool printLimitedDebug = - false); // Given a port to print to, enable debug - // messages. Default to all, not limited. -#endif -#else - void enableDebugging(Stream &debugPort = Serial, - bool printLimitedDebug = - false); // Given a port to print to, enable debug - // messages. Default to all, not limited. -#endif - - void disableDebugging(void); // Turn off debug statements - void debugPrint(char *message); // Safely print debug statements - void debugPrintln(char *message); // Safely print debug statements - const char *statusString( - sfe_ublox_status_e stat); // Pretty print the return value - - // Check for the arrival of new I2C/Serial data - - void disableUBX7Fcheck( - bool disabled = true); // When logging RAWX data, we need to be able to - // disable the "7F" check in checkUbloxI2C - - // Changed in V1.8.1: provides backward compatibility for the examples that - // call checkUblox directly Will default to using packetCfg to look for - // explicit autoPVT packets so they get processed correctly by processUBX - bool checkUblox( - uint8_t requestedClass = 0, - uint8_t requestedID = 0); // Checks module with user selected commType - - bool checkUbloxI2C( - ubxPacket *incomingUBX, uint8_t requestedClass, - uint8_t requestedID); // Method for I2C polling of data, passing any - // new bytes to process() - bool checkUbloxSerial( - ubxPacket *incomingUBX, uint8_t requestedClass, - uint8_t requestedID); // Method for serial polling of data, passing any - // new bytes to process() - bool checkUbloxSpi( - ubxPacket *incomingUBX, uint8_t requestedClass, - uint8_t requestedID); // Method for spi polling of data, passing any - // new bytes to process() - - // Process the incoming data - - void process(uint8_t incoming, ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID); // Processes NMEA and UBX binary - // sentences one byte at a time - void processNMEA(char incoming) - __attribute__((weak)); // Given a NMEA character, do something with it. - // User can overwrite if desired to use - // something like tinyGPS or MicroNMEA libraries - virtual void processNMEA_v( - char incoming); // Given a NMEA character, do something with it. User - // can overwrite if desired to use something like - // tinyGPS or MicroNMEA libraries - sfe_ublox_sentence_types_e processRTCMframe(uint8_t incoming, - uint16_t *rtcmFrameCounter) - __attribute__(( - weak)); // Monitor the incoming bytes for start and length bytes - virtual sfe_ublox_sentence_types_e processRTCMframe_v( - uint8_t incoming, - uint16_t *rtcmFrameCounter); // Monitor the incoming bytes for start - // and length bytes - void processRTCM(uint8_t incoming) __attribute__(( - weak)); // Given rtcm byte, do something with it. User can overwrite if - // desired to pipe bytes to radio, internet, etc. - virtual void processRTCM_v( - uint8_t incoming); // Given rtcm byte, do something with it. User can - // overwrite if desired to pipe bytes to radio, - // internet, etc. - void processUBX(uint8_t incoming, ubxPacket *incomingUBX, - uint8_t requestedClass, - uint8_t requestedID); // Given a character, file it away - // into the uxb packet structure - void processUBXpacket( - ubxPacket - *msg); // Once a packet has been received and validated, identify - // this packet's class/id and update internal flags - - // Send I2C/Serial/SPI commands to the module - - void calcChecksum(ubxPacket *msg); // Sets the checksumA and checksumB of a - // given messages - sfe_ublox_status_e sendCommand( - ubxPacket *outgoingUBX, uint16_t maxWait = defaultMaxWait, - bool expectACKonly = - false); // Given a packet and payload, send everything including - // CRC bytes, return true if we got a response - sfe_ublox_status_e sendI2cCommand(ubxPacket *outgoingUBX, - uint16_t maxWait = defaultMaxWait); - void sendSerialCommand(ubxPacket *outgoingUBX); - void sendSpiCommand(ubxPacket *outgoingUBX); - - void printPacket(ubxPacket *packet, - bool alwaysPrintPayload = false); // Useful for debugging - - // After sending a message to the module, wait for the expected response - // (data+ACK or just data) - - sfe_ublox_status_e waitForACKResponse( - ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, - uint16_t maxTime = - defaultMaxWait); // Poll the module until a config packet and an - // ACK is received, or just an ACK - sfe_ublox_status_e waitForNoACKResponse( - ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, - uint16_t maxTime = defaultMaxWait); // Poll the module until a config - // packet is received - - // Check if any callbacks need to be called - void checkCallbacks(void); - - // Push (e.g.) RTCM data directly to the module - // Warning: this function does not check that the data is valid. It is the - // user's responsibility to ensure the data is valid before pushing. Default - // to using a restart between transmissions. But processors like ESP32 seem - // to need a stop (#30). Set stop to true to use a stop instead. - bool pushRawData(uint8_t *dataBytes, size_t numDataBytes, - bool stop = false); - -// Push MGA AssistNow data to the module. -// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE). -// Wait for maxWait millis after sending each packet (if mgaAck is NO). -// Return how many bytes were pushed successfully. -// If skipTime is true, any UBX-MGA-INI-TIME_UTC or UBX-MGA-INI-TIME_GNSS -// packets found in the data will be skipped, allowing the user to override with -// their own time data with setUTCTimeAssistance. offset allows a sub-set of the -// data to be sent - starting from offset. -#define defaultMGAdelay \ - 7 // Default to waiting for 7ms between each MGA message - size_t pushAssistNowData( - const String &dataBytes, size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - size_t pushAssistNowData( - const uint8_t *dataBytes, size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - size_t pushAssistNowData( - bool skipTime, const String &dataBytes, size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - size_t pushAssistNowData( - bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - size_t pushAssistNowData( - size_t offset, bool skipTime, const String &dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - size_t pushAssistNowData( - size_t offset, bool skipTime, const uint8_t *dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - -// Provide initial time assistance -#define defaultMGAINITIMEtAccS \ - 2 // Default to setting the seconds time accuracy to 2 seconds -#define defaultMGAINITIMEtAccNs \ - 0 // Default to setting the nanoseconds time accuracy to zero -#define defaultMGAINITIMEsource \ - 0 // Set default source to none, i.e. on receipt of message (will be - // inaccurate!) - bool setUTCTimeAssistance( - uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, - uint8_t second, uint32_t nanos = 0, - uint16_t tAccS = defaultMGAINITIMEtAccS, - uint32_t tAccNs = defaultMGAINITIMEtAccNs, - uint8_t source = defaultMGAINITIMEsource, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - - // Provide initial position assistance - // The units for ecefX/Y/Z and posAcc (stddev) are cm. - bool setPositionAssistanceXYZ( - int32_t ecefX, int32_t ecefY, int32_t ecefZ, uint32_t posAcc, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - // The units for lat and lon are degrees * 1e-7 (WGS84) - // The units for alt (WGS84) and posAcc (stddev) are cm. - bool setPositionAssistanceLLH( - int32_t lat, int32_t lon, int32_t alt, uint32_t posAcc, - sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, - uint16_t maxWait = defaultMGAdelay); - - // Find the start of the AssistNow Offline (UBX_MGA_ANO) data for the chosen - // day The daysIntoFture parameter makes it easy to get the data for (e.g.) - // tomorrow based on today's date Returns numDataBytes if unsuccessful TO - // DO: enhance this so it will find the nearest data for the chosen day - - // instead of an exact match - size_t findMGAANOForDate(const String &dataBytes, size_t numDataBytes, - uint16_t year, uint8_t month, uint8_t day, - uint8_t daysIntoFuture = 0); - size_t findMGAANOForDate(const uint8_t *dataBytes, size_t numDataBytes, - uint16_t year, uint8_t month, uint8_t day, - uint8_t daysIntoFuture = 0); - -// Read the whole navigation data base. The receiver will send all available -// data from its internal database. Data is written to dataBytes. Set -// maxNumDataBytes to the (maximum) size of dataBytes. If the database exceeds -// maxNumDataBytes, the excess bytes will be lost. The function returns the -// number of database bytes written to dataBytes. The return value will be equal -// to maxNumDataBytes if excess data was received. The function will timeout -// after maxWait milliseconds - in case the final UBX-MGA-ACK was missed. -#define defaultNavDBDMaxWait 3100 - size_t readNavigationDatabase(uint8_t *dataBytes, size_t maxNumDataBytes, - uint16_t maxWait = defaultNavDBDMaxWait); - - // Support for data logging - void setFileBufferSize( - uint16_t bufferSize); // Set the size of the file buffer. This must be - // called _before_ .begin. - uint16_t getFileBufferSize(void); // Return the size of the file buffer - uint16_t extractFileBufferData( - uint8_t *destination, - uint16_t - numBytes); // Extract numBytes of data from the file buffer. Copy - // it to destination. It is the user's responsibility to - // ensure destination is large enough. - uint16_t fileBufferAvailable( - void); // Returns the number of bytes available in file buffer which - // are waiting to be read - uint16_t getMaxFileBufferAvail( - void); // Returns the maximum number of bytes which the file buffer has - // contained. Handy for checking the buffer is large enough to - // handle all the incoming data. - void clearFileBuffer(void); // Empty the file buffer - discard all contents - void clearMaxFileBufferAvail(void); // Reset fileBufferMaxAvail - - // Specific commands - - // Port configurations - bool getPortSettings( - uint8_t portID, - uint16_t maxWait = - defaultMaxWait); // Returns the current protocol bits in the - // UBX-CFG-PRT command for a given port - bool setPortOutput( - uint8_t portID, uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure a given port to output UBX, NMEA, - // RTCM3, SPARTN or a combination thereof - bool setPortInput( - uint8_t portID, uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure a given port to input UBX, NMEA, - // RTCM3, SPARTN or a combination thereof - - bool setI2CAddress( - uint8_t deviceAddress, - uint16_t maxTime = - defaultMaxWait); // Changes the I2C address of the u-blox module - void setSerialRate( - uint32_t baudrate, uint8_t uartPort = COM_PORT_UART1, - uint16_t maxTime = - defaultMaxWait); // Changes the serial baud rate of the u-blox - // module, uartPort should be COM_PORT_UART1/2 - - bool setI2COutput( - uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure I2C port to output UBX, NMEA, RTCM3, - // SPARTN or a combination thereof - bool setUART1Output( - uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure UART1 port to output UBX, NMEA, - // RTCM3, SPARTN or a combination thereof - bool setUART2Output( - uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure UART2 port to output UBX, NMEA, - // RTCM3, SPARTN or a combination thereof - bool setUSBOutput( - uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure USB port to output UBX, NMEA, RTCM3, - // SPARTN or a combination thereof - bool setSPIOutput( - uint8_t comSettings, - uint16_t maxWait = - defaultMaxWait); // Configure SPI port to output UBX, NMEA, RTCM3, - // SPARTN or a combination thereof - void setNMEAOutputPort( - Stream &nmeaOutputPort); // Sets the internal variable for the port to - // direct NMEA characters to - void setOutputPort( - Stream &outputPort); // Sets the internal variable for the port to - // direct ALL characters to - - // Reset to defaults - - void factoryReset(); // Send factory reset sequence (i.e. load "default" - // configuration and perform hardReset) - void hardReset(); // Perform a reset leading to a cold start (zero info - // start-up) - void softwareResetGNSSOnly(); // Controlled Software Reset (GNSS only) only - // restarts the GNSS tasks, without - // reinitializing the full system or - // reloading any stored configuration. - bool factoryDefault( - uint16_t maxWait = defaultMaxWait); // Reset module to factory defaults - - // Save configuration to BBR / Flash - - bool saveConfiguration( - uint16_t maxWait = - defaultMaxWait); // Save current configuration to flash and BBR - // (battery backed RAM) - bool saveConfigSelective( - uint32_t configMask, - uint16_t maxWait = - defaultMaxWait); // Save the selected configuration sub-sections to - // flash and BBR (battery backed RAM) - - // Functions to turn on/off message types for a given port ID (see - // COM_PORT_I2C, etc above) - bool configureMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, - uint8_t sendRate, uint16_t maxWait = defaultMaxWait); - bool enableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, - uint8_t sendRate = 1, uint16_t maxWait = defaultMaxWait); - bool disableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, - uint16_t maxWait = defaultMaxWait); - bool enableNMEAMessage(uint8_t msgID, uint8_t portID, uint8_t sendRate = 1, - uint16_t maxWait = defaultMaxWait); - bool disableNMEAMessage(uint8_t msgID, uint8_t portID, - uint16_t maxWait = defaultMaxWait); - bool enableRTCMmessage( - uint8_t messageNumber, uint8_t portID, uint8_t sendRate, - uint16_t maxWait = - defaultMaxWait); // Given a message number turns on a message ID - // for output over given PortID - bool disableRTCMmessage( - uint8_t messageNumber, uint8_t portID, - uint16_t maxWait = - defaultMaxWait); // Turn off given RTCM message from a given port - - // Functions used for RTK and base station setup - bool getSurveyMode( - uint16_t maxWait = - defaultMaxWait); // Get the current TimeMode3 settings - bool getSurveyMode( - UBX_CFG_TMODE3_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Get the current TimeMode3 settings - bool setSurveyMode( - uint8_t mode, uint16_t observationTime, float requiredAccuracy, - uint16_t maxWait = defaultMaxWait); // Control survey in mode - bool setSurveyModeFull( - uint8_t mode, uint32_t observationTime, float requiredAccuracy, - uint16_t maxWait = defaultMaxWait); // Control survey in mode - bool enableSurveyMode( - uint16_t observationTime, float requiredAccuracy, - uint16_t maxWait = - defaultMaxWait); // Begin Survey-In for NEO-M8P / ZED-F9x - bool enableSurveyModeFull( - uint32_t observationTime, float requiredAccuracy, - uint16_t maxWait = - defaultMaxWait); // Begin Survey-In for NEO-M8P / ZED-F9x - bool disableSurveyMode( - uint16_t maxWait = defaultMaxWait); // Stop Survey-In mode - // Given coordinates, put receiver into static position. Set latlong to true - // to pass in lat/long values instead of ecef. For ECEF the units are: cm, - // 0.1mm, cm, 0.1mm, cm, 0.1mm For Lat/Lon/Alt the units are: degrees^-7, - // degrees^-9, degrees^-7, degrees^-9, cm, 0.1mm - bool setStaticPosition(int32_t ecefXOrLat, int8_t ecefXOrLatHP, - int32_t ecefYOrLon, int8_t ecefYOrLonHP, - int32_t ecefZOrAlt, int8_t ecefZOrAltHP, - bool latLong = false, - uint16_t maxWait = defaultMaxWait); - bool setStaticPosition(int32_t ecefXOrLat, int32_t ecefYOrLon, - int32_t ecefZOrAlt, bool latLong = false, - uint16_t maxWait = defaultMaxWait); - bool setDGNSSConfiguration( - sfe_ublox_dgnss_mode_e dgnssMode = SFE_UBLOX_DGNSS_MODE_FIXED, - uint16_t maxWait = defaultMaxWait); // Set the DGNSS differential mode - - // Read the module's protocol version - uint8_t getProtocolVersionHigh( - uint16_t maxWait = defaultMaxWait); // Returns the PROTVER XX.00 from - // UBX-MON-VER register - uint8_t getProtocolVersionLow( - uint16_t maxWait = defaultMaxWait); // Returns the PROTVER 00.XX from - // UBX-MON-VER register - bool getProtocolVersion( - uint16_t maxWait = - defaultMaxWait); // Queries module, loads low/high bytes - moduleSWVersion_t *moduleSWVersion = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - // Support for geofences - bool addGeofence(int32_t latitude, int32_t longitude, uint32_t radius, - byte confidence = 0, byte pinPolarity = 0, byte pin = 0, - uint16_t maxWait = defaultMaxWait); // Add a new geofence - bool clearGeofences( - uint16_t maxWait = defaultMaxWait); // Clears all geofences - bool clearAntPIO( - uint16_t maxWait = defaultMaxWait); // Clears the antenna control pin - // settings to release the PIOs - bool getGeofenceState( - geofenceState ¤tGeofenceState, - uint16_t maxWait = - defaultMaxWait); // Returns the combined geofence state - // Storage for the geofence parameters. RAM is allocated for this if/when - // required. - geofenceParams_t *currentGeofenceParams = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - // Power save / off - bool powerSaveMode(bool power_save = true, - uint16_t maxWait = defaultMaxWait); - uint8_t getPowerSaveMode( - uint16_t maxWait = - defaultMaxWait); // Returns 255 if the sendCommand fails - bool powerOff(uint32_t durationInMs, uint16_t maxWait = defaultMaxWait); - bool powerOffWithInterrupt( - uint32_t durationInMs, - uint32_t wakeupSources = VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0, - bool forceWhileUsb = true, uint16_t maxWait = defaultMaxWait); - // Power Mode Setup. Values period and onTime are only valid if mode is - // SFE_UBLOX_PMS_MODE_INTERVAL - bool setPowerManagement(sfe_ublox_pms_mode_e mode, uint16_t period = 0, - uint16_t onTime = 0, - uint16_t maxWait = defaultMaxWait); - bool setupPowerMode(sfe_ublox_rxm_mode_e mode, - uint16_t maxWait = defaultMaxWait); - - // Change the dynamic platform model using UBX-CFG-NAV5 - bool setDynamicModel(dynModel newDynamicModel = DYN_MODEL_PORTABLE, - uint16_t maxWait = defaultMaxWait); - uint8_t getDynamicModel( - uint16_t maxWait = defaultMaxWait); // Get the dynamic model - returns - // 255 if the sendCommand fails - - // Reset / enable / configure the odometer - bool resetOdometer( - uint16_t maxWait = defaultMaxWait); // Reset the odometer - bool enableOdometer( - bool enable = true, - uint16_t maxWait = defaultMaxWait); // Enable / disable the odometer - bool getOdometerConfig( - uint8_t *flags, uint8_t *odoCfg, uint8_t *cogMaxSpeed, - uint8_t *cogMaxPosAcc, uint8_t *velLpGain, uint8_t *cogLpGain, - uint16_t maxWait = defaultMaxWait); // Read the odometer configuration - bool setOdometerConfig( - uint8_t flags, uint8_t odoCfg, uint8_t cogMaxSpeed, - uint8_t cogMaxPosAcc, uint8_t velLpGain, uint8_t cogLpGain, - uint16_t maxWait = defaultMaxWait); // Configure the odometer - - // Enable/Disable individual GNSS systems using UBX-CFG-GNSS - // Note: you must leave at least one major GNSS enabled! If in doubt, enable - // GPS before disabling the others TO DO: Add support for sigCfgMask and - // maxTrkCh. (Need to resolve ambiguity with maxWait) - bool enableGNSS(bool enable, sfe_ublox_gnss_ids_e id, - uint16_t maxWait = defaultMaxWait); - bool isGNSSenabled(sfe_ublox_gnss_ids_e id, - uint16_t maxWait = defaultMaxWait); - - // Reset ESF automatic IMU-mount alignment - bool resetIMUalignment(uint16_t maxWait = defaultMaxWait); - - // Enable/disable esfAutoAlignment - bool getESFAutoAlignment(uint16_t maxWait = defaultMaxWait); - bool setESFAutoAlignment(bool enable, uint16_t maxWait = defaultMaxWait); - - // Configure Time Pulse Parameters - bool getTimePulseParameters( - UBX_CFG_TP5_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Get the time pulse parameters using UBX_CFG_TP5 - bool setTimePulseParameters( - UBX_CFG_TP5_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Set the time pulse parameters using UBX_CFG_TP5 - - // Jamming/interference monitor configuration - bool getJammingConfiguration( - UBX_CFG_ITFM_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Get the jamming/interference monitor - // configuration using UBX_CFG_ITFM - bool setJammingConfiguration( - UBX_CFG_ITFM_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Set the jamming/interference monitor - // configuration using UBX_CFG_ITFM - - // RF Information (including jamming) - ZED-F9 only - bool getRFinformation( - UBX_MON_RF_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Get the RF information using UBX_MON_RF - - // Hardware status (including jamming) - bool getHWstatus( - UBX_MON_HW_data_t *data = NULL, - uint16_t maxWait = - defaultMaxWait); // Get the hardware status using UBX_MON_HW - - // Extended hardware status - bool getHW2status( - UBX_MON_HW2_data_t *data = NULL, - uint16_t maxWait = defaultMaxWait); // Get the extended hardware status - // using UBX_MON_HW2 - - // UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, - // UBX-MGA-ACK messages will be sent by the module to acknowledge the MGA - // data - uint8_t getAckAiding( - uint16_t maxWait = defaultMaxWait); // Get the ackAiding byte - returns - // 255 if the sendCommand fails - bool setAckAiding( - uint8_t ackAiding, - uint16_t maxWait = defaultMaxWait); // Set the ackAiding byte - - // AssistNow Autonomous support - // UBX-CFG-NAVX5 - get/set the aopCfg byte and set the aopOrdMaxErr word. If - // aopOrbMaxErr is 0 (default), the max orbit error is reset to the firmware - // default. - uint8_t getAopCfg( - uint16_t maxWait = - defaultMaxWait); // Get the AssistNow Autonomous configuration - // (aopCfg) - returns 255 if the sendCommand fails - bool setAopCfg( - uint8_t aopCfg, uint16_t aopOrbMaxErr = 0, - uint16_t maxWait = - defaultMaxWait); // Set the aopCfg byte and the aopOrdMaxErr word - - // SPARTN dynamic keys - //"When the receiver boots, the host should send 'current' and 'next' keys - //in one message." - Use setDynamicSPARTNKeys for this. "Every time the - //'current' key is expired, 'next' takes its place." "Therefore the host - //should then retrieve the new 'next' key and send only that." - Use - //setDynamicSPARTNKey for this. - // The key can be provided in binary (uint8_t) format or in ASCII Hex (char) - // format, but in both cases keyLengthBytes _must_ represent the binary key - // length in bytes. - bool setDynamicSPARTNKey(uint8_t keyLengthBytes, uint16_t validFromWno, - uint32_t validFromTow, const char *key); - bool setDynamicSPARTNKey(uint8_t keyLengthBytes, uint16_t validFromWno, - uint32_t validFromTow, const uint8_t *key); - bool setDynamicSPARTNKeys(uint8_t keyLengthBytes1, uint16_t validFromWno1, - uint32_t validFromTow1, const char *key1, - uint8_t keyLengthBytes2, uint16_t validFromWno2, - uint32_t validFromTow2, const char *key2); - bool setDynamicSPARTNKeys(uint8_t keyLengthBytes1, uint16_t validFromWno1, - uint32_t validFromTow1, const uint8_t *key1, - uint8_t keyLengthBytes2, uint16_t validFromWno2, - uint32_t validFromTow2, const uint8_t *key2); - - // General configuration (used only on protocol v27 and higher - ie, - // ZED-F9P) - - uint32_t createKey(uint16_t group, uint16_t id, - uint8_t size); // Form 32-bit key from group/id/size - sfe_ublox_status_e getVal( - uint32_t keyID, uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Load payload with response - uint8_t getVal8(uint32_t keyID, uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Returns the value at - // a given key location - uint16_t getVal16( - uint32_t keyID, uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = - defaultMaxWait); // Returns the value at a given key location - uint32_t getVal32( - uint32_t keyID, uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = - defaultMaxWait); // Returns the value at a given key location - uint64_t getVal64( - uint32_t keyID, uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = - defaultMaxWait); // Returns the value at a given key location - uint8_t getVal8( - uint16_t group, uint16_t id, uint8_t size, - uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Returns the value at a given - // group/id/size location - uint16_t getVal16( - uint16_t group, uint16_t id, uint8_t size, - uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Returns the value at a given - // group/id/size location - uint32_t getVal32( - uint16_t group, uint16_t id, uint8_t size, - uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Returns the value at a given - // group/id/size location - uint64_t getVal64( - uint16_t group, uint16_t id, uint8_t size, - uint8_t layer = VAL_LAYER_RAM, - uint16_t maxWait = defaultMaxWait); // Returns the value at a given - // group/id/size location - uint8_t setVal( - uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL, - uint16_t maxWait = defaultMaxWait); // Sets the 16-bit value at a given - // group/id/size location - uint8_t setVal8( - uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_ALL, - uint16_t maxWait = defaultMaxWait); // Sets the 8-bit value at a given - // group/id/size location - uint8_t setVal16( - uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL, - uint16_t maxWait = defaultMaxWait); // Sets the 16-bit value at a given - // group/id/size location - uint8_t setVal32( - uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_ALL, - uint16_t maxWait = defaultMaxWait); // Sets the 32-bit value at a given - // group/id/size location - uint8_t setVal64( - uint32_t keyID, uint64_t value, uint8_t layer = VAL_LAYER_ALL, - uint16_t maxWait = defaultMaxWait); // Sets the 64-bit value at a given - // group/id/size location - uint8_t newCfgValset( - uint8_t layer = - VAL_LAYER_ALL); // Create a new, empty UBX-CFG-VALSET. Add entries - // with addCfgValset8/16/32/64 - uint8_t newCfgValset8( - uint32_t keyID, uint8_t value, - uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the - // given KeyID and 8-bit value - uint8_t newCfgValset16( - uint32_t keyID, uint16_t value, - uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the - // given KeyID and 16-bit value - uint8_t newCfgValset32( - uint32_t keyID, uint32_t value, - uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the - // given KeyID and 32-bit value - uint8_t newCfgValset64( - uint32_t keyID, uint64_t value, - uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the - // given KeyID and 64-bit value - uint8_t addCfgValset8( - uint32_t keyID, uint8_t value); // Add a new KeyID and 8-bit value to - // an existing UBX-CFG-VALSET ubxPacket - uint8_t addCfgValset16( - uint32_t keyID, - uint16_t value); // Add a new KeyID and 16-bit value to an existing - // UBX-CFG-VALSET ubxPacket - uint8_t addCfgValset32( - uint32_t keyID, - uint32_t value); // Add a new KeyID and 32-bit value to an existing - // UBX-CFG-VALSET ubxPacket - uint8_t addCfgValset64( - uint32_t keyID, - uint64_t value); // Add a new KeyID and 64-bit value to an existing - // UBX-CFG-VALSET ubxPacket - uint8_t sendCfgValset8( - uint32_t keyID, uint8_t value, - uint16_t maxWait = - defaultMaxWait); // Add the final KeyID and 8-bit value to an - // existing UBX-CFG-VALSET ubxPacket and send it - uint8_t sendCfgValset16( - uint32_t keyID, uint16_t value, - uint16_t maxWait = - defaultMaxWait); // Add the final KeyID and 16-bit value to an - // existing UBX-CFG-VALSET ubxPacket and send it - uint8_t sendCfgValset32( - uint32_t keyID, uint32_t value, - uint16_t maxWait = - defaultMaxWait); // Add the final KeyID and 32-bit value to an - // existing UBX-CFG-VALSET ubxPacket and send it - uint8_t sendCfgValset64( - uint32_t keyID, uint64_t value, - uint16_t maxWait = - defaultMaxWait); // Add the final KeyID and 64-bit value to an - // existing UBX-CFG-VALSET ubxPacket and send it - uint8_t sendCfgValset( - uint16_t maxWait = - defaultMaxWait); // Send the CfgValset (UBX-CFG-VALSET) construct - uint8_t getCfgValsetLen(); // Returns the length of the current CfgValset - // construct as number-of-keyIDs - size_t getCfgValsetSpaceRemaining(); // Returns the number of free bytes - // remaining in packetCfg - void autoSendCfgValsetAtSpaceRemaining(size_t spaceRemaining) { - _autoSendAtSpaceRemaining = spaceRemaining; - } // Cause CFG_VALSET packets to be sent automatically when packetCfg has - // less than this many bytes available - - // get and set functions for all of the "automatic" message processing - - // Navigation (NAV) - - // getPVT will only return data once in each navigation cycle. By default, - // that is once per second. Therefore we should set defaultMaxWait to - // slightly longer than that. If you change the navigation frequency to - // (e.g.) 4Hz using setNavigationFrequency(4) then you should use a shorter - // maxWait. 300msec would be about right: getPVT(300) - - bool getNAVPOSECEF(uint16_t maxWait = defaultMaxWait); // NAV POSECEF - bool setAutoNAVPOSECEF( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic POSECEF reports at the - // navigation frequency - bool setAutoNAVPOSECEF( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic POSECEF reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVPOSECEFrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic POSECEF reports - bool setAutoNAVPOSECEFcallback( - void (*callbackPointer)(UBX_NAV_POSECEF_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic POSECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVPOSECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_POSECEF_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic POSECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVPOSECEF( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // POSECEF is send cyclically already - void flushNAVPOSECEF(); // Mark all the data as read/stale - void logNAVPOSECEF(bool enabled = true); // Log data to file buffer - - bool getNAVSTATUS(uint16_t maxWait = defaultMaxWait); // NAV STATUS - bool setAutoNAVSTATUS( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic STATUS reports at the - // navigation frequency - bool setAutoNAVSTATUS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic STATUS reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVSTATUSrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic STATUS reports - bool setAutoNAVSTATUScallback( - void (*callbackPointer)(UBX_NAV_STATUS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic STATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_STATUS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic STATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVSTATUS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // STATUS is send cyclically already - void flushNAVSTATUS(); // Mark all the data as read/stale - void logNAVSTATUS(bool enabled = true); // Log data to file buffer - - bool getDOP( - uint16_t maxWait = - defaultMaxWait); // Query module for latest dilution of precision - // values and load global vars:. If autoDOP is - // disabled, performs an explicit poll and waits, - // if enabled does not block. Returns true if new - // DOP is available. - bool setAutoDOP(bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic DOP - // reports at the navigation frequency - bool setAutoDOP( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic DOP reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoDOPrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic DOP reports - bool setAutoDOPcallback( - void (*callbackPointer)(UBX_NAV_DOP_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic DOP reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoDOPcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_DOP_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic DOP reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoDOP( - bool enabled, bool implicitUpdate = - true); // In case no config access to the GPS is - // possible and DOP is send cyclically already - void flushDOP(); // Mark all the DOP data as read/stale - void logNAVDOP(bool enabled = true); // Log data to file buffer - - bool getVehAtt(uint16_t maxWait = defaultMaxWait); // NAV ATT Helper - bool getNAVATT(uint16_t maxWait = defaultMaxWait); // NAV ATT - bool setAutoNAVATT( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic vehicle attitude - // reports at the navigation frequency - bool setAutoNAVATT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic vehicle attitude - // reports at the navigation frequency, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoNAVATTrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic ATT reports - bool setAutoNAVATTcallback( - void (*callbackPointer)(UBX_NAV_ATT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ATT reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoNAVATTcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_ATT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ATT reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoNAVATT( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // vehicle attitude is send cyclically already - void flushNAVATT(); // Mark all the data as read/stale - void logNAVATT(bool enabled = true); // Log data to file buffer - - bool getPVT(uint16_t maxWait = - defaultMaxWait); // Query module for latest group of datums - // and load global vars: lat, long, alt, - // speed, SIV, accuracies, etc. If autoPVT - // is disabled, performs an explicit poll - // and waits, if enabled does not block. - // Returns true if new PVT is available. - bool setAutoPVT(bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic PVT - // reports at the navigation frequency - bool setAutoPVT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic PVT reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoPVTrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic PVT reports - bool setAutoPVTcallback( - void (*callbackPointer)(UBX_NAV_PVT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVT reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoPVTcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_PVT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVT reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoPVT( - bool enabled, bool implicitUpdate = - true); // In case no config access to the GPS is - // possible and PVT is send cyclically already - void flushPVT(); // Mark all the PVT data as read/stale - void logNAVPVT(bool enabled = true); // Log data to file buffer - - bool getNAVODO(uint16_t maxWait = defaultMaxWait); // NAV ODO - bool setAutoNAVODO( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ODO reports at the - // navigation frequency - bool setAutoNAVODO( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ODO reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVODOrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic ODO reports - bool setAutoNAVODOcallback( - void (*callbackPointer)(UBX_NAV_ODO_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ODO reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoNAVODOcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_ODO_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ODO reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoNAVODO( - bool enabled, bool implicitUpdate = - true); // In case no config access to the GPS is - // possible and ODO is send cyclically already - void flushNAVODO(); // Mark all the data as read/stale - void logNAVODO(bool enabled = true); // Log data to file buffer - - bool getNAVVELECEF(uint16_t maxWait = defaultMaxWait); // NAV VELECEF - bool setAutoNAVVELECEF( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic VELECEF reports at the - // navigation frequency - bool setAutoNAVVELECEF( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic VELECEF reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVVELECEFrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic VELECEF reports - bool setAutoNAVVELECEFcallback( - void (*callbackPointer)(UBX_NAV_VELECEF_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic VELECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVVELECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_VELECEF_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic VELECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVVELECEF( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // VELECEF is send cyclically already - void flushNAVVELECEF(); // Mark all the data as read/stale - void logNAVVELECEF(bool enabled = true); // Log data to file buffer - - bool getNAVVELNED(uint16_t maxWait = defaultMaxWait); // NAV VELNED - bool setAutoNAVVELNED( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic VELNED reports at the - // navigation frequency - bool setAutoNAVVELNED( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic VELNED reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVVELNEDrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic VELNED reports - bool setAutoNAVVELNEDcallback( - void (*callbackPointer)(UBX_NAV_VELNED_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic VELNED reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVVELNEDcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_VELNED_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic VELNED reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVVELNED( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // VELNED is send cyclically already - void flushNAVVELNED(); // Mark all the data as read/stale - void logNAVVELNED(bool enabled = true); // Log data to file buffer - - bool getNAVHPPOSECEF(uint16_t maxWait = defaultMaxWait); // NAV HPPOSECEF - bool setAutoNAVHPPOSECEF( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HPPOSECEF reports at - // the navigation frequency - bool setAutoNAVHPPOSECEF( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HPPOSECEF reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVHPPOSECEFrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic HPPOSECEF reports - bool setAutoNAVHPPOSECEFcallback( - void (*callbackPointer)(UBX_NAV_HPPOSECEF_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic HPPOSECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVHPPOSECEFcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_HPPOSECEF_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic HPPOSECEF reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVHPPOSECEF( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // HPPOSECEF is send cyclically already - void flushNAVHPPOSECEF(); // Mark all the data as read/stale - void logNAVHPPOSECEF(bool enabled = true); // Log data to file buffer - - bool getHPPOSLLH(uint16_t maxWait = defaultMaxWait); // NAV HPPOSLLH - bool setAutoHPPOSLLH( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HPPOSLLH reports at - // the navigation frequency - bool setAutoHPPOSLLH( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HPPOSLLH reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoHPPOSLLHrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic HPPOSLLH reports - bool setAutoHPPOSLLHcallback( - void (*callbackPointer)(UBX_NAV_HPPOSLLH_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic HPPOSLLH reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoHPPOSLLHcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_HPPOSLLH_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic HPPOSLLH reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoHPPOSLLH( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // HPPOSLLH is send cyclically already - void flushHPPOSLLH(); // Mark all the HPPPOSLLH data as read/stale. This is - // handy to get data alignment after CRC failure - void logNAVHPPOSLLH(bool enabled = true); // Log data to file buffer - - bool getNAVPVAT(uint16_t maxWait = defaultMaxWait); // NAV PVAT - bool setAutoNAVPVAT( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic PVAT reports at the - // navigation frequency - bool setAutoNAVPVAT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic PVAT reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVPVATrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic PVAT reports - bool setAutoNAVPVATcallback( - void (*callbackPointer)(UBX_NAV_PVAT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVAT reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoNAVPVATcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_PVAT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVAT reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoNAVPVAT( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and PVAT - // is send cyclically already - void flushNAVPVAT(); // Mark all the PVAT data as read/stale - void logNAVPVAT(bool enabled = true); // Log data to file buffer - - bool getNAVTIMEUTC(uint16_t maxWait = defaultMaxWait); // NAV TIMEUTC - bool setAutoNAVTIMEUTC( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic TIMEUTC reports at the - // navigation frequency - bool setAutoNAVTIMEUTC( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic TIMEUTC reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVTIMEUTCrate( - uint8_t rate, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic TIMEUTC reports - bool setAutoNAVTIMEUTCcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_TIMEUTC_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic TIMEUTC reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVTIMEUTC( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // TIMEUTC is send cyclically already - void flushNAVTIMEUTC(); // Mark all the data as read/stale - void logNAVTIMEUTC(bool enabled = true); // Log data to file buffer - - bool getNAVCLOCK(uint16_t maxWait = defaultMaxWait); // NAV CLOCK - bool setAutoNAVCLOCK( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic clock reports at the - // navigation frequency - bool setAutoNAVCLOCK( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic clock reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVCLOCKrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic CLOCK reports - bool setAutoNAVCLOCKcallback( - void (*callbackPointer)(UBX_NAV_CLOCK_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic CLOCK reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVCLOCKcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_CLOCK_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic CLOCK reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVCLOCK( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and clock - // is send cyclically already - void flushNAVCLOCK(); // Mark all the data as read/stale - void logNAVCLOCK(bool enabled = true); // Log data to file buffer - - bool getSurveyStatus( - uint16_t maxWait = 2100); // NAV SVIN - Reads survey in status - bool setAutoNAVSVIN( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic survey in reports at - // the navigation frequency - bool setAutoNAVSVIN( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic survey in reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVSVINrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic SVIN reports - bool setAutoNAVSVINcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic SVIN reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoNAVSVIN( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // survey in is send cyclically already - void flushNAVSVIN(); // Mark all the data as read/stale - void logNAVSVIN(bool enabled = true); // Log data to file buffer - - bool getNAVEOE( - uint16_t maxWait = - defaultMaxWait); // Query module for latest dilution of precision - // values and load global vars:. If autoEOE is - // disabled, performs an explicit poll and waits, - // if enabled does not block. Returns true if new - // EOE is available. - bool setAutoNAVEOE( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic EOE reports at the - // navigation frequency - bool setAutoNAVEOE( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic EOE reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVEOErate( - uint8_t rate, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic EOE reports - bool setAutoNAVEOEcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_EOE_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic EOE reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoNAVEOE( - bool enabled, bool implicitUpdate = - true); // In case no config access to the GPS is - // possible and EOE is send cyclically already - void flushNAVEOE(); // Mark all the EOE data as read/stale - void logNAVEOE(bool enabled = true); // Log data to file buffer - - // Add "auto" support for NAV TIMELS - to avoid needing 'global' storage - bool getLeapSecondEvent( - uint16_t maxWait = defaultMaxWait); // Reads leap second event info - - bool getNAVSAT( - uint16_t maxWait = - defaultMaxWait); // Query module for latest AssistNow Autonomous - // status and load global vars:. If autoNAVSAT is - // disabled, performs an explicit poll and waits, - // if enabled does not block. Returns true if new - // NAVSAT is available. - bool setAutoNAVSAT( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic NAVSAT reports at the - // navigation frequency - bool setAutoNAVSAT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic NAVSAT reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoNAVSATrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic NAVSAT reports - bool setAutoNAVSATcallback( - void (*callbackPointer)(UBX_NAV_SAT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic NAVSAT reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoNAVSATcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_SAT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic NAVSAT reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoNAVSAT( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // NAVSAT is send cyclically already - void flushNAVSAT(); // Mark all the NAVSAT data as read/stale - void logNAVSAT(bool enabled = true); // Log data to file buffer - - bool getRELPOSNED( - uint16_t maxWait = defaultMaxWait); // Get Relative Positioning - // Information of the NED frame - bool setAutoRELPOSNED( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RELPOSNED reports - bool setAutoRELPOSNED( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RELPOSNED, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoRELPOSNEDrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic RELPOSNEDreports - bool setAutoRELPOSNEDcallback( - void (*callbackPointer)(UBX_NAV_RELPOSNED_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RELPOSNED reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoRELPOSNEDcallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_RELPOSNED_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RELPOSNED reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoRELPOSNED( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // RELPOSNED is send cyclically already - void flushNAVRELPOSNED(); // Mark all the data as read/stale - void logNAVRELPOSNED(bool enabled = true); // Log data to file buffer - - bool getAOPSTATUS( - uint16_t maxWait = - defaultMaxWait); // Query module for latest AssistNow Autonomous - // status and load global vars:. If autoAOPSTATUS - // is disabled, performs an explicit poll and - // waits, if enabled does not block. Returns true - // if new AOPSTATUS is available. - bool setAutoAOPSTATUS( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic AOPSTATUS reports at - // the navigation frequency - bool setAutoAOPSTATUS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic AOPSTATUS reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoAOPSTATUSrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic AOPSTATUS reports - bool setAutoAOPSTATUScallback( - void (*callbackPointer)(UBX_NAV_AOPSTATUS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic AOPSTATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoAOPSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_NAV_AOPSTATUS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic AOPSTATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoAOPSTATUS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and - // AOPSTATUS is send cyclically already - void flushAOPSTATUS(); // Mark all the AOPSTATUS data as read/stale - void logAOPSTATUS(bool enabled = true); // Log data to file buffer - - // Receiver Manager Messages (RXM) - - // Configure a callback for the UBX-RXM-PMP messages produced by the NEO-D9S - // Note: on the NEO-D9S, the UBX-RXM-PMP messages are enabled by default on - // all ports. - // You can disable them by calling (e.g.) - // setVal8(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 0) The NEO-D9S does not - // support UBX-CFG-MSG - bool setRXMPMPcallbackPtr(void (*callbackPointerPtr)( - UBX_RXM_PMP_data_t - *)); // Callback receives a pointer to the data, instead of _all_ - // the data. Much kinder on the stack! - bool setRXMPMPmessageCallbackPtr(void (*callbackPointerPtr)( - UBX_RXM_PMP_message_data_t - *)); // Use this if you want all of the PMP message (including sync - // chars, checksum, etc.) to push to a GNSS - - // Configure a callback for the UBX-RXM-QZSSL6 messages produced by the - // NEO-D9C Note: on the NEO-D9C, the UBX-RXM-QZSSL6 messages are enabled by - // default on all ports. - // You can disable them by calling (e.g.) - // setVal8(UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_I2C, 0) The NEO-D9C does - // not support UBX-CFG-MSG - bool setRXMQZSSL6messageCallbackPtr(void (*callbackPointerPtr)( - UBX_RXM_QZSSL6_message_data_t - *)); // Use this if you want all of the QZSSL6 message (including - // sync chars, checksum, etc.) to push to a GNSS - - bool setRXMCORcallbackPtr( - void (*callbackPointerPtr)(UBX_RXM_COR_data_t *)); // RXM COR - - bool getRXMSFRBX(uint16_t maxWait = defaultMaxWait); // RXM SFRBX - bool setAutoRXMSFRBX( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RXM SFRBX reports at - // the navigation frequency - bool setAutoRXMSFRBX( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RXM SFRBX reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoRXMSFRBXrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic SFRBX reports - bool setAutoRXMSFRBXcallback( - void (*callbackPointer)(UBX_RXM_SFRBX_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic SFRBX reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoRXMSFRBXcallbackPtr( - void (*callbackPointerPtr)(UBX_RXM_SFRBX_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic SFRBX reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoRXMSFRBX( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and RXM - // SFRBX is send cyclically already - void flushRXMSFRBX(); // Mark all the data as read/stale - void logRXMSFRBX(bool enabled = true); // Log data to file buffer - - bool getRXMRAWX(uint16_t maxWait = defaultMaxWait); // RXM RAWX - bool setAutoRXMRAWX( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RXM RAWX reports at - // the navigation frequency - bool setAutoRXMRAWX( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic RXM RAWX reports at - // the navigation frequency, with implicitUpdate - // == false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoRXMRAWXrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic RAWX reports - bool setAutoRXMRAWXcallback( - void (*callbackPointer)(UBX_RXM_RAWX_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RAWX reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoRXMRAWXcallbackPtr( - void (*callbackPointerPtr)(UBX_RXM_RAWX_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RAWX reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoRXMRAWX( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and RXM - // RAWX is send cyclically already - void flushRXMRAWX(); // Mark all the data as read/stale - void logRXMRAWX(bool enabled = true); // Log data to file buffer - - // Configuration (CFG) - - // Add "auto" support for CFG PRT - because we use it for isConnected (to - // stop it being mugged by other messages) - bool getPortSettingsInternal( - uint8_t portID, - uint16_t maxWait = defaultMaxWait); // Read the port configuration for - // a given port using UBX-CFG-PRT - bool getNavigationFrequencyInternal( - uint16_t maxWait = - defaultMaxWait); // Get the number of nav solutions sent per second - // currently being output by module - - // Timing messages (TIM) - - bool getTIMTM2(uint16_t maxWait = defaultMaxWait); // TIM TM2 - bool setAutoTIMTM2( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic TIM TM2 reports at the - // navigation frequency - bool setAutoTIMTM2( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic TIM TM2 reports at the - // navigation frequency, with implicitUpdate == - // false accessing stale data will not issue - // parsing of data in the rxbuffer of your - // interface, instead you have to call checkUblox - // when you want to perform an update - bool setAutoTIMTM2rate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic TIM TM2 reports - bool setAutoTIMTM2callback( - void (*callbackPointer)(UBX_TIM_TM2_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic TM2 reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoTIMTM2callbackPtr( - void (*callbackPointerPtr)(UBX_TIM_TM2_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic TM2 reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoTIMTM2( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and TIM - // TM2 is send cyclically already - void flushTIMTM2(); // Mark all the data as read/stale - void logTIMTM2(bool enabled = true); // Log data to file buffer - - // Sensor fusion (dead reckoning) (ESF) - - bool getEsfAlignment(uint16_t maxWait = defaultMaxWait); // ESF ALG Helper - bool getESFALG(uint16_t maxWait = defaultMaxWait); // ESF ALG - bool setAutoESFALG( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF ALG reports - bool setAutoESFALG( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF ALG reports, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoESFALGrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic ALG reports - bool setAutoESFALGcallback( - void (*callbackPointer)(UBX_ESF_ALG_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ALG reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoESFALGcallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_ALG_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ALG reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoESFALG( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and ESF - // ALG is send cyclically already - void flushESFALG(); // Mark all the data as read/stale - void logESFALG(bool enabled = true); // Log data to file buffer - - bool getEsfInfo(uint16_t maxWait = defaultMaxWait); // ESF STATUS Helper - bool getESFSTATUS(uint16_t maxWait = defaultMaxWait); // ESF STATUS - bool setAutoESFSTATUS( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF STATUS reports - bool setAutoESFSTATUS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF STATUS reports, - // with implicitUpdate == false accessing stale - // data will not issue parsing of data in the - // rxbuffer of your interface, instead you have to - // call checkUblox when you want to perform an - // update - bool setAutoESFSTATUSrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic STATUS reports - bool setAutoESFSTATUScallback( - void (*callbackPointer)(UBX_ESF_STATUS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic STATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool setAutoESFSTATUScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_STATUS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic STATUS reports at the - // navigation frequency. Data is accessed from the - // callback. - bool assumeAutoESFSTATUS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and ESF - // STATUS is send cyclically already - void flushESFSTATUS(); // Mark all the data as read/stale - void logESFSTATUS(bool enabled = true); // Log data to file buffer - - bool getEsfIns(uint16_t maxWait = defaultMaxWait); // ESF INS Helper - bool getESFINS(uint16_t maxWait = defaultMaxWait); // ESF INS - bool setAutoESFINS( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF INS reports - bool setAutoESFINS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF INS reports, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoESFINSrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic INS reports - bool setAutoESFINScallback( - void (*callbackPointer)(UBX_ESF_INS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic INS reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoESFINScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_INS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic INS reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoESFINS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and ESF - // INS is send cyclically already - void flushESFINS(); // Mark all the data as read/stale - void logESFINS(bool enabled = true); // Log data to file buffer - - bool setAutoESFMEAS( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF MEAS reports - bool setAutoESFMEAS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF MEAS reports, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoESFMEASrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic MEAS reports - bool setAutoESFMEAScallback( - void (*callbackPointer)(UBX_ESF_MEAS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic MEAS reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoESFMEAScallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_MEAS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic MEAS reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoESFMEAS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and ESF - // MEAS is send cyclically already - void logESFMEAS(bool enabled = true); // Log data to file buffer - - bool setAutoESFRAW( - bool enabled, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF RAW reports - bool setAutoESFRAW( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic ESF RAW reports, with - // implicitUpdate == false accessing stale data - // will not issue parsing of data in the rxbuffer - // of your interface, instead you have to call - // checkUblox when you want to perform an update - bool setAutoESFRAWrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic RAW reports - bool setAutoESFRAWcallback( - void (*callbackPointer)(UBX_ESF_RAW_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RAW reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoESFRAWcallbackPtr( - void (*callbackPointerPtr)(UBX_ESF_RAW_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic RAW reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoESFRAW( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and ESF - // RAW is send cyclically already - void logESFRAW(bool enabled = true); // Log data to file buffer - - // High navigation rate (HNR) - - bool getHNRAtt(uint16_t maxWait = defaultMaxWait); // HNR ATT Helper - bool getHNRATT( - uint16_t maxWait = defaultMaxWait); // Returns true if the get HNR - // attitude is successful - bool setAutoHNRATT( - bool enabled, - uint16_t maxWait = defaultMaxWait); // Enable/disable automatic HNR - // Attitude reports at the HNR rate - bool setAutoHNRATT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HNR Attitude reports - // at the HNR rate, with implicitUpdate == false - // accessing stale data will not issue parsing of - // data in the rxbuffer of your interface, instead - // you have to call checkUblox when you want to - // perform an update - bool setAutoHNRATTrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic ATT reports - bool setAutoHNRATTcallback( - void (*callbackPointer)(UBX_HNR_ATT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ATT reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoHNRATTcallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_ATT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic ATT reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoHNRATT( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and HNR - // Attitude is send cyclically already - void flushHNRATT(); // Mark all the data as read/stale - void logHNRATT(bool enabled = true); // Log data to file buffer - - bool getHNRDyn(uint16_t maxWait = defaultMaxWait); // HNR INS Helper - bool getHNRINS( - uint16_t maxWait = defaultMaxWait); // Returns true if the get HNR - // dynamics is successful - bool setAutoHNRINS( - bool enabled, - uint16_t maxWait = defaultMaxWait); // Enable/disable automatic HNR - // dynamics reports at the HNR rate - bool setAutoHNRINS( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HNR dynamics reports - // at the HNR rate, with implicitUpdate == false - // accessing stale data will not issue parsing of - // data in the rxbuffer of your interface, instead - // you have to call checkUblox when you want to - // perform an update - bool setAutoHNRINSrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic INS reports - bool setAutoHNRINScallback( - void (*callbackPointer)(UBX_HNR_INS_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic INS reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoHNRINScallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_INS_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic INS reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoHNRINS( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and HNR - // dynamics is send cyclically already - void flushHNRINS(); // Mark all the data as read/stale - void logHNRINS(bool enabled = true); // Log data to file buffer - - bool getHNRPVT( - uint16_t maxWait = - defaultMaxWait); // Returns true if the get HNR PVT is successful - bool setAutoHNRPVT( - bool enabled, - uint16_t maxWait = defaultMaxWait); // Enable/disable automatic HNR PVT - // reports at the HNR rate - bool setAutoHNRPVT( - bool enabled, bool implicitUpdate, - uint16_t maxWait = - defaultMaxWait); // Enable/disable automatic HNR PVT reports at the - // HNR rate, with implicitUpdate == false - // accessing stale data will not issue parsing of - // data in the rxbuffer of your interface, instead - // you have to call checkUblox when you want to - // perform an update - bool setAutoHNRPVTrate( - uint8_t rate, bool implicitUpdate = true, - uint16_t maxWait = - defaultMaxWait); // Set the rate for automatic PVT reports - bool setAutoHNRPVTcallback( - void (*callbackPointer)(UBX_HNR_PVT_data_t), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVT reports at the navigation - // frequency. Data is accessed from the callback. - bool setAutoHNRPVTcallbackPtr( - void (*callbackPointerPtr)(UBX_HNR_PVT_data_t *), - uint16_t maxWait = - defaultMaxWait); // Enable automatic PVT reports at the navigation - // frequency. Data is accessed from the callback. - bool assumeAutoHNRPVT( - bool enabled, - bool implicitUpdate = - true); // In case no config access to the GPS is possible and HNR - // PVT is send cyclically already - void flushHNRPVT(); // Mark all the data as read/stale - void logHNRPVT(bool enabled = true); // Log data to file buffer - - // Helper functions for CFG RATE - - bool setNavigationFrequency( - uint8_t navFreq, - uint16_t maxWait = - defaultMaxWait); // Set the number of nav solutions sent per second - uint8_t getNavigationFrequency( - uint16_t maxWait = - defaultMaxWait); // Get the number of nav solutions sent per second - // currently being output by module - bool setMeasurementRate( - uint16_t rate, - uint16_t maxWait = - defaultMaxWait); // Set the elapsed time between GNSS measurements - // in milliseconds, which defines the rate - uint16_t getMeasurementRate( - uint16_t maxWait = - defaultMaxWait); // Return the elapsed time between GNSS - // measurements in milliseconds - bool setNavigationRate( - uint16_t rate, - uint16_t maxWait = - defaultMaxWait); // Set the ratio between the number of - // measurements and the number of navigation - // solutions. Unit is cycles. Max is 127 - uint16_t getNavigationRate( - uint16_t maxWait = - defaultMaxWait); // Return the ratio between the number of - // measurements and the number of navigation - // solutions. Unit is cycles - void flushCFGRATE(); // Mark the measurement and navigation rate data as - // stale - used by the set rate functions - - // Helper functions for DOP - - uint16_t getGeometricDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getPositionDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getTimeDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getVerticalDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getHorizontalDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getNorthingDOP(uint16_t maxWait = defaultMaxWait); - uint16_t getEastingDOP(uint16_t maxWait = defaultMaxWait); - - // Helper functions for ATT - - float getATTroll(uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getATTpitch( - uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getATTheading( - uint16_t maxWait = defaultMaxWait); // Returned as degrees - - // Helper functions for PVT - - uint32_t getTimeOfWeek(uint16_t maxWait = defaultMaxWait); - uint16_t getYear(uint16_t maxWait = defaultMaxWait); - uint8_t getMonth(uint16_t maxWait = defaultMaxWait); - uint8_t getDay(uint16_t maxWait = defaultMaxWait); - uint8_t getHour(uint16_t maxWait = defaultMaxWait); - uint8_t getMinute(uint16_t maxWait = defaultMaxWait); - uint8_t getSecond(uint16_t maxWait = defaultMaxWait); - uint16_t getMillisecond(uint16_t maxWait = defaultMaxWait); - int32_t getNanosecond(uint16_t maxWait = defaultMaxWait); - uint32_t getUnixEpoch(uint16_t maxWait = defaultMaxWait); - uint32_t getUnixEpoch(uint32_t µsecond, - uint16_t maxWait = defaultMaxWait); - - bool getDateValid(uint16_t maxWait = defaultMaxWait); - bool getTimeValid(uint16_t maxWait = defaultMaxWait); - bool getTimeFullyResolved(uint16_t maxWait = defaultMaxWait); - bool getConfirmedDate(uint16_t maxWait = defaultMaxWait); - bool getConfirmedTime(uint16_t maxWait = defaultMaxWait); - - uint8_t getFixType( - uint16_t maxWait = defaultMaxWait); // Returns the type of fix: 0=no, - // 3=3D, 4=GNSS+Deadreckoning - - bool getGnssFixOk(uint16_t maxWait = - defaultMaxWait); // Get whether we have a valid fix - // (i.e within DOP & accuracy masks) - bool getNAVPVTPSMMode( - uint16_t maxWait = - defaultMaxWait); // Not fully documented power save mode value - bool getDiffSoln( - uint16_t maxWait = defaultMaxWait); // Get whether differential - // corrections were applied - bool getHeadVehValid(uint16_t maxWait = defaultMaxWait); - uint8_t getCarrierSolutionType( - uint16_t maxWait = - defaultMaxWait); // Returns RTK solution: 0=no, 1=float solution, - // 2=fixed solution - - uint8_t getSIV(uint16_t maxWait = - defaultMaxWait); // Returns number of sats used in fix - int32_t getLongitude( - uint16_t maxWait = - defaultMaxWait); // Returns the current longitude in degrees * - // 10-7. Auto selects between HighPrecision and - // Regular depending on ability of module. - int32_t getLatitude( - uint16_t maxWait = - defaultMaxWait); // Returns the current latitude in degrees * - // 10^-7. Auto selects between HighPrecision and - // Regular depending on ability of module. - int32_t getAltitude( - uint16_t maxWait = defaultMaxWait); // Returns the current altitude in - // mm above ellipsoid - int32_t getAltitudeMSL( - uint16_t maxWait = defaultMaxWait); // Returns the current altitude in - // mm above mean sea level - int32_t getHorizontalAccEst(uint16_t maxWait = defaultMaxWait); - int32_t getVerticalAccEst(uint16_t maxWait = defaultMaxWait); - int32_t getNedNorthVel(uint16_t maxWait = defaultMaxWait); - int32_t getNedEastVel(uint16_t maxWait = defaultMaxWait); - int32_t getNedDownVel(uint16_t maxWait = defaultMaxWait); - int32_t getGroundSpeed( - uint16_t maxWait = defaultMaxWait); // Returns speed in mm/s - int32_t getHeading( - uint16_t maxWait = - defaultMaxWait); // Returns heading in degrees * 10^-5 - uint32_t getSpeedAccEst(uint16_t maxWait = defaultMaxWait); - uint32_t getHeadingAccEst(uint16_t maxWait = defaultMaxWait); - uint16_t getPDOP(uint16_t maxWait = - defaultMaxWait); // Returns positional dillution of - // precision * 10^-2 (dimensionless) - - bool getInvalidLlh(uint16_t maxWait = defaultMaxWait); - - int32_t getHeadVeh(uint16_t maxWait = defaultMaxWait); - int16_t getMagDec(uint16_t maxWait = defaultMaxWait); - uint16_t getMagAcc(uint16_t maxWait = defaultMaxWait); - - int32_t getGeoidSeparation(uint16_t maxWait = defaultMaxWait); - - // Helper functions for HPPOSECEF - - uint32_t getPositionAccuracy( - uint16_t maxWait = - defaultMaxWait); // Returns the 3D accuracy of the current - // high-precision fix, in mm. Supported on - // NEO-M8P, ZED-F9P, - int32_t getHighResECEFX( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF X coordinate (cm) - int32_t getHighResECEFY( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF Y coordinate (cm) - int32_t getHighResECEFZ( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF Z coordinate (cm) - int8_t getHighResECEFXHp( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF X coordinate High Precision - // Component (0.1 mm) - int8_t getHighResECEFYHp( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF Y coordinate High Precision - // Component (0.1 mm) - int8_t getHighResECEFZHp( - uint16_t maxWait = - defaultMaxWait); // Returns the ECEF Z coordinate High Precision - // Component (0.1 mm) - - // Helper functions for HPPOSLLH - - uint32_t getTimeOfWeekFromHPPOSLLH(uint16_t maxWait = defaultMaxWait); - int32_t getHighResLongitude(uint16_t maxWait = defaultMaxWait); - int32_t getHighResLatitude(uint16_t maxWait = defaultMaxWait); - int32_t getElipsoid(uint16_t maxWait = defaultMaxWait); - int32_t getMeanSeaLevel(uint16_t maxWait = defaultMaxWait); - int8_t getHighResLongitudeHp(uint16_t maxWait = defaultMaxWait); - int8_t getHighResLatitudeHp(uint16_t maxWait = defaultMaxWait); - int8_t getElipsoidHp(uint16_t maxWait = defaultMaxWait); - int8_t getMeanSeaLevelHp(uint16_t maxWait = defaultMaxWait); - uint32_t getHorizontalAccuracy(uint16_t maxWait = defaultMaxWait); - uint32_t getVerticalAccuracy(uint16_t maxWait = defaultMaxWait); - - // Helper functions for PVAT - - int32_t getVehicleRoll( - uint16_t maxWait = - defaultMaxWait); // Returns vehicle roll in degrees * 10^-5 - int32_t getVehiclePitch( - uint16_t maxWait = - defaultMaxWait); // Returns vehicle pitch in degrees * 10^-5 - int32_t getVehicleHeading( - uint16_t maxWait = - defaultMaxWait); // Returns vehicle heading in degrees * 10^-5 - int32_t getMotionHeading( - uint16_t maxWait = - defaultMaxWait); // Returns the motion heading in degrees * 10^-5 - - // Helper functions for SVIN - - bool getSurveyInActive(uint16_t maxWait = defaultMaxWait); - bool getSurveyInValid(uint16_t maxWait = defaultMaxWait); - uint16_t getSurveyInObservationTime( - uint16_t maxWait = defaultMaxWait); // Truncated to 65535 seconds - uint32_t getSurveyInObservationTimeFull( - uint16_t maxWait = defaultMaxWait); // Return the full uint32_t - float getSurveyInMeanAccuracy( - uint16_t maxWait = defaultMaxWait); // Returned as m - - // Helper functions for TIMELS - - uint8_t getLeapIndicator(int32_t &timeToLsEvent, - uint16_t maxWait = defaultMaxWait); - int8_t getCurrentLeapSeconds(sfe_ublox_ls_src_e &source, - uint16_t maxWait = defaultMaxWait); - - // Helper functions for RELPOSNED - - float getRelPosN(uint16_t maxWait = defaultMaxWait); // Returned as m - float getRelPosE(uint16_t maxWait = defaultMaxWait); // Returned as m - float getRelPosD(uint16_t maxWait = defaultMaxWait); // Returned as m - float getRelPosAccN(uint16_t maxWait = defaultMaxWait); // Returned as m - float getRelPosAccE(uint16_t maxWait = defaultMaxWait); // Returned as m - float getRelPosAccD(uint16_t maxWait = defaultMaxWait); // Returned as m - - // Helper functions for AOPSTATUS - - uint8_t getAOPSTATUSuseAOP( - uint16_t maxWait = - defaultMaxWait); // Returns the UBX-NAV-AOPSTATUS useAOP flag. - // Don't confuse this with getAopCfg - which - // returns the aopCfg byte from UBX-CFG-NAVX5 - uint8_t getAOPSTATUSstatus( - uint16_t maxWait = - defaultMaxWait); // Returns the UBX-NAV-AOPSTATUS status field. A - // host application can determine the optimal time - // to shut down the receiver by monitoring the - // status field for a steady 0. - - // Helper functions for ESF - - float getESFroll(uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getESFpitch( - uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getESFyaw(uint16_t maxWait = defaultMaxWait); // Returned as degrees - bool getSensorFusionMeasurement(UBX_ESF_MEAS_sensorData_t *sensorData, - UBX_ESF_MEAS_data_t ubxDataStruct, - uint8_t sensor); - bool getRawSensorMeasurement(UBX_ESF_RAW_sensorData_t *sensorData, - UBX_ESF_RAW_data_t ubxDataStruct, - uint8_t sensor); - bool getSensorFusionStatus(UBX_ESF_STATUS_sensorStatus_t *sensorStatus, - uint8_t sensor, - uint16_t maxWait = defaultMaxWait); - bool getSensorFusionStatus(UBX_ESF_STATUS_sensorStatus_t *sensorStatus, - UBX_ESF_STATUS_data_t ubxDataStruct, - uint8_t sensor); - - // Helper functions for HNR - - bool setHNRNavigationRate( - uint8_t rate, - uint16_t maxWait = - defaultMaxWait); // Returns true if the setHNRNavigationRate is - // successful - uint8_t getHNRNavigationRate( - uint16_t maxWait = - defaultMaxWait); // Returns 0 if the getHNRNavigationRate fails - float getHNRroll(uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getHNRpitch( - uint16_t maxWait = defaultMaxWait); // Returned as degrees - float getHNRheading( - uint16_t maxWait = defaultMaxWait); // Returned as degrees - - // Set the mainTalkerId used by NMEA messages - allows all NMEA messages - // except GSV to be prefixed with GP instead of GN - bool setMainTalkerID( - sfe_ublox_talker_ids_e id = SFE_UBLOX_MAIN_TALKER_ID_DEFAULT, - uint16_t maxWait = defaultMaxWait); - - // Enable/Disable NMEA High Precision Mode - include extra decimal places in - // the Lat and Lon - bool setHighPrecisionMode(bool enable = true, - uint16_t maxWait = defaultMaxWait); - - // Helper functions for NMEA logging - void setNMEALoggingMask( - uint32_t messages = - SFE_UBLOX_FILTER_NMEA_ALL); // Add selected NMEA messages to file - // buffer - if enabled. Default to - // adding ALL messages to the file - // buffer - uint32_t - getNMEALoggingMask(); // Return which NMEA messages are selected for - // logging to the file buffer - if enabled - - // Helper functions to control which NMEA messages are passed to processNMEA - void setProcessNMEAMask( - uint32_t messages = - SFE_UBLOX_FILTER_NMEA_ALL); // Control which NMEA messages are - // passed to processNMEA. Default to - // passing ALL messages - uint32_t getProcessNMEAMask(); // Return which NMEA messages are passed to - // processNMEA - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - // Support for "auto" storage of NMEA messages - uint8_t getLatestNMEAGPGGA( - NMEA_GGA_data_t *data); // Return the most recent GPGGA: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGPGGAcallback(void (*callbackPointer)( - NMEA_GGA_data_t)); // Enable a callback on the arrival of a GPGGA - // message - bool setNMEAGPGGAcallbackPtr(void (*callbackPointerPtr)( - NMEA_GGA_data_t - *)); // Enable a callback on the arrival of a GPGGA message - uint8_t getLatestNMEAGNGGA( - NMEA_GGA_data_t *data); // Return the most recent GNGGA: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGNGGAcallback(void (*callbackPointer)( - NMEA_GGA_data_t)); // Enable a callback on the arrival of a GNGGA - // message - bool setNMEAGNGGAcallbackPtr(void (*callbackPointerPtr)( - NMEA_GGA_data_t - *)); // Enable a callback on the arrival of a GNGGA message - uint8_t getLatestNMEAGPVTG( - NMEA_VTG_data_t *data); // Return the most recent GPVTG: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGPVTGcallback(void (*callbackPointer)( - NMEA_VTG_data_t)); // Enable a callback on the arrival of a GPVTG - // message - bool setNMEAGPVTGcallbackPtr(void (*callbackPointerPtr)( - NMEA_VTG_data_t - *)); // Enable a callback on the arrival of a GPVTG message - uint8_t getLatestNMEAGNVTG( - NMEA_VTG_data_t *data); // Return the most recent GNVTG: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGNVTGcallback(void (*callbackPointer)( - NMEA_VTG_data_t)); // Enable a callback on the arrival of a GNVTG - // message - bool setNMEAGNVTGcallbackPtr(void (*callbackPointerPtr)( - NMEA_VTG_data_t - *)); // Enable a callback on the arrival of a GNVTG message - uint8_t getLatestNMEAGPRMC( - NMEA_RMC_data_t *data); // Return the most recent GPRMC: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGPRMCcallback(void (*callbackPointer)( - NMEA_RMC_data_t)); // Enable a callback on the arrival of a GPRMC - // message - bool setNMEAGPRMCcallbackPtr(void (*callbackPointerPtr)( - NMEA_RMC_data_t - *)); // Enable a callback on the arrival of a GPRMC message - uint8_t getLatestNMEAGNRMC( - NMEA_RMC_data_t *data); // Return the most recent GNRMC: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGNRMCcallback(void (*callbackPointer)( - NMEA_RMC_data_t)); // Enable a callback on the arrival of a GNRMC - // message - bool setNMEAGNRMCcallbackPtr(void (*callbackPointerPtr)( - NMEA_RMC_data_t - *)); // Enable a callback on the arrival of a GNRMC message - uint8_t getLatestNMEAGPZDA( - NMEA_ZDA_data_t *data); // Return the most recent GPZDA: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGPZDAcallback(void (*callbackPointer)( - NMEA_ZDA_data_t)); // Enable a callback on the arrival of a GPZDA - // message - bool setNMEAGPZDAcallbackPtr(void (*callbackPointerPtr)( - NMEA_ZDA_data_t - *)); // Enable a callback on the arrival of a GPZDA message - uint8_t getLatestNMEAGNZDA( - NMEA_ZDA_data_t *data); // Return the most recent GNZDA: 0 = no data, 1 - // = stale data, 2 = fresh data - bool setNMEAGNZDAcallback(void (*callbackPointer)( - NMEA_ZDA_data_t)); // Enable a callback on the arrival of a GNZDA - // message - bool setNMEAGNZDAcallbackPtr(void (*callbackPointerPtr)( - NMEA_ZDA_data_t - *)); // Enable a callback on the arrival of a GNZDA message -#endif - - // Functions to extract signed and unsigned 8/16/32-bit data from a - // ubxPacket From v2.0: These are public. The user can call these to extract - // data from custom packets - uint64_t extractLongLong(ubxPacket *msg, - uint16_t spotToStart); // Combine eight bytes from - // payload into uint64_t - uint32_t extractLong( - ubxPacket *msg, - uint16_t spotToStart); // Combine four bytes from payload into long - int32_t extractSignedLong( - ubxPacket *msg, - uint16_t - spotToStart); // Combine four bytes from payload into signed long - // (avoiding any ambiguity caused by casting) - uint16_t extractInt( - ubxPacket *msg, - uint16_t spotToStart); // Combine two bytes from payload into int - int16_t extractSignedInt(ubxPacket *msg, uint16_t spotToStart); - uint8_t extractByte(ubxPacket *msg, - uint16_t spotToStart); // Get byte from payload - int8_t extractSignedChar( - ubxPacket *msg, - uint16_t spotToStart); // Get signed 8-bit value from payload - - // Pointers to storage for the "automatic" messages - // RAM is allocated for these if/when required. - - UBX_NAV_POSECEF_t *packetUBXNAVPOSECEF = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_STATUS_t *packetUBXNAVSTATUS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_DOP_t *packetUBXNAVDOP = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_EOE_t *packetUBXNAVEOE = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_ATT_t *packetUBXNAVATT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_PVT_t *packetUBXNAVPVT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_ODO_t *packetUBXNAVODO = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_TIMEUTC_t *packetUBXNAVTIMEUTC = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_VELECEF_t *packetUBXNAVVELECEF = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_VELNED_t *packetUBXNAVVELNED = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_HPPOSECEF_t *packetUBXNAVHPPOSECEF = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_HPPOSLLH_t *packetUBXNAVHPPOSLLH = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_PVAT_t *packetUBXNAVPVAT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_CLOCK_t *packetUBXNAVCLOCK = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_TIMELS_t *packetUBXNAVTIMELS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_SVIN_t *packetUBXNAVSVIN = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_SAT_t *packetUBXNAVSAT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_RELPOSNED_t *packetUBXNAVRELPOSNED = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_NAV_AOPSTATUS_t *packetUBXNAVAOPSTATUS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_RXM_PMP_t *packetUBXRXMPMP = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_RXM_PMP_message_t *packetUBXRXMPMPmessage = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_RXM_QZSSL6_message_t *packetUBXRXMQZSSL6message = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_RXM_COR_t *packetUBXRXMCOR = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_RXM_SFRBX_t *packetUBXRXMSFRBX = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_RXM_RAWX_t *packetUBXRXMRAWX = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_CFG_PRT_t *packetUBXCFGPRT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_CFG_RATE_t *packetUBXCFGRATE = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_TIM_TM2_t *packetUBXTIMTM2 = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_ESF_ALG_t *packetUBXESFALG = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_ESF_INS_t *packetUBXESFINS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_ESF_MEAS_t *packetUBXESFMEAS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_ESF_RAW_t *packetUBXESFRAW = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_ESF_STATUS_t *packetUBXESFSTATUS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_HNR_PVT_t *packetUBXHNRPVT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_HNR_ATT_t *packetUBXHNRATT = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_HNR_INS_t *packetUBXHNRINS = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - - UBX_MGA_ACK_DATA0_t *packetUBXMGAACK = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - UBX_MGA_DBD_t *packetUBXMGADBD = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - NMEA_GPGGA_t *storageNMEAGPGGA = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GNGGA_t *storageNMEAGNGGA = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GPVTG_t *storageNMEAGPVTG = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GNVTG_t *storageNMEAGNVTG = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GPRMC_t *storageNMEAGPRMC = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GNRMC_t *storageNMEAGNRMC = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GPZDA_t *storageNMEAGPZDA = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary - NMEA_GNZDA_t *storageNMEAGNZDA = - NULL; // Pointer to struct. RAM will be allocated for this if/when - // necessary -#endif - - uint16_t rtcmFrameCounter = - 0; // Tracks the type of incoming byte inside RTCM frame - - private: - // Depending on the ubx binary response class, store binary responses into - // different places - enum classTypes { - CLASS_NONE = 0, - CLASS_ACK, - CLASS_NOT_AN_ACK - } ubxFrameClass = CLASS_NONE; - - enum commTypes { - COMM_TYPE_I2C = 0, - COMM_TYPE_SERIAL, - COMM_TYPE_SPI - } commType = - COMM_TYPE_I2C; // Controls which port we look to for incoming bytes - - // Functions - bool checkUbloxInternal( - ubxPacket *incomingUBX, uint8_t requestedClass = 255, - uint8_t requestedID = - 255); // Checks module with user selected commType - void addToChecksum( - uint8_t incoming); // Given an incoming byte, adjust rollingChecksumA/B - size_t pushAssistNowDataInternal(size_t offset, bool skipTime, - const uint8_t *dataBytes, - size_t numDataBytes, - sfe_ublox_mga_assist_ack_e mgaAck, - uint16_t maxWait); - size_t findMGAANOForDateInternal(const uint8_t *dataBytes, - size_t numDataBytes, uint16_t year, - uint8_t month, uint8_t day, - uint8_t daysIntoFuture); - - // Return true if this "automatic" message has storage allocated for it - bool checkAutomatic(uint8_t Class, uint8_t ID); - - // Calculate how much RAM is needed to store the payload for a given - // automatic message - uint16_t getMaxPayloadSize(uint8_t Class, uint8_t ID); - - // Do the actual transfer to SPI - void spiTransfer(uint8_t byteToTransfer); - - bool initGeofenceParams(); // Allocate RAM for currentGeofenceParams and - // initialize it - bool initModuleSWVersion(); // Allocate RAM for moduleSWVersion and - // initialize it - - // The initPacket functions need to be private as they don't check if memory - // has already been allocated. Functions like setAutoNAVPOSECEF will check - // that memory has not been allocated before calling initPacket. - bool initPacketUBXNAVPOSECEF(); // Allocate RAM for packetUBXNAVPOSECEF and - // initialize it - bool initPacketUBXNAVSTATUS(); // Allocate RAM for packetUBXNAVSTATUS and - // initialize it - bool initPacketUBXNAVDOP(); // Allocate RAM for packetUBXNAVDOP and - // initialize it - bool initPacketUBXNAVATT(); // Allocate RAM for packetUBXNAVATT and - // initialize it - bool initPacketUBXNAVPVT(); // Allocate RAM for packetUBXNAVPVT and - // initialize it - bool initPacketUBXNAVODO(); // Allocate RAM for packetUBXNAVODO and - // initialize it - bool initPacketUBXNAVVELECEF(); // Allocate RAM for packetUBXNAVVELECEF and - // initialize it - bool initPacketUBXNAVVELNED(); // Allocate RAM for packetUBXNAVVELNED and - // initialize it - bool initPacketUBXNAVHPPOSECEF(); // Allocate RAM for packetUBXNAVHPPOSECEF - // and initialize it - bool initPacketUBXNAVHPPOSLLH(); // Allocate RAM for packetUBXNAVHPPOSLLH - // and initialize it - bool initPacketUBXNAVPVAT(); // Allocate RAM for packetUBXNAVPVAT and - // initialize it - bool initPacketUBXNAVTIMEUTC(); // Allocate RAM for packetUBXNAVTIMEUTC and - // initialize it - bool initPacketUBXNAVCLOCK(); // Allocate RAM for packetUBXNAVCLOCK and - // initialize it - bool initPacketUBXNAVTIMELS(); // Allocate RAM for packetUBXNAVTIMELS and - // initialize it - bool initPacketUBXNAVSVIN(); // Allocate RAM for packetUBXNAVSVIN and - // initialize it - bool initPacketUBXNAVSAT(); // Allocate RAM for packetUBXNAVSAT and - // initialize it - bool initPacketUBXNAVRELPOSNED(); // Allocate RAM for packetUBXNAVRELPOSNED - // and initialize it - bool initPacketUBXNAVAOPSTATUS(); // Allocate RAM for packetUBXNAVAOPSTATUS - // and initialize it - bool initPacketUBXNAVEOE(); // Allocate RAM for packetUBXNAVEOE and - // initialize it - bool initPacketUBXRXMPMP(); // Allocate RAM for packetUBXRXMPMP and - // initialize it - bool initPacketUBXRXMPMPmessage(); // Allocate RAM for packetUBXRXMPMPRaw - // and initialize it - bool - initPacketUBXRXMQZSSL6message(); // Allocate RAM for packetUBXRXMQZSSL6raw - // and initialize it - bool initPacketUBXRXMCOR(); // Allocate RAM for packetUBXRXMCOR and - // initialize it - bool initPacketUBXRXMSFRBX(); // Allocate RAM for packetUBXRXMSFRBX and - // initialize it - bool initPacketUBXRXMRAWX(); // Allocate RAM for packetUBXRXMRAWX and - // initialize it - bool initPacketUBXCFGPRT(); // Allocate RAM for packetUBXCFGPRT and - // initialize it - bool initPacketUBXCFGRATE(); // Allocate RAM for packetUBXCFGRATE and - // initialize it - bool initPacketUBXTIMTM2(); // Allocate RAM for packetUBXTIMTM2 and - // initialize it - bool initPacketUBXESFALG(); // Allocate RAM for packetUBXESFALG and - // initialize it - bool initPacketUBXESFSTATUS(); // Allocate RAM for packetUBXESFSTATUS and - // initialize it - bool initPacketUBXESFINS(); // Allocate RAM for packetUBXESFINS and - // initialize it - bool initPacketUBXESFMEAS(); // Allocate RAM for packetUBXESFMEAS and - // initialize it - bool initPacketUBXESFRAW(); // Allocate RAM for packetUBXESFRAW and - // initialize it - bool initPacketUBXHNRATT(); // Allocate RAM for packetUBXHNRATT and - // initialize it - bool initPacketUBXHNRINS(); // Allocate RAM for packetUBXHNRINS and - // initialize it - bool initPacketUBXHNRPVT(); // Allocate RAM for packetUBXHNRPVT and - // initialize it - bool initPacketUBXMGAACK(); // Allocate RAM for packetUBXMGAACK and - // initialize it - bool initPacketUBXMGADBD(); // Allocate RAM for packetUBXMGADBD and - // initialize it - -#ifndef SFE_UBLOX_DISABLE_AUTO_NMEA - bool initStorageNMEAGPGGA(); // Allocate RAM for incoming NMEA GPGGA - // messages and initialize it - bool initStorageNMEAGNGGA(); // Allocate RAM for incoming NMEA GNGGA - // messages and initialize it - bool initStorageNMEAGPVTG(); // Allocate RAM for incoming NMEA GPVTG - // messages and initialize it - bool initStorageNMEAGNVTG(); // Allocate RAM for incoming NMEA GNVTG - // messages and initialize it - bool initStorageNMEAGPRMC(); // Allocate RAM for incoming NMEA GPRMC - // messages and initialize it - bool initStorageNMEAGNRMC(); // Allocate RAM for incoming NMEA GNRMC - // messages and initialize it - bool initStorageNMEAGPZDA(); // Allocate RAM for incoming NMEA GPZDA - // messages and initialize it - bool initStorageNMEAGNZDA(); // Allocate RAM for incoming NMEA GNZDA - // messages and initialize it -#endif - - // Variables - TwoWire *_i2cPort; // The generic connection to user's chosen I2C hardware - Stream * - _serialPort; // The generic connection to user's chosen Serial hardware - Stream *_nmeaOutputPort = NULL; // The user can assign an output port to - // print NMEA sentences if they wish - Stream *_debugSerial; // The stream to send debug messages to if enabled - Stream *_outputPort = NULL; - SPIClass *_spiPort; // The instance of SPIClass - uint8_t _csPin; // The chip select pin - uint32_t _spiSpeed; // The speed to use for SPI (Hz) - - uint8_t _gpsI2Caddress = 0x42; // Default 7-bit unshifted address of the - // ublox 6/7/8/M8/F9 series - // This can be changed using the ublox configuration software - - bool _printDebug = false; // Flag to print the serial commands we are - // sending to the Serial port for debug - bool _printLimitedDebug = - false; // Flag to print limited debug messages. Useful for I2C - // debugging or high navigation rates - - bool ubx7FcheckDisabled = false; // Flag to indicate if the "7F" check - // should be ignored in checkUbloxI2C - - sfe_ublox_nmea_filtering_t - _logNMEA; // Flags to indicate which NMEA messages should be added to - // the file buffer for logging - sfe_ublox_nmea_filtering_t - _processNMEA; // Flags to indicate which NMEA messages should be passed - // to processNMEA - - // The packet buffers - // These are pointed at from within the ubxPacket - uint8_t payloadAck[2]; // Holds the requested ACK/NACK - uint8_t payloadBuf[2]; // Temporary buffer used to screen incoming packets - // or dump unrequested packets - size_t packetCfgPayloadSize = - 0; // Size for the packetCfg payload. .begin will set this to - // MAX_PAYLOAD_SIZE if necessary. User can change with - // setPacketCfgPayloadSize - uint8_t *payloadCfg = NULL; - uint8_t *payloadAuto = NULL; - - uint8_t *spiBuffer = - NULL; // A buffer to store any bytes being recieved back from the - // device while we are sending via SPI - uint8_t spiBufferIndex = 0; // Index into the SPI buffer - uint8_t spiTransactionSize = - SFE_UBLOX_SPI_BUFFER_SIZE; // Default size of the SPI buffer - - // Init the packet structures and init them with pointers to the payloadAck, - // payloadCfg, payloadBuf and payloadAuto arrays - ubxPacket packetAck = {0, - 0, - 0, - 0, - 0, - payloadAck, - 0, - 0, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; - ubxPacket packetBuf = {0, - 0, - 0, - 0, - 0, - payloadBuf, - 0, - 0, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; - ubxPacket packetCfg = {0, - 0, - 0, - 0, - 0, - payloadCfg, - 0, - 0, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; - ubxPacket packetAuto = {0, - 0, - 0, - 0, - 0, - payloadAuto, - 0, - 0, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, - SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; - - // Flag if this packet is unrequested (and so should be ignored and not - // copied into packetCfg or packetAck) - bool ignoreThisPayload = false; - - // Identify which buffer is in use - // Data is stored in packetBuf until the requested class and ID can be - // validated If a match is seen, data is diverted into packetAck or - // packetCfg - //"Automatic" messages which have RAM allocated for them are diverted into - //packetAuto - sfe_ublox_packet_buffer_e activePacketBuffer = SFE_UBLOX_PACKET_PACKETBUF; - - // Limit checking of new data to every X ms - // If we are expecting an update every X Hz then we should check every - // quarter that amount of time Otherwise we may block ourselves from seeing - // new data - uint8_t i2cPollingWait = - 100; // Default to 100ms. Adjusted when user calls - // setNavigationFrequency() or setHNRNavigationRate() or - // setMeasurementRate() - uint8_t i2cPollingWaitNAV = 100; // We need to record the desired polling - // rate for standard nav messages - uint8_t i2cPollingWaitHNR = 100; // and for HNR too so we can set - // i2cPollingWait to the lower of the two - - // The SPI polling wait is a little different. checkUbloxSpi will delay for - // this amount before returning if there is no data waiting to be read. This - // prevents waitForACKResponse from pounding the SPI bus too hard. - uint8_t spiPollingWait = - 9; // Default to 9ms; waitForACKResponse delays for 1ms on top of this. - // User can adjust with setSPIPollingWait. - - unsigned long lastCheck = 0; - - uint16_t - ubxFrameCounter; // Count all UBX frame bytes. [Fixed header(2bytes), - // CLS(1byte), ID(1byte), length(2bytes), payload(x - // bytes), checksums(2bytes)] - uint8_t - rollingChecksumA; // Rolls forward as we receive incoming bytes. - // Checked against the last two A/B checksum bytes - uint8_t - rollingChecksumB; // Rolls forward as we receive incoming bytes. - // Checked against the last two A/B checksum bytes - - int8_t nmeaByteCounter; // Count all NMEA message bytes. - // Abort NMEA message reception if nmeaByteCounter exceeds maxNMEAByteCount. - // The user can adjust maxNMEAByteCount by calling setMaxNMEAByteCount - int8_t maxNMEAByteCount = SFE_UBLOX_MAX_NMEA_BYTE_COUNT; - uint8_t nmeaAddressField[6]; // NMEA Address Field - includes the start - // character (*) - bool logThisNMEA(); // Return true if we should log this NMEA message - bool processThisNMEA(); // Return true if we should pass this NMEA message - // to processNMEA - bool isNMEAHeaderValid(); // Return true if the six byte NMEA header - // appears valid. Used to set _signsOfLife - - bool isThisNMEAauto(); // Check if the NMEA message (in nmeaAddressField) - // is "auto" (i.e. has RAM allocated for it) - bool doesThisNMEAHaveCallback(); // Do we need to copy the data into the - // callback copy? - uint8_t * - getNMEAWorkingLengthPtr(); // Get a pointer to the working copy length - uint8_t * - getNMEAWorkingNMEAPtr(); // Get a pointer to the working copy NMEA data - uint8_t * - getNMEACompleteLengthPtr(); // Get a pointer to the complete copy length - uint8_t * - getNMEACompleteNMEAPtr(); // Get a pointer to the complete copy NMEA data - uint8_t * - getNMEACallbackLengthPtr(); // Get a pointer to the callback copy length - uint8_t * - getNMEACallbackNMEAPtr(); // Get a pointer to the callback copy NMEA data - uint8_t getNMEAMaxLength(); // Get the maximum length of this NMEA message - nmeaAutomaticFlags *getNMEAFlagsPtr(); // Get a pointer to the flags - - // Flag to prevent reentry into checkCallbacks - // Prevent badness if the user accidentally calls checkCallbacks from inside - // a callback - volatile bool checkCallbacksReentrant = false; - - // Support for data logging - uint8_t *ubxFileBuffer = NULL; // Pointer to the file buffer. RAM is - // allocated for this if required in .begin - uint16_t fileBufferSize = - 0; // The size of the file buffer. This can be changed by calling - // setFileBufferSize _before_ .begin - uint16_t fileBufferHead; // The incoming byte is written into the file - // buffer at this location - uint16_t fileBufferTail; // The next byte to be read from the buffer will - // be read from this location - uint16_t fileBufferMaxAvail = - 0; // The maximum number of bytes the file buffer has contained. Handy - // for checking the buffer is large enough to handle all the - // incoming data. - bool createFileBuffer(void); // Create the file buffer. Called by .begin - uint16_t fileBufferSpaceAvailable( - void); // Check how much space is available in the buffer - uint16_t fileBufferSpaceUsed( - void); // Check how much space is used in the buffer - bool storePacket(ubxPacket *msg); // Add a UBX packet to the file buffer - bool storeFileBytes(uint8_t *theBytes, - uint16_t numBytes); // Add theBytes to the file buffer - void writeToFileBuffer( - uint8_t *theBytes, - uint16_t numBytes); // Write theBytes to the file buffer - - // Support for platforms like ESP32 which do not support multiple I2C - // restarts If _i2cStopRestart is true, endTransmission will always use a - // stop. If false, a restart will be used where needed. The default value - // for _i2cStopRestart is set in the class instantiation code. - bool _i2cStopRestart; - - // Storage just in case the user tries to push a single byte using - // pushRawBytes - bool _pushSingleByte = false; - uint8_t _pushThisSingleByte; - - // .begin will return true if the assumeSuccess parameter is true and if - // _signsOfLife is true _signsOfLife is set to true when: a valid UBX - // message is seen; a valig NMEA header is seen. - bool _signsOfLife; - - // Keep track of how many keys have been added to CfgValset - uint8_t _numCfgKeyIDs = 0; - - // Send the current CFG_VALSET message when packetCfg has less than this - // many bytes available - size_t _autoSendAtSpaceRemaining = 0; -}; - -#endif diff --git a/Code/BITS/BITSv5/test/test.cpp b/Code/BITS/BITSv5/test/test.cpp index 8975b5a3..75d3e358 100644 --- a/Code/BITS/BITSv5/test/test.cpp +++ b/Code/BITS/BITSv5/test/test.cpp @@ -4,7 +4,7 @@ #include "../../../libraries/rp2040-drf1262-lib/SX1262.h" #include "../../../libraries/rp2040-ms5607-lib/MS5607.h" -#include "BITSv5.h" +#include "../BITSv5.h" #include "hardware/flash.h" #include "hardware/gpio.h" #include "pico/binary_info.h" diff --git a/Code/BITS/BITSv5/test/u-blox_config_keys.h b/Code/BITS/BITSv5/test/u-blox_config_keys.h deleted file mode 100644 index a93ec336..00000000 --- a/Code/BITS/BITSv5/test/u-blox_config_keys.h +++ /dev/null @@ -1,1229 +0,0 @@ -/* - This is a library written for the u-blox ZED-F9P and NEO-M8P-2 - SparkFun sells these at its website: www.sparkfun.com - Do you like this library? Help support SparkFun. Buy a board! - https://www.sparkfun.com/products/16481 - https://www.sparkfun.com/products/15136 - https://www.sparkfun.com/products/15005 - https://www.sparkfun.com/products/15733 - https://www.sparkfun.com/products/15193 - https://www.sparkfun.com/products/15210 - - Original version by Nathan Seidle @ SparkFun Electronics, September 6th, 2018 - v2.0 rework by Paul Clark @ SparkFun Electronics, December 31st, 2020 - - This library handles configuring and handling the responses - from a u-blox GPS module. Works with most modules from u-blox including - the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others. - - https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library - - Development environment specifics: - Arduino IDE 1.8.13 - - SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT). - The MIT License (MIT) - Copyright (c) 2016 SparkFun Electronics - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - associated documentation files (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the Software is furnished to - do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef __u_blox_config_keys_h__ -#define __u_blox_config_keys_h__ - -// Define the maximum length of a multi-CfgValset construct -// "This message is limited to containing a maximum of 64 key-value pairs" -const uint8_t CFG_VALSET_MAX_KEYS = 64; - -// The following consts are used to generate KEY values for the advanced protocol functions of VELGET/SET/DEL -const uint8_t VAL_SIZE_1 = 0x01; // One bit -const uint8_t VAL_SIZE_8 = 0x02; // One byte -const uint8_t VAL_SIZE_16 = 0x03; // Two bytes -const uint8_t VAL_SIZE_32 = 0x04; // Four bytes -const uint8_t VAL_SIZE_64 = 0x05; // Eight bytes - -// These are the Bitfield layers definitions for the UBX-CFG-VALSET message (not to be confused with Bitfield deviceMask in UBX-CFG-CFG) -const uint8_t VAL_LAYER_RAM = (1 << 0); -const uint8_t VAL_LAYER_BBR = (1 << 1); -const uint8_t VAL_LAYER_FLASH = (1 << 2); -const uint8_t VAL_LAYER_ALL = VAL_LAYER_RAM | VAL_LAYER_BBR | VAL_LAYER_FLASH; // Not valid with getVal() - -// Below are various Groups, IDs, and sizes for various settings -// These can be used to call getVal/setVal/delVal -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint8_t VAL_ID_PROT_UBX = 0x01; -const uint8_t VAL_ID_PROT_NMEA = 0x02; -const uint8_t VAL_ID_PROT_RTCM3 = 0x04; - -const uint8_t VAL_GROUP_I2C = 0x51; -const uint8_t VAL_GROUP_I2COUTPROT = 0x72; -const uint8_t VAL_GROUP_UART1INPROT = 0x73; -const uint8_t VAL_GROUP_UART1OUTPROT = 0x74; -const uint8_t VAL_GROUP_UART2INPROT = 0x75; -const uint8_t VAL_GROUP_UART2OUTPROT = 0x76; -const uint8_t VAL_GROUP_USBINPROT = 0x77; -const uint8_t VAL_GROUP_USBOUTPROT = 0x78; - -const uint8_t VAL_GROUP_UART_SIZE = VAL_SIZE_1; // All fields in UART group are currently 1 bit -const uint8_t VAL_GROUP_I2C_SIZE = VAL_SIZE_8; // All fields in I2C group are currently 1 byte - -const uint8_t VAL_ID_I2C_ADDRESS = 0x01; - -// Below are the key values for a given configuration setting - -// CFG-BDS: BeiDou system configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_BDS_USE_PRN_1_TO_5 = 0x10340014; // Use BeiDou geostationary satellites (PRN 1-5) - -// CFG-GEOFENCE: Geofencing configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_GEOFENCE_CONFLVL = 0x20240011; // Required confidence level for state evaluation -const uint32_t UBLOX_CFG_GEOFENCE_USE_PIO = 0x10240012; // Use PIO combined fence state output -const uint32_t UBLOX_CFG_GEOFENCE_PINPOL = 0x20240013; // PIO pin polarity -const uint32_t UBLOX_CFG_GEOFENCE_PIN = 0x20240014; // PIO pin number -const uint32_t UBLOX_CFG_GEOFENCE_USE_FENCE1 = 0x10240020; // Use frst geofence -const uint32_t UBLOX_CFG_GEOFENCE_FENCE1_LAT = 0x40240021; // Latitude of the first geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE1_LON = 0x40240022; // Longitude of the first geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE1_RAD = 0x40240023; // Radius of the first geofence circle -const uint32_t UBLOX_CFG_GEOFENCE_USE_FENCE2 = 0x10240030; // Use second geofence -const uint32_t UBLOX_CFG_GEOFENCE_FENCE2_LAT = 0x40240031; // Latitude of the second geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE2_LON = 0x40240032; // Longitude of the second geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE2_RAD = 0x40240033; // Radius of the second geofence circle -const uint32_t UBLOX_CFG_GEOFENCE_USE_FENCE3 = 0x10240040; // Use third geofence -const uint32_t UBLOX_CFG_GEOFENCE_FENCE3_LAT = 0x40240041; // Latitude of the third geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE3_LON = 0x40240042; // Longitude of the third geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE3_RAD = 0x40240043; // Radius of the third geofence circle -const uint32_t UBLOX_CFG_GEOFENCE_USE_FENCE4 = 0x10240050; // Use fourth geofence -const uint32_t UBLOX_CFG_GEOFENCE_FENCE4_LAT = 0x40240051; // Latitude of the fourth geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE4_LON = 0x40240052; // Longitude of the fourth geofence circle center -const uint32_t UBLOX_CFG_GEOFENCE_FENCE4_RAD = 0x40240053; // Radius of the fourth geofence circle - -// CFG-HW: Hardware configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_HW_ANT_CFG_VOLTCTRL = 0x10a3002e; // Active antenna voltage control flag -const uint32_t UBLOX_CFG_HW_ANT_CFG_SHORTDET = 0x10a3002f; // Short antenna detection flag -const uint32_t UBLOX_CFG_HW_ANT_CFG_SHORTDET_POL = 0x10a30030; // Short antenna detection polarity -const uint32_t UBLOX_CFG_HW_ANT_CFG_OPENDET = 0x10a30031; // Open antenna detection flag -const uint32_t UBLOX_CFG_HW_ANT_CFG_OPENDET_POL = 0x10a30032; // Open antenna detection polarity -const uint32_t UBLOX_CFG_HW_ANT_CFG_PWRDOWN = 0x10a30033; // Power down antenna flag -const uint32_t UBLOX_CFG_HW_ANT_CFG_PWRDOWN_POL = 0x10a30034; // Power down antenna logic polarity -const uint32_t UBLOX_CFG_HW_ANT_CFG_RECOVER = 0x10a30035; // Automatic recovery from short state flag -const uint32_t UBLOX_CFG_HW_ANT_SUP_SWITCH_PIN = 0x20a30036; // ANT1 PIO number -const uint32_t UBLOX_CFG_HW_ANT_SUP_SHORT_PIN = 0x20a30037; // ANT0 PIO number -const uint32_t UBLOX_CFG_HW_ANT_SUP_OPEN_PIN = 0x20a30038; // ANT2 PIO number -const uint32_t UBLOX_CFG_HW_ANT_SUP_ENGINE = 0x20a30054; // Antenna supervisor engine selection -const uint32_t UBLOX_CFG_HW_ANT_SUP_SHORT_THR = 0x20a30055; // Antenna supervisor MADC engine short detection threshold -const uint32_t UBLOX_CFG_HW_ANT_SUP_OPEN_THR = 0x20a30056; // Antenna supervisor MADC engine open detection threshold - -// CFG-I2C: Configuration of the I2C interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_I2C_ADDRESS = 0x20510001; // I2C slave address of the receiver (7 bits) -const uint32_t UBLOX_CFG_I2C_EXTENDEDTIMEOUT = 0x10510002; // Flag to disable timeouting the interface after 1.5 s -const uint32_t UBLOX_CFG_I2C_ENABLED = 0x10510003; // Flag to indicate if the I2C interface should be enabled - -// CFG-I2CINPROT: Input protocol configuration of the I2C interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_I2CINPROT_UBX = 0x10710001; // Flag to indicate if UBX should be an input protocol on I2C -const uint32_t UBLOX_CFG_I2CINPROT_NMEA = 0x10710002; // Flag to indicate if NMEA should be an input protocol on I2C -const uint32_t UBLOX_CFG_I2CINPROT_RTCM3X = 0x10710004; // Flag to indicate if RTCM3X should be an input protocol on I2C -const uint32_t UBLOX_CFG_I2CINPROT_SPARTN = 0x10710005; // Flag to indicate if SPARTN should be an input protocol on I2C - -// CFG-I2COUTPROT: Output protocol configuration of the I2C interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_I2COUTPROT_UBX = 0x10720001; // Flag to indicate if UBX should be an output protocol on I2C -const uint32_t UBLOX_CFG_I2COUTPROT_NMEA = 0x10720002; // Flag to indicate if NMEA should be an output protocol on I2C -const uint32_t UBLOX_CFG_I2COUTPROT_RTCM3X = 0x10720004; // Flag to indicate if RTCM3X should be an output protocol on I2C - -// CFG-INFMSG: Information message configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_INFMSG_UBX_I2C = 0x20920001; // Information message enable flags for the UBX protocol on the I2C interface -const uint32_t UBLOX_CFG_INFMSG_UBX_UART1 = 0x20920002; // Information message enable flags for the UBX protocol on the UART1 interface -const uint32_t UBLOX_CFG_INFMSG_UBX_UART2 = 0x20920003; // Information message enable flags for the UBX protocol on the UART2 interface -const uint32_t UBLOX_CFG_INFMSG_UBX_USB = 0x20920004; // Information message enable flags for the UBX protocol on the USB interface -const uint32_t UBLOX_CFG_INFMSG_UBX_SPI = 0x20920005; // Information message enable flags for the UBX protocol on the SPI interface -const uint32_t UBLOX_CFG_INFMSG_NMEA_I2C = 0x20920006; // Information message enable flags for the NMEA protocol on the I2C interface -const uint32_t UBLOX_CFG_INFMSG_NMEA_UART1 = 0x20920007; // Information message enable flags for the NMEA protocol on the UART1 interface -const uint32_t UBLOX_CFG_INFMSG_NMEA_UART2 = 0x20920008; // Information message enable flags for the NMEA protocol on the UART2 interface -const uint32_t UBLOX_CFG_INFMSG_NMEA_USB = 0x20920009; // Information message enable flags for the NMEA protocol on the USB interface -const uint32_t UBLOX_CFG_INFMSG_NMEA_SPI = 0x2092000a; // Information message enable flags for the NMEA protocol on the SPI interface - -// CFG-ITFM: Jamming and interference monitor configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_ITFM_BBTHRESHOLD = 0x20410001; // Broadband jamming detection threshold -const uint32_t UBLOX_CFG_ITFM_CWTHRESHOLD = 0x20410002; // CW jamming detection threshold -const uint32_t UBLOX_CFG_ITFM_ENABLE = 0x1041000d; // Enable interference detection -const uint32_t UBLOX_CFG_ITFM_ANTSETTING = 0x20410010; // Antenna setting -const uint32_t UBLOX_CFG_ITFM_ENABLE_AUX = 0x10410013; // Scan auxiliary bands - -// CFG-LOGFILTER: Data logger configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_LOGFILTER_RECORD_ENA = 0x10de0002; // Recording enabled -const uint32_t UBLOX_CFG_LOGFILTER_ONCE_PER_WAKE_UP_ENA = 0x10de0003; // Once per wake up -const uint32_t UBLOX_CFG_LOGFILTER_APPLY_ALL_FILTERS = 0x10de0004; // Apply all filter settings -const uint32_t UBLOX_CFG_LOGFILTER_MIN_INTERVAL = 0x30de0005; // Minimum time interval between loggedpositions -const uint32_t UBLOX_CFG_LOGFILTER_TIME_THRS = 0x30de0006; // Time threshold -const uint32_t UBLOX_CFG_LOGFILTER_SPEED_THRS = 0x30de0007; // Speed threshold -const uint32_t UBLOX_CFG_LOGFILTER_POSITION_THRS = 0x40de0008; // Position threshold - -// CFG-MOT: Motion detector configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_MOT_GNSSSPEED_THRS = 0x20250038; // GNSS speed threshold below which platform is considered as stationary (a.k.a. static hold threshold) -const uint32_t UBLOX_CFG_MOT_GNSSDIST_THRS = 0x3025003b; // Distance above which GNSS-based stationary motion is exit (a.k.a. static hold distance threshold) - -// CFG-MSGOUT: Message output configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -// For each message and port a separate output rate (per second, per epoch) can be configured. -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_DTM_I2C = 0x209100a6; // Output rate of the NMEA-GX-DTM message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_DTM_SPI = 0x209100aa; // Output rate of the NMEA-GX-DTM message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_DTM_UART1 = 0x209100a7; // Output rate of the NMEA-GX-DTM message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_DTM_UART2 = 0x209100a8; // Output rate of the NMEA-GX-DTM message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_DTM_USB = 0x209100a9; // Output rate of the NMEA-GX-DTM message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GBS_I2C = 0x209100dd; // Output rate of the NMEA-GX-GBS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GBS_SPI = 0x209100e1; // Output rate of the NMEA-GX-GBS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GBS_UART1 = 0x209100de; // Output rate of the NMEA-GX-GBS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GBS_UART2 = 0x209100df; // Output rate of the NMEA-GX-GBS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GBS_USB = 0x209100e0; // Output rate of the NMEA-GX-GBS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GGA_I2C = 0x209100ba; // Output rate of the NMEA-GX-GGA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GGA_SPI = 0x209100be; // Output rate of the NMEA-GX-GGA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GGA_UART1 = 0x209100bb; // Output rate of the NMEA-GX-GGA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GGA_UART2 = 0x209100bc; // Output rate of the NMEA-GX-GGA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GGA_USB = 0x209100bd; // Output rate of the NMEA-GX-GGA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GLL_I2C = 0x209100c9; // Output rate of the NMEA-GX-GLL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GLL_SPI = 0x209100cd; // Output rate of the NMEA-GX-GLL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GLL_UART1 = 0x209100ca; // Output rate of the NMEA-GX-GLL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GLL_UART2 = 0x209100cb; // Output rate of the NMEA-GX-GLL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GLL_USB = 0x209100cc; // Output rate of the NMEA-GX-GLL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GNS_I2C = 0x209100b5; // Output rate of the NMEA-GX-GNS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GNS_SPI = 0x209100b9; // Output rate of the NMEA-GX-GNS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GNS_UART1 = 0x209100b6; // Output rate of the NMEA-GX-GNS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GNS_UART2 = 0x209100b7; // Output rate of the NMEA-GX-GNS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GNS_USB = 0x209100b8; // Output rate of the NMEA-GX-GNS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GRS_I2C = 0x209100ce; // Output rate of the NMEA-GX-GRS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GRS_SPI = 0x209100d2; // Output rate of the NMEA-GX-GRS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GRS_UART1 = 0x209100cf; // Output rate of the NMEA-GX-GRS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GRS_UART2 = 0x209100d0; // Output rate of the NMEA-GX-GRS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GRS_USB = 0x209100d1; // Output rate of the NMEA-GX-GRS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSA_I2C = 0x209100bf; // Output rate of the NMEA-GX-GSA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSA_SPI = 0x209100c3; // Output rate of the NMEA-GX-GSA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSA_UART1 = 0x209100c0; // Output rate of the NMEA-GX-GSA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSA_UART2 = 0x209100c1; // Output rate of the NMEA-GX-GSA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSA_USB = 0x209100c2; // Output rate of the NMEA-GX-GSA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GST_I2C = 0x209100d3; // Output rate of the NMEA-GX-GST message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GST_SPI = 0x209100d7; // Output rate of the NMEA-GX-GST message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GST_UART1 = 0x209100d4; // Output rate of the NMEA-GX-GST message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GST_UART2 = 0x209100d5; // Output rate of the NMEA-GX-GST message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GST_USB = 0x209100d6; // Output rate of the NMEA-GX-GST message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSV_I2C = 0x209100c4; // Output rate of the NMEA-GX-GSV message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSV_SPI = 0x209100c8; // Output rate of the NMEA-GX-GSV message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSV_UART1 = 0x209100c5; // Output rate of the NMEA-GX-GSV message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSV_UART2 = 0x209100c6; // Output rate of the NMEA-GX-GSV message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_GSV_USB = 0x209100c7; // Output rate of the NMEA-GX-GSV message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RLM_I2C = 0x20910400; // Output rate of the NMEA-GX-RLM message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RLM_SPI = 0x20910404; // Output rate of the NMEA-GX-RLM message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RLM_UART1 = 0x20910401; // Output rate of the NMEA-GX-RLM message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RLM_UART2 = 0x20910402; // Output rate of the NMEA-GX-RLM message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RLM_USB = 0x20910403; // Output rate of the NMEA-GX-RLM message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RMC_I2C = 0x209100ab; // Output rate of the NMEA-GX-RMC message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RMC_SPI = 0x209100af; // Output rate of the NMEA-GX-RMC message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RMC_UART1 = 0x209100ac; // Output rate of the NMEA-GX-RMC message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RMC_UART2 = 0x209100ad; // Output rate of the NMEA-GX-RMC message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_RMC_USB = 0x209100ae; // Output rate of the NMEA-GX-RMC message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VLW_I2C = 0x209100e7; // Output rate of the NMEA-GX-VLW message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VLW_SPI = 0x209100eb; // Output rate of the NMEA-GX-VLW message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VLW_UART1 = 0x209100e8; // Output rate of the NMEA-GX-VLW message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VLW_UART2 = 0x209100e9; // Output rate of the NMEA-GX-VLW message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VLW_USB = 0x209100ea; // Output rate of the NMEA-GX-VLW message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VTG_I2C = 0x209100b0; // Output rate of the NMEA-GX-VTG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VTG_SPI = 0x209100b4; // Output rate of the NMEA-GX-VTG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VTG_UART1 = 0x209100b1; // Output rate of the NMEA-GX-VTG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VTG_UART2 = 0x209100b2; // Output rate of the NMEA-GX-VTG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_VTG_USB = 0x209100b3; // Output rate of the NMEA-GX-VTG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_ZDA_I2C = 0x209100d8; // Output rate of the NMEA-GX-ZDA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_ZDA_SPI = 0x209100dc; // Output rate of the NMEA-GX-ZDA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_ZDA_UART1 = 0x209100d9; // Output rate of the NMEA-GX-ZDA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_ZDA_UART2 = 0x209100da; // Output rate of the NMEA-GX-ZDA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_ZDA_USB = 0x209100db; // Output rate of the NMEA-GX-ZDA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYP_I2C = 0x209100ec; // Output rate of the NMEA-GX-PUBX00 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYP_SPI = 0x209100f0; // Output rate of the NMEA-GX-PUBX00 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYP_UART1 = 0x209100ed; // Output rate of the NMEA-GX-PUBX00 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYP_UART2 = 0x209100ee; // Output rate of the NMEA-GX-PUBX00 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYP_USB = 0x209100ef; // Output rate of the NMEA-GX-PUBX00 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYS_I2C = 0x209100f1; // Output rate of the NMEA-GX-PUBX03 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYS_SPI = 0x209100f5; // Output rate of the NMEA-GX-PUBX03 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYS_UART1 = 0x209100f2; // Output rate of the NMEA-GX-PUBX03 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYS_UART2 = 0x209100f3; // Output rate of the NMEA-GX-PUBX03 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYS_USB = 0x209100f4; // Output rate of the NMEA-GX-PUBX03 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYT_I2C = 0x209100f6; // Output rate of the NMEA-GX-PUBX04 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYT_SPI = 0x209100fa; // Output rate of the NMEA-GX-PUBX04 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYT_UART1 = 0x209100f7; // Output rate of the NMEA-GX-PUBX04 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYT_UART2 = 0x209100f8; // Output rate of the NMEA-GX-PUBX04 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_PUBX_ID_POLYT_USB = 0x209100f9; // Output rate of the NMEA-GX-PUBX04 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_I2C = 0x209102bd; // Output rate of the RTCM-3X-TYPE1005 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_SPI = 0x209102c1; // Output rate of the RTCM-3X-TYPE1005 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_UART1 = 0x209102be; // Output rate of the RTCM-3X-TYPE1005 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_UART2 = 0x209102bf; // Output rate of the RTCM-3X-TYPE1005 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_USB = 0x209102c0; // Output rate of the RTCM-3X-TYPE1005 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_I2C = 0x2091035e; // Output rate of the RTCM-3X-TYPE1074 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_SPI = 0x20910362; // Output rate of the RTCM-3X-TYPE1074 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_UART1 = 0x2091035f; // Output rate of the RTCM-3X-TYPE1074 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_UART2 = 0x20910360; // Output rate of the RTCM-3X-TYPE1074 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1074_USB = 0x20910361; // Output rate of the RTCM-3X-TYPE1074 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_I2C = 0x209102cc; // Output rate of the RTCM-3X-TYPE1077 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_SPI = 0x209102d0; // Output rate of the RTCM-3X-TYPE1077 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_UART1 = 0x209102cd; // Output rate of the RTCM-3X-TYPE1077 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_UART2 = 0x209102ce; // Output rate of the RTCM-3X-TYPE1077 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_USB = 0x209102cf; // Output rate of the RTCM-3X-TYPE1077 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_I2C = 0x20910363; // Output rate of the RTCM-3X-TYPE1084 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_SPI = 0x20910367; // Output rate of the RTCM-3X-TYPE1084 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_UART1 = 0x20910364; // Output rate of the RTCM-3X-TYPE1084 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_UART2 = 0x20910365; // Output rate of the RTCM-3X-TYPE1084 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1084_USB = 0x20910366; // Output rate of the RTCM-3X-TYPE1084 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_I2C = 0x209102d1; // Output rate of the RTCM-3X-TYPE1087 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_SPI = 0x209102d5; // Output rate of the RTCM-3X-TYPE1087 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_UART1 = 0x209102d2; // Output rate of the RTCM-3X-TYPE1087 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_UART2 = 0x209102d3; // Output rate of the RTCM-3X-TYPE1087 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_USB = 0x209102d4; // Output rate of the RTCM-3X-TYPE1087 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_I2C = 0x20910368; // Output rate of the RTCM-3X-TYPE1094 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_SPI = 0x2091036c; // Output rate of the RTCM-3X-TYPE1094 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_UART1 = 0x20910369; // Output rate of the RTCM-3X-TYPE1094 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_UART2 = 0x2091036a; // Output rate of the RTCM-3X-TYPE1094 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1094_USB = 0x2091036b; // Output rate of the RTCM-3X-TYPE1094 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_I2C = 0x20910318; // Output rate of the RTCM-3X-TYPE1097 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_SPI = 0x2091031c; // Output rate of the RTCM-3X-TYPE1097 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_UART1 = 0x20910319; // Output rate of the RTCM-3X-TYPE1097 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_UART2 = 0x2091031a; // Output rate of the RTCM-3X-TYPE1097 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_USB = 0x2091031b; // Output rate of the RTCM-3X-TYPE1097 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_I2C = 0x2091036d; // Output rate of the RTCM-3X-TYPE1124 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_SPI = 0x20910371; // Output rate of the RTCM-3X-TYPE1124 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_UART1 = 0x2091036e; // Output rate of the RTCM-3X-TYPE1124 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_UART2 = 0x2091036f; // Output rate of the RTCM-3X-TYPE1124 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1124_USB = 0x20910370; // Output rate of the RTCM-3X-TYPE1124 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_I2C = 0x209102d6; // Output rate of the RTCM-3X-TYPE1127 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_SPI = 0x209102da; // Output rate of the RTCM-3X-TYPE1127 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_UART1 = 0x209102d7; // Output rate of the RTCM-3X-TYPE1127 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_UART2 = 0x209102d8; // Output rate of the RTCM-3X-TYPE1127 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_USB = 0x209102d9; // Output rate of the RTCM-3X-TYPE1127 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_I2C = 0x20910303; // Output rate of the RTCM-3X-TYPE1230 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_SPI = 0x20910307; // Output rate of the RTCM-3X-TYPE1230 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_UART1 = 0x20910304; // Output rate of the RTCM-3X-TYPE1230 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_UART2 = 0x20910305; // Output rate of the RTCM-3X-TYPE1230 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_USB = 0x20910306; // Output rate of the RTCM-3X-TYPE1230 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_0_I2C = 0x209102fe; // Output rate of the RTCM-3X-TYPE4072_0 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_0_SPI = 0x20910302; // Output rate of the RTCM-3X-TYPE4072_0 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_0_UART1 = 0x209102ff; // Output rate of the RTCM-3X-TYPE4072_0 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_0_UART2 = 0x20910300; // Output rate of the RTCM-3X-TYPE4072_0 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_0_USB = 0x20910301; // Output rate of the RTCM-3X-TYPE4072_0 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_1_I2C = 0x20910381; // Output rate of the RTCM-3X-TYPE4072_1 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_1_SPI = 0x20910385; // Output rate of the RTCM-3X-TYPE4072_1 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_1_UART1 = 0x20910382; // Output rate of the RTCM-3X-TYPE4072_1 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_1_UART2 = 0x20910383; // Output rate of the RTCM-3X-TYPE4072_1 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_RTCM_3X_TYPE4072_1_USB = 0x20910384; // Output rate of the RTCM-3X-TYPE4072_1 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_LOG_INFO_I2C = 0x20910259; // Output rate of the UBX-LOG-INFO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_LOG_INFO_SPI = 0x2091025d; // Output rate of the UBX-LOG-INFO message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_LOG_INFO_UART1 = 0x2091025a; // Output rate of the UBX-LOG-INFO message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_LOG_INFO_UART2 = 0x2091025b; // Output rate of the UBX-LOG-INFO message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_LOG_INFO_USB = 0x2091025c; // Output rate of the UBX-LOG-INFO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_COMMS_I2C = 0x2091034f; // Output rate of the UBX-MON-COMMS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_COMMS_SPI = 0x20910353; // Output rate of the UBX-MON-COMMS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_COMMS_UART1 = 0x20910350; // Output rate of the UBX-MON-COMMS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_COMMS_UART2 = 0x20910351; // Output rate of the UBX-MON-COMMS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_COMMS_USB = 0x20910352; // Output rate of the UBX-MON-COMMS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW2_I2C = 0x209101b9; // Output rate of the UBX-MON-HW2 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW2_SPI = 0x209101bd; // Output rate of the UBX-MON-HW2 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW2_UART1 = 0x209101ba; // Output rate of the UBX-MON-HW2 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW2_UART2 = 0x209101bb; // Output rate of the UBX-MON-HW2 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW2_USB = 0x209101bc; // Output rate of the UBX-MON-HW2 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW3_I2C = 0x20910354; // Output rate of the UBX-MON-HW3 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW3_SPI = 0x20910358; // Output rate of the UBX-MON-HW3 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW3_UART1 = 0x20910355; // Output rate of the UBX-MON-HW3 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW3_UART2 = 0x20910356; // Output rate of the UBX-MON-HW3 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW3_USB = 0x20910357; // Output rate of the UBX-MON-HW3 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW_I2C = 0x209101b4; // Output rate of the UBX-MON-HW message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW_SPI = 0x209101b8; // Output rate of the UBX-MON-HW message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW_UART1 = 0x209101b5; // Output rate of the UBX-MON-HW message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW_UART2 = 0x209101b6; // Output rate of the UBX-MON-HW message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_HW_USB = 0x209101b7; // Output rate of the UBX-MON-HW message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_IO_I2C = 0x209101a5; // Output rate of the UBX-MON-IO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_IO_SPI = 0x209101a9; // Output rate of the UBX-MON-IO message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_IO_UART1 = 0x209101a6; // Output rate of the UBX-MON-IO message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_IO_UART2 = 0x209101a7; // Output rate of the UBX-MON-IO message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_IO_USB = 0x209101a8; // Output rate of the UBX-MON-IO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_MSGPP_I2C = 0x20910196; // Output rate of the UBX-MON-MSGPP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_MSGPP_SPI = 0x2091019a; // Output rate of the UBX-MON-MSGPP message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_MSGPP_UART1 = 0x20910197; // Output rate of the UBX-MON-MSGPP message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_MSGPP_UART2 = 0x20910198; // Output rate of the UBX-MON-MSGPP message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_MSGPP_USB = 0x20910199; // Output rate of the UBX-MON-MSGPP message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RF_I2C = 0x20910359; // Output rate of the UBX-MON-RF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RF_SPI = 0x2091035d; // Output rate of the UBX-MON-RF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RF_UART1 = 0x2091035a; // Output rate of the UBX-MON-RF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RF_UART2 = 0x2091035b; // Output rate of the UBX-MON-RF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RF_USB = 0x2091035c; // Output rate of the UBX-MON-RF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXBUF_I2C = 0x209101a0; // Output rate of the UBX-MON-RXBUF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXBUF_SPI = 0x209101a4; // Output rate of the UBX-MON-RXBUF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXBUF_UART1 = 0x209101a1; // Output rate of the UBX-MON-RXBUF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXBUF_UART2 = 0x209101a2; // Output rate of the UBX-MON-RXBUF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXBUF_USB = 0x209101a3; // Output rate of the UBX-MON-RXBUF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXR_I2C = 0x20910187; // Output rate of the UBX-MON-RXR message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXR_SPI = 0x2091018b; // Output rate of the UBX-MON-RXR message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXR_UART1 = 0x20910188; // Output rate of the UBX-MON-RXR message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXR_UART2 = 0x20910189; // Output rate of the UBX-MON-RXR message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_RXR_USB = 0x2091018a; // Output rate of the UBX-MON-RXR message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SPAN_I2C = 0x2091038b; // Output rate of the UBX-MON-SPAN message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SPAN_SPI = 0x2091038f; // Output rate of the UBX-MON-SPAN message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SPAN_UART1 = 0x2091038c; // Output rate of the UBX-MON-SPAN message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SPAN_UART2 = 0x2091038d; // Output rate of the UBX-MON-SPAN message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SPAN_USB = 0x2091038e; // Output rate of the UBX-MON-SPAN message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SYS_I2C = 0x2091069d; // Output rate of the UBX-MON-SYS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SYS_SPI = 0x209106a1; // Output rate of the UBX-MON-SYS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SYS_UART1 = 0x2091069e; // Output rate of the UBX-MON-SYS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SYS_UART2 = 0x2091069f; // Output rate of the UBX-MON-SYS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_SYS_USB = 0x209106a0; // Output rate of the UBX-MON-SYS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_TXBUF_I2C = 0x2091019b; // Output rate of the UBX-MON-TXBUF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_TXBUF_SPI = 0x2091019f; // Output rate of the UBX-MON-TXBUF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_TXBUF_UART1 = 0x2091019c; // Output rate of the UBX-MON-TXBUF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_TXBUF_UART2 = 0x2091019d; // Output rate of the UBX-MON-TXBUF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_TXBUF_USB = 0x2091019e; // Output rate of the UBX-MON-TXBUF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ATT_I2C = 0x2091001f; // Output rate of the UBX_NAV_ATT message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ATT_SPI = 0x20910023; // Output rate of the UBX_NAV_ATT message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ATT_UART1 = 0x20910020; // Output rate of the UBX_NAV_ATT message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ATT_UART2 = 0x20910021; // Output rate of the UBX_NAV_ATT message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ATT_USB = 0x20910022; // Output rate of the UBX_NAV_ATT message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_CLOCK_I2C = 0x20910065; // Output rate of the UBX-NAV-CLOCK message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_CLOCK_SPI = 0x20910069; // Output rate of the UBX-NAV-CLOCK message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_CLOCK_UART1 = 0x20910066; // Output rate of the UBX-NAV-CLOCK message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_CLOCK_UART2 = 0x20910067; // Output rate of the UBX-NAV-CLOCK message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_CLOCK_USB = 0x20910068; // Output rate of the UBX-NAV-CLOCK message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_DOP_I2C = 0x20910038; // Output rate of the UBX-NAV-DOP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_DOP_SPI = 0x2091003c; // Output rate of the UBX-NAV-DOP message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_DOP_UART1 = 0x20910039; // Output rate of the UBX-NAV-DOP message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_DOP_UART2 = 0x2091003a; // Output rate of the UBX-NAV-DOP message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_DOP_USB = 0x2091003b; // Output rate of the UBX-NAV-DOP message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EOE_I2C = 0x2091015f; // Output rate of the UBX-NAV-EOE message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EOE_SPI = 0x20910163; // Output rate of the UBX-NAV-EOE message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EOE_UART1 = 0x20910160; // Output rate of the UBX-NAV-EOE message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EOE_UART2 = 0x20910161; // Output rate of the UBX-NAV-EOE message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EOE_USB = 0x20910162; // Output rate of the UBX-NAV-EOE message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_GEOFENCE_I2C = 0x209100a1; // Output rate of the UBX-NAV-GEOFENCE message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_GEOFENCE_SPI = 0x209100a5; // Output rate of the UBX-NAV-GEOFENCE message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_GEOFENCE_UART1 = 0x209100a2; // Output rate of the UBX-NAV-GEOFENCE message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_GEOFENCE_UART2 = 0x209100a3; // Output rate of the UBX-NAV-GEOFENCE message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_GEOFENCE_USB = 0x209100a4; // Output rate of the UBX-NAV-GEOFENCE message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSECEF_I2C = 0x2091002e; // Output rate of the UBX-NAV-HPPOSECEF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSECEF_SPI = 0x20910032; // Output rate of the UBX-NAV-HPPOSECEF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSECEF_UART1 = 0x2091002f; // Output rate of the UBX-NAV-HPPOSECEF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSECEF_UART2 = 0x20910030; // Output rate of the UBX-NAV-HPPOSECEF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSECEF_USB = 0x20910031; // Output rate of the UBX-NAV-HPPOSECEF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSLLH_I2C = 0x20910033; // Output rate of the UBX-NAV-HPPOSLLH message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSLLH_SPI = 0x20910037; // Output rate of the UBX-NAV-HPPOSLLH message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSLLH_UART1 = 0x20910034; // Output rate of the UBX-NAV-HPPOSLLH message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSLLH_UART2 = 0x20910035; // Output rate of the UBX-NAV-HPPOSLLH message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_HPPOSLLH_USB = 0x20910036; // Output rate of the UBX-NAV-HPPOSLLH message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ODO_I2C = 0x2091007e; // Output rate of the UBX-NAV-ODO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ODO_SPI = 0x20910082; // Output rate of the UBX-NAV-ODO message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ODO_UART1 = 0x2091007f; // Output rate of the UBX-NAV-ODO message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ODO_UART2 = 0x20910080; // Output rate of the UBX-NAV-ODO message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ODO_USB = 0x20910081; // Output rate of the UBX-NAV-ODO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ORB_I2C = 0x20910010; // Output rate of the UBX-NAV-ORB message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ORB_SPI = 0x20910014; // Output rate of the UBX-NAV-ORB message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ORB_UART1 = 0x20910011; // Output rate of the UBX-NAV-ORB message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ORB_UART2 = 0x20910012; // Output rate of the UBX-NAV-ORB message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_ORB_USB = 0x20910013; // Output rate of the UBX-NAV-ORB message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PL_I2C = 0x20910415; // Output rate of the UBX-NAV-PL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PL_SPI = 0x20910419; // Output rate of the UBX-NAV-PL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PL_UART1 = 0x20910416; // Output rate of the UBX-NAV-PL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PL_UART2 = 0x20910417; // Output rate of the UBX-NAV-PL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PL_USB = 0x20910418; // Output rate of the UBX-NAV-PL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSECEF_I2C = 0x20910024; // Output rate of the UBX-NAV-POSECEF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSECEF_SPI = 0x20910028; // Output rate of the UBX-NAV-POSECEF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSECEF_UART1 = 0x20910025; // Output rate of the UBX-NAV-POSECEF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSECEF_UART2 = 0x20910026; // Output rate of the UBX-NAV-POSECEF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSECEF_USB = 0x20910027; // Output rate of the UBX-NAV-POSECEF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSLLH_I2C = 0x20910029; // Output rate of the UBX-NAV-POSLLH message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSLLH_SPI = 0x2091002d; // Output rate of the UBX-NAV-POSLLH message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSLLH_UART1 = 0x2091002a; // Output rate of the UBX-NAV-POSLLH message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSLLH_UART2 = 0x2091002b; // Output rate of the UBX-NAV-POSLLH message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_POSLLH_USB = 0x2091002c; // Output rate of the UBX-NAV-POSLLH message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVT_I2C = 0x20910006; // Output rate of the UBX-NAV-PVT message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVT_SPI = 0x2091000a; // Output rate of the UBX-NAV-PVT message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVT_UART1 = 0x20910007; // Output rate of the UBX-NAV-PVT message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVT_UART2 = 0x20910008; // Output rate of the UBX-NAV-PVT message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVT_USB = 0x20910009; // Output rate of the UBX-NAV-PVT message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_RELPOSNED_I2C = 0x2091008d; // Output rate of the UBX-NAV-RELPOSNED message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_RELPOSNED_SPI = 0x20910091; // Output rate of the UBX-NAV-RELPOSNED message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_RELPOSNED_UART1 = 0x2091008e; // Output rate of the UBX-NAV-RELPOSNED message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_RELPOSNED_UART2 = 0x2091008f; // Output rate of the UBX-NAV-RELPOSNED message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_RELPOSNED_USB = 0x20910090; // Output rate of the UBX-NAV-RELPOSNED message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SAT_I2C = 0x20910015; // Output rate of the UBX-NAV-SAT message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SAT_SPI = 0x20910019; // Output rate of the UBX-NAV-SAT message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SAT_UART1 = 0x20910016; // Output rate of the UBX-NAV-SAT message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SAT_UART2 = 0x20910017; // Output rate of the UBX-NAV-SAT message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SAT_USB = 0x20910018; // Output rate of the UBX-NAV-SAT message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SBAS_I2C = 0x2091006a; // Output rate of the UBX-NAV-SBAS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SBAS_SPI = 0x2091006e; // Output rate of the UBX-NAV-SBAS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SBAS_UART1 = 0x2091006b; // Output rate of the UBX-NAV-SBAS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SBAS_UART2 = 0x2091006c; // Output rate of the UBX-NAV-SBAS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SBAS_USB = 0x2091006d; // Output rate of the UBX-NAV-SBAS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SIG_I2C = 0x20910345; // Output rate of the UBX-NAV-SIG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SIG_SPI = 0x20910349; // Output rate of the UBX-NAV-SIG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SIG_UART1 = 0x20910346; // Output rate of the UBX-NAV-SIG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SIG_UART2 = 0x20910347; // Output rate of the UBX-NAV-SIG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SIG_USB = 0x20910348; // Output rate of the UBX-NAV-SIG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SLAS_I2C = 0x20910336; // Output rate of the UBX-NAV-SLAS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SLAS_SPI = 0x2091033a; // Output rate of the UBX-NAV-SLAS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SLAS_UART1 = 0x20910337; // Output rate of the UBX-NAV-SLAS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SLAS_UART2 = 0x20910338; // Output rate of the UBX-NAV-SLAS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SLAS_USB = 0x20910339; // Output rate of the UBX-NAV-SLAS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_STATUS_I2C = 0x2091001a; // Output rate of the UBX-NAV-STATUS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_STATUS_SPI = 0x2091001e; // Output rate of the UBX-NAV-STATUS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_STATUS_UART1 = 0x2091001b; // Output rate of the UBX-NAV-STATUS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_STATUS_UART2 = 0x2091001c; // Output rate of the UBX-NAV-STATUS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_STATUS_USB = 0x2091001d; // Output rate of the UBX-NAV-STATUS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SVIN_I2C = 0x20910088; // Output rate of the UBX-NAV-SVIN message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SVIN_SPI = 0x2091008c; // Output rate of the UBX-NAV-SVIN message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SVIN_UART1 = 0x20910089; // Output rate of the UBX-NAV-SVIN message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SVIN_UART2 = 0x2091008a; // Output rate of the UBX-NAV-SVIN message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_SVIN_USB = 0x2091008b; // Output rate of the UBX-NAV-SVIN message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEBDS_I2C = 0x20910051; // Output rate of the UBX-NAV-TIMEBDS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEBDS_SPI = 0x20910055; // Output rate of the UBX-NAV-TIMEBDS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEBDS_UART1 = 0x20910052; // Output rate of the UBX-NAV-TIMEBDS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEBDS_UART2 = 0x20910053; // Output rate of the UBX-NAV-TIMEBDS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEBDS_USB = 0x20910054; // Output rate of the UBX-NAV-TIMEBDS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGAL_I2C = 0x20910056; // Output rate of the UBX-NAV-TIMEGAL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGAL_SPI = 0x2091005a; // Output rate of the UBX-NAV-TIMEGAL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGAL_UART1 = 0x20910057; // Output rate of the UBX-NAV-TIMEGAL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGAL_UART2 = 0x20910058; // Output rate of the UBX-NAV-TIMEGAL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGAL_USB = 0x20910059; // Output rate of the UBX-NAV-TIMEGAL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGLO_I2C = 0x2091004c; // Output rate of the UBX-NAV-TIMEGLO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGLO_SPI = 0x20910050; // Output rate of the UBX-NAV-TIMEGLO message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGLO_UART1 = 0x2091004d; // Output rate of the UBX-NAV-TIMEGLO message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGLO_UART2 = 0x2091004e; // Output rate of the UBX-NAV-TIMEGLO message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGLO_USB = 0x2091004f; // Output rate of the UBX-NAV-TIMEGLO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGPS_I2C = 0x20910047; // Output rate of the UBX-NAV-TIMEGPS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGPS_SPI = 0x2091004b; // Output rate of the UBX-NAV-TIMEGPS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1 = 0x20910048; // Output rate of the UBX-NAV-TIMEGPS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGPS_UART2 = 0x20910049; // Output rate of the UBX-NAV-TIMEGPS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEGPS_USB = 0x2091004a; // Output rate of the UBX-NAV-TIMEGPS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMELS_I2C = 0x20910060; // Output rate of the UBX-NAV-TIMELS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMELS_SPI = 0x20910064; // Output rate of the UBX-NAV-TIMELS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMELS_UART1 = 0x20910061; // Output rate of the UBX-NAV-TIMELS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMELS_UART2 = 0x20910062; // Output rate of the UBX-NAV-TIMELS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMELS_USB = 0x20910063; // Output rate of the UBX-NAV-TIMELS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEQZSS_I2C = 0x20910386; // Output rate of the UBX-NAV-TIMEQZSSmessage on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEQZSS_SPI = 0x2091038a; // Output rate of the UBX-NAV-TIMEQZSSmessage on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEQZSS_UART1 = 0x20910387; // Output rate of the UBX-NAV-TIMEQZSSmessage on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEQZSS_UART2 = 0x20910388; // Output rate of the UBX-NAV-TIMEQZSSmessage on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEQZSS_USB = 0x20910389; // Output rate of the UBX-NAV-TIMEQZSSmessage on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEUTC_I2C = 0x2091005b; // Output rate of the UBX-NAV-TIMEUTC message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEUTC_SPI = 0x2091005f; // Output rate of the UBX-NAV-TIMEUTC message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEUTC_UART1 = 0x2091005c; // Output rate of the UBX-NAV-TIMEUTC message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEUTC_UART2 = 0x2091005d; // Output rate of the UBX-NAV-TIMEUTC message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_TIMEUTC_USB = 0x2091005e; // Output rate of the UBX-NAV-TIMEUTC message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELECEF_I2C = 0x2091003d; // Output rate of the UBX-NAV-VELECEF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELECEF_SPI = 0x20910041; // Output rate of the UBX-NAV-VELECEF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELECEF_UART1 = 0x2091003e; // Output rate of the UBX-NAV-VELECEF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELECEF_UART2 = 0x2091003f; // Output rate of the UBX-NAV-VELECEF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELECEF_USB = 0x20910040; // Output rate of the UBX-NAV-VELECEF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELNED_I2C = 0x20910042; // Output rate of the UBX-NAV-VELNED message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELNED_SPI = 0x20910046; // Output rate of the UBX-NAV-VELNED message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELNED_UART1 = 0x20910043; // Output rate of the UBX-NAV-VELNED message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELNED_UART2 = 0x20910044; // Output rate of the UBX-NAV-VELNED message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_VELNED_USB = 0x20910045; // Output rate of the UBX-NAV-VELNED message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_COR_I2C = 0x209106b6; // Output rate of the UBX-RXM-COR message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_COR_SPI = 0x209106ba; // Output rate of the UBX-RXM-COR message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_COR_UART1 = 0x209106b7; // Output rate of the UBX-RXM-COR message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_COR_UART2 = 0x209106b8; // Output rate of the UBX-RXM-COR message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_COR_USB = 0x209106b9; // Output rate of the UBX-RXM-COR message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_MEASX_I2C = 0x20910204; // Output rate of the UBX-RXM-MEASX message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_MEASX_SPI = 0x20910208; // Output rate of the UBX-RXM-MEASX message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_MEASX_UART1 = 0x20910205; // Output rate of the UBX-RXM-MEASX message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_MEASX_UART2 = 0x20910206; // Output rate of the UBX-RXM-MEASX message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_MEASX_USB = 0x20910207; // Output rate of the UBX-RXM-MEASX message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RAWX_I2C = 0x209102a4; // Output rate of the UBX-RXM-RAWX message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RAWX_SPI = 0x209102a8; // Output rate of the UBX-RXM-RAWX message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RAWX_UART1 = 0x209102a5; // Output rate of the UBX-RXM-RAWX message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RAWX_UART2 = 0x209102a6; // Output rate of the UBX-RXM-RAWX message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RAWX_USB = 0x209102a7; // Output rate of the UBX-RXM-RAWX message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RLM_I2C = 0x2091025e; // Output rate of the UBX-RXM-RLM message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RLM_SPI = 0x20910262; // Output rate of the UBX-RXM-RLM message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RLM_UART1 = 0x2091025f; // Output rate of the UBX-RXM-RLM message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RLM_UART2 = 0x20910260; // Output rate of the UBX-RXM-RLM message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RLM_USB = 0x20910261; // Output rate of the UBX-RXM-RLM message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RTCM_I2C = 0x20910268; // Output rate of the UBX-RXM-RTCM message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RTCM_SPI = 0x2091026c; // Output rate of the UBX-RXM-RTCM message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RTCM_UART1 = 0x20910269; // Output rate of the UBX-RXM-RTCM message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RTCM_UART2 = 0x2091026a; // Output rate of the UBX-RXM-RTCM message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_RTCM_USB = 0x2091026b; // Output rate of the UBX-RXM-RTCM message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SFRBX_I2C = 0x20910231; // Output rate of the UBX-RXM-SFRBX message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SFRBX_SPI = 0x20910235; // Output rate of the UBX-RXM-SFRBX message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SFRBX_UART1 = 0x20910232; // Output rate of the UBX-RXM-SFRBX message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SFRBX_UART2 = 0x20910233; // Output rate of the UBX-RXM-SFRBX message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SFRBX_USB = 0x20910234; // Output rate of the UBX-RXM-SFRBX message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SPARTN_I2C = 0x20910605; // Output rate of the UBX-RXM-SPARTN message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SPARTN_UART1 = 0x20910606; // Output rate of the UBX-RXM-SPARTN message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SPARTN_UART2 = 0x20910607; // Output rate of the UBX-RXM-SPARTN message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SPARTN_USB = 0x20910608; // Output rate of the UBX-RXM-SPARTN message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_SPARTN_SPI = 0x20910609; // Output rate of the UBX-RXM-SPARTN message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIG_I2C = 0x20910634; // Output rate of the UBX-SEC-SIG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIG_SPI = 0x20910638; // Output rate of the UBX-SEC-SIG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIG_UART1 = 0x20910635; // Output rate of the UBX-SEC-SIG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIG_UART2 = 0x20910636; // Output rate of the UBX-SEC-SIG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIG_USB = 0x20910637; // Output rate of the UBX-SEC-SIG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TM2_I2C = 0x20910178; // Output rate of the UBX-TIM-TM2 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TM2_SPI = 0x2091017c; // Output rate of the UBX-TIM-TM2 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TM2_UART1 = 0x20910179; // Output rate of the UBX-TIM-TM2 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TM2_UART2 = 0x2091017a; // Output rate of the UBX-TIM-TM2 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TM2_USB = 0x2091017b; // Output rate of the UBX-TIM-TM2 message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TP_I2C = 0x2091017d; // Output rate of the UBX-TIM-TP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TP_SPI = 0x20910181; // Output rate of the UBX-TIM-TP message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TP_UART1 = 0x2091017e; // Output rate of the UBX-TIM-TP message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TP_UART2 = 0x2091017f; // Output rate of the UBX-TIM-TP message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_TP_USB = 0x20910180; // Output rate of the UBX-TIM-TP message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_VRFY_I2C = 0x20910092; // Output rate of the UBX-TIM-VRFY message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_VRFY_SPI = 0x20910096; // Output rate of the UBX-TIM-VRFY message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_VRFY_UART1 = 0x20910093; // Output rate of the UBX-TIM-VRFY message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_VRFY_UART2 = 0x20910094; // Output rate of the UBX-TIM-VRFY message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_VRFY_USB = 0x20910095; // Output rate of the UBX-TIM-VRFY message on port USB - -// Additional CFG_MSGOUT keys for the ZED-F9R HPS121 -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_COV_I2C = 0x20910083; // Output rate of the UBX-NAV-COV message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_COV_UART1 = 0x20910084; // Output rate of the UBX-NAV-COV message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_COV_UART2 = 0x20910085; // Output rate of the UBX-NAV-COV message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_COV_USB = 0x20910086; // Output rate of the UBX-NAV-COV message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_COV_SPI = 0x20910087; // Output rate of the UBX-NAV-COV message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_THS_I2C = 0x209100e2; // Output rate of the NMEA-GX-THS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_THS_UART1 = 0x209100e3; // Output rate of the NMEA-GX-THS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_THS_UART2 = 0x209100e4; // Output rate of the NMEA-GX-THS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_THS_USB = 0x209100e5; // Output rate of the NMEA-GX-THS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_ID_THS_SPI = 0x209100e6; // Output rate of the NMEA-GX-THS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_STATUS_I2C = 0x20910105; // Output rate of the UBX-ESF-STATUS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_STATUS_UART1 = 0x20910106; // Output rate of the UBX-ESF-STATUS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_STATUS_UART2 = 0x20910107; // Output rate of the UBX-ESF-STATUS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_STATUS_USB = 0x20910108; // Output rate of the UBX-ESF-STATUS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_STATUS_SPI = 0x20910109; // Output rate of the UBX-ESF-STATUS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_I2C = 0x2091010f; // Output rate of the UBX-ESF-ALG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_UART1 = 0x20910110; // Output rate of the UBX-ESF-ALG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_UART2 = 0x20910111; // Output rate of the UBX-ESF-ALG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_USB = 0x20910112; // Output rate of the UBX-ESF-ALG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_SPI = 0x20910113; // Output rate of the UBX-ESF-ALG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_INS_I2C = 0x20910114; // Output rate of the UBX-ESF-INS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_INS_UART1 = 0x20910115; // Output rate of the UBX-ESF-INS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_INS_UART2 = 0x20910116; // Output rate of the UBX-ESF-INS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_INS_USB = 0x20910117; // Output rate of the UBX-ESF-INS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_INS_SPI = 0x20910118; // Output rate of the UBX-ESF-INS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_MEAS_I2C = 0x20910277; // Output rate of the UBX-ESF-MEAS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_MEAS_UART1 = 0x20910278; // Output rate of the UBX-ESF-MEAS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_MEAS_UART2 = 0x20910279; // Output rate of the UBX-ESF-MEAS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_MEAS_USB = 0x2091027a; // Output rate of the UBX-ESF-MEAS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_MEAS_SPI = 0x2091027b; // Output rate of the UBX-ESF-MEAS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_RAW_I2C = 0x2091029f; // Output rate of the UBX-ESF-RAW message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_RAW_UART1 = 0x209102a0; // Output rate of the UBX-ESF-RAW message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_RAW_UART2 = 0x209102a1; // Output rate of the UBX-ESF-RAW message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_RAW_USB = 0x209102a2; // Output rate of the UBX-ESF-RAW message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_RAW_SPI = 0x209102a3; // Output rate of the UBX-ESF-RAW message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EELL_I2C = 0x20910313; // Output rate of the UBX-NAV-EELL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EELL_UART1 = 0x20910314; // Output rate of the UBX-NAV-EELL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EELL_UART2 = 0x20910315; // Output rate of the UBX-NAV-EELL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EELL_USB = 0x20910316; // Output rate of the UBX-NAV-EELL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_EELL_SPI = 0x20910317; // Output rate of the UBX-NAV-EELL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVAT_I2C = 0x2091062a; // Output rate of the UBX-NAV-PVAT message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVAT_UART1 = 0x2091062b; // Output rate of the UBX-NAV-PVAT message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVAT_UART2 = 0x2091062c; // Output rate of the UBX-NAV-PVAT message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVAT_USB = 0x2091062d; // Output rate of the UBX-NAV-PVAT message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_PVAT_SPI = 0x2091062e; // Output rate of the UBX-NAV-PVAT message on port SPI - -// Additional CFG_MSGOUT keys for the ZED-F9T -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GGA_I2C = 0x20910661; // Output rate of the NMEA-NAV2-GX-GGA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GGA_SPI = 0x20910665; // Output rate of the NMEA-NAV2-GX-GGA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GGA_UART1 = 0x20910662; // Output rate of the NMEA-NAV2-GX-GGA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GGA_UART2 = 0x20910663; // Output rate of the NMEA-NAV2-GX-GGA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GGA_USB = 0x20910664; // Output rate of the NMEA-NAV2-GX-GGA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GLL_I2C = 0x20910670; // Output rate of the NMEA-NAV2-GX-GLL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GLL_SPI = 0x20910674; // Output rate of the NMEA-NAV2-GX-GLL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GLL_UART1 = 0x20910671; // Output rate of the NMEA-NAV2-GX-GLL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GLL_UART2 = 0x20910672; // Output rate of the NMEA-NAV2-GX-GLL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GLL_USB = 0x20910673; // Output rate of the NMEA-NAV2-GX-GLL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GNS_I2C = 0x2091065c; // Output rate of the NMEA-NAV2-GX-GNS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GNS_SPI = 0x20910660; // Output rate of the NMEA-NAV2-GX-GNS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GNS_UART1 = 0x2091065d; // Output rate of the NMEA-NAV2-GX-GNS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GNS_UART2 = 0x2091065e; // Output rate of the NMEA-NAV2-GX-GNS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GNS_USB = 0x2091065f; // Output rate of the NMEA-NAV2-GX-GNS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GSA_I2C = 0x20910666; // Output rate of the NMEA-NAV2-GX-GSA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GSA_SPI = 0x2091066a; // Output rate of the NMEA-NAV2-GX-GSA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GSA_UART1 = 0x20910667; // Output rate of the NMEA-NAV2-GX-GSA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GSA_UART2 = 0x20910668; // Output rate of the NMEA-NAV2-GX-GSA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_GSA_USB = 0x20910669; // Output rate of the NMEA-NAV2-GX-GSA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_RMC_I2C = 0x20910652; // Output rate of the NMEA-NAV2-GX-RMC message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_RMC_SPI = 0x20910656; // Output rate of the NMEA-NAV2-GX-RMC message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_RMC_UART1 = 0x20910653; // Output rate of the NMEA-NAV2-GX-RMC message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_RMC_UART2 = 0x20910654; // Output rate of the NMEA-NAV2-GX-RMC message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_RMC_USB = 0x20910655; // Output rate of the NMEA-NAV2-GX-RMC message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_VTG_I2C = 0x20910657; // Output rate of the NMEA-NAV2-GX-VTG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_VTG_SPI = 0x2091065b; // Output rate of the NMEA-NAV2-GX-VTG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_VTG_UART1 = 0x20910658; // Output rate of the NMEA-NAV2-GX-VTG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_VTG_UART2 = 0x20910659; // Output rate of the NMEA-NAV2-GX-VTG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_VTG_USB = 0x2091065a; // Output rate of the NMEA-NAV2-GX-VTG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_ZDA_I2C = 0x2091067f; // Output rate of the NMEA-NAV2-GX-ZDA message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_ZDA_SPI = 0x20910683; // Output rate of the NMEA-NAV2-GX-ZDA message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_ZDA_UART1 = 0x20910680; // Output rate of the NMEA-NAV2-GX-ZDA message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_ZDA_UART2 = 0x20910681; // Output rate of the NMEA-NAV2-GX-ZDA message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_NMEA_NAV2_ID_ZDA_USB = 0x20910682; // Output rate of the NMEA-NAV2-GX-ZDA message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_CLOCK_I2C = 0x20910430; // Output rate of the UBX-NAV2-CLOCK message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_CLOCK_SPI = 0x20910434; // Output rate of the UBX-NAV2-CLOCK message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_CLOCK_UART1 = 0x20910431; // Output rate of the UBX-NAV2-CLOCK message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_CLOCK_UART2 = 0x20910432; // Output rate of the UBX-NAV2-CLOCK message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_CLOCK_USB = 0x20910433; // Output rate of the UBX-NAV2-CLOCK message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_COV_I2C = 0x20910435; // Output rate of the UBX-NAV2-COV message onport I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_COV_SPI = 0x20910439; // Output rate of the UBX-NAV2-COV message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_COV_UART1 = 0x20910436; // Output rate of the UBX-NAV2-COV message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_COV_UART2 = 0x20910437; // Output rate of the UBX-NAV2-COV message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_COV_USB = 0x20910438; // Output rate of the UBX-NAV2-COV message onport USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_I2C = 0x20910465; // Output rate of the UBX-NAV2-DOP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_SPI = 0x20910469; // Output rate of the UBX-NAV2-DOP message onport SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_UART1 = 0x20910466; // Output rate of the UBX-NAV2-DOP message onport UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_UART2 = 0x20910467; // Output rate of the UBX-NAV2-DOP message onport UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_USB = 0x20910468; // Output rate of the UBX-NAV2-DOP message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EOE_I2C = 0x20910565; // Output rate of the UBX-NAV2-EOE message onport I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EOE_SPI = 0x20910569; // Output rate of the UBX-NAV2-EOE message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EOE_UART1 = 0x20910566; // Output rate of the UBX-NAV2-EOE message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EOE_UART2 = 0x20910567; // Output rate of the UBX-NAV2-EOE message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EOE_USB = 0x20910568; // Output rate of the UBX-NAV2-EOE message onport USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_ODO_I2C = 0x20910475; // Output rate of the UBX-NAV2-ODO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_ODO_SPI = 0x20910479; // Output rate of the UBX-NAV2-ODO message onport SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_ODO_UART1 = 0x20910476; // Output rate of the UBX-NAV2-ODO message onport UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_ODO_UART2 = 0x20910477; // Output rate of the UBX-NAV2-ODO message onport UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_ODO_USB = 0x20910478; // Output rate of the UBX-NAV2-ODO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSECEF_I2C = 0x20910480; // Output rate of the UBX-NAV2-POSECEF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSECEF_SPI = 0x20910484; // Output rate of the UBX-NAV2-POSECEF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSECEF_UART1 = 0x20910481; // Output rate of the UBX-NAV2-POSECEF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSECEF_UART2 = 0x20910482; // Output rate of the UBX-NAV2-POSECEF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSECEF_USB = 0x20910483; // Output rate of the UBX-NAV2-POSECEF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_I2C = 0x20910485; // Output rate of the UBX-NAV2-POSLLH message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_SPI = 0x20910489; // Output rate of the UBX-NAV2-POSLLH message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_UART1 = 0x20910486; // Output rate of the UBX-NAV2-POSLLH message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_UART2 = 0x20910487; // Output rate of the UBX-NAV2-POSLLH message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_USB = 0x20910488; // Output rate of the UBX-NAV2-POSLLH message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVT_I2C = 0x20910490; // Output rate of the UBX-NAV2-PVT message onport I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVT_SPI = 0x20910494; // Output rate of the UBX-NAV2-PVT message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVT_UART1 = 0x20910491; // Output rate of the UBX-NAV2-PVT message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVT_UART2 = 0x20910492; // Output rate of the UBX-NAV2-PVT message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVT_USB = 0x20910493; // Output rate of the UBX-NAV2-PVT message onport USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SAT_I2C = 0x20910495; // Output rate of the UBX-NAV2-SAT message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SAT_SPI = 0x20910499; // Output rate of the UBX-NAV2-SAT message onport SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SAT_UART1 = 0x20910496; // Output rate of the UBX-NAV2-SAT message onport UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SAT_UART2 = 0x20910497; // Output rate of the UBX-NAV2-SAT message onport UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SAT_USB = 0x20910498; // Output rate of the UBX-NAV2-SAT message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SBAS_I2C = 0x20910500; // Output rate of the UBX-NAV2-SBAS messageon port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SBAS_SPI = 0x20910504; // Output rate of the UBX-NAV2-SBAS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SBAS_UART1 = 0x20910501; // Output rate of the UBX-NAV2-SBAS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SBAS_UART2 = 0x20910502; // Output rate of the UBX-NAV2-SBAS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SBAS_USB = 0x20910503; // Output rate of the UBX-NAV2-SBAS messageon port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SIG_I2C = 0x20910505; // Output rate of the UBX-NAV2-SIG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SIG_SPI = 0x20910509; // Output rate of the UBX-NAV2-SIG message onport SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SIG_UART1 = 0x20910506; // Output rate of the UBX-NAV2-SIG message onport UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SIG_UART2 = 0x20910507; // Output rate of the UBX-NAV2-SIG message onport UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SIG_USB = 0x20910508; // Output rate of the UBX-NAV2-SIG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SLAS_I2C = 0x20910510; // Output rate of the UBX-NAV2-SLAS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SLAS_SPI = 0x20910514; // Output rate of the UBX-NAV2-SLAS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SLAS_UART1 = 0x20910511; // Output rate of the UBX-NAV2-SLAS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SLAS_UART2 = 0x20910512; // Output rate of the UBX-NAV2-SLAS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SLAS_USB = 0x20910513; // Output rate of the UBX-NAV2-SLAS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_STATUS_I2C = 0x20910515; // Output rate of the UBX-NAV2-STATUS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_STATUS_SPI = 0x20910519; // Output rate of the UBX-NAV2-STATUS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_STATUS_UART1 = 0x20910516; // Output rate of the UBX-NAV2-STATUS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_STATUS_UART2 = 0x20910517; // Output rate of the UBX-NAV2-STATUS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_STATUS_USB = 0x20910518; // Output rate of the UBX-NAV2-STATUS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SVIN_I2C = 0x20910520; // Output rate of the UBX-NAV2-SVIN message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SVIN_SPI = 0x20910524; // Output rate of the UBX-NAV2-SVIN message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SVIN_UART1 = 0x20910521; // Output rate of the UBX-NAV2-SVIN message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SVIN_UART2 = 0x20910522; // Output rate of the UBX-NAV2-SVIN message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_SVIN_USB = 0x20910523; // Output rate of the UBX-NAV2-SVIN message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEBDS_I2C = 0x20910525; // Output rate of the UBX-NAV2-TIMEBDS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEBDS_SPI = 0x20910529; // Output rate of the UBX-NAV2-TIMEBDS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEBDS_UART1 = 0x20910526; // Output rate of the UBX-NAV2-TIMEBDS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEBDS_UART2 = 0x20910527; // Output rate of the UBX-NAV2-TIMEBDS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEBDS_USB = 0x20910528; // Output rate of the UBX-NAV2-TIMEBDS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGAL_I2C = 0x20910530; // Output rate of the UBX-NAV2-TIMEGAL message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGAL_SPI = 0x20910534; // Output rate of the UBX-NAV2-TIMEGAL message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGAL_UART1 = 0x20910531; // Output rate of the UBX-NAV2-TIMEGAL message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGAL_UART2 = 0x20910532; // Output rate of the UBX-NAV2-TIMEGAL message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGAL_USB = 0x20910533; // Output rate of the UBX-NAV2-TIMEGAL message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGLO_I2C = 0x20910535; // Output rate of the UBX-NAV2-TIMEGLO message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGLO_SPI = 0x20910539; // Output rate of the UBX-NAV2-TIMEGLO message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGLO_UART1 = 0x20910536; // Output rate of the UBX-NAV2-TIMEGLO message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGLO_UART2 = 0x20910537; // Output rate of the UBX-NAV2-TIMEGLO message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGLO_USB = 0x20910538; // Output rate of the UBX-NAV2-TIMEGLO message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGPS_I2C = 0x20910540; // Output rate of the UBX-NAV2-TIMEGPS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGPS_SPI = 0x20910544; // Output rate of the UBX-NAV2-TIMEGPS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGPS_UART1 = 0x20910541; // Output rate of the UBX-NAV2-TIMEGPS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGPS_UART2 = 0x20910542; // Output rate of the UBX-NAV2-TIMEGPS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEGPS_USB = 0x20910543; // Output rate of the UBX-NAV2-TIMEGPS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMELS_I2C = 0x20910545; // Output rate of the UBX-NAV2-TIMELS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMELS_SPI = 0x20910549; // Output rate of the UBX-NAV2-TIMELS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMELS_UART1 = 0x20910546; // Output rate of the UBX-NAV2-TIMELS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMELS_UART2 = 0x20910547; // Output rate of the UBX-NAV2-TIMELS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMELS_USB = 0x20910548; // Output rate of the UBX-NAV2-TIMELS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEQZSS_I2C = 0x20910575; // Output rate of the UBX-NAV2-TIMEQZSS message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEQZSS_SPI = 0x20910579; // Output rate of the UBX-NAV2-TIMEQZSS message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEQZSS_UART1 = 0x20910576; // Output rate of the UBX-NAV2-TIMEQZSS message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEQZSS_UART2 = 0x20910577; // Output rate of the UBX-NAV2-TIMEQZSS message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEQZSS_USB = 0x20910578; // Output rate of the UBX-NAV2-TIMEQZSS message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEUTC_I2C = 0x20910550; // Output rate of the UBX-NAV2-TIMEUTC message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEUTC_SPI = 0x20910554; // Output rate of the UBX-NAV2-TIMEUTC message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEUTC_UART1 = 0x20910551; // Output rate of the UBX-NAV2-TIMEUTC message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEUTC_UART2 = 0x20910552; // Output rate of the UBX-NAV2-TIMEUTC message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_TIMEUTC_USB = 0x20910553; // Output rate of the UBX-NAV2-TIMEUTC message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELECEF_I2C = 0x20910555; // Output rate of the UBX-NAV2-VELECEF message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELECEF_SPI = 0x20910559; // Output rate of the UBX-NAV2-VELECEF message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELECEF_UART1 = 0x20910556; // Output rate of the UBX-NAV2-VELECEF message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELECEF_UART2 = 0x20910557; // Output rate of the UBX-NAV2-VELECEF message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELECEF_USB = 0x20910558; // Output rate of the UBX-NAV2-VELECEF message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELNED_I2C = 0x20910560; // Output rate of the UBX-NAV2-VELNED message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELNED_SPI = 0x20910564; // Output rate of the UBX-NAV2-VELNED message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELNED_UART1 = 0x20910561; // Output rate of the UBX-NAV2-VELNED message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELNED_UART2 = 0x20910562; // Output rate of the UBX-NAV2-VELNED message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_VELNED_USB = 0x20910563; // Output rate of the UBX-NAV2-VELNED message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_NMI_I2C = 0x20910590; // Output rate of the UBX-NAV-NMI message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_NMI_SPI = 0x20910594; // Output rate of the UBX-NAV-NMI message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_NMI_UART1 = 0x20910591; // Output rate of the UBX-NAV-NMI message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_NMI_UART2 = 0x20910592; // Output rate of the UBX-NAV-NMI message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV_NMI_USB = 0x20910593; // Output rate of the UBX-NAV-NMI message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_TM_I2C = 0x20910610; // Output rate of the UBX-RXM-TM message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_TM_SPI = 0x20910614; // Output rate of the UBX-RXM-TM message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_TM_UART1 = 0x20910611; // Output rate of the UBX-RXM-TM message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_TM_UART2 = 0x20910612; // Output rate of the UBX-RXM-TM message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_TM_USB = 0x20910613; // Output rate of the UBX-RXM-TM message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIGLOG_I2C = 0x20910689; // Output rate of the UBX-SEC-SIGLOG message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIGLOG_SPI = 0x2091068d; // Output rate of the UBX-SEC-SIGLOG message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIGLOG_UART1 = 0x2091068a; // Output rate of the UBX-SEC-SIGLOG message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIGLOG_UART2 = 0x2091068b; // Output rate of the UBX-SEC-SIGLOG message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_SEC_SIGLOG_USB = 0x2091068c; // Output rate of the UBX-SEC-SIGLOG message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_SVIN_I2C = 0x20910097; // Output rate of the UBX-TIM-SVIN message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_SVIN_SPI = 0x2091009b; // Output rate of the UBX-TIM-SVIN message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_SVIN_UART1 = 0x20910098; // Output rate of the UBX-TIM-SVIN message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_SVIN_UART2 = 0x20910099; // Output rate of the UBX-TIM-SVIN message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_TIM_SVIN_USB = 0x2091009a; // Output rate of the UBX-TIM-SVIN message on port USB - -// Additional CFG_MSGOUT keys for the NEO-D9S -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C = 0x2091031d; // Output rate of the UBX_RXM_PMP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_PMP_SPI = 0x20910321; // Output rate of the UBX_RXM_PMP message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1 = 0x2091031e; // Output rate of the UBX_RXM_PMP message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2 = 0x2091031f; // Output rate of the UBX_RXM_PMP message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_PMP_USB = 0x20910320; // Output rate of the UBX_RXM_PMP message on port USB -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_PMP_I2C = 0x20910322; // Output rate of the UBX_MON_PMP message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_PMP_SPI = 0x20910326; // Output rate of the UBX_MON_PMP message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_PMP_UART1 = 0x20910323; // Output rate of the UBX_MON_PMP message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_PMP_UART2 = 0x20910324; // Output rate of the UBX_MON_PMP message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_MON_PMP_USB = 0x20910325; // Output rate of the UBX_MON_PMP message on port USB - -// Additional CFG_MSGOUT keys for the NEO-D9S -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_I2C = 0x2091033f; // Output rate of the UBX_RXM_QZSSL6 message on port I2C -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_SPI = 0x2091033e; // Output rate of the UBX_RXM_QZSSL6 message on port SPI -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_UART1 = 0x2091033b; // Output rate of the UBX_RXM_QZSSL6 message on port UART1 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_UART2 = 0x2091033c; // Output rate of the UBX_RXM_QZSSL6 message on port UART2 -const uint32_t UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_USB = 0x2091033d; // Output rate of the UBX_RXM_QZSSL6 message on port USB - -// CFG-NAV2: Secondary output configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_NAV2_OUT_ENABLED = 0x10170001; // Enable secondary (NAV2) output -const uint32_t UBLOX_CFG_NAV2_SBAS_USE_INTEGRITY = 0x10170002; // Use SBAS integrity information in the secondary output - -// CFG-NAVHPG: High precision navigation configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_NAVHPG_DGNSSMODE = 0x20140011; // Differential corrections mode - -// CFG-NAVSPG: Standard precision navigation configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_NAVSPG_FIXMODE = 0x20110011; // Position fix mode -const uint32_t UBLOX_CFG_NAVSPG_INIFIX3D = 0x10110013; // Initial fix must be a 3D fix -const uint32_t UBLOX_CFG_NAVSPG_WKNROLLOVER = 0x30110017; // GPS week rollover number -const uint32_t UBLOX_CFG_NAVSPG_USE_PPP = 0x10110019; // Use precise point positioning (PPP) -const uint32_t UBLOX_CFG_NAVSPG_UTCSTANDARD = 0x2011001c; // UTC standard to be used -const uint32_t UBLOX_CFG_NAVSPG_DYNMODEL = 0x20110021; // Dynamic platform model -const uint32_t UBLOX_CFG_NAVSPG_ACKAIDING = 0x10110025; // Acknowledge assistance input messages -const uint32_t UBLOX_CFG_NAVSPG_USE_USRDAT = 0x10110061; // Use user geodetic datum parameters -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_MAJA = 0x50110062; // Geodetic datum semi-major axis -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_FLAT = 0x50110063; // Geodetic datum 1.0 flattening -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_DX = 0x40110064; // Geodetic datum X axis shift at the origin -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_DY = 0x40110065; // Geodetic datum Y axis shift at the origin -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_DZ = 0x40110066; // Geodetic datum Z axis shift at the origin -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_ROTX = 0x40110067; // arcsec Geodetic datum rotation about the X axis -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_ROTY = 0x40110068; // arcsec Geodetic datum rotation about the Y axis -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_ROTZ = 0x40110069; // arcsec Geodetic datum rotation about the Z axis -const uint32_t UBLOX_CFG_NAVSPG_USRDAT_SCALE = 0x4011006a; // ppm Geodetic datum scale factor -const uint32_t UBLOX_CFG_NAVSPG_INFIL_MINSVS = 0x201100a1; // Minimum number of satellites for navigation -const uint32_t UBLOX_CFG_NAVSPG_INFIL_MAXSVS = 0x201100a2; // Maximum number of satellites for navigation -const uint32_t UBLOX_CFG_NAVSPG_INFIL_MINCNO = 0x201100a3; // Minimum satellite signal level for navigation -const uint32_t UBLOX_CFG_NAVSPG_INFIL_MINELEV = 0x201100a4; // Minimum elevation for a GNSS satellite to be used in navigation -const uint32_t UBLOX_CFG_NAVSPG_INFIL_NCNOTHRS = 0x201100aa; // Number of satellites required to have C/N0 above const uint32_t UBLOX_CFG_NAVSPG-INFIL_CNOTHRS for a fix to be attempted -const uint32_t UBLOX_CFG_NAVSPG_INFIL_CNOTHRS = 0x201100ab; // C/N0 threshold for deciding whether to attempt a fix -const uint32_t UBLOX_CFG_NAVSPG_OUTFIL_PDOP = 0x301100b1; // Output filter position DOP mask (threshold) -const uint32_t UBLOX_CFG_NAVSPG_OUTFIL_TDOP = 0x301100b2; // Output filter time DOP mask (threshold) -const uint32_t UBLOX_CFG_NAVSPG_OUTFIL_PACC = 0x301100b3; // Output filter position accuracy mask (threshold) -const uint32_t UBLOX_CFG_NAVSPG_OUTFIL_TACC = 0x301100b4; // Output filter time accuracy mask (threshold) -const uint32_t UBLOX_CFG_NAVSPG_OUTFIL_FACC = 0x301100b5; // Output filter frequency accuracy mask (threshold) -const uint32_t UBLOX_CFG_NAVSPG_CONSTR_ALT = 0x401100c1; // Fixed altitude (mean sea level) for 2D fix mode -const uint32_t UBLOX_CFG_NAVSPG_CONSTR_ALTVAR = 0x401100c2; // Fixed altitude variance for 2D mode -const uint32_t UBLOX_CFG_NAVSPG_CONSTR_DGNSSTO = 0x201100c4; // DGNSS timeout -const uint32_t UBLOX_CFG_NAVSPG_SIGATTCOMP = 0x201100d6; // Permanently attenuated signal compensation mode -const uint32_t UBLOX_CFG_NAVSPG_PL_ENA = 0x101100d7; // Enable Protection level. If enabled, protection level computing will be on. - -// CFG-NMEA: NMEA protocol configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_NMEA_PROTVER = 0x20930001; // NMEA protocol version -const uint32_t UBLOX_CFG_NMEA_MAXSVS = 0x20930002; // Maximum number of SVs to report per Talker ID -const uint32_t UBLOX_CFG_NMEA_COMPAT = 0x10930003; // Enable compatibility mode -const uint32_t UBLOX_CFG_NMEA_CONSIDER = 0x10930004; // Enable considering mode -const uint32_t UBLOX_CFG_NMEA_LIMIT82 = 0x10930005; // Enable strict limit to 82 characters maximum NMEA message length -const uint32_t UBLOX_CFG_NMEA_HIGHPREC = 0x10930006; // Enable high precision mode -const uint32_t UBLOX_CFG_NMEA_SVNUMBERING = 0x20930007; // Display configuration for SVs that do not have value defined in NMEA -const uint32_t UBLOX_CFG_NMEA_FILT_GPS = 0x10930011; // Disable reporting of GPS satellites -const uint32_t UBLOX_CFG_NMEA_FILT_SBAS = 0x10930012; // Disable reporting of SBAS satellites -const uint32_t UBLOX_CFG_NMEA_FILT_GAL = 0x10930013; // Disable reporting of Galileo satellites -const uint32_t UBLOX_CFG_NMEA_FILT_QZSS = 0x10930015; // Disable reporting of QZSS satellites -const uint32_t UBLOX_CFG_NMEA_FILT_GLO = 0x10930016; // Disable reporting of GLONASS satellites -const uint32_t UBLOX_CFG_NMEA_FILT_BDS = 0x10930017; // Disable reporting of BeiDou satellites -const uint32_t UBLOX_CFG_NMEA_OUT_INVFIX = 0x10930021; // Enable position output for failed or invalid fixes -const uint32_t UBLOX_CFG_NMEA_OUT_MSKFIX = 0x10930022; // Enable position output for invalid fixes -const uint32_t UBLOX_CFG_NMEA_OUT_INVTIME = 0x10930023; // Enable time output for invalid times -const uint32_t UBLOX_CFG_NMEA_OUT_INVDATE = 0x10930024; // Enable date output for invalid dates -const uint32_t UBLOX_CFG_NMEA_OUT_ONLYGPS = 0x10930025; // Restrict output to GPS satellites only -const uint32_t UBLOX_CFG_NMEA_OUT_FROZENCOG = 0x10930026; // Enable course over ground output even if it is frozen -const uint32_t UBLOX_CFG_NMEA_MAINTALKERID = 0x20930031; // Main Talker ID -const uint32_t UBLOX_CFG_NMEA_GSVTALKERID = 0x20930032; // Talker ID for GSV NMEA messages -const uint32_t UBLOX_CFG_NMEA_BDSTALKERID = 0x30930033; // BeiDou Talker ID - -// CFG-ODO: Odometer and low-speed course over ground filter -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_ODO_USE_ODO = 0x10220001; // Use odometer -const uint32_t UBLOX_CFG_ODO_USE_COG = 0x10220002; // Use low-speed course over ground filter -const uint32_t UBLOX_CFG_ODO_OUTLPVEL = 0x10220003; // Output low-pass filtered velocity -const uint32_t UBLOX_CFG_ODO_OUTLPCOG = 0x10220004; // Output low-pass filtered course over ground (heading) -const uint32_t UBLOX_CFG_ODO_PROFILE = 0x20220005; // Odometer profile configuration -const uint32_t UBLOX_CFG_ODO_COGMAXSPEED = 0x20220021; // Upper speed limit for low-speed course over ground filter -const uint32_t UBLOX_CFG_ODO_COGMAXPOSACC = 0x20220022; // Maximum acceptable position accuracy for computing low-speed filtered course over ground -const uint32_t UBLOX_CFG_ODO_VELLPGAIN = 0x20220031; // Velocity low-pass filter level -const uint32_t UBLOX_CFG_ODO_COGLPGAIN = 0x20220032; // Course over ground low-pass filter level (at speed < 8 m/s) - -// CFG-PM: Configuration for receiver power management (NEO-D9S) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_PM_EXTINTSEL = 0x20d0000b; // EXTINT pin select -const uint32_t UBLOX_CFG_PM_EXTINTWAKE = 0x10d0000c; // EXTINT pin control (Wake). Enable to keep receiver awake as long as selected EXTINT pin is "high". -const uint32_t UBLOX_CFG_PM_EXTINTBACKUP = 0x10d0000d; // EXTINT pin control (Backup). Enable to force receiver into BACKUP mode when selected EXTINT pin is "low". -const uint32_t UBLOX_CFG_PM_EXTINTINACTIVE = 0x10d0000e; // EXTINT pin control (Inactive). Enable to force backup in case EXTINT Pin is inactive for time longer than CFG-PM-EXTINTINACTIVITY. -const uint32_t UBLOX_CFG_PM_EXTINTINACTIVITY = 0x40d0000f; // Inactivity time out on EXTINT pin if enabled - -// CFG-PMP: Point to multipoint (PMP) configuration (NEO-D9S) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_PMP_CENTER_FREQUENCY = 0x40b10011; // Center frequency. The center frequency for the receiver can be set from 1525000000 to 1559000000 Hz. -const uint32_t UBLOX_CFG_PMP_SEARCH_WINDOW = 0x30b10012; // Search window. Search window can be set from 0 to 65535 Hz. It is +/- this value from the center frequency set by CENTER_FREQUENCY. -const uint32_t UBLOX_CFG_PMP_USE_SERVICE_ID = 0x10b10016; // Use service ID. Enable/disable service ID check to confirm the correct service is received. -const uint32_t UBLOX_CFG_PMP_SERVICE_ID = 0x30b10017; // Service identifier. Defines the expected service ID. -const uint32_t UBLOX_CFG_PMP_DATA_RATE = 0x30b10013; // bps Data rate. The data rate of the received data. -const uint32_t UBLOX_CFG_PMP_USE_DESCRAMBLER = 0x10b10014; // Use descrambler. Enables/disables the descrambler. -const uint32_t UBLOX_CFG_PMP_DESCRAMBLER_INIT = 0x30b10015; // Descrambler initialization. Set the intialisation value for the descrambler. -const uint32_t UBLOX_CFG_PMP_USE_PRESCRAMBLING = 0x10b10019; // Use prescrambling. Enables/disables the prescrambling. -const uint32_t UBLOX_CFG_PMP_UNIQUE_WORD = 0x50b1001a; // Unique word. Defines value of unique word. - -// CFG-QZSS-L6: QZSS system configuration configuration (NEO-D9C) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_QZSSL6_SVIDA = 0x20370020; // QZSS L6 SV Id to be decoded by channel A -const uint32_t UBLOX_CFG_QZSSL6_SVIDB = 0x20370030; // QZSS L6 SV Id to be decoded by channel B -const uint32_t UBLOX_CFG_QZSSL6_MSGA = 0x20370050; // QZSS L6 messages to be decoded by channel A -const uint32_t UBLOX_CFG_QZSSL6_MSGB = 0x20370060; // QZSS L6 messages to be decoded by channel B -const uint32_t UBLOX_CFG_QZSSL6_RSDECODER = 0x20370080; // QZSS L6 message Reed-Solomon decoder mode - -// CFG-QZSS: QZSS system configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_QZSS_USE_SLAS_DGNSS = 0x10370005; // Apply QZSS SLAS DGNSS corrections -const uint32_t UBLOX_CFG_QZSS_USE_SLAS_TESTMODE = 0x10370006; // Use QZSS SLAS data when it is in test mode (SLAS msg 0) -const uint32_t UBLOX_CFG_QZSS_USE_SLAS_RAIM_UNCORR = 0x10370007; // Raim out measurements that are not corrected by QZSS SLAS, if at least 5 measurements are corrected -const uint32_t UBLOX_CFG_QZSS_SLAS_MAX_BASELINE = 0x30370008; // Maximum baseline distance to closest Ground Monitoring Station: km - -// CFG-RATE: Navigation and measurement rate configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_RATE_MEAS = 0x30210001; // Nominal time between GNSS measurements -const uint32_t UBLOX_CFG_RATE_NAV = 0x30210002; // Ratio of number of measurements to number of navigation solutions -const uint32_t UBLOX_CFG_RATE_TIMEREF = 0x20210003; // Time system to which measurements are aligned -const uint32_t UBLOX_CFG_RATE_NAV_PRIO = 0x20210004; // Output rate of priority navigation mode messages - -// CFG-RINV: Remote inventory -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_RINV_DUMP = 0x10c70001; // Dump data at startup -const uint32_t UBLOX_CFG_RINV_BINARY = 0x10c70002; // Data is binary -const uint32_t UBLOX_CFG_RINV_DATA_SIZE = 0x20c70003; // Size of data -const uint32_t UBLOX_CFG_RINV_CHUNK0 = 0x50c70004; // Data bytes 1-8 (LSB) -const uint32_t UBLOX_CFG_RINV_CHUNK1 = 0x50c70005; // Data bytes 9-16 -const uint32_t UBLOX_CFG_RINV_CHUNK2 = 0x50c70006; // Data bytes 17-240x44434241. -const uint32_t UBLOX_CFG_RINV_CHUNK3 = 0x50c70007; // Data bytes 25-30 (MSB) - -// CFG-RTCM: RTCM protocol configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_RTCM_DF003_OUT = 0x30090001; // RTCM DF003 (Reference station ID) output value -const uint32_t UBLOX_CFG_RTCM_DF003_IN = 0x30090008; // RTCM DF003 (Reference station ID) input value -const uint32_t UBLOX_CFG_RTCM_DF003_IN_FILTER = 0x20090009; // RTCM input filter configuration based on RTCM DF003 (Reference station ID) value - -// CFG-SBAS: SBAS configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SBAS_USE_TESTMODE = 0x10360002; // Use SBAS data when it is in test mode (SBAS msg 0) -const uint32_t UBLOX_CFG_SBAS_USE_RANGING = 0x10360003; // Use SBAS GEOs as a ranging source (for navigation) -const uint32_t UBLOX_CFG_SBAS_USE_DIFFCORR = 0x10360004; // Use SBAS differential corrections -const uint32_t UBLOX_CFG_SBAS_USE_INTEGRITY = 0x10360005; // Use SBAS integrity information -const uint32_t UBLOX_CFG_SBAS_PRNSCANMASK = 0x50360006; // SBAS PRN search configuration - -// CFG-SEC: Security configuration (ZED-F9R) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SEC_CFG_LOCK = 0x10f60009; // Configuration lockdown -const uint32_t UBLOX_CFG_SEC_CFG_LOCK_UNLOCKGRP1 = 0x30f6000a; // Configuration lockdown exempted group 1 -const uint32_t UBLOX_CFG_SEC_CFG_LOCK_UNLOCKGRP2 = 0x30f6000b; // Configuration lockdown exempted group 2 - -// CFG-SFCORE: Sensor fusion (SF) core configuration (ZED-F9R) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SFCORE_USE_SF = 0x10080001; // Use ADR/UDR sensor fusion - -// CFG-SFIMU: Sensor fusion (SF) inertial measurement unit (IMU) configuration (ZED-F9R) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SFIMU_GYRO_TC_UPDATE_PERIOD = 0x30060007; // Time period between each update for the saved temperature-dependent gyroscope bias table -const uint32_t UBLOX_CFG_SFIMU_GYRO_RMSTHDL = 0x20060008; // Gyroscope sensor RMS threshold -const uint32_t UBLOX_CFG_SFIMU_GYRO_FREQUENCY = 0x20060009; // Nominal gyroscope sensor data sampling frequency -const uint32_t UBLOX_CFG_SFIMU_GYRO_LATENCY = 0x3006000a; // Gyroscope sensor data latency due to e.g. CAN bus -const uint32_t UBLOX_CFG_SFIMU_GYRO_ACCURACY = 0x3006000b; // Gyroscope sensor data accuracy -const uint32_t UBLOX_CFG_SFIMU_ACCEL_RMSTHDL = 0x20060015; // Accelerometer RMS threshold -const uint32_t UBLOX_CFG_SFIMU_ACCEL_FREQUENCY = 0x20060016; // Nominal accelerometer sensor data sampling frequency -const uint32_t UBLOX_CFG_SFIMU_ACCEL_LATENCY = 0x30060017; // Accelerometer sensor data latency due to e.g. CAN bus -const uint32_t UBLOX_CFG_SFIMU_ACCEL_ACCURACY = 0x30060018; // Accelerometer sensor data accuracy -const uint32_t UBLOX_CFG_SFIMU_IMU_EN = 0x1006001d; // IMU enabled -const uint32_t UBLOX_CFG_SFIMU_IMU_I2C_SCL_PIO = 0x2006001e; // SCL PIO of the IMU I2C -const uint32_t UBLOX_CFG_SFIMU_IMU_I2C_SDA_PIO = 0x2006001f; // SDA PIO of the IMU I2C -const uint32_t UBLOX_CFG_SFIMU_AUTO_MNTALG_ENA = 0x10060027; // Enable automatic IMU-mount alignment -const uint32_t UBLOX_CFG_SFIMU_IMU_MNTALG_YAW = 0x4006002d; // User-defined IMU-mount yaw angle [0, 360] -const uint32_t UBLOX_CFG_SFIMU_IMU_MNTALG_PITCH = 0x3006002e; // User-defined IMU-mount pitch angle [-90, 90] -const uint32_t UBLOX_CFG_SFIMU_IMU_MNTALG_ROLL = 0x3006002f; // User-defined IMU-mount roll angle [-180, 180] - -// CFG-SFODO: Sensor fusion (SF) odometer configuration (ZED-F9R) -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SFODO_COMBINE_TICKS = 0x10070001; // Use combined rear wheel ticks instead of the single tick -const uint32_t UBLOX_CFG_SFODO_USE_SPEED = 0x10070003; // Use speed measurements -const uint32_t UBLOX_CFG_SFODO_DIS_AUTOCOUNTMAX = 0x10070004; // Disable automatic estimation of maximum absolute wheel tick counter -const uint32_t UBLOX_CFG_SFODO_DIS_AUTODIRPINPOL = 0x10070005; // Disable automatic wheel tick direction pin polarity detection -const uint32_t UBLOX_CFG_SFODO_DIS_AUTOSPEED = 0x10070006; // Disable automatic receiver reconfiguration for processing speed data -const uint32_t UBLOX_CFG_SFODO_FACTOR = 0x40070007; // Wheel tick scale factor -const uint32_t UBLOX_CFG_SFODO_QUANT_ERROR = 0x40070008; // Wheel tick quantization -const uint32_t UBLOX_CFG_SFODO_COUNT_MAX = 0x40070009; // Wheel tick counter maximum value -const uint32_t UBLOX_CFG_SFODO_LATENCY = 0x3007000a; // Wheel tick data latency due to e.g. CAN bus -const uint32_t UBLOX_CFG_SFODO_FREQUENCY = 0x2007000b; // Nominal wheel tick data frequency (0 = not set) -const uint32_t UBLOX_CFG_SFODO_CNT_BOTH_EDGES = 0x1007000d; // Count both rising and falling edges on wheel tick signal -const uint32_t UBLOX_CFG_SFODO_SPEED_BAND = 0x3007000e; // Speed sensor dead band (0 = not set) -const uint32_t UBLOX_CFG_SFODO_USE_WT_PIN = 0x1007000f; // Wheel tick signal enabled -const uint32_t UBLOX_CFG_SFODO_DIR_PINPOL = 0x10070010; // Wheel tick direction pin polarity -const uint32_t UBLOX_CFG_SFODO_DIS_AUTOSW = 0x10070011; // Disable automatic use of wheel tick or speed data received over the software interface - -// CFG-SIGNAL: Satellite systems (GNSS) signal configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SIGNAL_GPS_ENA = 0x1031001f; // GPS enable -const uint32_t UBLOX_CFG_SIGNAL_GPS_L1CA_ENA = 0x10310001; // GPS L1C/A -const uint32_t UBLOX_CFG_SIGNAL_GPS_L5_ENA = 0x10310004; // GPS L5 -const uint32_t UBLOX_CFG_SIGNAL_GPS_L2C_ENA = 0x10310003; // GPS L2C (only on u-blox F9 platform products) -const uint32_t UBLOX_CFG_SIGNAL_SBAS_ENA = 0x10310020; // SBAS enable -const uint32_t UBLOX_CFG_SIGNAL_SBAS_L1CA_ENA = 0x10310005; // SBAS L1C/A -const uint32_t UBLOX_CFG_SIGNAL_GAL_ENA = 0x10310021; // Galileo enable -const uint32_t UBLOX_CFG_SIGNAL_GAL_E1_ENA = 0x10310007; // Galileo E1 -const uint32_t UBLOX_CFG_SIGNAL_GAL_E5A_ENA = 0x10310009; // Galileo E5a -const uint32_t UBLOX_CFG_SIGNAL_GAL_E5B_ENA = 0x1031000a; // Galileo E5b (only on u-blox F9 platform products) -const uint32_t UBLOX_CFG_SIGNAL_BDS_ENA = 0x10310022; // BeiDou Enable -const uint32_t UBLOX_CFG_SIGNAL_BDS_B1_ENA = 0x1031000d; // BeiDou B1I -const uint32_t UBLOX_CFG_SIGNAL_BDS_B1C_ENA = 0x1031000f; // BeiDou B1C -const uint32_t UBLOX_CFG_SIGNAL_BDS_B2A_ENA = 0x10310028; // BeiDou B2a -const uint32_t UBLOX_CFG_SIGNAL_BDS_B2_ENA = 0x1031000e; // BeiDou B2I (only on u-blox F9 platform products) -const uint32_t UBLOX_CFG_SIGNAL_QZSS_ENA = 0x10310024; // QZSS enable -const uint32_t UBLOX_CFG_SIGNAL_QZSS_L1CA_ENA = 0x10310012; // QZSS L1C/A -const uint32_t UBLOX_CFG_SIGNAL_QZSS_L5_ENA = 0x10310017; // QZSS L5 -const uint32_t UBLOX_CFG_SIGNAL_QZSS_L1S_ENA = 0x10310014; // QZSS L1S -const uint32_t UBLOX_CFG_SIGNAL_QZSS_L2C_ENA = 0x10310015; // QZSS L2C (only on u-blox F9 platform products) -const uint32_t UBLOX_CFG_SIGNAL_GLO_ENA = 0x10310025; // GLONASS enable -const uint32_t UBLOX_CFG_SIGNAL_GLO_L1_ENA = 0x10310018; // GLONASS L1 -const uint32_t UBLOX_CFG_SIGNAL_GLO_L2_ENA = 0x1031001a; // GLONASS L2 (only on u-blox F9 platform products) - -// CFG-SPARTN: Configuration of the SPARTN interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SPARTN_USE_SOURCE = 0x20a70001; - -// CFG-SPI: Configuration of the SPI interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SPI_MAXFF = 0x20640001; // Number of bytes containing 0xFF to receive before switching off reception. Range: 0 (mechanism off) - 63 -const uint32_t UBLOX_CFG_SPI_CPOLARITY = 0x10640002; // Clock polarity select: 0: Active Hight Clock, SCLK idles low, 1: Active Low Clock, SCLK idles high -const uint32_t UBLOX_CFG_SPI_CPHASE = 0x10640003; // Clock phase select: 0: Data captured on first edge of SCLK, 1: Data captured on second edge of SCLK -const uint32_t UBLOX_CFG_SPI_EXTENDEDTIMEOUT = 0x10640005; // Flag to disable timeouting the interface after 1.5s -const uint32_t UBLOX_CFG_SPI_ENABLED = 0x10640006; // Flag to indicate if the SPI interface should be enabled - -// CFG-SPIINPROT: Input protocol configuration of the SPI interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SPIINPROT_UBX = 0x10790001; // Flag to indicate if UBX should be an input protocol on SPI -const uint32_t UBLOX_CFG_SPIINPROT_NMEA = 0x10790002; // Flag to indicate if NMEA should be an input protocol on SPI -const uint32_t UBLOX_CFG_SPIINPROT_RTCM3X = 0x10790004; // Flag to indicate if RTCM3X should be an input protocol on SPI -const uint32_t UBLOX_CFG_SPIINPROT_SPARTN = 0x10790005; // Flag to indicate if SPARTN should be an input protocol on SPI - -// CFG-SPIOUTPROT: Output protocol configuration of the SPI interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SPIOUTPROT_UBX = 0x107a0001; // Flag to indicate if UBX should be an output protocol on SPI -const uint32_t UBLOX_CFG_SPIOUTPROT_NMEA = 0x107a0002; // Flag to indicate if NMEA should be an output protocol on SPI -const uint32_t UBLOX_CFG_SPIOUTPROT_RTCM3X = 0x107a0004; // Flag to indicate if RTCM3X should be an output protocol on SPI - -// CFG-TMODE: Time mode configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_TMODE_MODE = 0x20030001; // Receiver mode -const uint32_t UBLOX_CFG_TMODE_POS_TYPE = 0x20030002; // Determines whether the ARP position is given in ECEF or LAT/LON/HEIGHT? -const uint32_t UBLOX_CFG_TMODE_ECEF_X = 0x40030003; // ECEF X coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_ECEF_Y = 0x40030004; // ECEF Y coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_ECEF_Z = 0x40030005; // ECEF Z coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_ECEF_X_HP = 0x20030006; // High-precision ECEF X coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_ECEF_Y_HP = 0x20030007; // High-precision ECEF Y coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_ECEF_Z_HP = 0x20030008; // High-precision ECEF Z coordinate of the ARP position. -const uint32_t UBLOX_CFG_TMODE_LAT = 0x40030009; // Latitude of the ARP position. -const uint32_t UBLOX_CFG_TMODE_LON = 0x4003000a; // Longitude of the ARP position. -const uint32_t UBLOX_CFG_TMODE_HEIGHT = 0x4003000b; // Height of the ARP position. -const uint32_t UBLOX_CFG_TMODE_LAT_HP = 0x2003000c; // High-precision latitude of the ARP position -const uint32_t UBLOX_CFG_TMODE_LON_HP = 0x2003000d; // High-precision longitude of the ARP position. -const uint32_t UBLOX_CFG_TMODE_HEIGHT_HP = 0x2003000e; // High-precision height of the ARP position. -const uint32_t UBLOX_CFG_TMODE_FIXED_POS_ACC = 0x4003000f; // Fixed position 3D accuracy -const uint32_t UBLOX_CFG_TMODE_SVIN_MIN_DUR = 0x40030010; // Survey-in minimum duration -const uint32_t UBLOX_CFG_TMODE_SVIN_ACC_LIMIT = 0x40030011; // Survey-in position accuracy limit - -// CFG-TP: Timepulse configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_TP_PULSE_DEF = 0x20050023; // Determines whether the time pulse is interpreted as frequency or period -const uint32_t UBLOX_CFG_TP_PULSE_LENGTH_DEF = 0x20050030; // Determines whether the time pulse length is interpreted as length[us] or pulse ratio[%] -const uint32_t UBLOX_CFG_TP_ANT_CABLEDELAY = 0x30050001; // Antenna cable delay -const uint32_t UBLOX_CFG_TP_PERIOD_TP1 = 0x40050002; // Time pulse period (TP1) -const uint32_t UBLOX_CFG_TP_PERIOD_LOCK_TP1 = 0x40050003; // Time pulse period when locked to GNSS time (TP1) -const uint32_t UBLOX_CFG_TP_FREQ_TP1 = 0x40050024; // Time pulse frequency (TP1) -const uint32_t UBLOX_CFG_TP_FREQ_LOCK_TP1 = 0x40050025; // Time pulse frequency when locked to GNSS time (TP1) -const uint32_t UBLOX_CFG_TP_LEN_TP1 = 0x40050004; // Time pulse length (TP1) -const uint32_t UBLOX_CFG_TP_LEN_LOCK_TP1 = 0x40050005; // Time pulse length when locked to GNSS time (TP1) -const uint32_t UBLOX_CFG_TP_DUTY_TP1 = 0x5005002a; // Time pulse duty cycle (TP1) -const uint32_t UBLOX_CFG_TP_DUTY_LOCK_TP1 = 0x5005002b; // Time pulse duty cycle when locked to GNSS time (TP1) -const uint32_t UBLOX_CFG_TP_USER_DELAY_TP1 = 0x40050006; // User-configurable time pulse delay (TP1) -const uint32_t UBLOX_CFG_TP_TP1_ENA = 0x10050007; // Enable the first timepulse -const uint32_t UBLOX_CFG_TP_SYNC_GNSS_TP1 = 0x10050008; // Sync time pulse to GNSS time or local clock (TP1) -const uint32_t UBLOX_CFG_TP_USE_LOCKED_TP1 = 0x10050009; // Use locked parameters when possible (TP1) -const uint32_t UBLOX_CFG_TP_ALIGN_TO_TOW_TP1 = 0x1005000a; // Align time pulse to top of second (TP1) -const uint32_t UBLOX_CFG_TP_POL_TP1 = 0x1005000b; // Set time pulse polarity (TP1) -const uint32_t UBLOX_CFG_TP_TIMEGRID_TP1 = 0x2005000c; // Time grid to use (TP1) -const uint32_t UBLOX_CFG_TP_PERIOD_TP2 = 0x4005000d; // Time pulse period (TP2) -const uint32_t UBLOX_CFG_TP_PERIOD_LOCK_TP2 = 0x4005000e; // Time pulse period when locked to GNSS time -const uint32_t UBLOX_CFG_TP_FREQ_TP2 = 0x40050026; // Time pulse frequency (TP2) -const uint32_t UBLOX_CFG_TP_FREQ_LOCK_TP2 = 0x40050027; // Time pulse frequency when locked to GNSS time -const uint32_t UBLOX_CFG_TP_LEN_TP2 = 0x4005000f; // Time pulse length (TP2) -const uint32_t UBLOX_CFG_TP_LEN_LOCK_TP2 = 0x40050010; // Time pulse length when locked to GNSS time -const uint32_t UBLOX_CFG_TP_DUTY_TP2 = 0x5005002c; // Time pulse duty cycle (TP2) -const uint32_t UBLOX_CFG_TP_DUTY_LOCK_TP2 = 0x5005002d; // Time pulse duty cycle when locked to GNSS time -const uint32_t UBLOX_CFG_TP_USER_DELAY_TP2 = 0x40050011; // User-configurable time pulse delay (TP2) -const uint32_t UBLOX_CFG_TP_TP2_ENA = 0x10050012; // Enable the second timepulse -const uint32_t UBLOX_CFG_TP_SYNC_GNSS_TP2 = 0x10050013; // Sync time pulse to GNSS time or local clock -const uint32_t UBLOX_CFG_TP_USE_LOCKED_TP2 = 0x10050014; // Use locked parameters when possible (TP2) -const uint32_t UBLOX_CFG_TP_ALIGN_TO_TOW_TP2 = 0x10050015; // Align time pulse to top of second (TP2) -const uint32_t UBLOX_CFG_TP_POL_TP2 = 0x10050016; // Set time pulse polarity (TP2) -const uint32_t UBLOX_CFG_TP_TIMEGRID_TP2 = 0x20050017; // Time grid to use (TP2) -const uint32_t UBLOX_CFG_TP_DRSTR_TP1 = 0x20050035; // Set drive strength of TP1 -const uint32_t UBLOX_CFG_TP_DRSTR_TP2 = 0x20050036; // Set drive strength of TP2 - -// CFG-TXREADY: TX ready configuration -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_TXREADY_ENABLED = 0x10a20001; // Flag to indicate if TX ready pin mechanism should be enabled -const uint32_t UBLOX_CFG_TXREADY_POLARITY = 0x10a20002; // The polarity of the TX ready pin: false:high- active, true:low-active -const uint32_t UBLOX_CFG_TXREADY_PIN = 0x20a20003; // Pin number to use for the TX ready functionality -const uint32_t UBLOX_CFG_TXREADY_THRESHOLD = 0x30a20004; // Amount of data that should be ready on the interface before triggering the TX ready pin -const uint32_t UBLOX_CFG_TXREADY_INTERFACE = 0x20a20005; // Interface where the TX ready feature should be linked to - -// CFG-UART1: Configuration of the UART1 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART1_BAUDRATE = 0x40520001; // The baud rate that should be configured on the UART1 -const uint32_t UBLOX_CFG_UART1_STOPBITS = 0x20520002; // Number of stopbits that should be used on UART1 -const uint32_t UBLOX_CFG_UART1_DATABITS = 0x20520003; // Number of databits that should be used on UART1 -const uint32_t UBLOX_CFG_UART1_PARITY = 0x20520004; // Parity mode that should be used on UART1 -const uint32_t UBLOX_CFG_UART1_ENABLED = 0x10520005; // Flag to indicate if the UART1 should be enabled - -// CFG-UART1INPROT: Input protocol configuration of the UART1 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART1INPROT_UBX = 0x10730001; // Flag to indicate if UBX should be an input protocol on UART1 -const uint32_t UBLOX_CFG_UART1INPROT_NMEA = 0x10730002; // Flag to indicate if NMEA should be an input protocol on UART1 -const uint32_t UBLOX_CFG_UART1INPROT_RTCM3X = 0x10730004; // Flag to indicate if RTCM3X should be an input protocol on UART1 -const uint32_t UBLOX_CFG_UART1INPROT_SPARTN = 0x10730005; // Flag to indicate if SPARTN should be an input protocol on UART1 - -// CFG-UART1OUTPROT: Output protocol configuration of the UART1 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART1OUTPROT_UBX = 0x10740001; // Flag to indicate if UBX should be an output protocol on UART1 -const uint32_t UBLOX_CFG_UART1OUTPROT_NMEA = 0x10740002; // Flag to indicate if NMEA should be an output protocol on UART1 -const uint32_t UBLOX_CFG_UART1OUTPROT_RTCM3X = 0x10740004; // Flag to indicate if RTCM3X should be an output protocol on UART1 - -// CFG-UART2: Configuration of the UART2 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART2_BAUDRATE = 0x40530001; // The baud rate that should be configured on the UART2 -const uint32_t UBLOX_CFG_UART2_STOPBITS = 0x20530002; // Number of stopbits that should be used on UART2 -const uint32_t UBLOX_CFG_UART2_DATABITS = 0x20530003; // Number of databits that should be used on UART2 -const uint32_t UBLOX_CFG_UART2_PARITY = 0x20530004; // Parity mode that should be used on UART2 -const uint32_t UBLOX_CFG_UART2_ENABLED = 0x10530005; // Flag to indicate if the UART2 should be enabled -const uint32_t UBLOX_CFG_UART2_REMAP = 0x10530006; // UART2 Remapping - -// CFG-UART2INPROT: Input protocol configuration of the UART2 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART2INPROT_UBX = 0x10750001; // Flag to indicate if UBX should be an input protocol on UART2 -const uint32_t UBLOX_CFG_UART2INPROT_NMEA = 0x10750002; // Flag to indicate if NMEA should be an input protocol on UART2 -const uint32_t UBLOX_CFG_UART2INPROT_RTCM3X = 0x10750004; // Flag to indicate if RTCM3X should be an input protocol on UART2 -const uint32_t UBLOX_CFG_UART2INPROT_SPARTN = 0x10750005; // Flag to indicate if SPARTN should be an input protocol on UART2 - -// CFG-UART2OUTPROT: Output protocol configuration of the UART2 interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_UART2OUTPROT_UBX = 0x10760001; // Flag to indicate if UBX should be an output protocol on UART2 -const uint32_t UBLOX_CFG_UART2OUTPROT_NMEA = 0x10760002; // Flag to indicate if NMEA should be an output protocol on UART2 -const uint32_t UBLOX_CFG_UART2OUTPROT_RTCM3X = 0x10760004; // Flag to indicate if RTCM3X should be an output protocol on UART2 - -// CFG-USB: Configuration of the USB interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_USB_ENABLED = 0x10650001; // Flag to indicate if the USB interface should be enabled -const uint32_t UBLOX_CFG_USB_SELFPOW = 0x10650002; // Self-powered device -const uint32_t UBLOX_CFG_USB_VENDOR_ID = 0x3065000a; // Vendor ID -const uint32_t UBLOX_CFG_USB_PRODUCT_ID = 0x3065000b; // Vendor ID -const uint32_t UBLOX_CFG_USB_POWER = 0x3065000c; // Power consumption -const uint32_t UBLOX_CFG_USB_VENDOR_STR0 = 0x5065000d; // Vendor string characters 0-7 -const uint32_t UBLOX_CFG_USB_VENDOR_STR1 = 0x5065000e; // Vendor string characters 8-15 -const uint32_t UBLOX_CFG_USB_VENDOR_STR2 = 0x5065000f; // Vendor string characters 16-23 -const uint32_t UBLOX_CFG_USB_VENDOR_STR3 = 0x50650010; // Vendor string characters 24-31 -const uint32_t UBLOX_CFG_USB_PRODUCT_STR0 = 0x50650011; // Product string characters 0-7 -const uint32_t UBLOX_CFG_USB_PRODUCT_STR1 = 0x50650012; // Product string characters 8-15 -const uint32_t UBLOX_CFG_USB_PRODUCT_STR2 = 0x50650013; // Product string characters 16-23 -const uint32_t UBLOX_CFG_USB_PRODUCT_STR3 = 0x50650014; // Product string characters 24-31 -const uint32_t UBLOX_CFG_USB_SERIAL_NO_STR0 = 0x50650015; // Serial number string characters 0-7 -const uint32_t UBLOX_CFG_USB_SERIAL_NO_STR1 = 0x50650016; // Serial number string characters 8-15 -const uint32_t UBLOX_CFG_USB_SERIAL_NO_STR2 = 0x50650017; // Serial number string characters 16-23 -const uint32_t UBLOX_CFG_USB_SERIAL_NO_STR3 = 0x50650018; // Serial number string characters 24-31 - -// CFG-USBINPROT: Input protocol configuration of the USB interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_USBINPROT_UBX = 0x10770001; // Flag to indicate if UBX should be an input protocol on USB -const uint32_t UBLOX_CFG_USBINPROT_NMEA = 0x10770002; // Flag to indicate if NMEA should be an input protocol on USB -const uint32_t UBLOX_CFG_USBINPROT_RTCM3X = 0x10770004; // Flag to indicate if RTCM3X should be an input protocol on USB -const uint32_t UBLOX_CFG_USBINPROT_SPARTN = 0x10770005; // Flag to indicate if SPARTN should be an input protocol on USB - -// CFG-USBOUTPROT: Output protocol configuration of the USB interface -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_USBOUTPROT_UBX = 0x10780001; // Flag to indicate if UBX should be an output protocol on USB -const uint32_t UBLOX_CFG_USBOUTPROT_NMEA = 0x10780002; // Flag to indicate if NMEA should be an output protocol on USB -const uint32_t UBLOX_CFG_USBOUTPROT_RTCM3X = 0x10780004; // Flag to indicate if RTCM3X should be an output protocol on USB - -#endif diff --git a/Code/BITS/BITSv5/test/u-blox_structs.h b/Code/BITS/BITSv5/test/u-blox_structs.h deleted file mode 100644 index 06160cef..00000000 --- a/Code/BITS/BITSv5/test/u-blox_structs.h +++ /dev/null @@ -1,2787 +0,0 @@ -/* - This is a library written for the u-blox ZED-F9P and NEO-M8P-2 - SparkFun sells these at its website: www.sparkfun.com - Do you like this library? Help support SparkFun. Buy a board! - https://www.sparkfun.com/products/16481 - https://www.sparkfun.com/products/15136 - https://www.sparkfun.com/products/15005 - https://www.sparkfun.com/products/15733 - https://www.sparkfun.com/products/15193 - https://www.sparkfun.com/products/15210 - - Original version by Nathan Seidle @ SparkFun Electronics, September 6th, 2018 - v2.0 rework by Paul Clark @ SparkFun Electronics, December 31st, 2020 - - This library handles configuring and handling the responses - from a u-blox GPS module. Works with most modules from u-blox including - the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others. - - https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library - - Development environment specifics: - Arduino IDE 1.8.13 - - SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT). - The MIT License (MIT) - Copyright (c) 2016 SparkFun Electronics - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - associated documentation files (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the Software is furnished to - do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef __u_blox_structs_h__ -#define __u_blox_structs_h__ - -#include "SparkFun_u-blox_GNSS_Arduino_Library.h" - -#ifndef DEF_NUM_SENS -#define DEF_NUM_SENS 7 // The maximum number of ESF sensors -#endif - -#ifndef DEF_MAX_NUM_ESF_RAW_REPEATS -#define DEF_MAX_NUM_ESF_RAW_REPEATS 10 // The NEO-M8U sends ESF RAW data in blocks / sets of ten readings. (The ZED-F9R sends them one at a time.) -#endif - -#ifndef DEF_MAX_NUM_ESF_MEAS -#define DEF_MAX_NUM_ESF_MEAS 31 // numMeas is 5 bits, indicating up to 31 groups could be received -#endif - -// Additional flags and pointers that need to be stored with each message type -struct ubxAutomaticFlags -{ - union - { - uint8_t all; - struct - { - uint8_t automatic : 1; // Will this message be delivered and parsed "automatically" (without polling) - uint8_t implicitUpdate : 1; // Is the update triggered by accessing stale data (=true) or by a call to checkUblox (=false) - uint8_t addToFileBuffer : 1; // Should the raw UBX data be added to the file buffer? - uint8_t callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh? - } bits; - } flags; -}; - -// NAV-specific structs - -// UBX-NAV-POSECEF (0x01 0x01): Position solution in ECEF -const uint16_t UBX_NAV_POSECEF_LEN = 20; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t ecefX; // ECEF X coordinate: cm - int32_t ecefY; // ECEF Y coordinate: cm - int32_t ecefZ; // ECEF Z coordinate: cm - uint32_t pAcc; // Position Accuracy Estimate: cm -} UBX_NAV_POSECEF_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t ecefX : 1; - uint32_t ecefY : 1; - uint32_t ecefZ : 1; - uint32_t pAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_POSECEF_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_POSECEF_data_t data; - UBX_NAV_POSECEF_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_POSECEF_data_t); - void (*callbackPointerPtr)(UBX_NAV_POSECEF_data_t *); - UBX_NAV_POSECEF_data_t *callbackData; -} UBX_NAV_POSECEF_t; - -// UBX-NAV-POSLLH (0x01 0x02): Geodetic position solution -const uint16_t UBX_NAV_POSLLH_LEN = 28; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t lon; // Longitude: Degrees * 1e-7 - int32_t lat; // Latitude: Degrees * 1e-7 - int32_t height; // Height above ellipsoid: mm - int32_t hMSL; // Height above mean sea level: mm - uint32_t hAcc; // Horizontal Accuracy Estimate: mm - uint32_t vAcc; // Vertical Accuracy Estimate: mm -} UBX_NAV_POSLLH_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t lon : 1; - uint32_t lat : 1; - uint32_t height : 1; - uint32_t hMSL : 1; - uint32_t hAcc : 1; - uint32_t vAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_POSLLH_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_POSLLH_data_t data; - UBX_NAV_POSLLH_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_POSLLH_data_t); - void (*callbackPointerPtr)(UBX_NAV_POSLLH_data_t *); - UBX_NAV_POSLLH_data_t *callbackData; -} UBX_NAV_POSLLH_t; - -// UBX-NAV-STATUS (0x01 0x03): Receiver navigation status -const uint16_t UBX_NAV_STATUS_LEN = 16; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint8_t gpsFix; // GPSfix Type: 0x00 = no fix; 0x01 = dead reckoning only; 0x02 = 2D-fix; 0x03 = 3D-fix - // 0x04 = GPS + dead reckoning combined; 0x05 = Time only fix; 0x06..0xff = reserved - union - { - uint8_t all; - struct - { - uint8_t gpsFixOk : 1; // 1 = position and velocity valid and within DOP and ACC Masks. - uint8_t diffSoln : 1; // 1 = differential corrections were applied - uint8_t wknSet : 1; // 1 = Week Number valid (see Time Validity section for details) - uint8_t towSet : 1; // 1 = Time of Week valid (see Time Validity section for details) - } bits; - } flags; - union - { - uint8_t all; - struct - { - uint8_t diffCorr : 1; // 1 = differential corrections available - uint8_t carrSolnValid : 1; // 1 = valid carrSoln - uint8_t reserved : 4; - uint8_t mapMatching : 2; // map matching status: 00: none - // 01: valid but not used, i.e. map matching data was received, but was too old - // 10: valid and used, map matching data was applied - // 11: valid and used, map matching data was applied. - } bits; - } fixStat; - union - { - uint8_t all; - struct - { - uint8_t psmState : 2; // power save mode state - // 0: ACQUISITION [or when psm disabled] - // 1: TRACKING - // 2: POWER OPTIMIZED TRACKING - // 3: INACTIVE - uint8_t reserved1 : 1; - uint8_t spoofDetState : 2; // Spoofing detection state - // 0: Unknown or deactivated - // 1: No spoofing indicated - // 2: Spoofing indicated - // 3: Multiple spoofing indications - uint8_t reserved2 : 1; - uint8_t carrSoln : 2; // Carrier phase range solution status: - // 0: no carrier phase range solution - // 1: carrier phase range solution with floating ambiguities - // 2: carrier phase range solution with fixed ambiguities - } bits; - } flags2; - uint32_t ttff; // Time to first fix (millisecond time tag): ms - uint32_t msss; // Milliseconds since Startup / Reset: ms -} UBX_NAV_STATUS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t gpsFix : 1; - - uint32_t gpsFixOk : 1; - uint32_t diffSoln : 1; - uint32_t wknSet : 1; - uint32_t towSet : 1; - - uint32_t diffCorr : 1; - uint32_t carrSolnValid : 1; - uint32_t mapMatching : 1; - - uint32_t psmState : 1; - uint32_t spoofDetState : 1; - uint32_t carrSoln : 1; - - uint32_t ttff : 1; - uint32_t msss : 1; - } bits; - } moduleQueried; -} UBX_NAV_STATUS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_STATUS_data_t data; - UBX_NAV_STATUS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_STATUS_data_t); - void (*callbackPointerPtr)(UBX_NAV_STATUS_data_t *); - UBX_NAV_STATUS_data_t *callbackData; -} UBX_NAV_STATUS_t; - -// UBX-NAV-DOP (0x01 0x04): Dilution of precision -const uint16_t UBX_NAV_DOP_LEN = 18; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint16_t gDOP; // Geometric DOP: * 0.01 - uint16_t pDOP; // Position DOP: * 0.01 - uint16_t tDOP; // Time DOP: * 0.01 - uint16_t vDOP; // Vertical DOP: * 0.01 - uint16_t hDOP; // Horizontal DOP: * 0.01 - uint16_t nDOP; // Northing DOP: * 0.01 - uint16_t eDOP; // Easting DOP: * 0.01 -} UBX_NAV_DOP_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t gDOP : 1; - uint32_t pDOP : 1; - uint32_t tDOP : 1; - uint32_t vDOP : 1; - uint32_t hDOP : 1; - uint32_t nDOP : 1; - uint32_t eDOP : 1; - } bits; - } moduleQueried; -} UBX_NAV_DOP_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_DOP_data_t data; - UBX_NAV_DOP_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_DOP_data_t); - void (*callbackPointerPtr)(UBX_NAV_DOP_data_t *); - UBX_NAV_DOP_data_t *callbackData; -} UBX_NAV_DOP_t; - -// UBX-NAV-ATT (0x01 0x05): Attitude solution -const uint16_t UBX_NAV_ATT_LEN = 32; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[3]; - int32_t roll; // Vehicle roll: Degrees * 1e-5 - int32_t pitch; // Vehicle pitch: Degrees * 1e-5 - int32_t heading; // Vehicle heading: Degrees * 1e-5 - uint32_t accRoll; // Vehicle roll accuracy (if null, roll angle is not available): Degrees * 1e-5 - uint32_t accPitch; // Vehicle pitch accuracy (if null, roll angle is not available): Degrees * 1e-5 - uint32_t accHeading; // Vehicle heading accuracy (if null, roll angle is not available): Degrees * 1e-5 -} UBX_NAV_ATT_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - uint32_t roll : 1; - uint32_t pitch : 1; - uint32_t heading : 1; - uint32_t accRoll : 1; - uint32_t accPitch : 1; - uint32_t accHeading : 1; - } bits; - } moduleQueried; -} UBX_NAV_ATT_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_ATT_data_t data; - UBX_NAV_ATT_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_ATT_data_t); - void (*callbackPointerPtr)(UBX_NAV_ATT_data_t *); - UBX_NAV_ATT_data_t *callbackData; -} UBX_NAV_ATT_t; - -// UBX-NAV-PVT (0x01 0x07): Navigation position velocity time solution -const uint16_t UBX_NAV_PVT_LEN = 92; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint16_t year; // Year (UTC) - uint8_t month; // Month, range 1..12 (UTC) - uint8_t day; // Day of month, range 1..31 (UTC) - uint8_t hour; // Hour of day, range 0..23 (UTC) - uint8_t min; // Minute of hour, range 0..59 (UTC) - uint8_t sec; // Seconds of minute, range 0..60 (UTC) - union - { - uint8_t all; - struct - { - uint8_t validDate : 1; // 1 = valid UTC Date - uint8_t validTime : 1; // 1 = valid UTC time of day - uint8_t fullyResolved : 1; // 1 = UTC time of day has been fully resolved (no seconds uncertainty). - uint8_t validMag : 1; // 1 = valid magnetic declination - } bits; - } valid; - uint32_t tAcc; // Time accuracy estimate (UTC): ns - int32_t nano; // Fraction of second, range -1e9 .. 1e9 (UTC): ns - uint8_t fixType; // GNSSfix Type: - // 0: no fix - // 1: dead reckoning only - // 2: 2D-fix - // 3: 3D-fix - // 4: GNSS + dead reckoning combined - // 5: time only fix - union - { - uint8_t all; - struct - { - uint8_t gnssFixOK : 1; // 1 = valid fix (i.e within DOP & accuracy masks) - uint8_t diffSoln : 1; // 1 = differential corrections were applied - uint8_t psmState : 3; - uint8_t headVehValid : 1; // 1 = heading of vehicle is valid, only set if the receiver is in sensor fusion mode - uint8_t carrSoln : 2; // Carrier phase range solution status: - // 0: no carrier phase range solution - // 1: carrier phase range solution with floating ambiguities - // 2: carrier phase range solution with fixed ambiguities - } bits; - } flags; - union - { - uint8_t all; - struct - { - uint8_t reserved : 5; - uint8_t confirmedAvai : 1; // 1 = information about UTC Date and Time of Day validity confirmation is available - uint8_t confirmedDate : 1; // 1 = UTC Date validity could be confirmed - uint8_t confirmedTime : 1; // 1 = UTC Time of Day could be confirmed - } bits; - } flags2; - uint8_t numSV; // Number of satellites used in Nav Solution - int32_t lon; // Longitude: deg * 1e-7 - int32_t lat; // Latitude: deg * 1e-7 - int32_t height; // Height above ellipsoid: mm - int32_t hMSL; // Height above mean sea level: mm - uint32_t hAcc; // Horizontal accuracy estimate: mm - uint32_t vAcc; // Vertical accuracy estimate: mm - int32_t velN; // NED north velocity: mm/s - int32_t velE; // NED east velocity: mm/s - int32_t velD; // NED down velocity: mm/s - int32_t gSpeed; // Ground Speed (2-D): mm/s - int32_t headMot; // Heading of motion (2-D): deg * 1e-5 - uint32_t sAcc; // Speed accuracy estimate: mm/s - uint32_t headAcc; // Heading accuracy estimate (both motion and vehicle): deg * 1e-5 - uint16_t pDOP; // Position DOP * 0.01 - union - { - uint8_t all; - struct - { - uint8_t invalidLlh : 1; // 1 = Invalid lon, lat, height and hMSL - } bits; - } flags3; - uint8_t reserved1[5]; - int32_t headVeh; // Heading of vehicle (2-D): deg * 1e-5 - int16_t magDec; // Magnetic declination: deg * 1e-2 - uint16_t magAcc; // Magnetic declination accuracy: deg * 1e-2 -} UBX_NAV_PVT_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t year : 1; - uint32_t month : 1; - uint32_t day : 1; - uint32_t hour : 1; - uint32_t min : 1; - uint32_t sec : 1; - - uint32_t validDate : 1; - uint32_t validTime : 1; - uint32_t fullyResolved : 1; - uint32_t validMag : 1; - - uint32_t tAcc : 1; - uint32_t nano : 1; - uint32_t fixType : 1; - uint32_t gnssFixOK : 1; - uint32_t diffSoln : 1; - uint32_t psmState : 1; - uint32_t headVehValid : 1; - uint32_t carrSoln : 1; - - uint32_t confirmedAvai : 1; - uint32_t confirmedDate : 1; - uint32_t confirmedTime : 1; - - uint32_t numSV : 1; - uint32_t lon : 1; - uint32_t lat : 1; - uint32_t height : 1; - uint32_t hMSL : 1; - uint32_t hAcc : 1; - uint32_t vAcc : 1; - uint32_t velN : 1; - uint32_t velE : 1; - } bits; - } moduleQueried1; - union - { - uint32_t all; - struct - { - uint32_t velD : 1; - uint32_t gSpeed : 1; - uint32_t headMot : 1; - uint32_t sAcc : 1; - uint32_t headAcc : 1; - uint32_t pDOP : 1; - - uint32_t invalidLlh : 1; - - uint32_t headVeh : 1; - uint32_t magDec : 1; - uint32_t magAcc : 1; - } bits; - } moduleQueried2; -} UBX_NAV_PVT_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_PVT_data_t data; - UBX_NAV_PVT_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_PVT_data_t); - void (*callbackPointerPtr)(UBX_NAV_PVT_data_t *); - UBX_NAV_PVT_data_t *callbackData; -} UBX_NAV_PVT_t; - -// UBX-NAV-ODO (0x01 0x09): Odometer solution -const uint16_t UBX_NAV_ODO_LEN = 20; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[3]; - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint32_t distance; // Ground distance since last reset: m - uint32_t totalDistance; // Total cumulative ground distance: m - uint32_t distanceStd; // Ground distance accuracy (1-sigma): m -} UBX_NAV_ODO_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t iTOW : 1; - uint32_t distance : 1; - uint32_t totalDistance : 1; - uint32_t distanceStd : 1; - } bits; - } moduleQueried; -} UBX_NAV_ODO_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_ODO_data_t data; - UBX_NAV_ODO_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_ODO_data_t); - void (*callbackPointerPtr)(UBX_NAV_ODO_data_t *); - UBX_NAV_ODO_data_t *callbackData; -} UBX_NAV_ODO_t; - -// UBX-NAV-VELECEF (0x01 0x11): Velocity solution in ECEF -const uint16_t UBX_NAV_VELECEF_LEN = 20; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t ecefVX; // ECEF X velocity: cm/s - int32_t ecefVY; // ECEF Y velocity: cm/s - int32_t ecefVZ; // ECEF Z velocity: cm/s - uint32_t sAcc; // Speed accuracy estimate: cm/s -} UBX_NAV_VELECEF_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t ecefVX : 1; - uint32_t ecefVY : 1; - uint32_t ecefVZ : 1; - uint32_t sAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_VELECEF_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_VELECEF_data_t data; - UBX_NAV_VELECEF_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_VELECEF_data_t); - void (*callbackPointerPtr)(UBX_NAV_VELECEF_data_t *); - UBX_NAV_VELECEF_data_t *callbackData; -} UBX_NAV_VELECEF_t; - -// UBX-NAV-VELNED (0x01 0x12): Velocity solution in NED frame -const uint16_t UBX_NAV_VELNED_LEN = 36; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t velN; // North velocity component: cm/s - int32_t velE; // East velocity component: cm/s - int32_t velD; // Down velocity component: cm/s - uint32_t speed; // Speed (3-D): cm/s - uint32_t gSpeed; // Ground Speed (2-D): cm/s - int32_t heading; // Heading of motion 2-D: Degrees * 1e-5 - uint32_t sAcc; // Speed accuracy estimate: cm/s - uint32_t cAcc; // Course/Heading accuracy estimate: Degrees * 1e-5 -} UBX_NAV_VELNED_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t velN : 1; - uint32_t velE : 1; - uint32_t velD : 1; - uint32_t speed : 1; - uint32_t gSpeed : 1; - uint32_t heading : 1; - uint32_t sAcc : 1; - uint32_t cAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_VELNED_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_VELNED_data_t data; - UBX_NAV_VELNED_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_VELNED_data_t); - void (*callbackPointerPtr)(UBX_NAV_VELNED_data_t *); - UBX_NAV_VELNED_data_t *callbackData; -} UBX_NAV_VELNED_t; - -// UBX-NAV-HPPOSECEF (0x01 0x13): High precision position solution in ECEF -const uint16_t UBX_NAV_HPPOSECEF_LEN = 28; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[3]; - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t ecefX; // ECEF X coordinate: cm - int32_t ecefY; // ECEF Y coordinate: cm - int32_t ecefZ; // ECEF Z coordinate: cm - int8_t ecefXHp; // High precision component of ECEF X coordinate: mm * 0.1 - int8_t ecefYHp; // High precision component of ECEF Y coordinate: mm * 0.1 - int8_t ecefZHp; // High precision component of ECEF Z coordinate: mm * 0.1 - union - { - uint8_t all; - struct - { - uint8_t invalidEcef : 1; // 1 = Invalid ecefX, ecefY, ecefZ, ecefXHp, ecefYHp and ecefZHp - } bits; - } flags; - uint32_t pAcc; // Position Accuracy Estimate: mm * 0.1 -} UBX_NAV_HPPOSECEF_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t iTOW : 1; - uint32_t ecefX : 1; - uint32_t ecefY : 1; - uint32_t ecefZ : 1; - uint32_t ecefXHp : 1; - uint32_t ecefYHp : 1; - uint32_t ecefZHp : 1; - - uint32_t invalidEcef : 1; - - uint32_t pAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_HPPOSECEF_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_HPPOSECEF_data_t data; - UBX_NAV_HPPOSECEF_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_HPPOSECEF_data_t); - void (*callbackPointerPtr)(UBX_NAV_HPPOSECEF_data_t *); - UBX_NAV_HPPOSECEF_data_t *callbackData; -} UBX_NAV_HPPOSECEF_t; - -// UBX-NAV-HPPOSLLH (0x01 0x14): High precision geodetic position solution -const uint16_t UBX_NAV_HPPOSLLH_LEN = 36; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[2]; - union - { - uint8_t all; - struct - { - uint8_t invalidLlh : 1; // 1 = Invalid lon, lat, height, hMSL, lonHp, latHp, heightHp and hMSLHp - } bits; - } flags; - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t lon; // Longitude: deg * 1e-7 - int32_t lat; // Latitude: deg * 1e-7 - int32_t height; // Height above ellipsoid: mm - int32_t hMSL; // Height above mean sea level: mm - int8_t lonHp; // High precision component of longitude: deg * 1e-9 - int8_t latHp; // High precision component of latitude: deg * 1e-9 - int8_t heightHp; // High precision component of height above ellipsoid: mm * 0.1 - int8_t hMSLHp; // High precision component of height above mean sea level: mm * 0.1 - uint32_t hAcc; // Horizontal accuracy estimate: mm * 0.1 - uint32_t vAcc; // Vertical accuracy estimate: mm * 0.1 -} UBX_NAV_HPPOSLLH_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - - uint32_t invalidLlh : 1; - - uint32_t iTOW : 1; - uint32_t lon : 1; - uint32_t lat : 1; - uint32_t height : 1; - uint32_t hMSL : 1; - uint32_t lonHp : 1; - uint32_t latHp : 1; - uint32_t heightHp : 1; - uint32_t hMSLHp : 1; - uint32_t hAcc : 1; - uint32_t vAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_HPPOSLLH_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_HPPOSLLH_data_t data; - UBX_NAV_HPPOSLLH_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_HPPOSLLH_data_t); - void (*callbackPointerPtr)(UBX_NAV_HPPOSLLH_data_t *); - UBX_NAV_HPPOSLLH_data_t *callbackData; -} UBX_NAV_HPPOSLLH_t; - -// UBX-NAV-PVAT (0x01 0x17): Navigation position velocity attitude time solution -const uint16_t UBX_NAV_PVAT_LEN = 116; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint8_t version; // Message version (0x00 for this version) - union - { - uint8_t all; - struct - { - uint8_t validDate : 1; // 1 = valid UTC Date - uint8_t validTime : 1; // 1 = valid UTC time of day - uint8_t fullyResolved : 1; // 1 = UTC time of day has been fully resolved (no seconds uncertainty). - uint8_t validMag : 1; // 1 = valid magnetic declination - } bits; - } valid; - uint16_t year; // Year (UTC) - uint8_t month; // Month, range 1..12 (UTC) - uint8_t day; // Day of month, range 1..31 (UTC) - uint8_t hour; // Hour of day, range 0..23 (UTC) - uint8_t min; // Minute of hour, range 0..59 (UTC) - uint8_t sec; // Seconds of minute, range 0..60 (UTC) - uint8_t reserved0; - uint8_t reserved1[2]; - uint32_t tAcc; // Time accuracy estimate (UTC): ns - int32_t nano; // Fraction of second, range -1e9 .. 1e9 (UTC): ns - uint8_t fixType; // GNSSfix Type: - // 0: no fix - // 1: dead reckoning only - // 2: 2D-fix - // 3: 3D-fix - // 4: GNSS + dead reckoning combined - // 5: time only fix - union - { - uint8_t all; - struct - { - uint8_t gnssFixOK : 1; // 1 = valid fix (i.e within DOP & accuracy masks) - uint8_t diffSoln : 1; // 1 = differential corrections were applied - uint8_t reserved : 1; - uint8_t vehRollValid : 1; // 1 = roll of vehicle is valid, only set if the receiver is in sensor fusion mode - uint8_t vehPitchValid : 1; // 1 = pitch of vehicle is valid, only set if the receiver is in sensor fusion mode - uint8_t vehHeadingValid : 1; // 1 = heading of vehicle is valid, only set if the receiver is in sensor fusion mode - uint8_t carrSoln : 2; // Carrier phase range solution status: - // 0: no carrier phase range solution - // 1: carrier phase range solution with floating ambiguities - // 2: carrier phase range solution with fixed ambiguities - } bits; - } flags; - union - { - uint8_t all; - struct - { - uint8_t reserved : 5; - uint8_t confirmedAvai : 1; // 1 = information about UTC Date and Time of Day validity confirmation is available - uint8_t confirmedDate : 1; // 1 = UTC Date validity could be confirmed - uint8_t confirmedTime : 1; // 1 = UTC Time of Day could be confirmed - } bits; - } flags2; - uint8_t numSV; // Number of satellites used in Nav Solution - int32_t lon; // Longitude: deg * 1e-7 - int32_t lat; // Latitude: deg * 1e-7 - int32_t height; // Height above ellipsoid: mm - int32_t hMSL; // Height above mean sea level: mm - uint32_t hAcc; // Horizontal accuracy estimate: mm - uint32_t vAcc; // Vertical accuracy estimate: mm - int32_t velN; // NED north velocity: mm/s - int32_t velE; // NED east velocity: mm/s - int32_t velD; // NED down velocity: mm/s - int32_t gSpeed; // Ground Speed (2-D): mm/s - uint32_t sAcc; // Speed accuracy estimate: mm/s - int32_t vehRoll; // Vehicle roll: 1e-5 deg - int32_t vehPitch; // Vehicle pitch: 1e-5 deg - int32_t vehHeading; // Vehicle heading: 1e-5 deg - int32_t motHeading; // Motion heading.: 1e-5 deg - uint16_t accRoll; // Vehicle roll accuracy (if null, roll angle is not available): 1e-2 deg - uint16_t accPitch; // Vehicle pitch accuracy (if null, pitch angle is not available): 1e-2 deg - uint16_t accHeading; // Vehicle heading accuracy (if null, heading angle is not available): 1e-2 deg - int16_t magDec; // Magnetic declination: 1e-2 deg - uint16_t magAcc; // Magnetic declination accuracy: 1e-2 deg - uint16_t errEllipseOrient; // Orientation of semi-major axis of error ellipse (degrees from true north): 1e-2 deg - uint32_t errEllipseMajor; // Semi-major axis of error ellipse: mm - uint32_t errEllipseMinor; // Semi-minor axis of error ellipse: mm - uint8_t reserved2[4]; - uint8_t reserved3[4]; -} UBX_NAV_PVAT_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - - uint32_t validDate : 1; - uint32_t validTime : 1; - uint32_t fullyResolved : 1; - uint32_t validMag : 1; - - uint32_t year : 1; - uint32_t month : 1; - uint32_t day : 1; - uint32_t hour : 1; - uint32_t min : 1; - uint32_t sec : 1; - - uint32_t tAcc : 1; - uint32_t nano : 1; - uint32_t fixType : 1; - - uint32_t gnssFixOK : 1; - uint32_t diffSoln : 1; - uint32_t vehRollValid : 1; - uint32_t vehPitchValid : 1; - uint32_t vehHeadingValid : 1; - uint32_t carrSoln : 1; - - uint32_t confirmedAvai : 1; - uint32_t confirmedDate : 1; - uint32_t confirmedTime : 1; - - uint32_t numSV : 1; - uint32_t lon : 1; - uint32_t lat : 1; - uint32_t height : 1; - uint32_t hMSL : 1; - uint32_t hAcc : 1; - uint32_t vAcc : 1; - } bits; - } moduleQueried1; - union - { - uint32_t all; - struct - { - uint32_t velN : 1; - uint32_t velE : 1; - uint32_t velD : 1; - uint32_t gSpeed : 1; - uint32_t sAcc : 1; - uint32_t vehRoll : 1; - uint32_t vehPitch : 1; - uint32_t vehHeading : 1; - uint32_t motHeading : 1; - uint32_t accRoll : 1; - uint32_t accPitch : 1; - uint32_t accHeading : 1; - uint32_t magDec : 1; - uint32_t magAcc : 1; - uint32_t errEllipseOrient : 1; - uint32_t errEllipseMajor : 1; - uint32_t errEllipseMinor : 1; - } bits; - } moduleQueried2; -} UBX_NAV_PVAT_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_PVAT_data_t data; - UBX_NAV_PVAT_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_PVAT_data_t); - void (*callbackPointerPtr)(UBX_NAV_PVAT_data_t *); - UBX_NAV_PVAT_data_t *callbackData; -} UBX_NAV_PVAT_t; - -// UBX-NAV-TIMEUTC (0x01 0x21): UTC time solution -const uint16_t UBX_NAV_TIMEUTC_LEN = 20; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint32_t tAcc; // Time accuracy estimate (UTC): ns - int32_t nano; // Fraction of second, range -1e9 .. 1e9 (UTC): ns - uint16_t year; // Year (UTC) - uint8_t month; // Month, range 1..12 (UTC) - uint8_t day; // Day of month, range 1..31 (UTC) - uint8_t hour; // Hour of day, range 0..23 (UTC) - uint8_t min; // Minute of hour, range 0..59 (UTC) - uint8_t sec; // Seconds of minute, range 0..60 (UTC) - union - { - uint8_t all; - struct - { - uint8_t validTOW : 1; // 1 = Valid Time of Week - uint8_t validWKN : 1; // 1 = Valid Week Number - uint8_t validUTC : 1; // 1 = Valid UTC Time - uint8_t reserved : 1; - uint8_t utcStandard : 4; // UTC standard identifier - } bits; - } valid; -} UBX_NAV_TIMEUTC_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t tAcc : 1; - uint32_t nano : 1; - uint32_t year : 1; - uint32_t month : 1; - uint32_t day : 1; - uint32_t hour : 1; - uint32_t min : 1; - uint32_t sec : 1; - - uint32_t validTOW : 1; - uint32_t validWKN : 1; - uint32_t validUTC : 1; - uint32_t utcStandard : 1; - } bits; - } moduleQueried; -} UBX_NAV_TIMEUTC_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_TIMEUTC_data_t data; - UBX_NAV_TIMEUTC_moduleQueried_t moduleQueried; - void (*callbackPointerPtr)(UBX_NAV_TIMEUTC_data_t *); - UBX_NAV_TIMEUTC_data_t *callbackData; -} UBX_NAV_TIMEUTC_t; - -// UBX-NAV-CLOCK (0x01 0x22): Clock solution -const uint16_t UBX_NAV_CLOCK_LEN = 20; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t clkB; // Clock bias: ns - int32_t clkD; // Clock drift: ns/s - uint32_t tAcc; // Time accuracy estimate: ns - uint32_t fAcc; // Frequency accuracy estimate: ps/s -} UBX_NAV_CLOCK_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t clkB : 1; - uint32_t clkD : 1; - uint32_t tAcc : 1; - uint32_t fAcc : 1; - } bits; - } moduleQueried; -} UBX_NAV_CLOCK_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_CLOCK_data_t data; - UBX_NAV_CLOCK_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_CLOCK_data_t); - void (*callbackPointerPtr)(UBX_NAV_CLOCK_data_t *); - UBX_NAV_CLOCK_data_t *callbackData; -} UBX_NAV_CLOCK_t; - -// UBX-NAV-TIMELS (0x01 0x26): Leap second event information -const uint16_t UBX_NAV_TIMELS_LEN = 24; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[3]; - uint8_t srcOfCurrLs; // Information source for the current number of leap seconds - int8_t currLs; // Current number of leap seconds since start of GPS (Jan 6, 1980), s - uint8_t srcOfLsChange; // Information source for the future leap second event - int8_t lsChange; // Future leap second change if one is scheduled, +1, 0, -1s - int32_t timeToLsEvent; // Num of secs until the next or from the last leap second, s - uint16_t dateOfLsGpsWn; // GPS week num (WN) of the next or the last leap second event - uint16_t dateOfLsGpsDn; // GPS day of week num (DN) for the next or last leap second event - uint8_t reserved2[3]; - union - { - uint8_t all; - struct - { - uint8_t validCurrLs : 1; // 1 = Valid current number of leap seconds value - uint8_t validTimeToLsEvent : 1; // 1 = Valid time to next leap second event or from the last leap second event if no future event scheduled - } bits; - } valid; -} UBX_NAV_TIMELS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - uint32_t srcOfCurrLs : 1; - uint32_t currLs : 1; - uint32_t srcOfLsChange : 1; - uint32_t lsChange : 1; - uint32_t timeToLsEvent : 1; - uint32_t dateOfLsGpsWn : 1; - uint32_t dateOfLsGpsDn : 1; - uint32_t validCurrLs : 1; - uint32_t validTimeToLsEvent : 1; - } bits; - } moduleQueried; -} UBX_NAV_TIMELS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_TIMELS_data_t data; - UBX_NAV_TIMELS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_TIMELS_data_t); - void (*callbackPointerPtr)(UBX_NAV_TIMELS_data_t *); - UBX_NAV_TIMELS_data_t *callbackData; -} UBX_NAV_TIMELS_t; - -// UBX-NAV-SAT (0x01 0x35): Satellite Information -const uint16_t UBX_NAV_SAT_MAX_BLOCKS = 255; // numSvs is 8-bit -const uint16_t UBX_NAV_SAT_MAX_LEN = 8 + (12 * UBX_NAV_SAT_MAX_BLOCKS); - -typedef struct -{ - uint32_t iTOW; // GPS time of week - uint8_t version; // Message version (0x01 for this version) - uint8_t numSvs; // Number of satellites - uint8_t reserved1[2]; -} UBX_NAV_SAT_header_t; - -typedef struct -{ - uint8_t gnssId; // GNSS identifier - uint8_t svId; // Satellite identifier - uint8_t cno; // Carrier-to-noise density ratio: dB-Hz - int8_t elev; // Elevation (range: +/-90): deg - int16_t azim; // Azimuth (range 0-360): deg - int16_t prRes; // Pseudorange residual: m * 0.1 - union - { - uint32_t all; - struct - { - uint32_t qualityInd : 3; // Signal quality indicator: 0: no signal - // 1: searching signal - // 2: signal acquired - // 3: signal detected but unusable - // 4: code locked and time synchronized - // 5, 6, 7: code and carrier locked and time synchronized - uint32_t svUsed : 1; // 1 = Signal in the subset specified in Signal Identifiers is currently being used for navigation - uint32_t health : 2; // Signal health flag: 0: unknown 1: healthy 2: unhealthy - uint32_t diffCorr : 1; // 1 = differential correction data is available for this SV - uint32_t smoothed : 1; // 1 = carrier smoothed pseudorange used - uint32_t orbitSource : 3; // Orbit source: 0: no orbit information is available for this SV - // 1: ephemeris is used - // 2: almanac is used - // 3: AssistNow Offline orbit is used - // 4: AssistNow Autonomous orbit is used - // 5, 6, 7: other orbit information is used - uint32_t ephAvail : 1; // 1 = ephemeris is available for this SV - uint32_t almAvail : 1; // 1 = almanac is available for this SV - uint32_t anoAvail : 1; // 1 = AssistNow Offline data is available for this SV - uint32_t aopAvail : 1; // 1 = AssistNow Autonomous data is available for this SV - uint32_t reserved1 : 1; - uint32_t sbasCorrUsed : 1; // 1 = SBAS corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t rtcmCorrUsed : 1; // 1 = RTCM corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t slasCorrUsed : 1; // 1 = QZSS SLAS corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t spartnCorrUsed : 1; // 1 = SPARTN corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t prCorrUsed : 1; // 1 = Pseudorange corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t crCorrUsed : 1; // 1 = Carrier range corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t doCorrUsed : 1; // 1 = Range rate (Doppler) corrections have been used for a signal in the subset specified in Signal Identifiers - uint32_t reserved2 : 9; - } bits; - } flags; -} UBX_NAV_SAT_block_t; - -typedef struct -{ - UBX_NAV_SAT_header_t header; - UBX_NAV_SAT_block_t blocks[UBX_NAV_SAT_MAX_BLOCKS]; -} UBX_NAV_SAT_data_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_SAT_data_t data; - bool moduleQueried; - void (*callbackPointer)(UBX_NAV_SAT_data_t); - void (*callbackPointerPtr)(UBX_NAV_SAT_data_t *); - UBX_NAV_SAT_data_t *callbackData; -} UBX_NAV_SAT_t; - -// UBX-NAV-SVIN (0x01 0x3B): Survey-in data -const uint16_t UBX_NAV_SVIN_LEN = 40; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1[3]; - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint32_t dur; // Passed survey-in observation time: s - int32_t meanX; // Current survey-in mean position ECEF X coordinate: cm - int32_t meanY; // Current survey-in mean position ECEF Y coordinate: cm - int32_t meanZ; // Current survey-in mean position ECEF Z coordinate: cm - int8_t meanXHP; // Current high-precision survey-in mean position ECEF X coordinate: mm * 0.1 - int8_t meanYHP; // Current high-precision survey-in mean position ECEF Y coordinate: mm * 0.1 - int8_t meanZHP; // Current high-precision survey-in mean position ECEF Z coordinate: mm * 0.1 - uint8_t reserved2; - uint32_t meanAcc; // Current survey-in mean position accuracy: mm * 0.1 - uint32_t obs; // Number of position observations used during survey-in - int8_t valid; // Survey-in position validity flag, 1 = valid, otherwise 0 - int8_t active; // Survey-in in progress flag, 1 = in-progress, otherwise 0 - uint8_t reserved3[2]; -} UBX_NAV_SVIN_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t iTOW : 1; - uint32_t dur : 1; - uint32_t meanX : 1; - uint32_t meanY : 1; - uint32_t meanZ : 1; - uint32_t meanXHP : 1; - uint32_t meanYHP : 1; - uint32_t meanZHP : 1; - uint32_t meanAcc : 1; - uint32_t obs : 1; - uint32_t valid : 1; - uint32_t active : 1; - } bits; - } moduleQueried; -} UBX_NAV_SVIN_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_SVIN_data_t data; - UBX_NAV_SVIN_moduleQueried_t moduleQueried; - void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *); - UBX_NAV_SVIN_data_t *callbackData; -} UBX_NAV_SVIN_t; - -// UBX-NAV-RELPOSNED (0x01 0x3C): Relative positioning information in NED frame -// Note: -// RELPOSNED on the M8 is only 40 bytes long -// RELPOSNED on the F9 is 64 bytes long and contains much more information -const uint16_t UBX_NAV_RELPOSNED_LEN = 40; -const uint16_t UBX_NAV_RELPOSNED_LEN_F9 = 64; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved0; - uint16_t refStationId; // Reference Station ID - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - int32_t relPosN; // North component of relative position vector: cm - int32_t relPosE; // East component of relative position vector: cm - int32_t relPosD; // Down component of relative position vector: cm - int32_t relPosLength; // Length of the relative position vector: cm - int32_t relPosHeading; // Heading of the relative position vector: Degrees * 1e-5 - uint8_t reserved1[4]; - int8_t relPosHPN; // High-precision North component of relative position vector: mm * 0.1 - int8_t relPosHPE; // High-precision East component of relative position vector: mm * 0.1 - int8_t relPosHPD; // High-precision Down component of relative position vector: mm * 0.1 - int8_t relPosHPLength; // High-precision component of the length of the relative position vector: mm * 0.1 - uint32_t accN; // Accuracy of relative position North component: mm * 0.1 - uint32_t accE; // Accuracy of relative position East component: mm * 0.1 - uint32_t accD; // Accuracy of relative position Down component: mm * 0.1 - uint32_t accLength; // Accuracy of length of the relative position vector: mm * 0.1 - uint32_t accHeading; // Accuracy of heading of the relative position vector: Degrees * 1e-5 - uint8_t reserved2[4]; - union - { - uint32_t all; - struct - { - uint32_t gnssFixOK : 1; // A valid fix (i.e within DOP & accuracy masks) - uint32_t diffSoln : 1; // 1 if differential corrections were applied - uint32_t relPosValid : 1; // 1 if relative position components and accuracies are valid - uint32_t carrSoln : 2; // Carrier phase range solution status: - // 0 = no carrier phase range solution - // 1 = carrier phase range solution with floating ambiguities - // 2 = carrier phase range solution with fixed ambiguities - uint32_t isMoving : 1; // 1 if the receiver is operating in moving baseline mode - uint32_t refPosMiss : 1; // 1 if extrapolated reference position was used to compute moving baseline solution this epoch - uint32_t refObsMiss : 1; // 1 if extrapolated reference observations were used to compute moving baseline solution this epoch - uint32_t relPosHeadingValid : 1; // 1 if relPosHeading is valid - uint32_t relPosNormalized : 1; // 1 if the components of the relative position vector (including the high-precision parts) are normalized - } bits; - } flags; -} UBX_NAV_RELPOSNED_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t refStationId : 1; - uint32_t iTOW : 1; - uint32_t relPosN : 1; - uint32_t relPosE : 1; - uint32_t relPosD : 1; - uint32_t relPosLength : 1; - uint32_t relPosHeading : 1; - uint32_t relPosHPN : 1; - uint32_t relPosHPE : 1; - uint32_t relPosHPD : 1; - uint32_t relPosHPLength : 1; - uint32_t accN : 1; - uint32_t accE : 1; - uint32_t accD : 1; - uint32_t accLength : 1; - uint32_t accHeading : 1; - - uint32_t gnssFixOK : 1; - uint32_t diffSoln : 1; - uint32_t relPosValid : 1; - uint32_t carrSoln : 1; - uint32_t isMoving : 1; - uint32_t refPosMiss : 1; - uint32_t refObsMiss : 1; - uint32_t relPosHeadingValid : 1; - uint32_t relPosNormalized : 1; - } bits; - } moduleQueried; -} UBX_NAV_RELPOSNED_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_RELPOSNED_data_t data; - UBX_NAV_RELPOSNED_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_RELPOSNED_data_t); - void (*callbackPointerPtr)(UBX_NAV_RELPOSNED_data_t *); - UBX_NAV_RELPOSNED_data_t *callbackData; -} UBX_NAV_RELPOSNED_t; - -// UBX-NAV-AOPSTATUS (0x01 0x60): AssistNow Autonomous status -const uint16_t UBX_NAV_AOPSTATUS_LEN = 16; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - union - { - uint8_t all; - struct - { - uint8_t useAOP : 1; // AOP enabled flag - } bits; - } aopCfg; // AssistNow Autonomous configuration - uint8_t status; // AssistNow Autonomous subsystem is idle (0) or running (not 0) - uint8_t reserved1[10]; -} UBX_NAV_AOPSTATUS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - - uint32_t useAOP : 1; - - uint32_t status : 1; - } bits; - } moduleQueried; -} UBX_NAV_AOPSTATUS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_AOPSTATUS_data_t data; - UBX_NAV_AOPSTATUS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_NAV_AOPSTATUS_data_t); - void (*callbackPointerPtr)(UBX_NAV_AOPSTATUS_data_t *); - UBX_NAV_AOPSTATUS_data_t *callbackData; -} UBX_NAV_AOPSTATUS_t; - -// UBX-NAV-EOE (0x01 0x61): End of Epoch -const uint16_t UBX_NAV_EOE_LEN = 4; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms -} UBX_NAV_EOE_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - } bits; - } moduleQueried; -} UBX_NAV_EOE_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_NAV_EOE_data_t data; - UBX_NAV_EOE_moduleQueried_t moduleQueried; - void (*callbackPointerPtr)(UBX_NAV_EOE_data_t *); - UBX_NAV_EOE_data_t *callbackData; -} UBX_NAV_EOE_t; - -// RXM-specific structs - -// UBX-RXM-SFRBX (0x02 0x13): Broadcast navigation data subframe -// Note: length is variable -// Note: on protocol version 17: numWords is (0..16) -// on protocol version 18+: numWords is (0..10) -const uint8_t UBX_RXM_SFRBX_MAX_WORDS = 16; -const uint16_t UBX_RXM_SFRBX_MAX_LEN = 8 + (4 * UBX_RXM_SFRBX_MAX_WORDS); - -typedef struct -{ - uint8_t gnssId; // GNSS identifier - uint8_t svId; // Satellite identifier - uint8_t reserved1; - uint8_t freqId; // GLONASS frequency slot - uint8_t numWords; // The number of data words contained in this message (0..16) - uint8_t chn; // The tracking channel number the message was received on - uint8_t version; // Message version (0x01 for this version) - uint8_t reserved2; - uint32_t dwrd[UBX_RXM_SFRBX_MAX_WORDS]; // The data words -} UBX_RXM_SFRBX_data_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_RXM_SFRBX_data_t data; - bool moduleQueried; - void (*callbackPointer)(UBX_RXM_SFRBX_data_t); - void (*callbackPointerPtr)(UBX_RXM_SFRBX_data_t *); - UBX_RXM_SFRBX_data_t *callbackData; -} UBX_RXM_SFRBX_t; - -// UBX-RXM-RAWX (0x02 0x15): Multi-GNSS raw measurement data -// Note: length is variable -const uint8_t UBX_RXM_RAWX_MAX_BLOCKS = 92; // See issue #70 and PR #74 for more info -const uint16_t UBX_RXM_RAWX_MAX_LEN = 16 + (32 * UBX_RXM_RAWX_MAX_BLOCKS); - -typedef struct -{ - uint8_t rcvTow[8]; // Measurement time of week in receiver local time [64-bit float] - uint16_t week; // GPS week number - int8_t leapS; // GPS leap seconds - uint8_t numMeas; // Number of measurements to follow - union - { - uint8_t all; - struct - { - uint8_t leapSec : 1; // Leap seconds have been determined - uint8_t clkReset : 1; // Clock reset applied - } bits; - } recStat; - uint8_t version; // Message version (0x01 for this version) - uint8_t reserved1[2]; -} UBX_RXM_RAWX_header_t; - -typedef struct -{ - uint8_t prMes[8]; // Pseudorange measurement: m [64-bit float] - uint8_t cpMes[8]; // Carrier phase measurement: cycles [64-bit float] - uint8_t doMes[4]; // Doppler measurement: Hz [32-bit float] - uint8_t gnssId; // GNSS identifier - uint8_t svId; // Satellite identifier - uint8_t sigId; // New signal identifier - uint8_t freqId; // GLONASS frequency slot - uint16_t lockTime; // Carrier phase locktime counter: ms - uint8_t cno; // Carrier-to-noise density ratio: dB-Hz - uint8_t prStdev; // Estimated pseudorange measurement standard deviation: m * 0.01 * 2^n [4-bit] - uint8_t cpStdev; // Estimated carrier phase measurement standard deviation: cycles * 0.004 [4-bit] - uint8_t doStdev; // Estimated Doppler measurement standard deviation: Hz * 0.002 * 2^n [4-bit] - union - { - uint8_t all; - struct - { - uint8_t prValid : 1; // Pseudorange valid - uint8_t cpValid : 1; // Carrier phase valid - uint8_t halfCyc : 1; // Half cycle valid - uint8_t subHalfCyc : 1; // Half cycle subtracted from phase - } bits; - } trkStat; - uint8_t reserved2; -} UBX_RXM_RAWX_block_t; - -typedef struct -{ - UBX_RXM_RAWX_header_t header; - UBX_RXM_RAWX_block_t blocks[UBX_RXM_RAWX_MAX_BLOCKS]; -} UBX_RXM_RAWX_data_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_RXM_RAWX_data_t data; - bool moduleQueried; - void (*callbackPointer)(UBX_RXM_RAWX_data_t); - void (*callbackPointerPtr)(UBX_RXM_RAWX_data_t *); - UBX_RXM_RAWX_data_t *callbackData; -} UBX_RXM_RAWX_t; - -// UBX-RXM-COR (0x02 0x34): Differential correction input status -const uint16_t UBX_RXM_COR_LEN = 12; - -typedef struct -{ - uint8_t version; // Message version (0x01 for this version) - uint8_t ebno; // Energy per bit to noise power spectral density ratio (Eb/N0): 2^-3 dB - // 0: unknown. Reported only for protocol UBX-RXM-PMP (SPARTN) to monitor signal quality. - uint8_t reserved0[2]; // Reserved - union - { - uint32_t all; - struct - { - uint32_t protocol : 5; // Input correction data protocol: - // 0: Unknown - // 1: RTCM3 - // 2: SPARTN (Secure Position Augmentation for Real Time Navigation) - // 29: UBX-RXM-PMP (SPARTN) - // 30: UBX-RXM-QZSSL6 - uint32_t errStatus : 2; // Error status of the received correction message content based on possibly available error codes or checksums: - // 0: Unknown - // 1: Error-free - // 2: Erroneous - uint32_t msgUsed : 2; // Status of receiver using the input message: - // 0: Unknown - // 1: Not used - // 2: Used - uint32_t correctionId : 16; // Identifier for the correction stream: - // For RTCM 3: Reference station ID (DF003) of the received RTCM input message. - // Valid range 0-4095. - // For all other messages, reports 0xFFFF. - // For other correction protocols 0xFFFF. - uint32_t msgTypeValid : 1; // Validity of the msgType field. Set to False e.g. if the protocol does not define msgType. - uint32_t msgSubTypeValid : 1; // Validity of the msgSubType field. Set to False e.g. if the protocol does not define subtype for the msgType. - uint32_t msgInputHandle : 1; // Input handling support of the input message: - // 0: Receiver does not have input handling support for this message - // 1: Receiver has input handling support for this message - uint32_t msgEncrypted : 2; // Encryption status of the input message: - // 0: Unknown - // 1: Not encrypted - // 2: Encrypted - uint32_t msgDecrypted : 2; // Decryption status of the input message: - // 0: Unknown - // 1: Not decrypted - // 2: Successfully decrypted - } bits; - } statusInfo; - uint16_t msgType; // Message type - uint16_t msgSubType; // Message subtype -} UBX_RXM_COR_data_t; - -// The COR data can only be accessed via a callback. COR cannot be polled. -typedef struct -{ - ubxAutomaticFlags automaticFlags; - void (*callbackPointerPtr)(UBX_RXM_COR_data_t *); - UBX_RXM_COR_data_t *callbackData; -} UBX_RXM_COR_t; - -// UBX-RXM-PMP (0x02 0x72): PMP raw data (D9 modules) -// There are two versions of this message but, fortunately, both have a max len of 528 -const uint16_t UBX_RXM_PMP_MAX_USER_DATA = 504; -const uint16_t UBX_RXM_PMP_MAX_LEN = UBX_RXM_PMP_MAX_USER_DATA + 24; - -typedef struct -{ - uint8_t version; // Message version (0x00 / 0x01) - uint8_t reserved0; // Reserved - uint16_t numBytesUserData; // version 0x00: reserved0 ; version 0x01: Number of bytes the userData block has in this frame (0...504) - uint32_t timeTag; // Time since startup when frame started : ms - uint32_t uniqueWord[2]; // Received unique words - uint16_t serviceIdentifier; // Received service identifier - uint8_t spare; // Received spare data - uint8_t uniqueWordBitErrors; // Number of bit errors in both unique words - - // The position of fecBits, ebno and reserved1 depends on the message version - uint16_t fecBits; // Number of bits corrected by FEC (forward error correction) - uint8_t ebno; // Energy per bit to noise power spectral density ratio : 2^-3 dB - uint8_t reserved1; // Reserved - - uint8_t userData[UBX_RXM_PMP_MAX_USER_DATA]; // Received user data: version 0x00 : starts at byte 20 ; version 0x01 : starts at byte 24 - -} UBX_RXM_PMP_data_t; - -// The PMP data can only be accessed via a callback. PMP cannot be polled. -typedef struct -{ - ubxAutomaticFlags automaticFlags; - void (*callbackPointerPtr)(UBX_RXM_PMP_data_t *); - UBX_RXM_PMP_data_t *callbackData; -} UBX_RXM_PMP_t; - -// Define a struct to hold the entire PMP message so the whole thing can be pushed to a GNSS. -// Remember that the length of the payload could be variable (with version 1 messages). -typedef struct -{ - uint8_t sync1; // 0xB5 - uint8_t sync2; // 0x62 - uint8_t cls; - uint8_t ID; - uint8_t lengthLSB; - uint8_t lengthMSB; - uint8_t payload[UBX_RXM_PMP_MAX_LEN]; - uint8_t checksumA; - uint8_t checksumB; -} UBX_RXM_PMP_message_data_t; - -// The PMP data can only be accessed via a callback. PMP cannot be polled. -typedef struct -{ - ubxAutomaticFlags automaticFlags; - void (*callbackPointerPtr)(UBX_RXM_PMP_message_data_t *); - UBX_RXM_PMP_message_data_t *callbackData; -} UBX_RXM_PMP_message_t; - -// UBX-RXM-QZSSL6 (0x02 0x73): QZSS L6 raw data (D9C modules) -#define UBX_RXM_QZSSL6_NUM_CHANNELS 2 -const uint16_t UBX_RXM_QZSSL6_DATALEN = 250; -const uint16_t UBX_RXM_QZSSL6_MAX_LEN = UBX_RXM_QZSSL6_DATALEN + 14; - -typedef struct -{ - uint8_t version; // Message version (0x00 / 0x01) - uint8_t svId; // Satellite identifier - uint16_t cno; // Mean C/N0 - uint32_t timeTag; // Time since startup when frame started : ms - uint8_t groupDelay; // L6 group delay w.r.t. L2 on channel - uint8_t bitErrCorr; // Number of bit errors corrected by Reed-Solomon decoder - uint16_t chInfo; // Information about receiver channel associated with a received QZSS L6 message - uint8_t reserved0[2]; // Reserved - uint8_t msgBytes[UBX_RXM_QZSSL6_DATALEN]; // Bytes in a QZSS L6 message -} UBX_RXM_QZSSL6_data_t; - -struct ubxQZSSL6AutomaticFlags -{ - union - { - uint8_t all; - struct - { - uint8_t automatic : 1; // Will this message be delivered and parsed "automatically" (without polling) - uint8_t implicitUpdate : 1; // Is the update triggered by accessing stale data (=true) or by a call to checkUblox (=false) - uint8_t addToFileBuffer : 1; // Should the raw UBX data be added to the file buffer? - uint8_t callbackCopyValid : UBX_RXM_QZSSL6_NUM_CHANNELS; // Is the copies of the data structs used by the callback valid/fresh? - } bits; - } flags; -}; - -// Define a struct to hold the entire QZSSL6 message so the whole thing can be pushed to a GNSS. -// Remember that the length of the payload could be variable (with version 1 messages). -typedef struct -{ - uint8_t sync1; // 0xB5 - uint8_t sync2; // 0x62 - uint8_t cls; - uint8_t ID; - uint8_t lengthLSB; - uint8_t lengthMSB; - uint8_t payload[UBX_RXM_QZSSL6_MAX_LEN]; - uint8_t checksumA; - uint8_t checksumB; -} UBX_RXM_QZSSL6_message_data_t; - -// The QZSSL6 data can only be accessed via a callback. QZSSL6 cannot be polled. -typedef struct -{ - ubxQZSSL6AutomaticFlags automaticFlags; - void (*callbackPointerPtr)(UBX_RXM_QZSSL6_message_data_t *); - UBX_RXM_QZSSL6_message_data_t *callbackData; -} UBX_RXM_QZSSL6_message_t; - -// CFG-specific structs - -// UBX-CFG-PRT (0x06 0x00): Port configuration -// The content changes depending on which port type is being configured -// This struct defines the common structure -const uint16_t UBX_CFG_PRT_LEN = 20; - -typedef struct -{ - uint8_t portID; // Port identifier number - uint8_t reserved0; // Reserved - union - { - uint16_t all; - struct - { - uint16_t en : 1; // Enable TX ready feature for this port - uint16_t pol : 1; // Polarity: 0 High-active; 1 Low-active - uint16_t pin : 5; // PIO to be used (must not be in use by another function) - uint16_t thres : 9; // Threshold - } bits; - } txReady; - uint32_t mode; // Content changes depending on the port type - uint32_t baudRate; // Content changes depending on the port type - union - { - uint16_t all; - struct - { - uint16_t inUbx : 1; // UBX protocol - uint16_t inNmea : 1; // NMEA protocol - uint16_t inRtcm : 1; // RTCM2 protocol - uint16_t reserved : 2; - uint16_t inRtcm3 : 1; // RTCM3 protocol (not supported for protocol versions less than 20.00) - uint16_t inSPARTN : 1; - } bits; - } inProtoMask; - union - { - uint16_t all; - struct - { - uint16_t outUbx : 1; // UBX protocol - uint16_t outNmea : 1; // NMEA protocol - uint16_t reserved : 3; - uint16_t outRtcm3 : 1; // RTCM3 protocol (not supported for protocol versions less than 20.00) - uint16_t outSPARTN : 1; - } bits; - } outProtoMask; - uint16_t flags; // Content changes depending on the port type - uint16_t reserved1; -} UBX_CFG_PRT_data_t; - -typedef struct -{ - UBX_CFG_PRT_data_t data; - bool dataValid; -} UBX_CFG_PRT_t; - -// UBX-CFG-RATE (0x06 0x08): Navigation/measurement rate settings -const uint16_t UBX_CFG_RATE_LEN = 6; - -typedef struct -{ - uint16_t measRate; // The elapsed time between GNSS measurements, which defines the rate: ms - uint16_t navRate; // The ratio between the number of measurements and the number of navigation solutions: cycles - uint16_t timeRef; // The time system to which measurements are aligned: 0: UTC; 1: GPS; 2: GLONASS; 3: BeiDou; 4: Galileo -} UBX_CFG_RATE_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t measRate : 1; - uint32_t navRate : 1; - uint32_t timeRef : 1; - } bits; - } moduleQueried; -} UBX_CFG_RATE_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_CFG_RATE_data_t data; - UBX_CFG_RATE_moduleQueried_t moduleQueried; -} UBX_CFG_RATE_t; - -// UBX-CFG-TP5 (0x06 0x31): Time pulse parameters -const uint16_t UBX_CFG_TP5_LEN = 32; - -typedef struct -{ - uint8_t tpIdx; // Time pulse selection (0 = TIMEPULSE, 1 = TIMEPULSE2) - uint8_t version; // Message version (0x01 for this version) - uint8_t reserved1[2]; - int16_t antCableDelay; // Antenna cable delay: ns - int16_t rfGroupDelay; // RF group delay: ns - uint32_t freqPeriod; // Frequency or period time, depending on setting of bit 'isFreq': Hz_or_us - uint32_t freqPeriodLock; // Frequency or period time when locked to GNSS time, only used if 'lockedOtherSet' is set: Hz_or_us - uint32_t pulseLenRatio; // Pulse length or duty cycle, depending on 'isLength': us_or_2^-32 - uint32_t pulseLenRatioLock; // Pulse length or duty cycle when locked to GNSS time, only used if 'lockedOtherSet' is set: us_or_2^-32 - int32_t userConfigDelay; // User-configurable time pulse delay: ns - union - { - uint32_t all; - struct - { - uint32_t active : 1; // If set enable time pulse; if pin assigned to another function, other function takes precedence. - uint32_t lockGnssFreq : 1; // If set, synchronize time pulse to GNSS as soon as GNSS time is valid. If not set, or before GNSS time is valid, use local clock. - uint32_t lockedOtherSet : 1; // If set the receiver switches between the timepulse settings given by 'freqPeriodLocked' & 'pulseLenLocked' and those given by 'freqPeriod' & 'pulseLen'. - uint32_t isFreq : 1; // If set 'freqPeriodLock' and 'freqPeriod' are interpreted as frequency, otherwise interpreted as period. - uint32_t isLength : 1; // If set 'pulseLenRatioLock' and 'pulseLenRatio' interpreted as pulse length, otherwise interpreted as duty cycle. - uint32_t alignToTow : 1; // Align pulse to top of second (period time must be integer fraction of 1s). Also set 'lockGnssFreq' to use this feature. - uint32_t polarity : 1; // Pulse polarity: 0: falling edge at top of second; 1: rising edge at top of second - uint32_t gridUtcGnss : 4; // Timegrid to use: 0: UTC; 1: GPS; 2: GLONASS; 3: BeiDou; 4: Galileo - uint32_t syncMode : 3; // Sync Manager lock mode to use: - // 0: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, never switch back to 'freqPeriod' and 'pulseLenRatio' - // 1: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, and switch back to 'freqPeriod' and 'pulseLenRatio' as soon as time gets inaccurate - } bits; - } flags; -} UBX_CFG_TP5_data_t; - -// UBX-CFG-ITFM (0x06 0x39): Jamming/interference monitor configuration -const uint16_t UBX_CFG_ITFM_LEN = 8; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t bbThreshold : 4; // Broadband jamming detection threshold - uint32_t cwThreshold : 5; // CW jamming detection threshold - uint32_t algorithmBits : 22; // Reserved algorithm settings - should be set to 0x16B156 in hex for correct settings - uint32_t enable : 1; // Enable interference detection - } bits; - } config; - union - { - uint32_t all; - struct - { - uint32_t generalBits : 12; // General settings - should be set to 0x31E in hex for correct setting - uint32_t antSetting : 2; // Antenna setting, 0=unknown, 1=passive, 2=active - uint32_t enable2 : 1; // Set to 1 to scan auxiliary bands (u-blox 8 / u-blox M8 only, otherwise ignored) - } bits; - } config2; -} UBX_CFG_ITFM_data_t; - -// UBX-CFG-TMODE3 (0x06 0x71): Time Mode Settings 3 -const uint16_t UBX_CFG_TMODE3_LEN = 40; - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t reserved1; - union - { - uint16_t all; - struct - { - uint16_t mode : 8; // Receiver Mode: 0 Disabled; 1 Survey In; 2 Fixed Mode (true ARP position information required); 3-255 Reserved - uint16_t lla : 1; // Position is given in LAT/LON/ALT (default is ECEF) - } bits; - } flags; - int32_t ecefXOrLat; // WGS84 ECEF X coordinate (or latitude) of the ARP position, depending on flags above: cm or deg*1e-7 - int32_t ecefYOrLon; // WGS84 ECEF Y coordinate (or latitude) of the ARP position, depending on flags above: cm or deg*1e-7 - int32_t ecefZOrAlt; // WGS84 ECEF Z coordinate (or altitude) of the ARP position, depending on flags above: cm - int8_t ecefXOrLatHP; // High-precision WGS84 ECEF X coordinate (or latitude) of the ARP position, depending on flags above: 0.1 mm or deg*1e-9 - int8_t ecefYOrLonHP; // High-precision WGS84 ECEF Y coordinate (or longitude) of the ARP position, depending on flags above: 0.1 mm or deg*1e-9 - int8_t ecefZOrAltHP; // High-precision WGS84 ECEF Z coordinate (or altitude) of the ARP position, depending on flags above: 0.1 mm - uint8_t reserved2; - uint32_t fixedPosAcc; // Fixed position 3D accuracy: 0.1 mm - uint32_t svinMinDur; // Survey-in minimum duration: s - uint32_t svinAccLimit; // Survey-in position accuracy limit: 0.1 mm - uint8_t reserved3[8]; -} UBX_CFG_TMODE3_data_t; - -// MON-specific structs - -// UBX-MON-HW (0x0A 0x09): Hardware status -const uint16_t UBX_MON_HW_LEN = 60; - -typedef struct -{ - uint32_t pinSel; // Mask of pins set as peripheral/PIO - uint32_t pinBank; // Mask of pins set as bank A/B - uint32_t pinDir; // Mask of pins set as input/output - uint32_t pinVal; // Mask of pins value low/high - uint16_t noisePerMS; // Noise level as measured by the GPS core - uint16_t agcCnt; // AGC monitor (counts SIGHI xor SIGLO, range 0 to 8191) - uint8_t aStatus; // Status of the antenna supervisor state machine (0=INIT, 1=DONTKNOW, 2=OK, 3=SHORT, 4=OPEN) - uint8_t aPower; // Current power status of antenna (0=OFF, 1=ON, 2=DONTKNOW) - union - { - uint8_t all; - struct - { - uint8_t rtcCalib : 1; // RTC is calibrated - uint8_t safeBoot : 1; // Safeboot mode (0 = inactive, 1 = active) - uint8_t jammingState : 2; // Output from jamming/interference monitor (0 = unknown or feature disabled, - // 1 = ok - no significant jamming, - // 2 = warning - interference visible but fix OK, - // 3 = critical - interference visible and no fix) - uint8_t xtalAbsent : 1; // RTC xtal has been determined to be absent - } bits; - } flags; - uint8_t reserved1; // Reserved - uint32_t usedMask; // Mask of pins that are used by the virtual pin manager - uint8_t VP[17]; // Array of pin mappings for each of the 17 physical pins - uint8_t jamInd; // CW jamming indicator, scaled (0 = no CW jamming, 255 = strong CW jamming) - uint8_t reserved2[2]; // Reserved - uint32_t pinIrq; // Mask of pins value using the PIO Irq - uint32_t pullH; // Mask of pins value using the PIO pull high resistor - uint8_t pullL; // Mask of pins value using the PIO pull low resistor -} UBX_MON_HW_data_t; - -// UBX-MON-HW2 (0x0A 0x0B): Extended hardware status -const uint16_t UBX_MON_HW2_LEN = 28; - -typedef struct -{ - int8_t ofsI; // Imbalance of I-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) - uint8_t magI; // Magnitude of I-part of complex signal, scaled (0 = no signal, 255 = max. magnitude) - int8_t ofsQ; // Imbalance of Q-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) - uint8_t magQ; // Magnitude of Q-part of complex signal, scaled (0 = no signal, 255 = max. magnitude) - uint8_t cfgSource; // Source of low-level configuration (114 = ROM, 111 = OTP, 112 = config pins, 102 = flash image) - uint8_t reserved0[3]; - uint32_t lowLevCfg; // Low-level configuration (obsolete for protocol versions greater than 15.00) - uint8_t reserved1[8]; - uint32_t postStatus; // POST status word - uint8_t reserved2[4]; // Reserved -} UBX_MON_HW2_data_t; - -// UBX-MON-RF (0x0a 0x38): RF information -const uint16_t UBX_MON_RF_MAX_BLOCKS = 2; // 0 = L1; 1 = L2 / L5 -const uint16_t UBX_MON_RF_MAX_LEN = 4 + (24 * UBX_MON_RF_MAX_BLOCKS); - -typedef struct -{ - uint8_t version; // Message version (0x00 for this version) - uint8_t nBlocks; // The number of RF blocks included - uint8_t reserved0[2]; -} UBX_MON_RF_header_t; - -typedef struct -{ - uint8_t blockId; // RF block ID (0 = L1 band, 1 = L2 or L5 band depending on product configuration) - union - { - uint8_t all; - struct - { - uint8_t jammingState : 2; // output from Jamming/Interference Monitor (0 = unknown or feature disabled, - // 1 = ok - no significant jamming, - // 2 = warning - interference visible but fix OK, - // 3 = critical - interference visible and no fix) - } bits; - } flags; - uint8_t antStatus; // Status of the antenna supervisor state machine (0x00=INIT, 0x01=DONTKNOW, 0x02=OK, 0x03=SHORT, 0x04=OPEN) - uint8_t antPower; // Current power status of antenna (0x00=OFF, 0x01=ON, 0x02=DONTKNOW) - uint32_t postStatus; // POST status word - uint8_t reserved1[4]; // Reserved - uint16_t noisePerMS; // Noise level as measured by the GPS core - uint16_t agcCnt; // AGC Monitor (counts SIGHI xor SIGLO, range 0 to 8191) - uint8_t jamInd; // CW jamming indicator, scaled (0=no CW jamming, 255 = strong CW jamming) - int8_t ofsI; // Imbalance of I-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) - uint8_t magI; // Magnitude of I-part of complex signal, scaled (0 = no signal, 255 = max.magnitude) - int8_t ofsQ; // Imbalance of Q-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) - uint8_t magQ; // Magnitude of Q-part of complex signal, scaled (0 = no signal, 255 = max.magnitude) - uint8_t reserved2[3]; // Reserved -} UBX_MON_RF_block_t; - -typedef struct -{ - UBX_MON_RF_header_t header; - UBX_MON_RF_block_t blocks[UBX_MON_RF_MAX_BLOCKS]; -} UBX_MON_RF_data_t; - -// TIM-specific structs - -// UBX-TIM-TM2 (0x0D 0x03): Time mark data -const uint16_t UBX_TIM_TM2_LEN = 28; - -typedef struct -{ - uint8_t ch; // Channel (i.e. EXTINT) upon which the pulse was measured - union - { - uint8_t all; - struct - { - uint8_t mode : 1; // 0=single; 1=running - uint8_t run : 1; // 0=armed; 1=stopped - uint8_t newFallingEdge : 1; // New falling edge detected - uint8_t timeBase : 2; // 0=Time base is Receiver time; 1=Time base is GNSS time; 2=Time base is UTC - uint8_t utc : 1; // 0=UTC not available; 1=UTC available - uint8_t time : 1; // 0=Time is not valid; 1=Time is valid (Valid GNSS fix) - uint8_t newRisingEdge : 1; // New rising edge detected - } bits; - } flags; - uint16_t count; // Rising edge counter - uint16_t wnR; // Week number of last rising edge - uint16_t wnF; // Week number of last falling edge - uint32_t towMsR; // TOW of rising edge: ms - uint32_t towSubMsR; // Millisecond fraction of tow of rising edge: ns - uint32_t towMsF; // TOW of falling edge: ms - uint32_t towSubMsF; // Millisecond fraction of tow of falling edge: ns - uint32_t accEst; // Accuracy estimate: ns -} UBX_TIM_TM2_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t ch : 1; - uint32_t mode : 1; - uint32_t run : 1; - uint32_t newFallingEdge : 1; - uint32_t timeBase : 1; - uint32_t utc : 1; - uint32_t time : 1; - uint32_t newRisingEdge : 1; - - uint32_t count : 1; - uint32_t wnR : 1; - uint32_t wnF : 1; - uint32_t towMsR : 1; - uint32_t towSubMsR : 1; - uint32_t towMsF : 1; - uint32_t towSubMsF : 1; - uint32_t accEst : 1; - } bits; - } moduleQueried; -} UBX_TIM_TM2_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_TIM_TM2_data_t data; - UBX_TIM_TM2_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_TIM_TM2_data_t); - void (*callbackPointerPtr)(UBX_TIM_TM2_data_t *); - UBX_TIM_TM2_data_t *callbackData; -} UBX_TIM_TM2_t; - -// ESF-specific structs - -// UBX-ESF-ALG (0x10 0x14): IMU alignment information -const uint16_t UBX_ESF_ALG_LEN = 16; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the HNR epoch: ms - uint8_t version; // Message version (0x01 for this version) - union - { - uint8_t all; - struct - { - uint8_t autoMntAlgOn : 1; // Automatic IMU-mount alignment on/off bit - uint8_t status : 3; // Status of the IMU-mount alignment - // 0: user-defined/fixed angles are used - // 1: IMU-mount roll/pitch angles alignment is ongoing - // 2: IMU-mount roll/pitch/yaw angles alignment is ongoing - // 3: coarse IMU-mount alignment are used - // 4: fine IMU-mount alignment are used - } bits; - } flags; - union - { - uint8_t all; - struct - { - uint8_t tiltAlgError : 1; // IMU-mount tilt (roll and/or pitch) alignment error (0: no error, 1: error) - uint8_t yawAlgError : 1; // IMU-mount yaw alignment error (0: no error, 1: error) - uint8_t angleError : 1; // IMU-mount misalignment Euler angle singularity error (0: no error, 1: error) - } bits; - } error; - uint8_t reserved1; - uint32_t yaw; // IMU-mount yaw angle [0, 360]: Degrees * 1e-2 - int16_t pitch; // IMU-mount pitch angle [-90, 90]: Degrees * 1e-2 - int16_t roll; // IMU-mount roll angle [-180, 180]: Degrees * 1e-2 -} UBX_ESF_ALG_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - - uint32_t autoMntAlgOn : 1; - uint32_t status : 1; - - uint32_t tiltAlgError : 1; - uint32_t yawAlgError : 1; - uint32_t angleError : 1; - - uint32_t yaw : 1; - uint32_t pitch : 1; - uint32_t roll : 1; - } bits; - } moduleQueried; -} UBX_ESF_ALG_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_ESF_ALG_data_t data; - UBX_ESF_ALG_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_ESF_ALG_data_t); - void (*callbackPointerPtr)(UBX_ESF_ALG_data_t *); - UBX_ESF_ALG_data_t *callbackData; -} UBX_ESF_ALG_t; - -// UBX-ESF-INS (0x10 0x15): Vehicle dynamics information -const uint16_t UBX_ESF_INS_LEN = 36; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t version : 8; // Message version (0x01 for this version) - uint32_t xAngRateValid : 1; // Compensated x-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t yAngRateValid : 1; // Compensated y-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t zAngRateValid : 1; // Compensated z-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t xAccelValid : 1; // Compensated x-axis acceleration data validity flag (0: not valid, 1: valid) - uint32_t yAccelValid : 1; // Compensated y-axis acceleration data validity flag (0: not valid, 1: valid) - uint32_t zAccelValid : 1; // Compensated z-axis acceleration data validity flag (0: not valid, 1: valid) - } bits; - } bitfield0; - uint8_t reserved1[4]; - uint32_t iTOW; // GPS time of week of the HNR epoch: ms - int32_t xAngRate; // Compensated x-axis angular rate: Degrees/s * 1e-3 - int32_t yAngRate; // Compensated y-axis angular rate: Degrees/s * 1e-3 - int32_t zAngRate; // Compensated z-axis angular rate: Degrees/s * 1e-3 - int32_t xAccel; // Compensated x-axis acceleration (gravity-free): m/s^2 * 1e-2 - int32_t yAccel; // Compensated y-axis acceleration (gravity-free): m/s^2 * 1e-2 - int32_t zAccel; // Compensated z-axis acceleration (gravity-free): m/s^2 * 1e-2 -} UBX_ESF_INS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t xAngRateValid : 1; - uint32_t yAngRateValid : 1; - uint32_t zAngRateValid : 1; - uint32_t xAccelValid : 1; - uint32_t yAccelValid : 1; - uint32_t zAccelValid : 1; - - uint32_t iTOW : 1; - uint32_t xAngRate : 1; - uint32_t yAngRate : 1; - uint32_t zAngRate : 1; - uint32_t xAccel : 1; - uint32_t yAccel : 1; - uint32_t zAccel : 1; - } bits; - } moduleQueried; -} UBX_ESF_INS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_ESF_INS_data_t data; - UBX_ESF_INS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_ESF_INS_data_t); - void (*callbackPointerPtr)(UBX_ESF_INS_data_t *); - UBX_ESF_INS_data_t *callbackData; -} UBX_ESF_INS_t; - -// UBX-ESF-MEAS (0x10 0x02): External sensor fusion measurements -// Note: length is variable -// Note: ESF RAW data cannot be polled. It is "Output" only -const uint16_t UBX_ESF_MEAS_MAX_LEN = 8 + (4 * DEF_MAX_NUM_ESF_MEAS) + 4; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t dataField : 24; // Data - uint32_t dataType : 6; // Type of data (0 = no data; 1..63 = data type) - } bits; - } data; -} UBX_ESF_MEAS_sensorData_t; - -typedef struct -{ - uint32_t timeTag; // Time tag of measurement generated by external sensor - union - { - uint16_t all; - struct - { - uint16_t timeMarkSent : 2; // Time mark signal was supplied just prior to sending this message: - // 0 = none, 1 = on Ext0, 2 = on Ext1 - uint16_t timeMarkEdge : 1; // Trigger on rising (0) or falling (1) edge of time mark signal - uint16_t calibTtagValid : 1; // Calibration time tag available. Always set to zero. - uint16_t reserved : 7; - uint16_t numMeas : 5; // Number of measurements contained in this message (optional, can be obtained from message size) - } bits; - } flags; - uint16_t id; // Identification number of data provider - UBX_ESF_MEAS_sensorData_t data[DEF_MAX_NUM_ESF_MEAS]; - uint32_t calibTtag; // OPTIONAL: Receiver local time calibrated: ms -} UBX_ESF_MEAS_data_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_ESF_MEAS_data_t data; - void (*callbackPointer)(UBX_ESF_MEAS_data_t); - void (*callbackPointerPtr)(UBX_ESF_MEAS_data_t *); - UBX_ESF_MEAS_data_t *callbackData; -} UBX_ESF_MEAS_t; - -// UBX-ESF-RAW (0x10 0x03): Raw sensor measurements -// Note: length is variable -// Note: The ZED-F9R sends sets of seven sensor readings one at a time -// But the NEO-M8U sends them in sets of ten (i.e. seventy readings per message) -// Note: ESF RAW data cannot be polled. It is "Output" only -const uint16_t UBX_ESF_RAW_MAX_LEN = 4 + (8 * DEF_NUM_SENS * DEF_MAX_NUM_ESF_RAW_REPEATS); - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t dataField : 24; // Data - uint32_t dataType : 8; // Type of data (0 = no data; 1..255 = data type) - } bits; - } data; - uint32_t sTag; // Sensor time tag -} UBX_ESF_RAW_sensorData_t; - -typedef struct -{ - uint8_t reserved1[4]; - UBX_ESF_RAW_sensorData_t data[DEF_NUM_SENS * DEF_MAX_NUM_ESF_RAW_REPEATS]; - uint8_t numEsfRawBlocks; // Note: this is not contained in the ESF RAW message. It is calculated from the message length. -} UBX_ESF_RAW_data_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_ESF_RAW_data_t data; - void (*callbackPointer)(UBX_ESF_RAW_data_t); - void (*callbackPointerPtr)(UBX_ESF_RAW_data_t *); - UBX_ESF_RAW_data_t *callbackData; -} UBX_ESF_RAW_t; - -// UBX-ESF-STATUS (0x10 0x10): External sensor fusion status -// Note: length is variable -const uint16_t UBX_ESF_STATUS_MAX_LEN = 16 + (4 * DEF_NUM_SENS); - -typedef struct -{ - union - { - uint8_t all; - struct - { - uint8_t type : 6; // Sensor data type - uint8_t used : 1; // If set, sensor data is used for the current sensor fusion solution - uint8_t ready : 1; // If set, sensor is set up (configuration is available or not required) but not used for computing the current sensor fusion solution. - } bits; - } sensStatus1; - union - { - uint8_t all; - struct - { - uint8_t calibStatus : 2; // 00: Sensor is not calibrated - // 01: Sensor is calibrating - // 10/11: Sensor is calibrated - uint8_t timeStatus : 2; // 00: No data - // 01: Reception of the first byte used to tag the measurement - // 10: Event input used to tag the measurement - // 11: Time tag provided with the data - } bits; - } sensStatus2; - uint8_t freq; // Observation frequency: Hz - union - { - uint8_t all; - struct - { - uint8_t badMeas : 1; // Bad measurements detected - uint8_t badTTag : 1; // Bad measurement time-tags detected - uint8_t missingMeas : 1; // Missing or time-misaligned measurements detected - uint8_t noisyMeas : 1; // High measurement noise-level detected - } bits; - } faults; -} UBX_ESF_STATUS_sensorStatus_t; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the HNR epoch: ms - uint8_t version; // Message version (0x02 for this version) - uint8_t reserved1[7]; - uint8_t fusionMode; // Fusion mode: - // 0: Initialization mode: receiver is initializing some unknown values required for doing sensor fusion - // 1: Fusion mode: GNSS and sensor data are used for navigation solution computation - // 2: Suspended fusion mode: sensor fusion is temporarily disabled due to e.g. invalid sensor data or detected ferry - // 3: Disabled fusion mode: sensor fusion is permanently disabled until receiver reset due e.g. to sensor error - uint8_t reserved2[2]; - uint8_t numSens; // Number of sensors - UBX_ESF_STATUS_sensorStatus_t status[DEF_NUM_SENS]; -} UBX_ESF_STATUS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - uint32_t fusionMode : 1; - uint32_t numSens : 1; - - uint32_t status : DEF_NUM_SENS; - } bits; - } moduleQueried; -} UBX_ESF_STATUS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_ESF_STATUS_data_t data; - UBX_ESF_STATUS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_ESF_STATUS_data_t); - void (*callbackPointerPtr)(UBX_ESF_STATUS_data_t *); - UBX_ESF_STATUS_data_t *callbackData; -} UBX_ESF_STATUS_t; - -// MGA-specific structs - -// UBX-MGA-ACK-DATA0 (0x13 0x60): Multiple GNSS acknowledge message -const uint16_t UBX_MGA_ACK_DATA0_LEN = 8; - -typedef struct -{ - uint8_t type; // Type of acknowledgment: - // 0: The message was not used by the receiver (see infoCode field for an indication of why) - // 1: The message was accepted for use by the receiver (the infoCode field will be 0) - uint8_t version; // Message version - uint8_t infoCode; // Provides greater information on what the receiver chose to do with the message contents - // See sfe_ublox_mga_ack_infocode_e - uint8_t msgId; // UBX message ID of the acknowledged message - uint8_t msgPayloadStart[4]; // The first 4 bytes of the acknowledged message's payload -} UBX_MGA_ACK_DATA0_data_t; - -#define UBX_MGA_ACK_DATA0_RINGBUFFER_LEN 16 // Provide storage for 16 MGA ACK packets -typedef struct -{ - uint8_t head; - uint8_t tail; - UBX_MGA_ACK_DATA0_data_t data[UBX_MGA_ACK_DATA0_RINGBUFFER_LEN]; // Create a storage array for the MGA ACK packets -} UBX_MGA_ACK_DATA0_t; - -// UBX-MGA-DBD (0x13 0x80): Navigation database dump entry -const uint16_t UBX_MGA_DBD_LEN = 164; // "The maximum payload size for firmware 2.01 onwards is 164 bytes" - -typedef struct -{ - uint8_t dbdEntryHeader1; // We need to save the entire message - header, payload and checksum - uint8_t dbdEntryHeader2; - uint8_t dbdEntryClass; - uint8_t dbdEntryID; - uint8_t dbdEntryLenLSB; // We need to store the length of the DBD entry. The entry itself does not contain a length... - uint8_t dbdEntryLenMSB; - uint8_t dbdEntry[UBX_MGA_DBD_LEN]; - uint8_t dbdEntryChecksumA; - uint8_t dbdEntryChecksumB; -} UBX_MGA_DBD_data_t; - -#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR) -#define UBX_MGA_DBD_RINGBUFFER_LEN 190 // Fix to let the code compile on AVR platforms - including the UNO and DxCore (DA/DB). -#else -#define UBX_MGA_DBD_RINGBUFFER_LEN 250 // Provide storage for MGA DBD packets. TO DO: confirm if 250 is large enough for all modules! -#endif - -typedef struct -{ - uint8_t head; - uint8_t tail; - UBX_MGA_DBD_data_t data[UBX_MGA_DBD_RINGBUFFER_LEN]; // Create a storage array for the MGA DBD packets -} UBX_MGA_DBD_t; - -// HNR-specific structs - -// UBX-HNR-PVT (0x28 0x00): High rate output of PVT solution -const uint16_t UBX_HNR_PVT_LEN = 72; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the HNR epoch: ms - uint16_t year; // Year (UTC) - uint8_t month; // Month, range 1..12 (UTC) - uint8_t day; // Day of month, range 1..31 (UTC) - uint8_t hour; // Hour of day, range 0..23 (UTC) - uint8_t min; // Minute of hour, range 0..59 (UTC) - uint8_t sec; // Seconds of minute, range 0..60 (UTC) - union - { - uint8_t all; - struct - { - uint8_t validDate : 1; // 1 = Valid UTC Date - uint8_t validTime : 1; // 1 = Valid UTC Time of Day - uint8_t fullyResolved : 1; // 1 = UTC Time of Day has been fully resolved - } bits; - } valid; - int32_t nano; // Fraction of second (UTC): ns - uint8_t gpsFix; // GPSfix Type, range 0..5 - // 0x00 = No Fix - // 0x01 = Dead Reckoning only - // 0x02 = 2D-Fix - // 0x03 = 3D-Fix - // 0x04 = GPS + dead reckoning combined - // 0x05 = Time only fix - // 0x06..0xff: reserved - union - { - uint8_t all; - struct - { - uint8_t gpsFixOK : 1; // >1 = Fix within limits (e.g. DOP & accuracy) - uint8_t diffSoln : 1; // 1 = DGPS used - uint8_t WKNSET : 1; // 1 = Valid GPS week number - uint8_t TOWSET : 1; // 1 = Valid GPS time of week (iTOW & fTOW) - uint8_t headVehValid : 1; // 1= Heading of vehicle is valid - } bits; - } flags; - uint8_t reserved1[2]; - int32_t lon; // Longitude: Degrees * 1e-7 - int32_t lat; // Latitude: Degrees * 1e-7 - int32_t height; // Height above ellipsoid: mm - int32_t hMSL; // Height above MSL: mm - int32_t gSpeed; // Ground Speed (2-D): mm/s - int32_t speed; // Speed (3-D): mm/s - int32_t headMot; // Heading of motion (2-D): Degrees * 1e-5 - int32_t headVeh; // Heading of vehicle (2-D): Degrees * 1e-5 - uint32_t hAcc; // Horizontal accuracy: mm - uint32_t vAcc; // Vertical accuracy: mm - uint32_t sAcc; // Speed accuracy: mm/s - uint32_t headAcc; // Heading accuracy: Degrees * 1e-5 - uint8_t reserved2[4]; -} UBX_HNR_PVT_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t year : 1; - uint32_t month : 1; - uint32_t day : 1; - uint32_t hour : 1; - uint32_t min : 1; - uint32_t sec : 1; - - uint32_t validDate : 1; - uint32_t validTime : 1; - uint32_t fullyResolved : 1; - - uint32_t nano : 1; - uint32_t gpsFix : 1; - - uint32_t gpsFixOK : 1; - uint32_t diffSoln : 1; - uint32_t WKNSET : 1; - uint32_t TOWSET : 1; - uint32_t headVehValid : 1; - - uint32_t lon : 1; - uint32_t lat : 1; - uint32_t height : 1; - uint32_t hMSL : 1; - uint32_t gSpeed : 1; - uint32_t speed : 1; - uint32_t headMot : 1; - uint32_t headVeh : 1; - uint32_t hAcc : 1; - uint32_t vAcc : 1; - uint32_t sAcc : 1; - uint32_t headAcc : 1; - } bits; - } moduleQueried; -} UBX_HNR_PVT_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_HNR_PVT_data_t data; - UBX_HNR_PVT_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_HNR_PVT_data_t); - void (*callbackPointerPtr)(UBX_HNR_PVT_data_t *); - UBX_HNR_PVT_data_t *callbackData; -} UBX_HNR_PVT_t; - -// UBX-HNR-ATT (0x28 0x01): Attitude solution -const uint16_t UBX_HNR_ATT_LEN = 32; - -typedef struct -{ - uint32_t iTOW; // GPS time of week of the navigation epoch: ms - uint8_t version; - uint8_t reserved1[3]; - int32_t roll; // Vehicle roll: Degrees * 1e-5 - int32_t pitch; // Vehicle pitch: Degrees * 1e-5 - int32_t heading; // Vehicle heading: Degrees * 1e-5 - uint32_t accRoll; // Vehicle roll accuracy: Degrees * 1e-5 - uint32_t accPitch; // Vehicle pitch accuracy: Degrees * 1e-5 - uint32_t accHeading; // Vehicle heading accuracy: Degrees * 1e-5 -} UBX_HNR_ATT_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t iTOW : 1; - uint32_t version : 1; - uint32_t roll : 1; - uint32_t pitch : 1; - uint32_t heading : 1; - uint32_t accRoll : 1; - uint32_t accPitch : 1; - uint32_t accHeading : 1; - } bits; - } moduleQueried; -} UBX_HNR_ATT_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_HNR_ATT_data_t data; - UBX_HNR_ATT_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_HNR_ATT_data_t); - void (*callbackPointerPtr)(UBX_HNR_ATT_data_t *); - UBX_HNR_ATT_data_t *callbackData; -} UBX_HNR_ATT_t; - -// UBX-HNR-INS (0x28 0x02): Vehicle dynamics information -const uint16_t UBX_HNR_INS_LEN = 36; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t version : 8; // Message version (0x00 for this version) - uint32_t xAngRateValid : 1; // Compensated x-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t yAngRateValid : 1; // Compensated y-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t zAngRateValid : 1; // Compensated z-axis angular rate data validity flag (0: not valid, 1: valid) - uint32_t xAccelValid : 1; // Compensated x-axis acceleration data validity flag (0: not valid, 1: valid) - uint32_t yAccelValid : 1; // Compensated y-axis acceleration data validity flag (0: not valid, 1: valid) - uint32_t zAccelValid : 1; // Compensated z-axis acceleration data validity flag (0: not valid, 1: valid) - } bits; - } bitfield0; - uint8_t reserved1[4]; - uint32_t iTOW; // GPS time of week of the HNR epoch: ms - int32_t xAngRate; // Compensated x-axis angular rate: Degrees/s * 1e-3 - int32_t yAngRate; // Compensated y-axis angular rate: Degrees/s * 1e-3 - int32_t zAngRate; // Compensated z-axis angular rate: Degrees/s * 1e-3 - int32_t xAccel; // Compensated x-axis acceleration (with gravity): m/s^2 * 1e-2 - int32_t yAccel; // Compensated y-axis acceleration (with gravity): m/s^2 * 1e-2 - int32_t zAccel; // Compensated z-axis acceleration (with gravity): m/s^2 * 1e-2 -} UBX_HNR_INS_data_t; - -typedef struct -{ - union - { - uint32_t all; - struct - { - uint32_t all : 1; - - uint32_t version : 1; - uint32_t xAngRateValid : 1; - uint32_t yAngRateValid : 1; - uint32_t zAngRateValid : 1; - uint32_t xAccelValid : 1; - uint32_t yAccelValid : 1; - uint32_t zAccelValid : 1; - - uint32_t iTOW : 1; - uint32_t xAngRate : 1; - uint32_t yAngRate : 1; - uint32_t zAngRate : 1; - uint32_t xAccel : 1; - uint32_t yAccel : 1; - uint32_t zAccel : 1; - } bits; - } moduleQueried; -} UBX_HNR_INS_moduleQueried_t; - -typedef struct -{ - ubxAutomaticFlags automaticFlags; - UBX_HNR_INS_data_t data; - UBX_HNR_INS_moduleQueried_t moduleQueried; - void (*callbackPointer)(UBX_HNR_INS_data_t); - void (*callbackPointerPtr)(UBX_HNR_INS_data_t *); - UBX_HNR_INS_data_t *callbackData; -} UBX_HNR_INS_t; - -// NMEA-specific structs - -// Additional flags and pointers that need to be stored with each message type -struct nmeaAutomaticFlags -{ - union - { - uint8_t all; - struct - { - uint8_t completeCopyValid : 1; // Is the copy of the data struct used by the get function valid/fresh? 0 = invalid, 1 = valid - uint8_t completeCopyRead : 1; // Has the complete copy been read? 0 = unread, 1 = read - uint8_t callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh? 0 = invalid/stale, 1 = valid/fresh - } bits; - } flags; -}; - -// The max length for NMEA messages should be 82 bytes, but GGA messages can exceed that if they include the -// extra decimal places for "High Precision Mode". -// -// To be safe, let's allocate 100 bytes to store the GGA message - -const uint8_t NMEA_GGA_MAX_LENGTH = 100; - -typedef struct -{ - uint8_t length; // The number of bytes in nmea - uint8_t nmea[NMEA_GGA_MAX_LENGTH]; -} NMEA_GGA_data_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_GGA_data_t workingCopy; // Incoming data is added to the working copy - NMEA_GGA_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_GGA_data_t); - void (*callbackPointerPtr)(NMEA_GGA_data_t *); - NMEA_GGA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GPGGA_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_GGA_data_t workingCopy; // Incoming data is added to the working copy - NMEA_GGA_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_GGA_data_t); - void (*callbackPointerPtr)(NMEA_GGA_data_t *); - NMEA_GGA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GNGGA_t; - -const uint8_t NMEA_VTG_MAX_LENGTH = 100; - -typedef struct -{ - uint8_t length; // The number of bytes in nmea - uint8_t nmea[NMEA_VTG_MAX_LENGTH]; -} NMEA_VTG_data_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_VTG_data_t workingCopy; // Incoming data is added to the working copy - NMEA_VTG_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_VTG_data_t); - void (*callbackPointerPtr)(NMEA_VTG_data_t *); - NMEA_VTG_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GPVTG_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_VTG_data_t workingCopy; // Incoming data is added to the working copy - NMEA_VTG_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_VTG_data_t); - void (*callbackPointerPtr)(NMEA_VTG_data_t *); - NMEA_VTG_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GNVTG_t; - -const uint8_t NMEA_RMC_MAX_LENGTH = 100; - -typedef struct -{ - uint8_t length; // The number of bytes in nmea - uint8_t nmea[NMEA_RMC_MAX_LENGTH]; -} NMEA_RMC_data_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_RMC_data_t workingCopy; // Incoming data is added to the working copy - NMEA_RMC_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_RMC_data_t); - void (*callbackPointerPtr)(NMEA_RMC_data_t *); - NMEA_RMC_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GPRMC_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_RMC_data_t workingCopy; // Incoming data is added to the working copy - NMEA_RMC_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_RMC_data_t); - void (*callbackPointerPtr)(NMEA_RMC_data_t *); - NMEA_RMC_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GNRMC_t; - -const uint8_t NMEA_ZDA_MAX_LENGTH = 50; - -typedef struct -{ - uint8_t length; // The number of bytes in nmea - uint8_t nmea[NMEA_ZDA_MAX_LENGTH]; -} NMEA_ZDA_data_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_ZDA_data_t workingCopy; // Incoming data is added to the working copy - NMEA_ZDA_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_ZDA_data_t); - void (*callbackPointerPtr)(NMEA_ZDA_data_t *); - NMEA_ZDA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GPZDA_t; - -typedef struct -{ - nmeaAutomaticFlags automaticFlags; - NMEA_ZDA_data_t workingCopy; // Incoming data is added to the working copy - NMEA_ZDA_data_t completeCopy; // The working copy is copied into the complete copy when all data has been received and the checksum is valid - void (*callbackPointer)(NMEA_ZDA_data_t); - void (*callbackPointerPtr)(NMEA_ZDA_data_t *); - NMEA_ZDA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy -} NMEA_GNZDA_t; - -#endif diff --git a/Code/Not_XbeeJoint/test/test.cpp b/Code/Not_XbeeJoint/test/test.cpp index 41e62ea1..6f2416e9 100644 --- a/Code/Not_XbeeJoint/test/test.cpp +++ b/Code/Not_XbeeJoint/test/test.cpp @@ -4,10 +4,12 @@ #include #include "(Not)XBee_Joint.h" + extern "C" { #include "../../libraries/rp2040-console/console.h" #include "../../libraries/rp2040-console/std-cmd/command.h" } + #include "../../libraries/rp2040-drf1262-lib/SX1262.h" #include "hardware/flash.h" #include "hardware/gpio.h" @@ -33,7 +35,7 @@ extern "C" { #endif void rx_test(void); -void transmit_test(void); +void transmit_test(uint8_t *buf, short len); DRF1262 radio(spi0, CS_PIN, SCK_PIN, MOSI_PIN, MISO_PIN, TXEN_PIN, DIO1_PIN, BUSY_PIN, SW_PIN); @@ -89,16 +91,12 @@ int main() { } } -void transmit_test() { +void transmit_test(uint8_t *buf, short len) { printf("Transmit Test\n"); - char data[] = "hello"; - - data[4] = (char)get_rand_32(); + printf("Sending payload: %s\n", buf); - printf("Sending payload: %s\n", data); - - radio.radio_send((uint8_t *)data, 5); + radio.radio_send(buf, len); sleep_ms(100); @@ -115,9 +113,7 @@ void transmit_test() { } void rx_test() { - char data[6] = { - '\0', '\0', '\0', '\0', '\0', '\0', - }; + char data[100] = {0}; printf("Receive Test\n"); @@ -142,7 +138,7 @@ void rx_test() { void no_op_handler(uint8_t *args) { printf("handler not implemented\n"); } void test_handler(uint8_t *args) { printf("handler not implemented\n"); } -void text_handler(uint8_t *args) { printf("handler not implemented\n"); } + void vent_handler(uint8_t *args) { printf("handler not implemented\n"); } void reset_handler(uint8_t *args) { printf("handler not implemented\n"); } void pos_handler(uint8_t *args) { printf("handler not implemented\n"); } @@ -153,6 +149,41 @@ void err_handler(uint8_t *args) { printf("handler not implemented\n"); } void stat_handler(uint8_t *args) { printf("handler not implemented\n"); } void get_handler(uint8_t *args) { printf("handler not implemented\n"); } void set_handler(uint8_t *args) { printf("handler not implemented\n"); } + void help_handler(uint8_t *args) { printf("Enter commands at the promp below\nCommand format: Op-Code args\n"); -} \ No newline at end of file +} + +void send_handler(uint8_t *args) { + int current = 0; + char curr_char = 0; + char buf[100] = {0}; + + printf("\nEnter string to send: "); + + do { + curr_char = getchar_timeout_us(0); + + if (is_valid_char(&curr_char)) { + putchar_raw(curr_char); + + buf[current] = curr_char; + + switch (curr_char) { + case 8: + case 127: + if (current > 0) current--; + break; + default: + current++; + } + } + + } while (curr_char != 0x0A); + + buf[current] = 0; + + transmit_test((uint8_t *)(&buf), sizeof(buf)); +} + +void lstn_handler(uint8_t *args) {} \ No newline at end of file