From a1142c29c7a69c772061a911348e4f8423bb8a73 Mon Sep 17 00:00:00 2001 From: Lee Leahy Date: Sat, 30 Jul 2022 06:39:34 -1000 Subject: [PATCH] Make processRTCMframe weak Allow processRTCMframe to be overridden. Its replacement would now be able to place all of the bytes into a buffer for processing at a later time and eliminate a deep call stack for every byte. --- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 31 ++++++++++---------- src/SparkFun_u-blox_GNSS_Arduino_Library.h | 24 +++++++-------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 1b50c19..8a982f2 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -350,7 +350,7 @@ void SFE_UBLOX_GNSS::end(void) delete packetUBXRXMQZSSL6message; packetUBXRXMQZSSL6message = NULL; // Redundant? } - + if (packetUBXRXMCOR != NULL) { if (packetUBXRXMCOR->callbackData != NULL) @@ -2114,7 +2114,7 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r } else if (currentSentence == RTCM) { - processRTCMframe(incoming); // Deal with RTCM bytes + currentSentence = processRTCMframe(incoming, &rtcmFrameCounter); // Deal with RTCM bytes } } @@ -2876,13 +2876,15 @@ nmeaAutomaticFlags *SFE_UBLOX_GNSS::getNMEAFlagsPtr() // Byte 2: 10-bits of length of this packet including the first two-ish header bytes, + 6. // byte 3 + 4 bits: Msg type 12 bits // Example: D3 00 7C 43 F0 ... / 0x7C = 124+6 = 130 bytes in this packet, 0x43F = Msg type 1087 -void SFE_UBLOX_GNSS::processRTCMframe(uint8_t incoming) +SFE_UBLOX_GNSS::SentenceTypes SFE_UBLOX_GNSS::processRTCMframe(uint8_t incoming, uint16_t * rtcmFrameCounter) { - if (rtcmFrameCounter == 1) + static uint16_t rtcmLen = 0; + + if (*rtcmFrameCounter == 1) { rtcmLen = (incoming & 0x03) << 8; // Get the last two bits of this byte. Bits 8&9 of 10-bit length } - else if (rtcmFrameCounter == 2) + else if (*rtcmFrameCounter == 2) { rtcmLen |= incoming; // Bits 0-7 of packet length rtcmLen += 6; // There are 6 additional bytes of what we presume is header, msgType, CRC, and stuff @@ -2896,15 +2898,12 @@ void SFE_UBLOX_GNSS::processRTCMframe(uint8_t incoming) rtcmMsgType |= (incoming >> 4); //Message Type, bits 0-7 }*/ - rtcmFrameCounter++; + *rtcmFrameCounter++; processRTCM(incoming); // Here is where we expose this byte to the user - if (rtcmFrameCounter == rtcmLen) - { - // We're done! - currentSentence = NONE; // Reset and start looking for next sentence type - } + // Reset and start looking for next sentence type when done + return (*rtcmFrameCounter == rtcmLen) ? NONE : RTCM; } // This function is called for each byte of an RTCM frame @@ -3944,10 +3943,10 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg) // Note: length is variable with version 0x01 // Note: the field positions depend on the version { - // Full QZSSL6 message, including Class, ID and checksum + // Full QZSSL6 message, including Class, ID and checksum for (int ch = 0; ch < UBX_RXM_QZSSL6_NUM_CHANNELS; ch ++) { if (0 == (packetUBXRXMQZSSL6message->automaticFlags.flags.bits.callbackCopyValid & (1 << ch))) { - + packetUBXRXMQZSSL6message->callbackData[ch].sync1 = UBX_SYNCH_1; packetUBXRXMQZSSL6message->callbackData[ch].sync2 = UBX_SYNCH_2; packetUBXRXMQZSSL6message->callbackData[ch].cls = UBX_CLASS_RXM; @@ -3958,12 +3957,12 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg) memcpy(packetUBXRXMQZSSL6message->callbackData[ch].payload, msg->payload, msg->len); packetUBXRXMQZSSL6message->callbackData[ch].checksumA = msg->checksumA; - packetUBXRXMQZSSL6message->callbackData[ch].checksumB = msg->checksumB; + packetUBXRXMQZSSL6message->callbackData[ch].checksumB = msg->checksumB; packetUBXRXMQZSSL6message->automaticFlags.flags.bits.callbackCopyValid |= (1 << ch); break; // abort when added } - } + } } else if (msg->id == UBX_RXM_COR) { @@ -5605,7 +5604,7 @@ void SFE_UBLOX_GNSS::checkCallbacks(void) packetUBXRXMPMPmessage->callbackPointerPtr(packetUBXRXMPMPmessage->callbackData); // Call the callback packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale } - + if ((packetUBXRXMQZSSL6message != NULL) && // If RAM has been allocated for message storage (packetUBXRXMQZSSL6message->callbackData != NULL) && // If RAM has been allocated for the copy of the data (packetUBXRXMQZSSL6message->callbackPointerPtr != NULL)) // If the pointer to the callback has been defined diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 4cb9717..a7a2e3d 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -646,6 +646,15 @@ class SFE_UBLOX_GNSS SFE_UBLOX_GNSS(void); ~SFE_UBLOX_GNSS(void); + // Depending on the sentence type the processor will load characters into different arrays + enum SentenceTypes + { + NONE = 0, + NMEA, + UBX, + RTCM + } currentSentence = NONE; + // A default of 250ms for maxWait seems fine for I2C but is not enough for SerialUSB. // If you know you are only going to be using I2C / Qwiic communication, you can // safely reduce defaultMaxWait to 250. @@ -738,7 +747,7 @@ class SFE_UBLOX_GNSS void process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); // Processes NMEA and UBX binary sentences one byte at a time void processNMEA(char incoming) __attribute__((weak)); // Given a NMEA character, do something with it. User can overwrite if desired to use something like tinyGPS or MicroNMEA libraries - void processRTCMframe(uint8_t incoming); // Monitor the incoming bytes for start and length bytes + SentenceTypes processRTCMframe(uint8_t incoming, uint16_t * rtcmFrameCounter) __attribute__((weak)); // Monitor the incoming bytes for start and length bytes void processRTCM(uint8_t incoming) __attribute__((weak)); // Given rtcm byte, do something with it. User can overwrite if desired to pipe bytes to radio, internet, etc. void processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); // Given a character, file it away into the uxb packet structure void processUBXpacket(ubxPacket *msg); // Once a packet has been received and validated, identify this packet's class/id and update internal flags @@ -1187,7 +1196,7 @@ class SFE_UBLOX_GNSS // You can disable them by calling (e.g.) setVal8(UBLOX_CFG_MSGOUT_UBX_RXM_QZSSL6_I2C, 0) // The NEO-D9C does not support UBX-CFG-MSG bool setRXMQZSSL6messageCallbackPtr(void (*callbackPointerPtr)(UBX_RXM_QZSSL6_message_data_t *)); // Use this if you want all of the QZSSL6 message (including sync chars, checksum, etc.) to push to a GNSS - + bool setRXMCORcallbackPtr(void (*callbackPointerPtr)(UBX_RXM_COR_data_t *)); // RXM COR bool getRXMSFRBX(uint16_t maxWait = defaultMaxWait); // RXM SFRBX @@ -1582,15 +1591,6 @@ class SFE_UBLOX_GNSS uint16_t rtcmFrameCounter = 0; // Tracks the type of incoming byte inside RTCM frame private: - // Depending on the sentence type the processor will load characters into different arrays - enum SentenceTypes - { - NONE = 0, - NMEA, - UBX, - RTCM - } currentSentence = NONE; - // Depending on the ubx binary response class, store binary responses into different places enum classTypes { @@ -1761,8 +1761,6 @@ class SFE_UBLOX_GNSS uint8_t getNMEAMaxLength(); // Get the maximum length of this NMEA message nmeaAutomaticFlags *getNMEAFlagsPtr(); // Get a pointer to the flags - uint16_t rtcmLen = 0; - // Flag to prevent reentry into checkCallbacks // Prevent badness if the user accidentally calls checkCallbacks from inside a callback volatile bool checkCallbacksReentrant = false;