Skip to content

Support ubx cfg pm2 message #78

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

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 95 additions & 1 deletion src/SparkFun_u-blox_GNSS_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2599,7 +2599,7 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
{
packetUBXESFMEAS->data.data[i].data.all = extractLong(msg, 8 + (i * 4));
}
if (msg->len > (8 + (packetUBXESFMEAS->data.flags.bits.numMeas * 4))) // IGNORE COMPILER WARNING comparison between signed and unsigned integer expressions
if ((uint32_t) msg->len > (uint32_t) (8 + (packetUBXESFMEAS->data.flags.bits.numMeas * 4))) // Casting to uint32_t to prevent compiler warning about comparison between signed and unsigned integer expressions
packetUBXESFMEAS->data.calibTtag = extractLong(msg, 8 + (packetUBXESFMEAS->data.flags.bits.numMeas * 4));

//Mark all datums as fresh (not read before)
Expand Down Expand Up @@ -4823,6 +4823,100 @@ uint8_t SFE_UBLOX_GNSS::getPowerSaveMode(uint16_t maxWait)
return (payloadCfg[1]); // Return the low power mode
}

// Extended power management configuration
// Sends the UBX-CFG-PM2 message to configure extended power management
// Note: Section 32.10.23 of the u-blox 8 / u-blox M8 Receiver description document gives three different versions
// of this message. Version 0x01 is implemented here since it is the most widely supported version
boolean SFE_UBLOX_GNSS::configurePowerManagement(UBX_CFG_PM2_data_t* data, uint16_t maxWait)
{
if (data == NULL) // If the user forgot to include the data pointer, bail
return (false);

packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_PM2;
packetCfg.len = UBX_CFG_PM2_LEN;
packetCfg.startingSpot = 0;

// Insert the data, converting multi-byte values to little endian

memset(payloadCfg, 0, UBX_CFG_PM2_LEN);

payloadCfg[ 0] = 0x01; // Message version
payloadCfg[ 1] = 0; // Reserved
payloadCfg[ 2] = data->maxStartupStateDur;
payloadCfg[ 3] = 0; // Reserved

// Some MCUs don't support larger uints, so break flags into separate uint8s
uint8_t flags_0 = 0;
uint8_t flags_1 = 0;
uint8_t flags_2 = 0;
uint8_t flags_3 = 0;
flags_0 = flags_0 | (data->flagExtintSel << 4);
flags_0 = flags_0 | (data->flagExtintWake << 5);
flags_0 = flags_0 | (data->flagExtintBackup << 6);
flags_1 = flags_1 | (data->flagLimitPeakCurr << 0); // Uses bits 8 and 9
flags_1 = flags_1 | (data->flagWaitTimeFix << 2);
flags_1 = flags_1 | (data->flagUpdateRTC << 3);
flags_1 = flags_1 | (data->flagUpdateEPH << 4);
flags_2 = flags_2 | (data->flagDoNotEnterOff << 0);
flags_2 = flags_2 | (data->flagMode << 1); // Uses bits 17 and 18

payloadCfg[ 4] = flags_0;
payloadCfg[ 5] = flags_1;
payloadCfg[ 6] = flags_2;
payloadCfg[ 7] = flags_3;

payloadCfg[ 8] = (data->updatePeriod >> (8 * 0)) & 0xFF;
payloadCfg[ 9] = (data->updatePeriod >> (8 * 1)) & 0xFF;
payloadCfg[10] = (data->updatePeriod >> (8 * 2)) & 0xFF;
payloadCfg[11] = (data->updatePeriod >> (8 * 3)) & 0xFF;

payloadCfg[12] = (data->searchPeriod >> (8 * 0)) & 0xFF;
payloadCfg[13] = (data->searchPeriod >> (8 * 1)) & 0xFF;
payloadCfg[14] = (data->searchPeriod >> (8 * 2)) & 0xFF;
payloadCfg[15] = (data->searchPeriod >> (8 * 3)) & 0xFF;

payloadCfg[16] = (data->gridOffset >> (8 * 0)) & 0xFF;
payloadCfg[17] = (data->gridOffset >> (8 * 1)) & 0xFF;
payloadCfg[18] = (data->gridOffset >> (8 * 2)) & 0xFF;
payloadCfg[19] = (data->gridOffset >> (8 * 3)) & 0xFF;

payloadCfg[20] = (data->onTime >> (8 * 0)) & 0xFF;
payloadCfg[21] = (data->onTime >> (8 * 1)) & 0xFF;

payloadCfg[22] = (data->minAcqTime >> (8 * 0)) & 0xFF;
payloadCfg[23] = (data->minAcqTime >> (8 * 1)) & 0xFF;

// Bytes 24 through (UBX_CFG_PM2_LEN-1) are reserved

boolean cfg_result = sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT;

return (cfg_result); // We are only expecting an ACK
}

boolean SFE_UBLOX_GNSS::getPowerManagementConfiguration(uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_PM2;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

// Don't setup any payload items; we're just reading the current configuration
// Instead clear the structure since it will be read into
memset(payloadCfg, 0, UBX_CFG_PM2_LEN);

boolean cfg_result = sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT;

Serial.println("Data:");
Serial.println(payloadCfg[0]);
Serial.println(payloadCfg[1]);
Serial.println(payloadCfg[2]);
Serial.println(payloadCfg[3]);
Serial.println(payloadCfg[4]);

return (cfg_result); // We are only expecting an ACK
}

// Powers off the GPS device for a given duration to reduce power consumption.
// NOTE: Querying the device before the duration is complete, for example by "getLatitude()" will wake it up!
// Returns true if command has not been not acknowledged.
Expand Down
70 changes: 36 additions & 34 deletions src/SparkFun_u-blox_GNSS_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,40 +190,40 @@ const uint8_t UBX_CLASS_NMEA = 0xF0; //NMEA Strings: standard NMEA strings

//Class: CFG
//The following are used for configuration. Descriptions are from the ZED-F9P Interface Description pg 33-34 and NEO-M9N Interface Description pg 47-48
const uint8_t UBX_CFG_ANT = 0x13; //Antenna Control Settings. Used to configure the antenna control settings
const uint8_t UBX_CFG_BATCH = 0x93; //Get/set data batching configuration.
const uint8_t UBX_CFG_CFG = 0x09; //Clear, Save, and Load Configurations. Used to save current configuration
const uint8_t UBX_CFG_DAT = 0x06; //Set User-defined Datum or The currently defined Datum
const uint8_t UBX_CFG_DGNSS = 0x70; //DGNSS configuration
const uint8_t UBX_CFG_ESFALG = 0x56; //ESF alignment
const uint8_t UBX_CFG_ESFA = 0x4C; //ESF accelerometer
const uint8_t UBX_CFG_ESFG = 0x4D; //ESF gyro
const uint8_t UBX_CFG_GEOFENCE = 0x69; //Geofencing configuration. Used to configure a geofence
const uint8_t UBX_CFG_GNSS = 0x3E; //GNSS system configuration
const uint8_t UBX_CFG_HNR = 0x5C; //High Navigation Rate
const uint8_t UBX_CFG_INF = 0x02; //Depending on packet length, either: poll configuration for one protocol, or information message configuration
const uint8_t UBX_CFG_ITFM = 0x39; //Jamming/Interference Monitor configuration
const uint8_t UBX_CFG_ANT = 0x13; //Antenna Control Settings. Used to configure the antenna control settings
const uint8_t UBX_CFG_BATCH = 0x93; //Get/set data batching configuration.
const uint8_t UBX_CFG_CFG = 0x09; //Clear, Save, and Load Configurations. Used to save current configuration
const uint8_t UBX_CFG_DAT = 0x06; //Set User-defined Datum or The currently defined Datum
const uint8_t UBX_CFG_DGNSS = 0x70; //DGNSS configuration
const uint8_t UBX_CFG_ESFALG = 0x56; //ESF alignment
const uint8_t UBX_CFG_ESFA = 0x4C; //ESF accelerometer
const uint8_t UBX_CFG_ESFG = 0x4D; //ESF gyro
const uint8_t UBX_CFG_GEOFENCE = 0x69; //Geofencing configuration. Used to configure a geofence
const uint8_t UBX_CFG_GNSS = 0x3E; //GNSS system configuration
const uint8_t UBX_CFG_HNR = 0x5C; //High Navigation Rate
const uint8_t UBX_CFG_INF = 0x02; //Depending on packet length, either: poll configuration for one protocol, or information message configuration
const uint8_t UBX_CFG_ITFM = 0x39; //Jamming/Interference Monitor configuration
const uint8_t UBX_CFG_LOGFILTER = 0x47; //Data Logger Configuration
const uint8_t UBX_CFG_MSG = 0x01; //Poll a message configuration, or Set Message Rate(s), or Set Message Rate
const uint8_t UBX_CFG_NAV5 = 0x24; //Navigation Engine Settings. Used to configure the navigation engine including the dynamic model.
const uint8_t UBX_CFG_NAVX5 = 0x23; //Navigation Engine Expert Settings
const uint8_t UBX_CFG_NMEA = 0x17; //Extended NMEA protocol configuration V1
const uint8_t UBX_CFG_ODO = 0x1E; //Odometer, Low-speed COG Engine Settings
const uint8_t UBX_CFG_PM2 = 0x3B; //Extended power management configuration
const uint8_t UBX_CFG_PMS = 0x86; //Power mode setup
const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics. Polls the configuration for one I/O Port, or Port configuration for UART ports, or Port configuration for USB port, or Port configuration for SPI port, or Port configuration for DDC port
const uint8_t UBX_CFG_PWR = 0x57; //Put receiver in a defined power state
const uint8_t UBX_CFG_RATE = 0x08; //Navigation/Measurement Rate Settings. Used to set port baud rates.
const uint8_t UBX_CFG_RINV = 0x34; //Contents of Remote Inventory
const uint8_t UBX_CFG_RST = 0x04; //Reset Receiver / Clear Backup Data Structures. Used to reset device.
const uint8_t UBX_CFG_RXM = 0x11; //RXM configuration
const uint8_t UBX_CFG_SBAS = 0x16; //SBAS configuration
const uint8_t UBX_CFG_TMODE3 = 0x71; //Time Mode Settings 3. Used to enable Survey In Mode
const uint8_t UBX_CFG_TP5 = 0x31; //Time Pulse Parameters
const uint8_t UBX_CFG_USB = 0x1B; //USB Configuration
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version u-blox modules (ie protocol v27 and above). Deletes values corresponding to provided keys/ provided keys with a transaction
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version u-blox modules (ie protocol v27 and above). Configuration Items
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version u-blox modules (ie protocol v27 and above). Sets values corresponding to provided key-value pairs/ provided key-value pairs within a transaction.
const uint8_t UBX_CFG_MSG = 0x01; //Poll a message configuration, or Set Message Rate(s), or Set Message Rate
const uint8_t UBX_CFG_NAV5 = 0x24; //Navigation Engine Settings. Used to configure the navigation engine including the dynamic model.
const uint8_t UBX_CFG_NAVX5 = 0x23; //Navigation Engine Expert Settings
const uint8_t UBX_CFG_NMEA = 0x17; //Extended NMEA protocol configuration V1
const uint8_t UBX_CFG_ODO = 0x1E; //Odometer, Low-speed COG Engine Settings
const uint8_t UBX_CFG_PM2 = 0x3B; //Extended power management configuration
const uint8_t UBX_CFG_PMS = 0x86; //Power mode setup
const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics. Polls the configuration for one I/O Port, or Port configuration for UART ports, or Port configuration for USB port, or Port configuration for SPI port, or Port configuration for DDC port
const uint8_t UBX_CFG_PWR = 0x57; //Put receiver in a defined power state
const uint8_t UBX_CFG_RATE = 0x08; //Navigation/Measurement Rate Settings. Used to set port baud rates.
const uint8_t UBX_CFG_RINV = 0x34; //Contents of Remote Inventory
const uint8_t UBX_CFG_RST = 0x04; //Reset Receiver / Clear Backup Data Structures. Used to reset device.
const uint8_t UBX_CFG_RXM = 0x11; //RXM configuration
const uint8_t UBX_CFG_SBAS = 0x16; //SBAS configuration
const uint8_t UBX_CFG_TMODE3 = 0x71; //Time Mode Settings 3. Used to enable Survey In Mode
const uint8_t UBX_CFG_TP5 = 0x31; //Time Pulse Parameters
const uint8_t UBX_CFG_USB = 0x1B; //USB Configuration
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version u-blox modules (ie protocol v27 and above). Deletes values corresponding to provided keys/ provided keys with a transaction
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version u-blox modules (ie protocol v27 and above). Configuration Items
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version u-blox modules (ie protocol v27 and above). Sets values corresponding to provided key-value pairs/ provided key-value pairs within a transaction.

//Class: NMEA
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
Expand Down Expand Up @@ -744,9 +744,11 @@ class SFE_UBLOX_GNSS
// Storage for the geofence parameters. RAM is allocated for this if/when required.
geofenceParams_t *currentGeofenceParams = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary

//Power save / off
//Power save / power management configuration / power off
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = defaultMaxWait);
uint8_t getPowerSaveMode(uint16_t maxWait = defaultMaxWait); // Returns 255 if the sendCommand fails
boolean configurePowerManagement(UBX_CFG_PM2_data_t* data = NULL, uint16_t maxWait = defaultMaxWait);
boolean getPowerManagementConfiguration(uint16_t maxWait = defaultMaxWait);
boolean powerOff(uint32_t durationInMs, uint16_t maxWait = defaultMaxWait);
boolean powerOffWithInterrupt(uint32_t durationInMs, uint32_t wakeupSources = VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0, boolean forceWhileUsb = true, uint16_t maxWait = 1100);

Expand Down
93 changes: 58 additions & 35 deletions src/u-blox_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,28 @@ typedef struct

// CFG-specific structs

// UBX-CFG-PM2 (0x06 0x3B): Extended power management configuration
const uint16_t UBX_CFG_PM2_LEN = 44;

typedef struct
{
uint8_t maxStartupStateDur;
uint8_t flagExtintSel;
uint8_t flagExtintWake;
uint8_t flagExtintBackup;
uint8_t flagLimitPeakCurr;
uint8_t flagWaitTimeFix;
uint8_t flagUpdateRTC;
uint8_t flagUpdateEPH;
uint8_t flagDoNotEnterOff;
uint8_t flagMode;
uint32_t updatePeriod;
uint32_t searchPeriod;
uint32_t gridOffset;
uint16_t onTime;
uint16_t minAcqTime;
} UBX_CFG_PM2_data_t;

// UBX-CFG-RATE (0x06 0x08): Navigation/measurement rate settings
const uint16_t UBX_CFG_RATE_LEN = 6;

Expand Down Expand Up @@ -1206,6 +1228,42 @@ typedef struct
UBX_CFG_RATE_data_t *callbackData;
} UBX_CFG_RATE_t;


// UBX-CFG-TP5 (0x06 0x31): Time pulse parameters
const uint16_t UBX_CFG_TP5_LEN = 32;

typedef struct
{
uint8_t tpIdx; // Time pulse selection (0 = TIMEPULSE, 1 = TIMEPULSE2)
uint8_t version; // Message version (0x01 for this version)
uint8_t reserved1[2];
int16_t antCableDelay; // Antenna cable delay: ns
int16_t rfGroupDelay; // RF group delay: ns
uint32_t freqPeriod; // Frequency or period time, depending on setting of bit 'isFreq': Hz_or_us
uint32_t freqPeriodLock; // Frequency or period time when locked to GNSS time, only used if 'lockedOtherSet' is set: Hz_or_us
uint32_t pulseLenRatio; // Pulse length or duty cycle, depending on 'isLength': us_or_2^-32
uint32_t pulseLenRatioLock; // Pulse length or duty cycle when locked to GNSS time, only used if 'lockedOtherSet' is set: us_or_2^-32
int32_t userConfigDelay; // User-configurable time pulse delay: ns
union
{
uint32_t all;
struct
{
uint32_t active : 1; // If set enable time pulse; if pin assigned to another function, other function takes precedence.
uint32_t lockGnssFreq : 1; // If set, synchronize time pulse to GNSS as soon as GNSS time is valid. If not set, or before GNSS time is valid, use local clock.
uint32_t lockedOtherSet : 1; // If set the receiver switches between the timepulse settings given by 'freqPeriodLocked' & 'pulseLenLocked' and those given by 'freqPeriod' & 'pulseLen'.
uint32_t isFreq : 1; // If set 'freqPeriodLock' and 'freqPeriod' are interpreted as frequency, otherwise interpreted as period.
uint32_t isLength : 1; // If set 'pulseLenRatioLock' and 'pulseLenRatio' interpreted as pulse length, otherwise interpreted as duty cycle.
uint32_t alignToTow : 1; // Align pulse to top of second (period time must be integer fraction of 1s). Also set 'lockGnssFreq' to use this feature.
uint32_t polarity : 1; // Pulse polarity: 0: falling edge at top of second; 1: rising edge at top of second
uint32_t gridUtcGnss : 4; // Timegrid to use: 0: UTC; 1: GPS; 2: GLONASS; 3: BeiDou; 4: Galileo
uint32_t syncMode : 3; // Sync Manager lock mode to use:
// 0: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, never switch back to 'freqPeriod' and 'pulseLenRatio'
// 1: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, and switch back to 'freqPeriod' and 'pulseLenRatio' as soon as time gets inaccurate
} bits;
} flags;
} UBX_CFG_TP5_data_t;

// TIM-specific structs

// UBX-TIM-TM2 (0x0D 0x03): Time mark data
Expand Down Expand Up @@ -1849,39 +1907,4 @@ typedef struct
UBX_HNR_INS_data_t *callbackData;
} UBX_HNR_INS_t;

// UBX-CFG-TP5 (0x06 0x31): Time pulse parameters
const uint16_t UBX_CFG_TP5_LEN = 32;

typedef struct
{
uint8_t tpIdx; // Time pulse selection (0 = TIMEPULSE, 1 = TIMEPULSE2)
uint8_t version; // Message version (0x01 for this version)
uint8_t reserved1[2];
int16_t antCableDelay; // Antenna cable delay: ns
int16_t rfGroupDelay; // RF group delay: ns
uint32_t freqPeriod; // Frequency or period time, depending on setting of bit 'isFreq': Hz_or_us
uint32_t freqPeriodLock; // Frequency or period time when locked to GNSS time, only used if 'lockedOtherSet' is set: Hz_or_us
uint32_t pulseLenRatio; // Pulse length or duty cycle, depending on 'isLength': us_or_2^-32
uint32_t pulseLenRatioLock; // Pulse length or duty cycle when locked to GNSS time, only used if 'lockedOtherSet' is set: us_or_2^-32
int32_t userConfigDelay; // User-configurable time pulse delay: ns
union
{
uint32_t all;
struct
{
uint32_t active : 1; // If set enable time pulse; if pin assigned to another function, other function takes precedence.
uint32_t lockGnssFreq : 1; // If set, synchronize time pulse to GNSS as soon as GNSS time is valid. If not set, or before GNSS time is valid, use local clock.
uint32_t lockedOtherSet : 1; // If set the receiver switches between the timepulse settings given by 'freqPeriodLocked' & 'pulseLenLocked' and those given by 'freqPeriod' & 'pulseLen'.
uint32_t isFreq : 1; // If set 'freqPeriodLock' and 'freqPeriod' are interpreted as frequency, otherwise interpreted as period.
uint32_t isLength : 1; // If set 'pulseLenRatioLock' and 'pulseLenRatio' interpreted as pulse length, otherwise interpreted as duty cycle.
uint32_t alignToTow : 1; // Align pulse to top of second (period time must be integer fraction of 1s). Also set 'lockGnssFreq' to use this feature.
uint32_t polarity : 1; // Pulse polarity: 0: falling edge at top of second; 1: rising edge at top of second
uint32_t gridUtcGnss : 4; // Timegrid to use: 0: UTC; 1: GPS; 2: GLONASS; 3: BeiDou; 4: Galileo
uint32_t syncMode : 3; // Sync Manager lock mode to use:
// 0: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, never switch back to 'freqPeriod' and 'pulseLenRatio'
// 1: switch to 'freqPeriodLock' and 'pulseLenRatioLock' as soon as Sync Manager has an accurate time, and switch back to 'freqPeriod' and 'pulseLenRatio' as soon as time gets inaccurate
} bits;
} flags;
} UBX_CFG_TP5_data_t;

#endif