From 5f50370fff81a66e012c589b81dfb2fbcde93e14 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Mon, 9 Oct 2023 18:02:23 +0300 Subject: [PATCH] Add user context to library The current overwrite method of weak pointer is a global overwrite. As class is not polymorphic type (aka the overwrite enabled methods are weak instead of virtual) and there is no vtable as none of the methods are virtual, there is no way to have instance specific overwrite. A user context will provide a method to call back into a context of a parent class and resolve the issue without making the class polymorphic. Signed-off-by: Alon Bar-Lev --- .../Example2_StartRTCMBase.ino | 37 ++++++++++++++++--- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 12 ++++++ src/SparkFun_u-blox_GNSS_Arduino_Library.h | 5 +++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/examples/NEO-M8P-2/Example2_StartRTCMBase/Example2_StartRTCMBase.ino b/examples/NEO-M8P-2/Example2_StartRTCMBase/Example2_StartRTCMBase.ino index a3ea14d..4b21af1 100644 --- a/examples/NEO-M8P-2/Example2_StartRTCMBase/Example2_StartRTCMBase.ino +++ b/examples/NEO-M8P-2/Example2_StartRTCMBase/Example2_StartRTCMBase.ino @@ -29,7 +29,30 @@ #include //Needed for I2C to GNSS #include //http://librarymanager/All#SparkFun_u-blox_GNSS -SFE_UBLOX_GNSS myGNSS; + +class MY_SFE_UBLOX_GNSS : public SFE_UBLOX_GNSS { + + friend SFE_UBLOX_GNSS; + +public: + MY_SFE_UBLOX_GNSS() + { + setUserContext(this); + } + +protected: + void myProcessRTCM(uint8_t incoming) + { + //Let's just pretty-print the HEX values for now + if (rtcmFrameCounter % 16 == 0) Serial.println(); + Serial.print(F(" ")); + if (incoming < 0x10) Serial.print(F("0")); + Serial.print(incoming, HEX); + } + +}; + +MY_SFE_UBLOX_GNSS myGNSS; void setup() { @@ -156,9 +179,11 @@ void loop() //Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc. void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming) { - //Let's just pretty-print the HEX values for now - if (myGNSS.rtcmFrameCounter % 16 == 0) Serial.println(); - Serial.print(F(" ")); - if (incoming < 0x10) Serial.print(F("0")); - Serial.print(incoming, HEX); + MY_SFE_UBLOX_GNSS *me; + + // jump into our instance + if ((me = static_cast(this)) != NULL) + { + me->myProcessRTCM(incoming); + } } diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 460dbce..03aefe9 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -633,6 +633,18 @@ size_t SFE_UBLOX_GNSS::getPacketCfgSpaceRemaining() return (packetCfgPayloadSize - packetCfg.len); } +// Sets user context +void SFE_UBLOX_GNSS::setUserContext(void *userContext) +{ + _userContext = userContext; +} + +// Retrive user context +void *SFE_UBLOX_GNSS::getUserContext(void) +{ + return _userContext; +} + // Initialize the I2C port bool SFE_UBLOX_GNSS::begin(TwoWire &wirePort, uint8_t deviceAddress, uint16_t maxWait, bool assumeSuccess) { diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index c83f002..6726127 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -682,6 +682,10 @@ class SFE_UBLOX_GNSS bool setPacketCfgPayloadSize(size_t payloadSize); // Set packetCfgPayloadSize size_t getPacketCfgSpaceRemaining(); // Returns the number of free bytes remaining in packetCfgPayload + // User context + void setUserContext(void *userContext); // Sets user context + void *getUserContext(void); // Retrive user context + // 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. // By default use the default I2C address, and use Wire port @@ -1708,6 +1712,7 @@ class SFE_UBLOX_GNSS SPIClass *_spiPort; // The instance of SPIClass uint8_t _csPin; // The chip select pin uint32_t _spiSpeed; // The speed to use for SPI (Hz) + void *_userContext; // Custom user context as callback context uint8_t _gpsI2Caddress = 0x42; // Default 7-bit unshifted address of the ublox 6/7/8/M8/F9 series // This can be changed using the ublox configuration software