From 93f0aee4a1007dbb7248da3c0a0b4fd49d306dc8 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 28 Oct 2022 10:15:54 +0100 Subject: [PATCH] Add newCfgValset, sendCfgValset, getCfgValsetLen --- keywords.txt | 5 + src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 222 ++++++++++++++++++- src/SparkFun_u-blox_GNSS_Arduino_Library.h | 20 +- src/u-blox_config_keys.h | 4 + 4 files changed, 236 insertions(+), 15 deletions(-) diff --git a/keywords.txt b/keywords.txt index 503c596..c654d5e 100644 --- a/keywords.txt +++ b/keywords.txt @@ -79,6 +79,7 @@ NMEA_ZDA_data_t KEYWORD1 ####################################### setPacketCfgPayloadSize KEYWORD2 +getPacketCfgSpaceRemaining KEYWORD2 begin KEYWORD2 end KEYWORD2 setI2CpollingWait KEYWORD2 @@ -232,6 +233,7 @@ setVal8 KEYWORD2 setVal16 KEYWORD2 setVal32 KEYWORD2 setVal64 KEYWORD2 +newCfgValset KEYWORD2 newCfgValset8 KEYWORD2 newCfgValset16 KEYWORD2 newCfgValset32 KEYWORD2 @@ -244,6 +246,9 @@ sendCfgValset8 KEYWORD2 sendCfgValset16 KEYWORD2 sendCfgValset32 KEYWORD2 sendCfgValset64 KEYWORD2 +sendCfgValset KEYWORD2 +getCfgValsetLen KEYWORD2 +getCfgValsetSpaceRemaining KEYWORD2 getNAVPOSECEF KEYWORD2 setAutoNAVPOSECEF KEYWORD2 diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 9ca2378..16dea7f 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -627,6 +627,12 @@ bool SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) 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) { @@ -9178,6 +9184,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset64(uint32_t key, uint64_t value, uint8_t lay 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); @@ -9215,6 +9223,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset32(uint32_t key, uint32_t value, uint8_t lay 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); @@ -9248,6 +9258,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset16(uint32_t key, uint16_t value, uint8_t lay 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); @@ -9279,7 +9291,9 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset8(uint32_t key, uint8_t value, uint8_t layer packetCfg.len = 4 + 4 + 1; // 4 byte header, 4 byte key ID, 1 byte value packetCfg.startingSpot = 0; - // Clear all of packet payload + _numCfgKeyIDs = 1; + +// Clear all of packet payload memset(payloadCfg, 0, packetCfgPayloadSize); payloadCfg[0] = 0; // Message Version - set to 0 @@ -9298,10 +9312,49 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset8(uint32_t key, uint8_t value, uint8_t layer 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 (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; @@ -9321,6 +9374,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value) // Update packet length: 4 byte key ID, 8 bytes of value packetCfg.len = packetCfg.len + 4 + 8; + _numCfgKeyIDs++; + // All done return (true); } @@ -9329,6 +9384,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value) // 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 (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; @@ -9344,6 +9417,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value) // Update packet length: 4 byte key ID, 4 bytes of value packetCfg.len = packetCfg.len + 4 + 4; + _numCfgKeyIDs++; + // All done return (true); } @@ -9352,6 +9427,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value) // 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 (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; @@ -9365,6 +9458,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value) // Update packet length: 4 byte key ID, 2 bytes of value packetCfg.len = packetCfg.len + 4 + 2; + _numCfgKeyIDs++; + // All done return (true); } @@ -9373,6 +9468,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value) // 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 (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; @@ -9385,6 +9498,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value) // Update packet length: 4 byte key ID, 1 byte value packetCfg.len = packetCfg.len + 4 + 1; + _numCfgKeyIDs++; + // All done return (true); } @@ -9393,8 +9508,25 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value) // 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) { - // Load keyID and value into outgoing payload - addCfgValset64(key, value); + 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 @@ -9404,8 +9536,25 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset64(uint32_t key, uint64_t value, uint16_t m // 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) { - // Load keyID and value into outgoing payload - addCfgValset32(key, value); + 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 @@ -9415,8 +9564,25 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset32(uint32_t key, uint32_t value, uint16_t m // 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) { - // Load keyID and value into outgoing payload - addCfgValset16(key, value); + 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 @@ -9426,13 +9592,51 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset16(uint32_t key, uint16_t value, uint16_t m // 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) { - // Load keyID and value into outgoing payload - addCfgValset8(key, value); + 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) +{ + _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 +} + +// 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 =-=-=-=-=-=-=-==-=-=-=-=-=-=-= //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 746eee7..5d4df7e 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -664,6 +664,7 @@ public: // 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. @@ -979,6 +980,7 @@ public: 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 @@ -991,6 +993,9 @@ public: 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 // get and set functions for all of the "automatic" message processing @@ -1402,12 +1407,12 @@ public: // 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) + 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 @@ -1788,6 +1793,9 @@ private: // .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; }; #endif diff --git a/src/u-blox_config_keys.h b/src/u-blox_config_keys.h index b1589fa..a93ec33 100644 --- a/src/u-blox_config_keys.h +++ b/src/u-blox_config_keys.h @@ -43,6 +43,10 @@ #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