From c1f95246241c9a84c6f3381666d9fa6245b394a9 Mon Sep 17 00:00:00 2001 From: rislec Date: Fri, 1 Jul 2022 08:38:21 -0400 Subject: [PATCH 1/3] Add missing initialization. --- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index d74ff8b..2860948 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -9842,6 +9842,7 @@ bool SFE_UBLOX_GNSS::initPacketUBXNAVDOP() } packetUBXNAVDOP->automaticFlags.flags.all = 0; packetUBXNAVDOP->callbackPointer = NULL; + packetUBXNAVDOP->callbackPointerPtr = NULL; packetUBXNAVDOP->callbackData = NULL; packetUBXNAVDOP->moduleQueried.moduleQueried.all = 0; return (true); From d2e76e6affbe3d604f1cb8f6adba08f444a7218f Mon Sep 17 00:00:00 2001 From: rislec Date: Fri, 1 Jul 2022 08:53:50 -0400 Subject: [PATCH 2/3] Correct paranthesis. --- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 2860948..88b18b4 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -17458,7 +17458,7 @@ bool SFE_UBLOX_GNSS::getSensorFusionMeasurement(UBX_ESF_MEAS_sensorData_t *senso if (packetUBXESFMEAS == NULL) // Bail if the RAM allocation failed return (false); - if (packetUBXESFMEAS->moduleQueried.moduleQueried.bits.data & ((1 << sensor) == 0)) + if ((packetUBXESFMEAS->moduleQueried.moduleQueried.bits.data & (1 << sensor)) == 0) getESFMEAS(maxWait); packetUBXESFMEAS->moduleQueried.moduleQueried.bits.data &= ~(1 << sensor); // Since we are about to give this to user, mark this data as stale packetUBXESFMEAS->moduleQueried.moduleQueried.bits.all = false; @@ -17479,7 +17479,7 @@ bool SFE_UBLOX_GNSS::getRawSensorMeasurement(UBX_ESF_RAW_sensorData_t *sensorDat if (packetUBXESFRAW == NULL) // Bail if the RAM allocation failed return (false); - if (packetUBXESFRAW->moduleQueried.moduleQueried.bits.data & ((1 << sensor) == 0)) + if ((packetUBXESFRAW->moduleQueried.moduleQueried.bits.data & (1 << sensor)) == 0) getESFRAW(maxWait); packetUBXESFRAW->moduleQueried.moduleQueried.bits.data &= ~(1 << sensor); // Since we are about to give this to user, mark this data as stale packetUBXESFRAW->moduleQueried.moduleQueried.bits.all = false; @@ -17502,7 +17502,7 @@ bool SFE_UBLOX_GNSS::getSensorFusionStatus(UBX_ESF_STATUS_sensorStatus_t *sensor if (packetUBXESFSTATUS == NULL) // Bail if the RAM allocation failed return (false); - if (packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.status & ((1 << sensor) == 0)) + 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; From 2386888962fef2343297a85a718d4b18ba4e9d02 Mon Sep 17 00:00:00 2001 From: rislec Date: Fri, 1 Jul 2022 10:28:47 -0400 Subject: [PATCH 3/3] Add EOE and TIMEUTC messaging. --- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 511 +++++++++++++++++++ src/SparkFun_u-blox_GNSS_Arduino_Library.h | 24 + src/u-blox_structs.h | 32 ++ 3 files changed, 567 insertions(+) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 88b18b4..0c71457 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -1295,6 +1295,10 @@ bool SFE_UBLOX_GNSS::checkAutomatic(uint8_t Class, uint8_t ID) if (packetUBXNAVDOP != NULL) result = true; break; + case UBX_NAV_EOE: + if (packetUBXNAVEOE != NULL) + result = true; + break; case UBX_NAV_ATT: if (packetUBXNAVATT != NULL) result = true; @@ -1307,6 +1311,10 @@ bool SFE_UBLOX_GNSS::checkAutomatic(uint8_t Class, uint8_t ID) if (packetUBXNAVODO != NULL) result = true; break; + case UBX_NAV_TIMEUTC: + if (packetUBXNAVTIMEUTC != NULL) + result = true; + break; case UBX_NAV_VELECEF: if (packetUBXNAVVELECEF != NULL) result = true; @@ -1487,6 +1495,9 @@ uint16_t SFE_UBLOX_GNSS::getMaxPayloadSize(uint8_t Class, uint8_t ID) case UBX_NAV_DOP: maxSize = UBX_NAV_DOP_LEN; break; + case UBX_NAV_EOE: + maxSize = UBX_NAV_EOE_LEN; + break; case UBX_NAV_ATT: maxSize = UBX_NAV_ATT_LEN; break; @@ -1496,6 +1507,9 @@ uint16_t SFE_UBLOX_GNSS::getMaxPayloadSize(uint8_t Class, uint8_t ID) case UBX_NAV_ODO: maxSize = UBX_NAV_ODO_LEN; break; + case UBX_NAV_TIMEUTC: + maxSize = UBX_NAV_TIMEUTC; + break; case UBX_NAV_VELECEF: maxSize = UBX_NAV_VELECEF_LEN; break; @@ -3231,6 +3245,31 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *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); + } + } + } 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 @@ -3349,6 +3388,40 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *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_VELECEF && msg->len == UBX_NAV_VELECEF_LEN) { // Parse various byte fields into storage - but only if we have memory allocated for it @@ -5182,6 +5255,25 @@ void SFE_UBLOX_GNSS::checkCallbacks(void) packetUBXNAVDOP->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->callbackPointer != NULL) // If the pointer to the callback has been defined + { + // if (_printDebug == true) + // _debugSerial->println(F("checkCallbacks: calling callback for NAV EOE")); + packetUBXNAVEOE->callbackPointer(*packetUBXNAVEOE->callbackData); // Call the callback + } + 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 ((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 @@ -5239,6 +5331,25 @@ void SFE_UBLOX_GNSS::checkCallbacks(void) packetUBXNAVODO->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->callbackPointer != NULL) // If the pointer to the callback has been defined + { + // if (_printDebug == true) + // _debugSerial->println(F("checkCallbacks: calling callback for NAV TIMEUTC")); + packetUBXNAVTIMEUTC->callbackPointer(*packetUBXNAVTIMEUTC->callbackData); // Call the callback + } + 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 ((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 @@ -9864,6 +9975,217 @@ void SFE_UBLOX_GNSS::logNAVDOP(bool enabled) packetUBXNAVDOP->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled; } +// ***** EOE automatic support + +bool SFE_UBLOX_GNSS::getEOE(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 + { + // if (_printDebug == true) + // { + // _debugSerial->println(F("getEOE: Polling")); + // } + + // 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) + { + // if (_printDebug == true) + // { + // _debugSerial->println(F("getEOE: data in packetCfg was OVERWRITTEN by another message (but that's OK)")); + // } + return (true); + } + + // if (_printDebug == true) + // { + // _debugSerial->print(F("getEOE retVal: ")); + // _debugSerial->println(statusString(retVal)); + // } + return (false); + } +} + +// Enable or disable automatic navigation message generation by the GNSS. This changes the way getEOE +// works. +bool SFE_UBLOX_GNSS::setAutoEOE(bool enable, uint16_t maxWait) +{ + return setAutoEOErate(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::setAutoEOE(bool enable, bool implicitUpdate, uint16_t maxWait) +{ + return setAutoEOErate(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::setAutoEOErate(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::setAutoEOEcallback(void (*callbackPointer)(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 = setAutoEOE(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("setAutoEOEcallback: RAM alloc failed!")); +#endif + return (false); + } + + packetUBXNAVEOE->callbackPointer = callbackPointer; + return (true); +} + +bool SFE_UBLOX_GNSS::setAutoEOEcallbackPtr(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 = setAutoEOE(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("setAutoEOEcallbackPtr: 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::assumeAutoEOE(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->callbackPointer = NULL; + 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::flushEOE() +{ + 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) @@ -10475,6 +10797,195 @@ void SFE_UBLOX_GNSS::logNAVODO(bool enabled) packetUBXNAVODO->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::setAutoNAVTIMEUTCcallback(void (*callbackPointer)(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("setAutoNAVTIMEUTCcallback: RAM alloc failed!")); +#endif + return (false); + } + + packetUBXNAVTIMEUTC->callbackPointer = callbackPointer; + return (true); +} + +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->callbackPointer = NULL; + 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 VELECEF automatic support bool SFE_UBLOX_GNSS::getNAVVELECEF(uint16_t maxWait) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index a60ee2b..1fbd364 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -1021,6 +1021,16 @@ class SFE_UBLOX_GNSS void flushDOP(); // Mark all the DOP data as read/stale void logNAVDOP(bool enabled = true); // Log data to file buffer + bool getEOE(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 setAutoEOE(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic EOE reports at the navigation frequency + bool setAutoEOE(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 setAutoEOErate(uint8_t rate, bool implicitUpdate, uint16_t maxWait = defaultMaxWait); // Set the rate for automatic EOE reports + bool setAutoEOEcallback(void (*callbackPointer)(UBX_NAV_EOE_data_t), uint16_t maxWait = defaultMaxWait); // Enable automatic EOE reports at the navigation frequency. Data is accessed from the callback. + bool setAutoEOEcallbackPtr(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 assumeAutoEOE(bool enabled, bool implicitUpdate = true); // In case no config access to the GPS is possible and EOE is send cyclically already + void flushEOE(); // Mark all the EOE data as read/stale + void logNAVEOE(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 @@ -1052,6 +1062,16 @@ class SFE_UBLOX_GNSS void flushNAVODO(); // Mark all the data as read/stale void logNAVODO(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 setAutoNAVTIMEUTCcallback(void (*callbackPointer)(UBX_NAV_TIMEUTC_data_t), uint16_t maxWait = defaultMaxWait); // Enable automatic TIMEUTC reports at the navigation frequency. Data is accessed from the callback. + 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 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 @@ -1501,9 +1521,11 @@ class SFE_UBLOX_GNSS 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 @@ -1601,9 +1623,11 @@ class SFE_UBLOX_GNSS 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 initPacketUBXNAVEOE(); // Allocate RAM for packetUBXNAVEOE 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 initPacketUBXNAVTIMEUTC(); // Allocate RAM for packetUBXNAVTIMEUTC 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 diff --git a/src/u-blox_structs.h b/src/u-blox_structs.h index 019aebb..fcaff3f 100644 --- a/src/u-blox_structs.h +++ b/src/u-blox_structs.h @@ -298,6 +298,38 @@ typedef struct UBX_NAV_DOP_data_t *callbackData; } UBX_NAV_DOP_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 (*callbackPointer)(UBX_NAV_EOE_data_t); + void (*callbackPointerPtr)(UBX_NAV_EOE_data_t *); + UBX_NAV_EOE_data_t *callbackData; +} UBX_NAV_EOE_t; + // UBX-NAV-ATT (0x01 0x05): Attitude solution const uint16_t UBX_NAV_ATT_LEN = 32;