diff --git a/examples/Example33_TimeFreqSyncManager/Example33_TimeFreqSyncManager.ino b/examples/Example33_TimeFreqSyncManager/Example33_TimeFreqSyncManager.ino new file mode 100644 index 0000000..5098b41 --- /dev/null +++ b/examples/Example33_TimeFreqSyncManager/Example33_TimeFreqSyncManager.ino @@ -0,0 +1,207 @@ +/* + Configure Time & Frequency Sync manager (UBX-CFG-SMGR) + By: Danylo Ulianych + SparkFun Electronics + Date: March 6th, 2024 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example reads / sets UBX-CFG-SMGR configuration and prints UBX-TIM-SMEAS messages. + Works only with Time & Frequency Sync products like LEA-M8F, etc. + + Feel like supporting open source hardware? + Buy a board from SparkFun! + ZED-F9P RTK2: https://www.sparkfun.com/products/15136 + NEO-M8P RTK: https://www.sparkfun.com/products/15005 + SAM-M8Q: https://www.sparkfun.com/products/15106 + + Hardware Connections: + Plug a Qwiic cable into the GNSS and a BlackBoard + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) + Open the serial monitor at 115200 baud to see the output +*/ + +#include //Needed for I2C to GNSS + +#include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS myGNSS; + + +// Callback: printTIMSMEASdata will be called when new TIM SMEA data arrives +// See u-blox_structs.h for the full definition of UBX_TIM_SMEAS_data_t +// _____ You can use any name you like for the callback. Use the same name when you call setAutoTIMTM2callback +// / _____ This _must_ be UBX_TIM_SMEAS_data_t +// | / _____ You can use any name you like for the struct +// | | / +// | | | +void printTIMSMEASdata(UBX_TIM_SMEAS_data_t smea) +{ + Serial.print("UBX-TIM-SMEAS:"); + Serial.printf("\n version: %u", smea.version); + Serial.printf("\n numMeas: %u", smea.numMeas); + Serial.printf("\n iTOW: %lu", smea.iTOW); + for (int i = 0; i < smea.numMeas; i++) { + Serial.printf("\n sourceId %u:", smea.data[i].sourceId); + Serial.printf("\n flags:"); + Serial.printf("\n freqValid %u", smea.data[i].flags.bits.freqValid); + Serial.printf("\n phaseValid %u", smea.data[i].flags.bits.phaseValid); + Serial.printf("\n phaseOffsetFrac %d", smea.data[i].phaseOffsetFrac); + Serial.printf("\n phaseUncFrac %u", smea.data[i].phaseUncFrac); + Serial.printf("\n phaseOffset %ld", smea.data[i].phaseOffset); + Serial.printf("\n phaseUnc %lu", smea.data[i].phaseUnc); + Serial.printf("\n freqOffset %ld", smea.data[i].freqOffset); + Serial.printf("\n freqUnc %lu", smea.data[i].freqUnc); + } +} + + +UBX_CFG_SMGR_data_t convertRawBufToCfgSmgr(const ubxPacket* msg) { + UBX_CFG_SMGR_data_t smgr; + if (msg->len < sizeof(UBX_CFG_SMGR_data_t)) { + Serial.printf("Payload message size (%zu) is too small to be converted to UBX_CFG_SMGR_data_t\n", msg->len); + return smgr; + } + + smgr.version = SFE_UBLOX_GNSS::extractByte(msg, 0); + smgr.minGNSSFix = SFE_UBLOX_GNSS::extractByte(msg, 1); + smgr.maxFreqChangeRate = SFE_UBLOX_GNSS::extractInt(msg, 2); + smgr.maxPhaseCorrRate = SFE_UBLOX_GNSS::extractInt(msg, 4); + smgr.freqTolerance = SFE_UBLOX_GNSS::extractInt(msg, 8); + smgr.timeTolerance = SFE_UBLOX_GNSS::extractInt(msg, 10); + smgr.messageCfg.all = SFE_UBLOX_GNSS::extractInt(msg, 12); + smgr.maxSlewRate = SFE_UBLOX_GNSS::extractInt(msg, 14); + smgr.flags.all = SFE_UBLOX_GNSS::extractLong(msg, 16); + + return smgr; +} + + +void printUbxCfgSmgr(const UBX_CFG_SMGR_data_t& smgr) { + Serial.printf("\nUBX-CFG-SMGR:"); + Serial.printf("\n version %u (0x%02x)", smgr.version, smgr.version); + Serial.printf("\n minGNSSFix %u (0x%02x)", smgr.minGNSSFix, smgr.minGNSSFix); + Serial.printf("\n maxFreqChangeRate %u (0x%02x)", smgr.maxFreqChangeRate, smgr.maxFreqChangeRate); + Serial.printf("\n maxPhaseCorrRate %u (0x%02x)", smgr.maxPhaseCorrRate, smgr.maxPhaseCorrRate); + Serial.printf("\n freqTolerance %u (0x%02x)", smgr.freqTolerance, smgr.freqTolerance); + Serial.printf("\n timeTolerance %u (0x%02x)", smgr.timeTolerance, smgr.timeTolerance); + Serial.printf("\n messageCfg:"); + Serial.printf("\n measInternal: %u", smgr.messageCfg.bits.measInternal); + Serial.printf("\n measGNSS: %u", smgr.messageCfg.bits.measGNSS); + Serial.printf("\n measEXTINT0: %u", smgr.messageCfg.bits.measEXTINT0); + Serial.printf("\n measEXTINT1: %u", smgr.messageCfg.bits.measEXTINT1); + Serial.printf("\n maxSlewRate %u (0x%02x)", smgr.maxSlewRate, smgr.maxSlewRate); + Serial.printf("\n flags:"); + Serial.printf("\n disableInternal: %u", smgr.flags.bits.disableInternal); + Serial.printf("\n disableExternal: %u", smgr.flags.bits.disableExternal); + Serial.printf("\n preferenceMode: %u", smgr.flags.bits.preferenceMode); + Serial.printf("\n enableGNSS: %u", smgr.flags.bits.enableGNSS); + Serial.printf("\n enableEXTINT0: %u", smgr.flags.bits.enableEXTINT0); + Serial.printf("\n enableEXTINT1: %u", smgr.flags.bits.enableEXTINT1); + Serial.printf("\n enableHostMeasInt: %u", smgr.flags.bits.enableHostMeasInt); + Serial.printf("\n enableHostMeasExt: %u", smgr.flags.bits.enableHostMeasExt); + Serial.printf("\n useAnyFix: %u", smgr.flags.bits.useAnyFix); + Serial.printf("\n disableMaxSlewRate: %u", smgr.flags.bits.disableMaxSlewRate); + Serial.printf("\n issueFreqWarn: %u", smgr.flags.bits.issueFreqWarn); + Serial.printf("\n issueTimeWarn: %u", smgr.flags.bits.issueTimeWarn); + Serial.printf("\n TPCoherent: %u", smgr.flags.bits.TPCoherent); + Serial.printf("\n disableOffset: %u", smgr.flags.bits.disableOffset); + Serial.println("\n"); +} + + +void setup() +{ + Serial.begin(115200); + while (!Serial); // wait for Serial ready + Serial.println("SparkFun u-blox Example"); + + Wire.begin(); + + if (myGNSS.begin() == false) + { + Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } + + myGNSS.setI2COutput(COM_TYPE_UBX); // ignore NMEA messages + + // setPacketCfgPayloadSize tells the library how many bytes our customPayload can hold. + // It is more memory-efficient to call setPacketCfgPayloadSize before .begin (to avoid creating a new buffer, copying across + // the contents of the old buffer and then deleting the old buffer). But let's call it here just to prove that we can. + myGNSS.setPacketCfgPayloadSize(MAX_PAYLOAD_SIZE); + + uint8_t customPayload[MAX_PAYLOAD_SIZE]; // This array holds the payload data bytes. MAX_PAYLOAD_SIZE defaults to 256. The CFG_RATE payload is only 6 bytes! + + // The next line creates and initialises the packet information which wraps around the payload + ubxPacket customCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; + + // The structure of ubxPacket is: + // uint8_t cls : The message Class + // uint8_t id : The message 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 : The payload + // uint8_t checksumA : Given to us by the 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 + + // sendCommand will return: + // SFE_UBLOX_STATUS_DATA_RECEIVED if the data we requested was read / polled successfully + // SFE_UBLOX_STATUS_DATA_SENT if the data we sent was writted successfully (ACK'd) + // Other values indicate errors. Please see the sfe_ublox_status_e enum for further details. + + // Referring to the u-blox M8 Receiver Description and Protocol Specification we see that + // the navigation rate is configured using the UBX-CFG-RATE message. So let's load our + // custom packet with the correct information so we can read (poll / get) the current settings. + + customCfg.cls = UBX_CLASS_CFG; // This is the message Class + customCfg.id = UBX_CFG_SMGR; // This is the message ID + customCfg.len = 0; // Setting the len (length) to zero let's us poll the current settings + customCfg.startingSpot = 0; // Always set the startingSpot to zero (unless you really know what you are doing) + + // We also need to tell sendCommand how long it should wait for a reply + uint16_t maxWait = 250; // Wait for up to 250ms (Serial may need a lot longer e.g. 1100) + + // Now let's read the current UBX-CFG-SMGR settings. The results will be loaded into customCfg. + if (myGNSS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK + { + Serial.println(F("sendCommand (poll / get) failed! Freezing...")); + while (1) + ; + } + + UBX_CFG_SMGR_data_t cfgSmgrPayload = convertRawBufToCfgSmgr(&customCfg); + + printUbxCfgSmgr(cfgSmgrPayload); + + cfgSmgrPayload.minGNSSFix = 5; // update the min no. of GNSS fixes to start freq/phase sync + cfgSmgrPayload.flags.bits.useAnyFix = 1; // use any fix + + // update the raw payload buffer + memmove(customPayload, &cfgSmgrPayload, sizeof(UBX_CFG_SMGR_data_t)); + + // Now let's set the updated settings. + if (myGNSS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_SENT) // We are expecting data and an ACK + { + Serial.println(F("sendCommand set failed! Freezing...")); + while (1) + ; + } + + Serial.println("UBX-CFG-SMGR successfully updated"); + + myGNSS.setAutoTIMSMEAcallback(&printTIMSMEASdata); + + // Enable info/warns messages + // myGNSS.setVal8(UBLOX_CFG_INFMSG_UBX_I2C, 1); +} + +void loop() +{ + myGNSS.checkUblox(); //See if new UBX data is available. Process bytes as they come in. + myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed. + + delay(250); //Don't pound too hard on the I2C bus +} diff --git a/keys/u-blox-M9-MDR-2.16_InterfaceDescription_UBX-22037308.txt b/keys/u-blox-M9-MDR-2.16_InterfaceDescription_UBX-22037308.txt new file mode 100644 index 0000000..9b2e075 --- /dev/null +++ b/keys/u-blox-M9-MDR-2.16_InterfaceDescription_UBX-22037308.txt @@ -0,0 +1,806 @@ +0x10050007 +0x10050008 +0x10050009 +0x1005000a +0x1005000b +0x10050012 +0x10050013 +0x10050014 +0x10050015 +0x10050016 +0x1006001d +0x10060027 +0x10070001 +0x10070003 +0x10070004 +0x10070005 +0x10070006 +0x1007000d +0x1007000f +0x10070010 +0x10070011 +0x1007001c +0x10080001 +0x10110013 +0x10110025 +0x10110061 +0x10170001 +0x10170002 +0x10220001 +0x10220002 +0x10220003 +0x10220004 +0x10240012 +0x10240020 +0x10240030 +0x10240040 +0x10240050 +0x10310001 +0x10310005 +0x10310007 +0x1031000d +0x10310012 +0x10310014 +0x10310018 +0x1031001f +0x10310020 +0x10310021 +0x10310022 +0x10310024 +0x10310025 +0x10340014 +0x10360002 +0x10360003 +0x10360004 +0x10360005 +0x10360007 +0x10370005 +0x10370006 +0x10370007 +0x10510002 +0x10510003 +0x10520005 +0x10530005 +0x10640002 +0x10640003 +0x10640005 +0x10640006 +0x10650001 +0x10650002 +0x10710001 +0x10710002 +0x10720001 +0x10720002 +0x10730001 +0x10730002 +0x10740001 +0x10740002 +0x10750001 +0x10750002 +0x10760001 +0x10760002 +0x10770001 +0x10770002 +0x10780001 +0x10780002 +0x10790001 +0x10790002 +0x107a0001 +0x107a0002 +0x10930003 +0x10930004 +0x10930005 +0x10930006 +0x10930011 +0x10930012 +0x10930013 +0x10930015 +0x10930016 +0x10930017 +0x10930021 +0x10930022 +0x10930023 +0x10930024 +0x10930025 +0x10930026 +0x10a20001 +0x10a20002 +0x10a3002e +0x10a3002f +0x10a30030 +0x10a30031 +0x10a30032 +0x10a30033 +0x10a30034 +0x10a30035 +0x10c70001 +0x10c70002 +0x10f60009 +0x10f60051 +0x2005000c +0x20050017 +0x20050023 +0x20050030 +0x20050035 +0x20050036 +0x20060008 +0x20060009 +0x20060015 +0x20060016 +0x2006001e +0x2006001f +0x2007000b +0x20110011 +0x2011001c +0x20110021 +0x201100a1 +0x201100a2 +0x201100a3 +0x201100a4 +0x201100aa +0x201100ab +0x201100c4 +0x201100d6 +0x20210003 +0x20210004 +0x20220005 +0x20220021 +0x20220022 +0x20220031 +0x20220032 +0x20240011 +0x20240013 +0x20240014 +0x20250038 +0x20510001 +0x20520002 +0x20520003 +0x20520004 +0x20530002 +0x20530003 +0x20530004 +0x20640001 +0x20910006 +0x20910007 +0x20910008 +0x20910009 +0x2091000a +0x20910010 +0x20910011 +0x20910012 +0x20910013 +0x20910014 +0x20910015 +0x20910016 +0x20910017 +0x20910018 +0x20910019 +0x2091001a +0x2091001b +0x2091001c +0x2091001d +0x2091001e +0x2091001f +0x20910020 +0x20910021 +0x20910022 +0x20910023 +0x20910024 +0x20910025 +0x20910026 +0x20910027 +0x20910028 +0x20910029 +0x2091002a +0x2091002b +0x2091002c +0x2091002d +0x20910038 +0x20910039 +0x2091003a +0x2091003b +0x2091003c +0x2091003d +0x2091003e +0x2091003f +0x20910040 +0x20910041 +0x20910042 +0x20910043 +0x20910044 +0x20910045 +0x20910046 +0x20910047 +0x20910048 +0x20910049 +0x2091004a +0x2091004b +0x2091004c +0x2091004d +0x2091004e +0x2091004f +0x20910050 +0x20910051 +0x20910052 +0x20910053 +0x20910054 +0x20910055 +0x20910056 +0x20910057 +0x20910058 +0x20910059 +0x2091005a +0x2091005b +0x2091005c +0x2091005d +0x2091005e +0x2091005f +0x20910060 +0x20910061 +0x20910062 +0x20910063 +0x20910064 +0x20910065 +0x20910066 +0x20910067 +0x20910068 +0x20910069 +0x2091006a +0x2091006b +0x2091006c +0x2091006d +0x2091006e +0x2091007e +0x2091007f +0x20910080 +0x20910081 +0x20910082 +0x20910083 +0x20910084 +0x20910085 +0x20910086 +0x20910087 +0x20910092 +0x20910093 +0x20910094 +0x20910095 +0x20910096 +0x209100a1 +0x209100a2 +0x209100a3 +0x209100a4 +0x209100a5 +0x209100a6 +0x209100a7 +0x209100a8 +0x209100a9 +0x209100aa +0x209100ab +0x209100ac +0x209100ad +0x209100ae +0x209100af +0x209100b0 +0x209100b1 +0x209100b2 +0x209100b3 +0x209100b4 +0x209100b5 +0x209100b6 +0x209100b7 +0x209100b8 +0x209100b9 +0x209100ba +0x209100bb +0x209100bc +0x209100bd +0x209100be +0x209100bf +0x209100c0 +0x209100c1 +0x209100c2 +0x209100c3 +0x209100c4 +0x209100c5 +0x209100c6 +0x209100c7 +0x209100c8 +0x209100c9 +0x209100ca +0x209100cb +0x209100cc +0x209100cd +0x209100ce +0x209100cf +0x209100d0 +0x209100d1 +0x209100d2 +0x209100d3 +0x209100d4 +0x209100d5 +0x209100d6 +0x209100d7 +0x209100d8 +0x209100d9 +0x209100da +0x209100db +0x209100dc +0x209100dd +0x209100de +0x209100df +0x209100e0 +0x209100e1 +0x209100e2 +0x209100e3 +0x209100e4 +0x209100e5 +0x209100e6 +0x209100e7 +0x209100e8 +0x209100e9 +0x209100ea +0x209100eb +0x209100ec +0x209100ed +0x209100ee +0x209100ef +0x209100f0 +0x209100f1 +0x209100f2 +0x209100f3 +0x209100f4 +0x209100f5 +0x209100f6 +0x209100f7 +0x209100f8 +0x209100f9 +0x209100fa +0x20910105 +0x20910106 +0x20910107 +0x20910108 +0x20910109 +0x2091010f +0x20910110 +0x20910111 +0x20910112 +0x20910113 +0x20910114 +0x20910115 +0x20910116 +0x20910117 +0x20910118 +0x2091015f +0x20910160 +0x20910161 +0x20910162 +0x20910163 +0x20910178 +0x20910179 +0x2091017a +0x2091017b +0x2091017c +0x2091017d +0x2091017e +0x2091017f +0x20910180 +0x20910181 +0x20910187 +0x20910188 +0x20910189 +0x2091018a +0x2091018b +0x20910196 +0x20910197 +0x20910198 +0x20910199 +0x2091019a +0x2091019b +0x2091019c +0x2091019d +0x2091019e +0x2091019f +0x209101a0 +0x209101a1 +0x209101a2 +0x209101a3 +0x209101a4 +0x209101a5 +0x209101a6 +0x209101a7 +0x209101a8 +0x209101a9 +0x209101b4 +0x209101b5 +0x209101b6 +0x209101b7 +0x209101b8 +0x209101b9 +0x209101ba +0x209101bb +0x209101bc +0x209101bd +0x20910204 +0x20910205 +0x20910206 +0x20910207 +0x20910208 +0x20910231 +0x20910232 +0x20910233 +0x20910234 +0x20910235 +0x2091025e +0x2091025f +0x20910260 +0x20910261 +0x20910262 +0x20910277 +0x20910278 +0x20910279 +0x2091027a +0x2091027b +0x2091029f +0x209102a0 +0x209102a1 +0x209102a2 +0x209102a3 +0x209102a4 +0x209102a5 +0x209102a6 +0x209102a7 +0x209102a8 +0x20910313 +0x20910314 +0x20910315 +0x20910316 +0x20910317 +0x20910336 +0x20910337 +0x20910338 +0x20910339 +0x2091033a +0x20910345 +0x20910346 +0x20910347 +0x20910348 +0x20910349 +0x2091034f +0x20910350 +0x20910351 +0x20910352 +0x20910353 +0x20910354 +0x20910355 +0x20910356 +0x20910357 +0x20910358 +0x20910359 +0x2091035a +0x2091035b +0x2091035c +0x2091035d +0x20910386 +0x20910387 +0x20910388 +0x20910389 +0x2091038a +0x2091038b +0x2091038c +0x2091038d +0x2091038e +0x2091038f +0x20910400 +0x20910401 +0x20910402 +0x20910403 +0x20910404 +0x20910430 +0x20910431 +0x20910432 +0x20910433 +0x20910434 +0x20910435 +0x20910436 +0x20910437 +0x20910438 +0x20910439 +0x20910465 +0x20910466 +0x20910467 +0x20910468 +0x20910469 +0x20910470 +0x20910471 +0x20910472 +0x20910473 +0x20910474 +0x20910475 +0x20910476 +0x20910477 +0x20910478 +0x20910479 +0x20910480 +0x20910481 +0x20910482 +0x20910483 +0x20910484 +0x20910485 +0x20910486 +0x20910487 +0x20910488 +0x20910489 +0x20910490 +0x20910491 +0x20910492 +0x20910493 +0x20910494 +0x20910495 +0x20910496 +0x20910497 +0x20910498 +0x20910499 +0x20910500 +0x20910501 +0x20910502 +0x20910503 +0x20910504 +0x20910505 +0x20910506 +0x20910507 +0x20910508 +0x20910509 +0x20910510 +0x20910511 +0x20910512 +0x20910513 +0x20910514 +0x20910515 +0x20910516 +0x20910517 +0x20910518 +0x20910519 +0x20910525 +0x20910526 +0x20910527 +0x20910528 +0x20910529 +0x20910530 +0x20910531 +0x20910532 +0x20910533 +0x20910534 +0x20910535 +0x20910536 +0x20910537 +0x20910538 +0x20910539 +0x20910540 +0x20910541 +0x20910542 +0x20910543 +0x20910544 +0x20910545 +0x20910546 +0x20910547 +0x20910548 +0x20910549 +0x20910550 +0x20910551 +0x20910552 +0x20910553 +0x20910554 +0x20910555 +0x20910556 +0x20910557 +0x20910558 +0x20910559 +0x20910560 +0x20910561 +0x20910562 +0x20910563 +0x20910564 +0x20910565 +0x20910566 +0x20910567 +0x20910568 +0x20910569 +0x20910575 +0x20910576 +0x20910577 +0x20910578 +0x20910579 +0x2091062a +0x2091062b +0x2091062c +0x2091062d +0x2091062e +0x2091062f +0x20910630 +0x20910631 +0x20910632 +0x20910633 +0x20910634 +0x20910635 +0x20910636 +0x20910637 +0x20910638 +0x20910652 +0x20910653 +0x20910654 +0x20910655 +0x20910656 +0x20910657 +0x20910658 +0x20910659 +0x2091065a +0x2091065b +0x2091065c +0x2091065d +0x2091065e +0x2091065f +0x20910660 +0x20910661 +0x20910662 +0x20910663 +0x20910664 +0x20910665 +0x20910666 +0x20910667 +0x20910668 +0x20910669 +0x2091066a +0x20910670 +0x20910671 +0x20910672 +0x20910673 +0x20910674 +0x2091067f +0x20910680 +0x20910681 +0x20910682 +0x20910683 +0x20910689 +0x2091068a +0x2091068b +0x2091068c +0x2091068d +0x2091069d +0x2091069e +0x2091069f +0x209106a0 +0x209106a1 +0x209106ac +0x209106ad +0x209106ae +0x209106af +0x209106b0 +0x20920001 +0x20920002 +0x20920003 +0x20920004 +0x20920005 +0x20920006 +0x20920007 +0x20920008 +0x20920009 +0x2092000a +0x20930001 +0x20930002 +0x20930007 +0x20930031 +0x20930032 +0x20a20003 +0x20a20005 +0x20a30036 +0x20a30037 +0x20a30038 +0x20a30054 +0x20a30055 +0x20a30056 +0x20a30063 +0x20a30064 +0x20c70003 +0x30050001 +0x30060007 +0x3006000a +0x3006000b +0x30060017 +0x30060018 +0x30060020 +0x30060021 +0x30060022 +0x3006002e +0x3006002f +0x3007000a +0x3007000e +0x30070012 +0x30070013 +0x30070014 +0x30080002 +0x30080003 +0x30080004 +0x30110017 +0x301100b1 +0x301100b2 +0x301100b3 +0x301100b4 +0x301100b5 +0x30210001 +0x30210002 +0x30250016 +0x3025003b +0x30360008 +0x30370008 +0x3065000a +0x3065000b +0x3065000c +0x30930033 +0x30a20004 +0x30a3003c +0x30f6000a +0x30f6000b +0x40050002 +0x40050003 +0x40050004 +0x40050005 +0x40050006 +0x4005000d +0x4005000e +0x4005000f +0x40050010 +0x40050011 +0x40050024 +0x40050025 +0x40050026 +0x40050027 +0x4006002d +0x40070007 +0x40070008 +0x40070009 +0x40110064 +0x40110065 +0x40110066 +0x40110067 +0x40110068 +0x40110069 +0x4011006a +0x401100c1 +0x401100c2 +0x40240021 +0x40240022 +0x40240023 +0x40240031 +0x40240032 +0x40240033 +0x40240041 +0x40240042 +0x40240043 +0x40240051 +0x40240052 +0x40240053 +0x40520001 +0x40530001 +0x5005002a +0x5005002b +0x5005002c +0x5005002d +0x50110062 +0x50110063 +0x50360006 +0x5065000d +0x5065000e +0x5065000f +0x50650010 +0x50650011 +0x50650012 +0x50650013 +0x50650014 +0x50650015 +0x50650016 +0x50650017 +0x50650018 +0x50c70004 +0x50c70005 +0x50c70006 +0x50c70007 diff --git a/keys/u-blox_config_keys_sorted.txt b/keys/u-blox_config_keys_sorted.txt index 0e4a7a9..1be6657 100644 --- a/keys/u-blox_config_keys_sorted.txt +++ b/keys/u-blox_config_keys_sorted.txt @@ -19,6 +19,7 @@ 0x1007000f 0x10070010 0x10070011 +0x1007001c 0x10080001 0x10110013 0x10110019 @@ -64,6 +65,7 @@ 0x10360003 0x10360004 0x10360005 +0x10360007 0x10370005 0x10370006 0x10370007 @@ -153,6 +155,7 @@ 0x10de0003 0x10de0004 0x10f60009 +0x10f60051 0x20030001 0x20030002 0x20030006 @@ -674,6 +677,11 @@ 0x20910467 0x20910468 0x20910469 +0x20910470 +0x20910471 +0x20910472 +0x20910473 +0x20910474 0x20910475 0x20910476 0x20910477 @@ -794,6 +802,11 @@ 0x2091062c 0x2091062d 0x2091062e +0x2091062f +0x20910630 +0x20910631 +0x20910632 +0x20910633 0x20910634 0x20910635 0x20910636 @@ -844,6 +857,11 @@ 0x2091069f 0x209106a0 0x209106a1 +0x209106ac +0x209106ad +0x209106ae +0x209106af +0x209106b0 0x209106b6 0x209106b7 0x209106b8 @@ -872,6 +890,8 @@ 0x20a30054 0x20a30055 0x20a30056 +0x20a30063 +0x20a30064 0x20a70001 0x20c70003 0x20d0000b @@ -881,10 +901,19 @@ 0x3006000b 0x30060017 0x30060018 +0x30060020 +0x30060021 +0x30060022 0x3006002e 0x3006002f 0x3007000a 0x3007000e +0x30070012 +0x30070013 +0x30070014 +0x30080002 +0x30080003 +0x30080004 0x30090001 0x30090008 0x30110017 @@ -895,13 +924,16 @@ 0x301100b5 0x30210001 0x30210002 +0x30250016 0x3025003b +0x30360008 0x30370008 0x3065000a 0x3065000b 0x3065000c 0x30930033 0x30a20004 +0x30a3003c 0x30b10012 0x30b10013 0x30b10015 diff --git a/keywords.txt b/keywords.txt index 92afc5e..de2ffd6 100644 --- a/keywords.txt +++ b/keywords.txt @@ -21,6 +21,7 @@ UBX_CFG_RATE_data_t KEYWORD1 UBX_CFG_TP5_data_t KEYWORD1 UBX_CFG_ITFM_data_t KEYWORD1 UBX_CFG_TMODE3_data_t KEYWORD1 +UBX_CFG_SMGR_data_t KEYWORD1 UBX_MON_RF_data_t KEYWORD1 UBX_MON_HW_data_t KEYWORD1 @@ -55,6 +56,7 @@ UBX_RXM_RAWX_data_t KEYWORD1 UBX_RXM_QZSSL6_message_data_t KEYWORD1 UBX_TIM_TM2_data_t KEYWORD1 +UBX_TIM_SMEAS_data_t KEYWORD1 UBX_ESF_ALG_data_t KEYWORD1 UBX_ESF_INS_data_t KEYWORD1 @@ -459,6 +461,11 @@ assumeAutoTIMTM2 KEYWORD2 flushTIMTM2 KEYWORD2 logTIMTM2 KEYWORD2 +setAutoTIMSMEA KEYWORD2 +setAutoTIMSMEAcallback KEYWORD2 +flushTIMSMEA KEYWORD2 +logTIMSMEA KEYWORD2 + getEsfAlignment KEYWORD2 getESFALG KEYWORD2 setAutoESFALG KEYWORD2 @@ -812,6 +819,7 @@ UBX_RXM_SPARTN LITERAL1 UBX_RXM_QZSSL6 LITERAL1 UBX_TIM_TM2 LITERAL1 +UBX_TIM_SMEAS LITERAL1 UBX_RTCM_MSB LITERAL1 UBX_RTCM_1005 LITERAL1 diff --git a/library.properties b/library.properties index 14ab073..1fd6258 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun u-blox GNSS Arduino Library -version=2.2.27 +version=2.2.28 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=Library for I2C, Serial and SPI Communication with u-blox GNSS modules

diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 943340e..4ed6325 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -397,6 +397,16 @@ void SFE_UBLOX_GNSS::end(void) packetUBXTIMTM2 = NULL; // Redundant? } + if (packetUBXTIMSMEAS != NULL) + { + if (packetUBXTIMSMEAS->callbackData != NULL) + { + delete packetUBXTIMSMEAS->callbackData; + } + delete packetUBXTIMSMEAS; + packetUBXTIMSMEAS = NULL; // Redundant + } + if (packetUBXESFALG != NULL) { if (packetUBXESFALG->callbackData != NULL) @@ -1448,6 +1458,10 @@ bool SFE_UBLOX_GNSS::checkAutomatic(uint8_t Class, uint8_t ID) if (packetUBXTIMTM2 != NULL) result = true; break; + case UBX_TIM_SMEAS: + if (packetUBXTIMSMEAS != NULL) + result = true; + break; } } break; @@ -1628,6 +1642,9 @@ uint16_t SFE_UBLOX_GNSS::getMaxPayloadSize(uint8_t Class, uint8_t ID) case UBX_TIM_TM2: maxSize = UBX_TIM_TM2_LEN; break; + case UBX_TIM_SMEAS: + maxSize = UBX_TIM_SMEAS_MAX_LEN; + break; } } break; @@ -4153,7 +4170,7 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg) 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)); + memcpy(packetUBXTIMTM2->callbackData, &packetUBXTIMTM2->data, sizeof(UBX_TIM_TM2_data_t)); packetUBXTIMTM2->automaticFlags.flags.bits.callbackCopyValid = true; } @@ -4164,6 +4181,45 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg) } } } + else if (msg->id == UBX_TIM_SMEAS && msg->len <= UBX_TIM_SMEAS_MAX_LEN) + { + // Parse various byte fields into storage - but only if we have memory allocated for it + if (packetUBXTIMSMEAS != NULL) + { + + packetUBXTIMSMEAS->data.version = extractByte(msg, 0); + packetUBXTIMSMEAS->data.numMeas = extractByte(msg, 1); + packetUBXTIMSMEAS->data.iTOW = extractLong(msg, 4); + + for (int i = 0; i < packetUBXTIMSMEAS->data.numMeas; i++) { + packetUBXTIMSMEAS->data.data[i].sourceId = extractByte(msg, 12 + 24 * i); + packetUBXTIMSMEAS->data.data[i].flags.all = extractByte(msg, 13 + 24 * i); + packetUBXTIMSMEAS->data.data[i].phaseOffsetFrac = extractSignedChar(msg, 14 + 24 * i); + packetUBXTIMSMEAS->data.data[i].phaseUncFrac = extractByte(msg, 15 + 24 * i); + packetUBXTIMSMEAS->data.data[i].phaseOffset = extractSignedLong(msg, 16 + 24 * i); + packetUBXTIMSMEAS->data.data[i].phaseUnc = extractLong(msg, 20 + 24 * i); + packetUBXTIMSMEAS->data.data[i].freqOffset = extractSignedLong(msg, 28 + 24 * i); + packetUBXTIMSMEAS->data.data[i].freqUnc = extractLong(msg, 32 + 24 * i); + } + + // Mark all datums as fresh (not read before) + packetUBXTIMSMEAS->moduleQueried.moduleQueried.all = 0xFFFFFFFF; + + // Check if we need to copy the data for the callback + if ((packetUBXTIMSMEAS->callbackData != NULL) // If RAM has been allocated for the copy of the data + && (packetUBXTIMSMEAS->automaticFlags.flags.bits.callbackCopyValid == false)) // AND the data is stale + { + memcpy(packetUBXTIMSMEAS->callbackData, &packetUBXTIMSMEAS->data, sizeof(UBX_TIM_SMEAS_data_t)); + packetUBXTIMSMEAS->automaticFlags.flags.bits.callbackCopyValid = true; + } + + // Check if we need to copy the data into the file buffer + if (packetUBXTIMSMEAS->automaticFlags.flags.bits.addToFileBuffer) + { + storePacket(msg); + } + } + } break; case UBX_CLASS_ESF: if (msg->id == UBX_ESF_ALG && msg->len == UBX_ESF_ALG_LEN) @@ -5703,6 +5759,19 @@ void SFE_UBLOX_GNSS::checkCallbacks(void) packetUBXTIMTM2->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale } + if ((packetUBXTIMSMEAS != NULL) // If RAM has been allocated for message storage + && (packetUBXTIMSMEAS->callbackData != NULL) // If RAM has been allocated for the copy of the data + && (packetUBXTIMSMEAS->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid + { + if (packetUBXTIMSMEAS->callbackPointer != NULL) // If the pointer to the callback has been defined + { + // if (_printDebug == true) + // _debugSerial->println(F("checkCallbacks: calling callback for TIM SMEA")); + packetUBXTIMSMEAS->callbackPointer(*packetUBXTIMSMEAS->callbackData); // Call the callback + } + packetUBXTIMSMEAS->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 @@ -14185,6 +14254,60 @@ bool SFE_UBLOX_GNSS::setAutoTIMTM2rate(uint8_t rate, bool implicitUpdate, uint16 return ok; } + +bool SFE_UBLOX_GNSS::setAutoTIMSMEA(bool enabled, bool implicitUpdate, uint16_t maxWait) +{ + if (packetUBXTIMSMEAS == NULL) + initPacketUBXTIMSMEA(); // Check that RAM has been allocated for the data + if (packetUBXTIMSMEAS == NULL) // Only attempt this if RAM allocation was successful + return false; + + uint8_t rate = enabled ? 1 : 0; + + 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_SMEAS; + 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) + { + packetUBXTIMSMEAS->automaticFlags.flags.bits.automatic = (rate > 0); + packetUBXTIMSMEAS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; + } + packetUBXTIMSMEAS->moduleQueried.moduleQueried.bits.all = false; + return ok; +} + + +bool SFE_UBLOX_GNSS::setAutoTIMSMEAcallback(void (*callbackPointer)(UBX_TIM_SMEAS_data_t), uint16_t maxWait) { + // Enable auto messages. Set implicitUpdate to false as we expect the user to call checkUblox manually. + bool result = setAutoTIMSMEA(true, false, maxWait); + if (!result) + return (result); // Bail if setAuto failed + + if (packetUBXTIMSMEAS->callbackData == NULL) // Check if RAM has been allocated for the callback copy + { + packetUBXTIMSMEAS->callbackData = new UBX_TIM_SMEAS_data_t; // Allocate RAM for the main struct + } + + if (packetUBXTIMSMEAS->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("setAutoTIMSMEAcallback: RAM alloc failed!")); +#endif + return (false); + } + + packetUBXTIMSMEAS->callbackPointer = callbackPointer; + return (true); +} + + // Enable automatic navigation message generation by the GNSS. bool SFE_UBLOX_GNSS::setAutoTIMTM2callback(void (*callbackPointer)(UBX_TIM_TM2_data_t), uint16_t maxWait) { @@ -14254,6 +14377,25 @@ bool SFE_UBLOX_GNSS::assumeAutoTIMTM2(bool enabled, bool implicitUpdate) return changes; } +// PRIVATE: Allocate RAM for packetUBXTIMSMEA and initialize it +bool SFE_UBLOX_GNSS::initPacketUBXTIMSMEA() +{ + packetUBXTIMSMEAS = new UBX_TIM_SMEAS_t; // Allocate RAM for the main struct + if (packetUBXTIMSMEAS == NULL) + { +#ifndef SFE_UBLOX_REDUCED_PROG_MEM + if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging + _debugSerial->println(F("initPacketUBXTIMSMEA: RAM alloc failed!")); +#endif + return (false); + } + packetUBXTIMSMEAS->automaticFlags.flags.all = 0; + packetUBXTIMSMEAS->callbackPointer = NULL; + packetUBXTIMSMEAS->callbackData = NULL; + packetUBXTIMSMEAS->moduleQueried.moduleQueried.all = 0; + return (true); +} + // PRIVATE: Allocate RAM for packetUBXTIMTM2 and initialize it bool SFE_UBLOX_GNSS::initPacketUBXTIMTM2() { @@ -14282,6 +14424,14 @@ void SFE_UBLOX_GNSS::flushTIMTM2() packetUBXTIMTM2->moduleQueried.moduleQueried.all = 0; // Mark all datums as stale (read before) } +// Mark all the data as read/stale +void SFE_UBLOX_GNSS::flushTIMSMEA() +{ + if (packetUBXTIMSMEAS == NULL) + return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!) + packetUBXTIMSMEAS->moduleQueried.moduleQueried.all = 0; // Mark all datums as stale (read before) +} + // Log this data in file buffer void SFE_UBLOX_GNSS::logTIMTM2(bool enabled) { @@ -14290,6 +14440,14 @@ void SFE_UBLOX_GNSS::logTIMTM2(bool enabled) packetUBXTIMTM2->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled; } +// Log this data in file buffer +void SFE_UBLOX_GNSS::logTIMSMEA(bool enabled) +{ + if (packetUBXTIMSMEAS == NULL) + return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!) + packetUBXTIMSMEAS->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled; +} + // ***** ESF ALG automatic support bool SFE_UBLOX_GNSS::getEsfAlignment(uint16_t maxWait) @@ -18552,7 +18710,7 @@ float SFE_UBLOX_GNSS::getHNRheading(uint16_t maxWait) // Returned as degrees // 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 SFE_UBLOX_GNSS::extractLongLong(const ubxPacket *msg, uint16_t spotToStart) { uint64_t val = 0; val |= (uint64_t)msg->payload[spotToStart + 0] << 8 * 0; @@ -18567,7 +18725,7 @@ uint64_t SFE_UBLOX_GNSS::extractLongLong(ubxPacket *msg, uint16_t spotToStart) } // 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 SFE_UBLOX_GNSS::extractLong(const ubxPacket *msg, uint16_t spotToStart) { uint32_t val = 0; val |= (uint32_t)msg->payload[spotToStart + 0] << 8 * 0; @@ -18578,7 +18736,7 @@ uint32_t SFE_UBLOX_GNSS::extractLong(ubxPacket *msg, uint16_t spotToStart) } // 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) +int32_t SFE_UBLOX_GNSS::extractSignedLong(const ubxPacket *msg, uint16_t spotToStart) { union // Use a union to convert from uint32_t to int32_t { @@ -18591,7 +18749,7 @@ int32_t SFE_UBLOX_GNSS::extractSignedLong(ubxPacket *msg, uint16_t spotToStart) } // 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 SFE_UBLOX_GNSS::extractInt(const ubxPacket *msg, uint16_t spotToStart) { uint16_t val = 0; val |= (uint16_t)msg->payload[spotToStart + 0] << 8 * 0; @@ -18600,7 +18758,7 @@ uint16_t SFE_UBLOX_GNSS::extractInt(ubxPacket *msg, uint16_t spotToStart) } // 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) +int16_t SFE_UBLOX_GNSS::extractSignedInt(const ubxPacket *msg, uint16_t spotToStart) { union // Use a union to convert from uint16_t to int16_t { @@ -18613,13 +18771,13 @@ int16_t SFE_UBLOX_GNSS::extractSignedInt(ubxPacket *msg, uint16_t spotToStart) } // Given a spot, extract a byte from the payload -uint8_t SFE_UBLOX_GNSS::extractByte(ubxPacket *msg, uint16_t spotToStart) +uint8_t SFE_UBLOX_GNSS::extractByte(const 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) +int8_t SFE_UBLOX_GNSS::extractSignedChar(const ubxPacket *msg, uint16_t spotToStart) { union // Use a union to convert from uint8_t to int8_t { diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index c0ac083..0f21c44 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -231,6 +231,7 @@ 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_SMGR = 0x62; // Synchronization manager 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 @@ -411,10 +412,17 @@ const uint8_t UBX_RXM_SPARTNKEY = 0x36; // Poll/transfer dynamic SPARTN keys 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 +// The following are used to configure the TIM UBX messages (timing messages). Descriptions from UBX messages overview (u-blox M8 Protocol Specification Document page 178) +const uint8_t UBX_TIM_DOSC = 0x11; // Disciplined oscillator control +const uint8_t UBX_TIM_FCHG = 0x16; // Oscillator freq changed notification +const uint8_t UBX_TIM_HOC = 0x17; // Host oscillator control +const uint8_t UBX_TIM_SMEAS = 0x13; // Source measurement +const uint8_t UBX_TIM_SVIN = 0x04; // Survey-in data +const uint8_t UBX_TIM_TM2 = 0x03; // Time mark data +const uint8_t UBX_TIM_TOS = 0x12; // Time Pulse time and freq data +const uint8_t UBX_TIM_TP = 0x01; // Time Pulse time data +const uint8_t UBX_TIM_VCOCAL = 0x15; // Calibration +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) @@ -1291,6 +1299,11 @@ class SFE_UBLOX_GNSS void flushTIMTM2(); // Mark all the data as read/stale void logTIMTM2(bool enabled = true); // Log data to file buffer + bool setAutoTIMSMEA(bool enabled, bool implicitUpdate, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic TIM SMEA 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 setAutoTIMSMEAcallback(void (*callbackPointer)(UBX_TIM_SMEAS_data_t), uint16_t maxWait = defaultMaxWait); // Enable automatic SMEA reports at the navigation frequency. Data is accessed from the callback. + void flushTIMSMEA(); // Mark all the data as read/stale + void logTIMSMEA(bool enabled = true); // Log data to file buffer + // Sensor fusion (dead reckoning) (ESF) bool getEsfAlignment(uint16_t maxWait = defaultMaxWait); // ESF ALG Helper @@ -1574,13 +1587,13 @@ class SFE_UBLOX_GNSS // 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 + static uint64_t extractLongLong(const ubxPacket *msg, uint16_t spotToStart); // Combine eight bytes from payload into uint64_t + static uint32_t extractLong(const ubxPacket *msg, uint16_t spotToStart); // Combine four bytes from payload into long + static int32_t extractSignedLong(const ubxPacket *msg, uint16_t spotToStart); // Combine four bytes from payload into signed long (avoiding any ambiguity caused by casting) + static uint16_t extractInt(const ubxPacket *msg, uint16_t spotToStart); // Combine two bytes from payload into int + static int16_t extractSignedInt(const ubxPacket *msg, uint16_t spotToStart); + static uint8_t extractByte(const ubxPacket *msg, uint16_t spotToStart); // Get byte from payload + static int8_t extractSignedChar(const 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. @@ -1615,7 +1628,8 @@ class SFE_UBLOX_GNSS 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_TIM_SMEAS_t *packetUBXTIMSMEAS = 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 @@ -1707,6 +1721,7 @@ class SFE_UBLOX_GNSS 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 initPacketUBXTIMSMEA(); // Allocate RAM for packetUBXTIMSMEA 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 diff --git a/src/u-blox_config_keys.h b/src/u-blox_config_keys.h index a93ec33..7691a5f 100644 --- a/src/u-blox_config_keys.h +++ b/src/u-blox_config_keys.h @@ -123,6 +123,9 @@ const uint32_t UBLOX_CFG_HW_ANT_CFG_RECOVER = 0x10a30035; // Automatic reco 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_ON_SHORT_US = 0x30a3003c; // Delay in microseconds before antenna is turned on after short detection +const uint32_t UBLOX_CFG_HW_SENS_WOM_MODE = 0x20a30063; // Wake on Motion mode +const uint32_t UBLOX_CFG_HW_SENS_WOM_THLD = 0x20a30064; // Wake on Motion threshold 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 @@ -181,6 +184,7 @@ const uint32_t UBLOX_CFG_LOGFILTER_POSITION_THRS = 0x40de0008; // Positio //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 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) +const uint32_t UBLOX_CFG_MOT_IMU_FILT_WINDOW = 0x30250016; // Averaging window for IMU measurements in noisy setups in milliseconds // CFG-MSGOUT: Message output configuration //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -618,6 +622,11 @@ const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_ALG_UART1 = 0x20910110; // Output rat 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_CAL_I2C = 0x209106ac; // Output rate of the UBX-ESF-CAL message on port I2C +const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_CAL_SPI = 0x209106b0; // Output rate of the UBX-ESF-CAL message on port SPI +const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_CAL_UART1 = 0x209106ad; // Output rate of the UBX-ESF-CAL message on port UART1 +const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_CAL_UART2 = 0x209106ae; // Output rate of the UBX-ESF-CAL message on port UART2 +const uint32_t UBLOX_CFG_MSGOUT_UBX_ESF_CAL_USB = 0x209106af; // Output rate of the UBX-ESF-CAL message on port USB 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 @@ -696,6 +705,11 @@ const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_DOP_SPI = 0x20910469; // Output 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_EELL_I2C = 0x20910470; // Output rate of the UBX-NAV2-EELL message on port I2C +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EELL_SPI = 0x20910474; // Output rate of the UBX-NAV2-EELL message on port SPI +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EELL_UART1 = 0x20910471; // Output rate of the UBX-NAV2-EELL message on port UART1 +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EELL_UART2 = 0x20910472; // Output rate of the UBX-NAV2-EELL message on port UART2 +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_EELL_USB = 0x20910473; // Output rate of the UBX-NAV2-EELL 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 @@ -716,6 +730,11 @@ const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_POSLLH_SPI = 0x20910489; // Output 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_PVAT_I2C = 0x2091062f; // Output rate of the UBX-NAV2-PVAT message on port I2C +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVAT_SPI = 0x20910633; // Output rate of the UBX-NAV2-PVAT message on port SPI +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVAT_UART1 = 0x20910630; // Output rate of the UBX-NAV2-PVAT message on port UART1 +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVAT_UART2 = 0x20910631; // Output rate of the UBX-NAV2-PVAT message on port UART2 +const uint32_t UBLOX_CFG_MSGOUT_UBX_NAV2_PVAT_USB = 0x20910632; // Output rate of the UBX-NAV2-PVAT 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 @@ -984,6 +1003,8 @@ const uint32_t UBLOX_CFG_SBAS_USE_TESTMODE = 0x10360002; // Use SBAS data when 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_SBS_ACCEPT_NOT_IN_PRNMASK = 0x30360008; // Accept corrections from SBAS SV, even if notself included in PRN MASK +const uint32_t UBLOX_CFG_SBAS_USE_IONOONLY = 0x10360007; // Use SBAS ionospheric corrections only const uint32_t UBLOX_CFG_SBAS_PRNSCANMASK = 0x50360006; // SBAS PRN search configuration // CFG-SEC: Security configuration (ZED-F9R) @@ -991,10 +1012,14 @@ const uint32_t UBLOX_CFG_SBAS_PRNSCANMASK = 0x50360006; // SBAS PRN search con 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 +const uint32_t UBLOX_CFG_JAMDET_SENSITIVITY_HI = 0x10f60051; // High sensitivity for jamming detection // CFG-SFCORE: Sensor fusion (SF) core configuration (ZED-F9R) //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const uint32_t UBLOX_CFG_SFCORE_USE_SF = 0x10080001; // Use ADR/UDR sensor fusion +const uint32_t UBLOX_CFG_SFCORE_USE_SF = 0x10080001; // Use ADR/UDR sensor fusion +const uint32_t UBLOX_SFCORE_IMU2CRP_LA_X = 0x30080002; // X coordinate in centimeters of IMU-to-CRP lever-arm in the installation frame +const uint32_t UBLOX_SFCORE_IMU2CRP_LA_Y = 0x30080003; // Y coordinate in centimeters of IMU-to-CRP lever-arm in the installation frame +const uint32_t UBLOX_SFCORE_IMU2CRP_LA_Z = 0x30080004; // Z coordinate in centimeters of IMU-to-CRP lever-arm in the installation frame // CFG-SFIMU: Sensor fusion (SF) inertial measurement unit (IMU) configuration (ZED-F9R) //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -1010,6 +1035,9 @@ const uint32_t UBLOX_CFG_SFIMU_ACCEL_ACCURACY = 0x30060018; // Accelerome 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_IMU2ANT_LA_X = 0x30060020; // X coordinate in centimeters of IMU-to-antenna lever-arm in the installation frame +const uint32_t UBLOX_CFG_IMU2ANT_LA_Y = 0x30060021; // Y coordinate in centimeters of IMU-to-antenna lever-arm in the installation frame +const uint32_t UBLOX_CFG_IMU2ANT_LA_Z = 0x30060022; // Z coordinate in centimeters of IMU-to-antenna lever-arm in the installation frame 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] @@ -1032,6 +1060,10 @@ const uint32_t UBLOX_CFG_SFODO_SPEED_BAND = 0x3007000e; // Speed sensor d 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 +const uint32_t UBLOX_CFG_SFODO_IMU2VRP_LA_X = 0x30070012; // X coordinate in centimeters of IMU-to-VRP lever-arm in the installation frame +const uint32_t UBLOX_CFG_SFODO_IMU2VRP_LA_Y = 0x30070013; // Y coordinate in centimeters of IMU-to-VRP lever-arm in the installation frame +const uint32_t UBLOX_CFG_SFODO_IMU2VRP_LA_Z = 0x30070014; // Z coordinate in centimeters of IMU-to-VRP lever-arm in the installation frame +const uint32_t UBLOX_SFODO_DIS_DIR_INFO = 0x1007001c; // Disable direction information in the odometer data // CFG-SIGNAL: Satellite systems (GNSS) signal configuration //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/src/u-blox_structs.h b/src/u-blox_structs.h index 06160ce..9247f3d 100644 --- a/src/u-blox_structs.h +++ b/src/u-blox_structs.h @@ -57,6 +57,10 @@ #define DEF_MAX_NUM_ESF_MEAS 31 // numMeas is 5 bits, indicating up to 31 groups could be received #endif +#ifndef DEF_MAX_NUM_TIM_SMEAS_BLOCKS +#define DEF_MAX_NUM_TIM_SMEAS_BLOCKS 6 +#endif + // Additional flags and pointers that need to be stored with each message type struct ubxAutomaticFlags { @@ -1877,6 +1881,51 @@ typedef struct uint8_t reserved3[8]; } UBX_CFG_TMODE3_data_t; + +// UBX-CFG-SMGR (0x06 0x62): Synchronization manager configuration +const uint16_t UBX_CFG_SMGR_LEN = 20; + +typedef struct +{ + uint8_t version; /* Message version (0x00 for this version) */ + uint8_t minGNSSFix; /* Minimum number of GNSS fixes before we commit to use it as a source */ + uint16_t maxFreqChangeRate; /* Maximum frequency change rate during disciplining. Must not exceed 30ppb/s*/ + uint16_t maxPhaseCorrRate; /* Maximum phase correction rate in coherent time pulse mode. */ + uint8_t reserved1[2]; /* Reserved. Do not use */ + uint16_t freqTolerance; /* Freq limit of possible deviation from nominal */ + uint16_t timeTolerance; /* Time pulse limit of possible deviation from nominal */ + union { + uint16_t all; + struct { + uint16_t measInternal : 1; /* 1 = report the estimated offset of the internal oscillator based on the oscillator model */ + uint16_t measGNSS : 1; /* 1 = report the internal oscillator's offset relative to GNSS */ + uint16_t measEXTINT0 : 1; /* 1 = report the internal oscillator's offset relative to the source on EXTINT0 */ + uint16_t measEXTINT1 : 1; /* 1 = report the internal oscillator's offset relative to the source on EXTINT1 */ + } bits; + } messageCfg; + uint16_t maxSlewRate; + union { + uint32_t all; + struct { + uint32_t disableInternal : 1; /* 1 = disable disciplining of the internal oscillator */ + uint32_t disableExternal : 1; /* 1 = disable disciplining of the external oscillator */ + uint32_t preferenceMode : 1; /* Reference selection preference: 0 - best frequency accuracy; 1 - best phase accuracy */ + uint32_t enableGNSS : 1; /* 1 = enable use of GNSS as synchronization source */ + uint32_t enableEXTINT0 : 1; /* 1 = enable use of EXTINT0 as synchronization source */ + uint32_t enableEXTINT1 : 1; /* 1 = enable use of EXTINT1 as synchronization source */ + uint32_t enableHostMeasInt : 1; /* 1 = enable use of host measurements on the internal oscillator as synchronization source */ + uint32_t enableHostMeasExt : 1; /* 1 = enable use of host measurements on the external oscillator as synchronization source */ + uint32_t reserved : 2; /* Reserved. Do not use */ + uint32_t useAnyFix : 1; /* 0 - use over-determined navigation solutions only; 1 - use any fix */ + uint32_t disableMaxSlewRate : 1; /* 1 - don't use the value in the field maxSlewRate */ + uint32_t issueFreqWarn : 1; /* 1 - issue a warning (via UBX-TIM-TOS flag) when frequency uncertainty exceeds freqTolerance */ + uint32_t issueTimeWarn : 1; /* 1 = issue a warning (via UBX-TIM-TOS flag) when time uncertainty exceeds timeTolerance */ + uint32_t TPCoherent : 2; /* Control time pulse coherency: 0 - Coherent pulses; 1 - Non-coherent pulses; 2 - Post-initialization coherent pulses*/ + uint32_t disableOffset : 1; /* 1 = disable automatic storage of oscillator offset */ + } bits; + } flags; +} UBX_CFG_SMGR_data_t; + // MON-specific structs // UBX-MON-HW (0x0A 0x09): Hardware status @@ -1980,6 +2029,76 @@ typedef struct // TIM-specific structs +// UBX-TIM-SMEAS (0x0D 0x13): Source measurement +// Note: length is variable +const uint16_t UBX_TIM_SMEAS_MAX_LEN = 12 + 24 * DEF_MAX_NUM_TIM_SMEAS_BLOCKS; + +typedef struct +{ + uint8_t sourceId; /* Index of source */ + union { + uint8_t all; + struct { + uint8_t freqValid : 1; /* 1 = frequency measurement is valid */ + uint8_t phaseValid : 1; /* 1 = phase measurement is valid */ + } bits; + } flags; + int8_t phaseOffsetFrac; /* Sub-nanosecond phase offset (scaled by 2^-8) */ + uint8_t phaseUncFrac; /* Sub-nanosecond phase uncertainty (scaled by 2^-8) */ + int32_t phaseOffset; /* Phase offset [ns] */ + uint32_t phaseUnc; /* Phase uncertainty (one standard deviation, ns) */ + uint8_t reserved3[4]; /* Reserved. Do not use. Set as zero */ + int32_t freqOffset; /* Frequency offset [ppb] */ + uint32_t freqUnc; /* Frequency uncertainty (one standard deviation, ppb) */ +} UBX_TIM_SMEAS_blockData_t; + + +typedef struct +{ + uint8_t version; /* Message version (0x00 for this version) */ + uint8_t numMeas; /* Number of measurements in repeated block */ + uint8_t reserved1[2]; /* Reserved. Do not use. Set as zero */ + uint32_t iTOW; /* Time of the week [ms] */ + uint8_t reserved2[4]; /* Reserved. Do not use. Set as zero */ + UBX_TIM_SMEAS_blockData_t data[DEF_MAX_NUM_TIM_SMEAS_BLOCKS]; +} UBX_TIM_SMEAS_data_t; + + +typedef struct +{ + union + { + uint32_t all; + struct + { + uint32_t all : 1; + + uint32_t sourceId : 1; + + uint32_t freqValid : 1; + uint32_t phaseValid : 1; + + uint32_t phaseOffsetFrac : 1; + uint32_t phaseUncFrac : 1; + uint32_t phaseOffset : 1; + uint32_t phaseUnc : 1; + uint32_t freqOffset : 1; + uint32_t freqUnc : 1; + } bits; + } moduleQueried; +} UBX_TIM_SMEAS_moduleQueried_t; + + +typedef struct +{ + ubxAutomaticFlags automaticFlags; + UBX_TIM_SMEAS_data_t data; // Internal buffer + UBX_TIM_SMEAS_moduleQueried_t moduleQueried; + void (*callbackPointer)(UBX_TIM_SMEAS_data_t); + UBX_TIM_SMEAS_data_t *callbackData; // Shown to the user +} UBX_TIM_SMEAS_t; + + // UBX-TIM-TM2 (0x0D 0x03): Time mark data const uint16_t UBX_TIM_TM2_LEN = 28;