Skip to content

Commit bfd03a7

Browse files
committed
Add support for multiple SFRBX message callbacks - for the PointPerfect Library
1 parent 2c588e6 commit bfd03a7

File tree

3 files changed

+144
-36
lines changed

3 files changed

+144
-36
lines changed

src/u-blox_GNSS.cpp

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@ void DevUBLOXGNSS::end(void)
375375
{
376376
delete packetUBXRXMSFRBX->callbackData;
377377
}
378+
if (packetUBXRXMSFRBX->callbackMessageData != nullptr)
379+
{
380+
delete[] packetUBXRXMSFRBX->callbackMessageData;
381+
}
378382
delete packetUBXRXMSFRBX;
379383
packetUBXRXMSFRBX = nullptr;
380384
}
@@ -4124,6 +4128,31 @@ void DevUBLOXGNSS::processUBXpacket(ubxPacket *msg)
41244128
packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackCopyValid = true;
41254129
}
41264130

4131+
// Check if we need to copy the data for the message callbacks
4132+
if (packetUBXRXMSFRBX->callbackMessageData != nullptr) // If RAM has been allocated for the copy of the data
4133+
{
4134+
for (uint16_t i = 0; i < UBX_RXM_SFRBX_MESSAGE_CALLBACK_BUFFERS; i++) // Check all available buffers
4135+
{
4136+
if ((packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackMessageCopyValid & (1 << i)) == 0) // AND the buffer is empty
4137+
{
4138+
packetUBXRXMSFRBX->callbackMessageData[i].sync1 = UBX_SYNCH_1;
4139+
packetUBXRXMSFRBX->callbackMessageData[i].sync2 = UBX_SYNCH_2;
4140+
packetUBXRXMSFRBX->callbackMessageData[i].cls = UBX_CLASS_RXM;
4141+
packetUBXRXMSFRBX->callbackMessageData[i].ID = UBX_RXM_SFRBX;
4142+
packetUBXRXMSFRBX->callbackMessageData[i].lengthLSB = msg->len & 0xFF;
4143+
packetUBXRXMSFRBX->callbackMessageData[i].lengthMSB = msg->len >> 8;
4144+
4145+
memcpy(packetUBXRXMSFRBX->callbackMessageData[i].payload, msg->payload, msg->len);
4146+
4147+
packetUBXRXMSFRBX->callbackMessageData[i].checksumA = msg->checksumA;
4148+
packetUBXRXMSFRBX->callbackMessageData[i].checksumB = msg->checksumB;
4149+
4150+
packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackMessageCopyValid |= (1 << i);
4151+
break; // abort when added
4152+
}
4153+
}
4154+
}
4155+
41274156
// Check if we need to copy the data into the file buffer
41284157
if (packetUBXRXMSFRBX->automaticFlags.flags.bits.addToFileBuffer)
41294158
{
@@ -5789,8 +5818,10 @@ void DevUBLOXGNSS::checkCallbacks(void)
57895818
packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
57905819
}
57915820

5792-
if (packetUBXRXMSFRBX != nullptr) // If RAM has been allocated for message storage
5793-
if (packetUBXRXMSFRBX->callbackData != nullptr) // If RAM has been allocated for the copy of the data
5821+
if (packetUBXRXMSFRBX != nullptr) // If RAM has been allocated for message storage
5822+
{
5823+
if (packetUBXRXMSFRBX->callbackData != nullptr) // If RAM has been allocated for the copy of the data
5824+
{
57945825
if (packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackCopyValid == true) // If the copy of the data is valid
57955826
{
57965827
if (packetUBXRXMSFRBX->callbackPointerPtr != nullptr) // If the pointer to the callback has been defined
@@ -5799,6 +5830,22 @@ void DevUBLOXGNSS::checkCallbacks(void)
57995830
}
58005831
packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
58015832
}
5833+
}
5834+
if (packetUBXRXMSFRBX->callbackMessageData != nullptr) // If RAM has been allocated for the copy of the data
5835+
{
5836+
for (uint16_t i = 0; i < UBX_RXM_SFRBX_MESSAGE_CALLBACK_BUFFERS; i++)
5837+
{
5838+
if ((packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackMessageCopyValid & (1 << i)) > 0) // If the copy of the data is valid
5839+
{
5840+
if (packetUBXRXMSFRBX->callbackMessagePointerPtr != nullptr) // If the pointer to the callback has been defined
5841+
{
5842+
packetUBXRXMSFRBX->callbackMessagePointerPtr(&packetUBXRXMSFRBX->callbackMessageData[i]); // Call the callback
5843+
}
5844+
packetUBXRXMSFRBX->automaticFlags.flags.bits.callbackMessageCopyValid &= ~(1 << i); // Mark the data as stale
5845+
}
5846+
}
5847+
}
5848+
}
58025849

58035850
if (packetUBXRXMRAWX != nullptr) // If RAM has been allocated for message storage
58045851
if (packetUBXRXMRAWX->callbackData != nullptr) // If RAM has been allocated for the copy of the data
@@ -6107,7 +6154,7 @@ bool DevUBLOXGNSS::pushRawData(uint8_t *dataBytes, size_t numDataBytes, bool cal
61076154
bytesLeftToWrite -= (size_t)bytesToWrite;
61086155
dataBytes += bytesToWrite;
61096156

6110-
if (callProcessBuffer) // Try and prevent data loss during large pushes by calling checkUbloxSerial between chunks
6157+
if (callProcessBuffer) // Try and prevent data loss during large pushes by calling checkUbloxSerial between chunks
61116158
checkUbloxSerial(&packetCfg, 0, 0); // Don't call checkUbloxInternal as we already have the lock!
61126159
}
61136160
}
@@ -9015,7 +9062,6 @@ const char *DevUBLOXGNSS::getUniqueChipIdStr(UBX_SEC_UNIQID_data_t *data, uint16
90159062
return ((const char *)uniqueId);
90169063
}
90179064

9018-
90199065
// CONFIGURATION INTERFACE (protocol v27 and above)
90209066

90219067
// Given a key, load the payload with data that can then be extracted to 8, 16, or 32 bits
@@ -13132,6 +13178,31 @@ bool DevUBLOXGNSS::setAutoRXMSFRBXcallbackPtr(void (*callbackPointerPtr)(UBX_RXM
1313213178
packetUBXRXMSFRBX->callbackPointerPtr = callbackPointerPtr;
1313313179
return (true);
1313413180
}
13181+
// Use this if you want all of the SFRBX message (including sync chars, checksum, etc.) to push to the PointPerfect Library
13182+
bool DevUBLOXGNSS::setAutoRXMSFRBXmessageCallbackPtr(void (*callbackMessagePointerPtr)(UBX_RXM_SFRBX_message_data_t *), uint8_t layer, uint16_t maxWait)
13183+
{
13184+
// Enable auto messages. Set implicitUpdate to false as we expect the user to call checkUblox manually.
13185+
bool result = setAutoRXMSFRBX(true, false, layer, maxWait);
13186+
if (!result)
13187+
return (result); // Bail if setAuto failed
13188+
13189+
if (packetUBXRXMSFRBX->callbackMessageData == nullptr) // Check if RAM has been allocated for the callback copy
13190+
{
13191+
packetUBXRXMSFRBX->callbackMessageData = new UBX_RXM_SFRBX_message_data_t[UBX_RXM_SFRBX_MESSAGE_CALLBACK_BUFFERS]; // Allocate RAM for the main struct
13192+
}
13193+
13194+
if (packetUBXRXMSFRBX->callbackMessageData == nullptr)
13195+
{
13196+
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
13197+
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
13198+
_debugSerial.println(F("setAutoRXMSFRBXmessageCallbackPtr: RAM alloc failed!"));
13199+
#endif
13200+
return (false);
13201+
}
13202+
13203+
packetUBXRXMSFRBX->callbackMessagePointerPtr = callbackMessagePointerPtr;
13204+
return (true);
13205+
}
1313513206

1313613207
// In case no config access to the GNSS is possible and SFRBX is send cyclically already
1313713208
// set config to suitable parameters
@@ -13166,6 +13237,8 @@ bool DevUBLOXGNSS::initPacketUBXRXMSFRBX()
1316613237
packetUBXRXMSFRBX->automaticFlags.flags.all = 0;
1316713238
packetUBXRXMSFRBX->callbackPointerPtr = nullptr;
1316813239
packetUBXRXMSFRBX->callbackData = nullptr;
13240+
packetUBXRXMSFRBX->callbackMessagePointerPtr = nullptr;
13241+
packetUBXRXMSFRBX->callbackMessageData = nullptr;
1316913242
packetUBXRXMSFRBX->moduleQueried = false;
1317013243
return (true);
1317113244
}
@@ -17806,11 +17879,11 @@ bool DevUBLOXGNSS::setLNAMode(sfe_ublox_lna_mode_e mode, uint8_t layer, uint16_t
1780617879
}
1780717880
bool DevUBLOXGNSS::getGPSL5HealthOverride(bool *override, uint8_t layer, uint16_t maxWait)
1780817881
{
17809-
return getVal8(UBLOX_CFG_SIGNAL_GPS_L5_HEALTH_OVERRIDE, (uint8_t *)override, layer, maxWait); // Get the GPS L5 health override status
17882+
return getVal8(UBLOX_CFG_SIGNAL_GPS_L5_HEALTH_OVERRIDE, (uint8_t *) override, layer, maxWait); // Get the GPS L5 health override status
1781017883
}
1781117884
bool DevUBLOXGNSS::setGPSL5HealthOverride(bool override, uint8_t layer, uint16_t maxWait)
1781217885
{
17813-
return setVal8(UBLOX_CFG_SIGNAL_GPS_L5_HEALTH_OVERRIDE, (uint8_t)override, layer, maxWait); // Set the GPS L5 health override status
17886+
return setVal8(UBLOX_CFG_SIGNAL_GPS_L5_HEALTH_OVERRIDE, (uint8_t) override, layer, maxWait); // Set the GPS L5 health override status
1781417887
}
1781517888

1781617889
#ifndef SFE_UBLOX_DISABLE_ESF

src/u-blox_GNSS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ class DevUBLOXGNSS
933933
bool setAutoRXMSFRBX(bool enabled, bool implicitUpdate, uint8_t layer = VAL_LAYER_RAM_BBR, uint16_t maxWait = kUBLOXGNSSDefaultMaxWait); // Enable/disable automatic RXM SFRBX 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
934934
bool setAutoRXMSFRBXrate(uint8_t rate, bool implicitUpdate = true, uint8_t layer = VAL_LAYER_RAM_BBR, uint16_t maxWait = kUBLOXGNSSDefaultMaxWait); // Set the rate for automatic SFRBX reports
935935
bool setAutoRXMSFRBXcallbackPtr(void (*callbackPointerPtr)(UBX_RXM_SFRBX_data_t *), uint8_t layer = VAL_LAYER_RAM_BBR, uint16_t maxWait = kUBLOXGNSSDefaultMaxWait); // Enable automatic SFRBX reports at the navigation frequency. Data is accessed from the callback.
936+
bool setAutoRXMSFRBXmessageCallbackPtr(void (*callbackMessagePointerPtr)(UBX_RXM_SFRBX_message_data_t *), uint8_t layer = VAL_LAYER_RAM_BBR, uint16_t maxWait = kUBLOXGNSSDefaultMaxWait); // Use this if you want all of the SFRBX message (including sync chars, checksum, etc.) to push to the PointPerfect Library
936937
bool assumeAutoRXMSFRBX(bool enabled, bool implicitUpdate = true); // In case no config access to the GPS is possible and RXM SFRBX is send cyclically already
937938
void flushRXMSFRBX(); // Mark all the data as read/stale
938939
void logRXMSFRBX(bool enabled = true); // Log data to file buffer

src/u-blox_structs.h

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ typedef struct
431431
uint8_t all;
432432
struct
433433
{
434-
uint8_t invalidLlh : 1; // 1 = Invalid lon, lat, height and hMSL
434+
uint8_t invalidLlh : 1; // 1 = Invalid lon, lat, height and hMSL
435435
uint8_t lastCorrectionAge : 4; // Age of the most recently received differential correction:
436436
// 0: Not available
437437
// 1: Age between 0 and 1 second
@@ -1429,6 +1429,7 @@ typedef struct
14291429
// Note: length is variable
14301430
// Note: on protocol version 17: numWords is (0..16)
14311431
// on protocol version 18+: numWords is (0..10)
1432+
#define UBX_RXM_SFRBX_MESSAGE_CALLBACK_BUFFERS 12
14321433
const uint8_t UBX_RXM_SFRBX_MAX_WORDS = 16;
14331434
const uint16_t UBX_RXM_SFRBX_MAX_LEN = 8 + (4 * UBX_RXM_SFRBX_MAX_WORDS);
14341435

@@ -1445,13 +1446,46 @@ typedef struct
14451446
uint32_t dwrd[UBX_RXM_SFRBX_MAX_WORDS]; // The data words
14461447
} UBX_RXM_SFRBX_data_t;
14471448

1449+
// Define a struct to hold the entire SFRBX message so the whole thing can be pushed to the PointPerfect Library
1450+
// Remember that the length of the payload will be variable.
14481451
typedef struct
14491452
{
1450-
ubxAutomaticFlags automaticFlags;
1453+
uint8_t sync1; // 0xB5
1454+
uint8_t sync2; // 0x62
1455+
uint8_t cls;
1456+
uint8_t ID;
1457+
uint8_t lengthLSB;
1458+
uint8_t lengthMSB;
1459+
uint8_t payload[UBX_RXM_SFRBX_MAX_LEN];
1460+
uint8_t checksumA;
1461+
uint8_t checksumB;
1462+
} UBX_RXM_SFRBX_message_data_t;
1463+
1464+
struct ubxSFRBXAutomaticFlags
1465+
{
1466+
union
1467+
{
1468+
uint16_t all;
1469+
struct
1470+
{
1471+
uint16_t automatic : 1; // Will this message be delivered and parsed "automatically" (without polling)
1472+
uint16_t implicitUpdate : 1; // Is the update triggered by accessing stale data (=true) or by a call to checkUblox (=false)
1473+
uint16_t addToFileBuffer : 1; // Should the raw UBX data be added to the file buffer?
1474+
uint16_t callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh?
1475+
uint16_t callbackMessageCopyValid : UBX_RXM_SFRBX_MESSAGE_CALLBACK_BUFFERS; // Are the copies of the data structs used by the callback valid/fresh?
1476+
} bits;
1477+
} flags;
1478+
};
1479+
1480+
typedef struct
1481+
{
1482+
ubxSFRBXAutomaticFlags automaticFlags;
14511483
UBX_RXM_SFRBX_data_t data;
14521484
bool moduleQueried;
14531485
void (*callbackPointerPtr)(UBX_RXM_SFRBX_data_t *);
14541486
UBX_RXM_SFRBX_data_t *callbackData;
1487+
void (*callbackMessagePointerPtr)(UBX_RXM_SFRBX_message_data_t *);
1488+
UBX_RXM_SFRBX_message_data_t *callbackMessageData;
14551489
} UBX_RXM_SFRBX_t;
14561490

14571491
// UBX-RXM-MEASX (0x02 0x14): Receiver Manager Messages: i.e. Satellite Status, RTC Status.
@@ -1798,7 +1832,7 @@ typedef struct
17981832
uint8_t reserved2[2]; // Reserved
17991833
uint32_t pinIrq; // Mask of pins value using the PIO Irq
18001834
uint32_t pullH; // Mask of pins value using the PIO pull high resistor
1801-
uint32_t pullL; // Mask of pins value using the PIO pull low resistor
1835+
uint32_t pullL; // Mask of pins value using the PIO pull low resistor
18021836
} UBX_MON_HW_data_t;
18031837

18041838
typedef struct
@@ -2793,8 +2827,8 @@ struct rtcmAutomaticFlags
27932827
uint8_t all;
27942828
struct
27952829
{
2796-
uint8_t dataValid : 1; // Is the copy of the data used by the get function valid/fresh? 0 = invalid, 1 = valid
2797-
uint8_t dataRead : 1; // Has the data been read? 0 = unread, 1 = read
2830+
uint8_t dataValid : 1; // Is the copy of the data used by the get function valid/fresh? 0 = invalid, 1 = valid
2831+
uint8_t dataRead : 1; // Has the data been read? 0 = unread, 1 = read
27982832
uint8_t callbackDataValid : 1; // Is the copy of the data used by the callback valid/fresh? 0 = invalid/stale, 1 = valid/fresh
27992833
} bits;
28002834
} flags;
@@ -2815,19 +2849,19 @@ const uint16_t RTCM_1005_MSG_LEN_BYTES = 19;
28152849

28162850
typedef struct
28172851
{
2818-
uint16_t MessageNumber; // Message Number (“1005” = 0x3ED)
2819-
uint16_t ReferenceStationID; // Reference Station ID
2820-
uint8_t ITRFRealizationYear; // ITRF Realization Year
2821-
bool GPSIndicator; // GPS Indicator
2822-
bool GLONASSIndicator; // GLONASS Indicator
2823-
bool GalileoIndicator; // Galileo Indicator
2824-
bool ReferenceStationIndicator; // Reference-Station Indicator
2825-
int64_t AntennaReferencePointECEFX; // Antenna Reference Point ECEF-X (0.0001m)
2852+
uint16_t MessageNumber; // Message Number (“1005” = 0x3ED)
2853+
uint16_t ReferenceStationID; // Reference Station ID
2854+
uint8_t ITRFRealizationYear; // ITRF Realization Year
2855+
bool GPSIndicator; // GPS Indicator
2856+
bool GLONASSIndicator; // GLONASS Indicator
2857+
bool GalileoIndicator; // Galileo Indicator
2858+
bool ReferenceStationIndicator; // Reference-Station Indicator
2859+
int64_t AntennaReferencePointECEFX; // Antenna Reference Point ECEF-X (0.0001m)
28262860
bool SingleReceiverOscillatorIndicator; // Single Receiver Oscillator Indicator
2827-
bool Reserved; // Reserved
2828-
int64_t AntennaReferencePointECEFY; // Antenna Reference Point ECEF-Y (0.0001m)
2829-
uint8_t QuarterCycleIndicator; // Quarter Cycle Indicator
2830-
int64_t AntennaReferencePointECEFZ; // Antenna Reference Point ECEF-Z (0.0001m)
2861+
bool Reserved; // Reserved
2862+
int64_t AntennaReferencePointECEFY; // Antenna Reference Point ECEF-Y (0.0001m)
2863+
uint8_t QuarterCycleIndicator; // Quarter Cycle Indicator
2864+
int64_t AntennaReferencePointECEFZ; // Antenna Reference Point ECEF-Z (0.0001m)
28312865
} RTCM_1005_data_t;
28322866

28332867
typedef struct
@@ -2844,18 +2878,18 @@ const uint16_t RTCM_1006_MSG_LEN_BYTES = 21;
28442878

28452879
typedef struct
28462880
{
2847-
uint16_t MessageNumber; // Message Number (“1006” = 0x3EE)
2848-
uint16_t ReferenceStationID; // Reference Station ID
2849-
uint8_t ITRFRealizationYear; // ITRF Realization Year
2850-
bool GPSIndicator; // GPS Indicator
2851-
bool GLONASSIndicator; // GLONASS Indicator
2852-
bool GalileoIndicator; // Galileo Indicator
2853-
bool ReferenceStationIndicator; // Reference-Station Indicator
2854-
int64_t AntennaReferencePointECEFX; // Antenna Reference Point ECEF-X (0.0001m)
2881+
uint16_t MessageNumber; // Message Number (“1006” = 0x3EE)
2882+
uint16_t ReferenceStationID; // Reference Station ID
2883+
uint8_t ITRFRealizationYear; // ITRF Realization Year
2884+
bool GPSIndicator; // GPS Indicator
2885+
bool GLONASSIndicator; // GLONASS Indicator
2886+
bool GalileoIndicator; // Galileo Indicator
2887+
bool ReferenceStationIndicator; // Reference-Station Indicator
2888+
int64_t AntennaReferencePointECEFX; // Antenna Reference Point ECEF-X (0.0001m)
28552889
bool SingleReceiverOscillatorIndicator; // Single Receiver Oscillator Indicator
2856-
bool Reserved; // Reserved
2857-
int64_t AntennaReferencePointECEFY; // Antenna Reference Point ECEF-Y (0.0001m)
2858-
uint8_t QuarterCycleIndicator; // Quarter Cycle Indicator
2859-
int64_t AntennaReferencePointECEFZ; // Antenna Reference Point ECEF-Z (0.0001m)
2860-
uint16_t AntennaHeight; // Antenna Height above the marker used in the survey campaign (0.0001m)
2890+
bool Reserved; // Reserved
2891+
int64_t AntennaReferencePointECEFY; // Antenna Reference Point ECEF-Y (0.0001m)
2892+
uint8_t QuarterCycleIndicator; // Quarter Cycle Indicator
2893+
int64_t AntennaReferencePointECEFZ; // Antenna Reference Point ECEF-Z (0.0001m)
2894+
uint16_t AntennaHeight; // Antenna Height above the marker used in the survey campaign (0.0001m)
28612895
} RTCM_1006_data_t;

0 commit comments

Comments
 (0)