-
Notifications
You must be signed in to change notification settings - Fork 103
added UBX_CFG_SMGR configuration support #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dizcza
wants to merge
3
commits into
sparkfun:main
Choose a base branch
from
dizcza:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
examples/Example33_TimeFreqSyncManager/Example33_TimeFreqSyncManager.ino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
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 polls for UBX 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 <Wire.h> //Needed for I2C to GNSS | ||
|
||
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS | ||
SFE_UBLOX_GNSS myGNSS; | ||
|
||
|
||
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.measInternal); | ||
Serial.printf("\n measGNSS: %u", smgr.messageCfg.measGNSS); | ||
Serial.printf("\n measEXTINT0: %u", smgr.messageCfg.measEXTINT0); | ||
Serial.printf("\n measEXTINT1: %u", smgr.messageCfg.measEXTINT1); | ||
Serial.printf("\n maxSlewRate %u (0x%02x)", smgr.maxSlewRate, smgr.maxSlewRate); | ||
Serial.printf("\n flags:"); | ||
Serial.printf("\n disableInternal: %u", smgr.flags.disableInternal); | ||
Serial.printf("\n disableExternal: %u", smgr.flags.disableExternal); | ||
Serial.printf("\n preferenceMode: %u", smgr.flags.preferenceMode); | ||
Serial.printf("\n enableGNSS: %u", smgr.flags.enableGNSS); | ||
Serial.printf("\n enableEXTINT0: %u", smgr.flags.enableEXTINT0); | ||
Serial.printf("\n enableEXTINT1: %u", smgr.flags.enableEXTINT1); | ||
Serial.printf("\n enableHostMeasInt: %u", smgr.flags.enableHostMeasInt); | ||
Serial.printf("\n enableHostMeasExt: %u", smgr.flags.enableHostMeasExt); | ||
Serial.printf("\n useAnyFix: %u", smgr.flags.useAnyFix); | ||
Serial.printf("\n disableMaxSlewRate: %u", smgr.flags.disableMaxSlewRate); | ||
Serial.printf("\n issueFreqWarn: %u", smgr.flags.issueFreqWarn); | ||
Serial.printf("\n issueTimeWarn: %u", smgr.flags.issueTimeWarn); | ||
Serial.printf("\n TPCoherent: %u", smgr.flags.TPCoherent); | ||
Serial.printf("\n disableOffset: %u", smgr.flags.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); | ||
|
||
UBX_CFG_SMGR_data_t cfgSmgrPayload; | ||
|
||
// The next line creates and initialises the packet information which wraps around the payload | ||
ubxPacket customCfg = {0, 0, 0, 0, 0, (uint8_t*) &cfgSmgrPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; | ||
dizcza marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// 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) | ||
; | ||
} | ||
|
||
printUbxCfgSmgr(cfgSmgrPayload); | ||
|
||
cfgSmgrPayload.minGNSSFix = 5; // update the min no. of GNSS fixes to start freq/phase sync | ||
cfgSmgrPayload.flags.useAnyFix = 1; // use any fix | ||
|
||
// 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.setOutputPort(Serial); | ||
} | ||
|
||
void loop() | ||
{ | ||
myGNSS.checkUblox(); //See if new UBX data is available. Process bytes as they come in. | ||
|
||
delay(250); //Don't pound too hard on the I2C bus | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1877,6 +1877,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. */ | ||
uint16_t reserved1; /* Reserved. Do not use */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strictly, this should be uint8_t [2] |
||
uint16_t freqTolerance; /* Freq limit of possible deviation from nominal */ | ||
uint16_t timeTolerance; /* Time pulse limit of possible deviation from nominal */ | ||
union { | ||
uint16_t messageCfgX; | ||
struct { | ||
uint8_t measInternal : 1; /* 1 = report the estimated offset of the internal oscillator based on the oscillator model */ | ||
dizcza marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint8_t measGNSS : 1; /* 1 = report the internal oscillator's offset relative to GNSS */ | ||
uint8_t measEXTINT0 : 1; /* 1 = report the internal oscillator's offset relative to the source on EXTINT0 */ | ||
uint8_t measEXTINT1 : 1; /* 1 = report the internal oscillator's offset relative to the source on EXTINT1 */ | ||
} messageCfg; | ||
}; | ||
uint16_t maxSlewRate; | ||
union { | ||
uint32_t flagsX; | ||
struct { | ||
uint8_t disableInternal : 1; /* 1 = disable disciplining of the internal oscillator */ | ||
dizcza marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint8_t disableExternal : 1; /* 1 = disable disciplining of the external oscillator */ | ||
uint8_t preferenceMode : 1; /* Reference selection preference: 0 - best frequency accuracy; 1 - best phase accuracy */ | ||
uint8_t enableGNSS : 1; /* 1 = enable use of GNSS as synchronization source */ | ||
uint8_t enableEXTINT0 : 1; /* 1 = enable use of EXTINT0 as synchronization source */ | ||
uint8_t enableEXTINT1 : 1; /* 1 = enable use of EXTINT1 as synchronization source */ | ||
uint8_t enableHostMeasInt : 1; /* 1 = enable use of host measurements on the internal oscillator as synchronization source */ | ||
uint8_t enableHostMeasExt : 1; /* 1 = enable use of host measurements on the external oscillator as synchronization source */ | ||
uint8_t reserved : 2; /* Reserved. Do not use */ | ||
uint8_t useAnyFix : 1; /* 0 - use over-determined navigation solutions only; 1 - use any fix */ | ||
uint8_t disableMaxSlewRate : 1; /* 1 - don't use the value in the field maxSlewRate */ | ||
uint8_t issueFreqWarn : 1; /* 1 - issue a warning (via UBX-TIM-TOS flag) when frequency uncertainty exceeds freqTolerance */ | ||
uint8_t issueTimeWarn : 1; /* 1 = issue a warning (via UBX-TIM-TOS flag) when time uncertainty exceeds timeTolerance */ | ||
uint8_t TPCoherent : 2; /* Control time pulse coherency: 0 - Coherent pulses; 1 - Non-coherent pulses; 2 - Post-initialization coherent pulses*/ | ||
uint8_t disableOffset : 1; /* 1 = disable automatic storage of oscillator offset */ | ||
} flags; | ||
}; | ||
} UBX_CFG_SMGR_data_t; | ||
|
||
// MON-specific structs | ||
|
||
// UBX-MON-HW (0x0A 0x09): Hardware status | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.