From 134fc75b67acefca55732445dfb995a70feb4669 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:26:42 -0400 Subject: [PATCH 1/3] UBX-RXM-PMREQ soft-off implemented --- src/gps/GPS.cpp | 31 ++++++++++++++++++++++++++++++- src/gps/GPS.h | 10 +++++++++- src/sleep.cpp | 13 +++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index e0b3e2e01..d2ebb6894 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -28,11 +28,19 @@ GPS *gps; /// Multiple GPS instances might use the same serial port (in sequence), but we can /// only init that port once. static bool didSerialInit; +uint8_t UBXscratch[250] = {0}; struct uBloxGnssModelInfo info; uint8_t uBloxProtocolVersion; -void GPS::UBXChecksum(byte *message, size_t length) +const uint8_t GPS::_message_PMREQ[] PROGMEM = { + 0x00, 0x00, // 4 bytes duration of request task + 0x00, 0x00, // (milliseconds) + 0x02, 0x00, // Task flag bitfield + 0x00, 0x00, // byte index 1 = sleep mode +}; + +void GPS::UBXChecksum(uint8_t *message, size_t length) { uint8_t CK_A = 0, CK_B = 0; @@ -47,6 +55,27 @@ void GPS::UBXChecksum(byte *message, size_t length) message[length - 1] = CK_B; } +// Function to create a ublox packet for editing in memory +uint8_t GPS::makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg) +{ + // Construct the UBX packet + UBXscratch[0] = 0xB5; // header + UBXscratch[1] = 0x62; // header + UBXscratch[2] = class_id; // class + UBXscratch[3] = msg_id; // id + UBXscratch[4] = payload_size; // length + UBXscratch[5] = 0x00; + + UBXscratch[6 + payload_size] = 0x00; // CK_A + UBXscratch[7 + payload_size] = 0x00; // CK_B + + for (int i = 0; i < payload_size; i++) { + UBXscratch[6 + i] = pgm_read_byte(&msg[i]); + } + UBXChecksum(UBXscratch, (payload_size + 8)); + return (payload_size + 8); +} + GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis) { uint8_t buffer[768] = {0}; diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 89ae7a916..eb5459ff2 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -62,6 +62,8 @@ class GPS : private concurrency::OSThread /** If !NULL we will use this serial port to construct our GPS */ static HardwareSerial *_serial_gps; + static const uint8_t _message_PMREQ[8]; + meshtastic_Position p = meshtastic_Position_init_default; GPS() : concurrency::OSThread("GPS") {} @@ -101,6 +103,9 @@ class GPS : private concurrency::OSThread // Empty the input buffer as quickly as possible void clearBuffer(); + // Create a ublox packet for editing in memory + uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); + protected: /// Do gps chipset specific init, return true for success virtual bool setupGPS(); @@ -141,6 +146,9 @@ class GPS : private concurrency::OSThread void setNumSatellites(uint8_t n); + // scratch space for creating ublox packets + uint8_t UBXscratch[250]; + private: /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs /// always returns 0 to indicate okay to sleep @@ -151,7 +159,7 @@ class GPS : private concurrency::OSThread int prepareDeepSleep(void *unused); // Calculate checksum - void UBXChecksum(byte *message, size_t length); + void UBXChecksum(uint8_t *message, size_t length); /** * Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode diff --git a/src/sleep.cpp b/src/sleep.cpp index 3d6da7feb..891cce228 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -204,6 +204,19 @@ void doGPSpowersave(bool on) notifyGPSSleep.notifyObservers(NULL); } #endif +#if !(defined(HAS_PMU) || defined(PIN_GPS_EN) || defined(PIN_GPS_WAKE)) + if (!on) { + uint8_t msglen; + notifyGPSSleep.notifyObservers(NULL); + msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ); + for (int i = 0; i < msglen; i++) { + gps->_serial_gps->write(gps->UBXscratch, msglen); + } + } else { + gps->forceWake(1); + gps->_serial_gps->write(0xFF); + } +#endif } void doDeepSleep(uint32_t msecToWake) From 4ff343b20fe3243f4bcefb586b28a6252a25d512 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:32:53 -0400 Subject: [PATCH 2/3] no byte... just 8 unsigned bits please --- src/gps/GPS.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index d2ebb6894..6221b0ff8 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -335,7 +335,7 @@ bool GPS::setupGPS() } else if (gnssModel == GNSS_MODEL_UBLOX) { /* uint8_t buffer[768] = {0}; - byte _message_GNSS[8] = {0xb5, 0x62, // Sync message for UBX protocol + uint8_t _message_GNSS[8] = {0xb5, 0x62, // Sync message for UBX protocol 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) 0x00, 0x00, // Length of payload (28 bytes) 0x00, 0x00}; @@ -359,7 +359,7 @@ bool GPS::setupGPS() 0) { // The original ublox 6 is GPS only and doesn't support the UBX-CFG-GNSS message if (strncmp(info.hwVersion, "00070000", 8) == 0) { // Max7 seems to only support GPS *or* GLONASS LOG_DEBUG("Setting GPS+SBAS\n"); - byte _message_GNSS[28] = { + uint8_t _message_GNSS[28] = { 0xb5, 0x62, // Sync message for UBX protocol 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) 0x14, 0x00, // Length of payload (28 bytes) @@ -377,7 +377,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); } else { - byte _message_GNSS[36] = { + uint8_t _message_GNSS[36] = { 0xb5, 0x62, // Sync message for UBX protocol 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) 0x1c, 0x00, // Length of payload (28 bytes) @@ -419,7 +419,7 @@ bool GPS::setupGPS() // Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board, // and we need to reduce interference from them - byte _message_JAM[16] = { + uint8_t _message_JAM[16] = { 0xB5, 0x62, // UBX protocol sync characters 0x06, 0x39, // Message class and ID (UBX-CFG-ITFM) 0x08, 0x00, // Length of payload (8 bytes) @@ -448,7 +448,7 @@ bool GPS::setupGPS() } // Configure navigation engine expert settings: - byte _message_NAVX5[48] = { + uint8_t _message_NAVX5[48] = { 0xb5, 0x62, // UBX protocol sync characters 0x06, 0x23, // Message class and ID (UBX-CFG-NAVX5) 0x28, 0x00, // Length of payload (40 bytes) @@ -498,7 +498,7 @@ bool GPS::setupGPS() // Lowering the update rate helps to save power. // Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz // is recommended to avoid a known issue with satellites disappearing. - byte _message_1Hz[] = { + uint8_t _message_1Hz[] = { 0xB5, 0x62, // UBX protocol sync characters 0x06, 0x08, // Message class and ID (UBX-CFG-RATE) 0x06, 0x00, // Length of payload (6 bytes) @@ -520,7 +520,7 @@ bool GPS::setupGPS() // Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical // coordinates. - byte _message_GGL[] = { + uint8_t _message_GGL[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -543,7 +543,7 @@ bool GPS::setupGPS() // Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and // the DOP (Dilution of Precision) - byte _message_GSA[] = { + uint8_t _message_GSA[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -560,7 +560,7 @@ bool GPS::setupGPS() } // Disable GSV. GSV - Satellites in view, details the number and location of satellites in view. - byte _message_GSV[] = { + uint8_t _message_GSV[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -578,7 +578,7 @@ bool GPS::setupGPS() // Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to // the ground. - byte _message_VTG[] = { + uint8_t _message_VTG[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -595,7 +595,7 @@ bool GPS::setupGPS() } // Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data. - byte _message_RMC[] = { + uint8_t _message_RMC[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -612,7 +612,7 @@ bool GPS::setupGPS() } // Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data. - byte _message_GGA[] = { + uint8_t _message_GGA[] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x01, // Message class and ID (UBX-CFG-MSG) 0x08, 0x00, // Length of payload (8 bytes) @@ -664,7 +664,7 @@ bool GPS::setupGPS() } } // We need save configuration to flash to make our config changes persistent - byte _message_SAVE[21] = { + uint8_t _message_SAVE[21] = { 0xB5, 0x62, // UBX protocol header 0x06, 0x09, // UBX class ID (Configuration Input Messages), message ID (UBX-CFG-CFG) 0x0D, 0x00, // Length of payload (13 bytes) @@ -1029,8 +1029,8 @@ GnssModel_t GPS::probe(int serialSpeed) // setting will not output command messages in UART1, resulting in unrecognized module information if (serialSpeed != 9600) { // Set the UART port to 9600 - byte _message_prt[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, - 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t _message_prt[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, + 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; UBXChecksum(_message_prt, sizeof(_message_prt)); _serial_gps->write(_message_prt, sizeof(_message_prt)); delay(500); @@ -1045,7 +1045,7 @@ GnssModel_t GPS::probe(int serialSpeed) } memset(buffer, 0, sizeof(buffer)); - byte _message_MONVER[8] = { + uint8_t _message_MONVER[8] = { 0xB5, 0x62, // Sync message for UBX protocol 0x0A, 0x04, // Message class and ID (UBX-MON-VER) 0x00, 0x00, // Length of payload (we're asking for an answer, so no payload) From c91e3066598a1fa2e9ae92d292c91875c9e9e064 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:59:34 -0400 Subject: [PATCH 3/3] Move packet scratch declaration to header --- src/gps/GPS.cpp | 1 - src/gps/GPS.h | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 6221b0ff8..8f2ce35d0 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -28,7 +28,6 @@ GPS *gps; /// Multiple GPS instances might use the same serial port (in sequence), but we can /// only init that port once. static bool didSerialInit; -uint8_t UBXscratch[250] = {0}; struct uBloxGnssModelInfo info; uint8_t uBloxProtocolVersion; diff --git a/src/gps/GPS.h b/src/gps/GPS.h index eb5459ff2..f6b4e95c8 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -106,6 +106,9 @@ class GPS : private concurrency::OSThread // Create a ublox packet for editing in memory uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); + // scratch space for creating ublox packets + uint8_t UBXscratch[250] = {0}; + protected: /// Do gps chipset specific init, return true for success virtual bool setupGPS(); @@ -146,9 +149,6 @@ class GPS : private concurrency::OSThread void setNumSatellites(uint8_t n); - // scratch space for creating ublox packets - uint8_t UBXscratch[250]; - private: /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs /// always returns 0 to indicate okay to sleep