From a90eef432fcf08e2a5483b3ebea4395530ebb58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 17 Aug 2023 12:17:36 +0200 Subject: [PATCH 01/97] update trunk to latest version --- .trunk/.gitignore | 2 +- .trunk/trunk.yaml | 35 ++++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.trunk/.gitignore b/.trunk/.gitignore index 8130ba6d1..695b51906 100644 --- a/.trunk/.gitignore +++ b/.trunk/.gitignore @@ -5,4 +5,4 @@ plugins user_trunk.yaml user.yaml -shims +tools diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 8ab9166fb..7e81046a7 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,37 +1,42 @@ version: 0.1 cli: - version: 1.10.0 + version: 1.13.0 plugins: sources: - id: trunk - ref: v0.0.17 + ref: v1.1.1 uri: https://github.com/trunk-io/plugins lint: enabled: - - taplo@0.7.0 - - ruff@0.0.265 + - bandit@1.7.5 + - checkov@2.4.1 + - terrascan@1.18.3 + - trivy@0.44.1 + - trufflehog@3.48.0 + - taplo@0.8.1 + - ruff@0.0.284 - yamllint@1.32.0 - isort@5.12.0 - - markdownlint@0.34.0 + - markdownlint@0.35.0 - oxipng@8.0.0 - svgo@3.0.2 - - actionlint@1.6.24 - - flake8@6.0.0 + - actionlint@1.6.25 + - flake8@6.1.0 - hadolint@2.12.0 - - shfmt@3.5.0 + - shfmt@3.6.0 - shellcheck@0.9.0 - - black@23.3.0 + - black@23.7.0 - git-diff-check - - gitleaks@8.16.3 - - clang-format@14.0.0 - - prettier@2.8.8 + - gitleaks@8.17.0 + - clang-format@16.0.3 + - prettier@3.0.2 disabled: - - taplo@0.7.0 + - taplo@0.8.1 - shellcheck@0.9.0 - - shfmt@3.5.0 + - shfmt@3.6.0 - oxipng@8.0.0 - actionlint@1.6.22 - - markdownlint@0.34.0 + - markdownlint@0.35.0 - hadolint@2.12.0 - svgo@3.0.2 runtimes: From 4767bd5497184323e81a46fadbf60f492d21a919 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 17 Aug 2023 20:22:34 -0500 Subject: [PATCH 02/97] Rename utils.h to avoid collision with library. (#2730) --- src/Power.cpp | 12 +++--------- src/graphics/Screen.cpp | 2 +- src/{utils.h => meshUtils.h} | 0 src/platform/esp32/main-esp32.cpp | 4 ++-- 4 files changed, 6 insertions(+), 12 deletions(-) rename src/{utils.h => meshUtils.h} (100%) diff --git a/src/Power.cpp b/src/Power.cpp index aad5b26ae..460f598b3 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -16,8 +16,8 @@ #include "buzz/buzz.h" #include "configuration.h" #include "main.h" +#include "meshUtils.h" #include "sleep.h" -#include "utils.h" #ifdef DEBUG_HEAP_MQTT #include "mqtt/MQTT.h" @@ -221,10 +221,7 @@ class AnalogBatteryLevel : public HasBatteryLevel /** * return true if there is a battery installed in this unit */ - virtual bool isBatteryConnect() override - { - return getBatteryPercent() != -1; - } + virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; } /// If we see a battery voltage higher than physics allows - assume charger is pumping /// in power @@ -245,10 +242,7 @@ class AnalogBatteryLevel : public HasBatteryLevel /// Assume charging if we have a battery and external power is connected. /// we can't be smart enough to say 'full'? - virtual bool isCharging() override - { - return isBatteryConnect() && isVbusIn(); - } + virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); } private: /// If we see a battery voltage higher than physics allows - assume charger is pumping diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index d4ed6fdb6..43635c441 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -36,11 +36,11 @@ along with this program. If not, see . #include "mesh-pb-constants.h" #include "mesh/Channels.h" #include "mesh/generated/meshtastic/deviceonly.pb.h" +#include "meshUtils.h" #include "modules/ExternalNotificationModule.h" #include "modules/TextMessageModule.h" #include "sleep.h" #include "target_specific.h" -#include "utils.h" #ifdef ARCH_ESP32 #include "esp_task_wdt.h" diff --git a/src/utils.h b/src/meshUtils.h similarity index 100% rename from src/utils.h rename to src/meshUtils.h diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 8abe6d56d..17a312664 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -9,10 +9,10 @@ #include "BleOta.h" #include "mesh/http/WiFiAPClient.h" +#include "meshUtils.h" #include "sleep.h" #include "soc/rtc.h" #include "target_specific.h" -#include "utils.h" #include #include #include @@ -220,4 +220,4 @@ void cpuDeepSleep(uint32_t msecToWake) esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs esp_deep_sleep_start(); // TBD mA sleep current (battery) -} +} \ No newline at end of file From 2dbdda204f421a63fce97c4f239962c8536545a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:17:55 -0500 Subject: [PATCH 03/97] [create-pull-request] automated change (#2731) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/portnums.pb.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index dc28ae3d1..d3dd7cfbe 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit dc28ae3d128b76707c0b87b6f3b2514c7f8514bd +Subproject commit d3dd7cfbe3bb7c0e406c055df58e6eccf94f1275 diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h index 44e9df70d..d354b7a42 100644 --- a/src/mesh/generated/meshtastic/portnums.pb.h +++ b/src/mesh/generated/meshtastic/portnums.pb.h @@ -69,6 +69,8 @@ typedef enum _meshtastic_PortNum { NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */ meshtastic_PortNum_AUDIO_APP = 9, + /* Same as Text Message but originating from Detection Sensor Module. */ + meshtastic_PortNum_DETECTION_SENSOR_APP = 10, /* Provides a 'ping' service that replies to any packet it receives. Also serves as a small example module. ENCODING: ASCII Plaintext */ From 5d78795065e51fde0ecbbd30a7e2193a50f7be0b Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 19 Aug 2023 07:46:34 -0500 Subject: [PATCH 04/97] Portnum promiscuity for text messages from other modules (#2732) * Add interested portnums to TextMessageModule * Send Detection Sensor Module messages on its own portnum * Add to Ext. Notification and consolidate logic * RANGE_TEST_APP portnum for RangeTestModule --- src/mesh/MeshService.h | 8 ++++++++ src/modules/DetectionSensorModule.h | 2 +- src/modules/ExternalNotificationModule.cpp | 9 +++++++-- src/modules/ExternalNotificationModule.h | 4 +++- src/modules/NeighborInfoModule.cpp | 2 +- src/modules/RangeTestModule.h | 2 +- src/modules/TextMessageModule.cpp | 6 ++++++ src/modules/TextMessageModule.h | 3 ++- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index fa184b391..eb40b7712 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -48,6 +48,14 @@ class MeshService uint32_t oldFromNum = 0; public: + static bool isTextPayload(const meshtastic_MeshPacket *p) + { + if (moduleConfig.range_test.enabled && p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) { + return true; + } + return p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP || + p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP; + } /// Called when some new packets have arrived from one of the radios Observable fromNumChanged; diff --git a/src/modules/DetectionSensorModule.h b/src/modules/DetectionSensorModule.h index bcc0b9419..ed6cddda5 100644 --- a/src/modules/DetectionSensorModule.h +++ b/src/modules/DetectionSensorModule.h @@ -5,7 +5,7 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh { public: DetectionSensorModule() - : SinglePortModule("detection", meshtastic_PortNum_TEXT_MESSAGE_APP), OSThread("DetectionSensorModule") + : SinglePortModule("detection", meshtastic_PortNum_DETECTION_SENSOR_APP), OSThread("DetectionSensorModule") { } diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index cbcf4e452..20191e706 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -128,6 +128,11 @@ int32_t ExternalNotificationModule::runOnce() } } +bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p) +{ + return MeshService::isTextPayload(p); +} + /** * Sets the external notification on for the specified index. * @@ -212,8 +217,8 @@ void ExternalNotificationModule::stopNow() } ExternalNotificationModule::ExternalNotificationModule() - : SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread( - "ExternalNotificationModule") + : SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP), + concurrency::OSThread("ExternalNotificationModule") { /* Uncomment the preferences below if you want to use the module diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index f8ec053dd..3331ec428 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -52,6 +52,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency: virtual int32_t runOnce() override; + virtual bool wantPacket(const meshtastic_MeshPacket *p) override; + bool isNagging = false; virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp, @@ -59,4 +61,4 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency: meshtastic_AdminMessage *response) override; }; -extern ExternalNotificationModule *externalNotificationModule; +extern ExternalNotificationModule *externalNotificationModule; \ No newline at end of file diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index 706b1db58..804384cb6 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -120,7 +120,7 @@ Assumes that the neighborInfo packet has been allocated */ uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo) { - int my_node_id = nodeDB.getNodeNum(); + uint my_node_id = nodeDB.getNodeNum(); neighborInfo->node_id = my_node_id; neighborInfo->last_sent_by_id = my_node_id; neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval; diff --git a/src/modules/RangeTestModule.h b/src/modules/RangeTestModule.h index ae2a8f182..b632d343e 100644 --- a/src/modules/RangeTestModule.h +++ b/src/modules/RangeTestModule.h @@ -29,7 +29,7 @@ class RangeTestModuleRadio : public SinglePortModule uint32_t lastRxID = 0; public: - RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_TEXT_MESSAGE_APP) + RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_RANGE_TEST_APP) { loopbackOk = true; // Allow locally generated messages to loop back to the client } diff --git a/src/modules/TextMessageModule.cpp b/src/modules/TextMessageModule.cpp index 8ff034fa9..0f86a6470 100644 --- a/src/modules/TextMessageModule.cpp +++ b/src/modules/TextMessageModule.cpp @@ -1,4 +1,5 @@ #include "TextMessageModule.h" +#include "MeshService.h" #include "NodeDB.h" #include "PowerFSM.h" #include "configuration.h" @@ -22,3 +23,8 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp return ProcessMessage::CONTINUE; // Let others look at this message also if they want } + +bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p) +{ + return MeshService::isTextPayload(p); +} \ No newline at end of file diff --git a/src/modules/TextMessageModule.h b/src/modules/TextMessageModule.h index 93b1bfaa2..cc0b0f9d5 100644 --- a/src/modules/TextMessageModule.h +++ b/src/modules/TextMessageModule.h @@ -20,6 +20,7 @@ class TextMessageModule : public SinglePortModule, public Observable Date: Sat, 19 Aug 2023 15:37:42 +0200 Subject: [PATCH 05/97] support BB Q10 keyboard (#2703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * support BB Q10 keyboard * remove debug code * fix wrong logic * fix left/right keys for cardkb * Try to enable Q10 kb after all * cppcheck * Only fire on Key release and assume 0x0a is a enter as well --------- Co-authored-by: Ben Meadors Co-authored-by: Thomas Göttgens --- src/configuration.h | 1 + src/detect/ScanI2C.cpp | 4 +- src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 1 + src/input/BBQ10Keyboard.cpp | 177 ++++++++++++++++++++++++++++ src/input/BBQ10Keyboard.h | 46 ++++++++ src/input/cardKbI2cImpl.cpp | 2 +- src/input/kbI2cBase.cpp | 84 +++++++++++-- src/input/kbI2cBase.h | 3 + src/main.cpp | 4 + src/modules/CannedMessageModule.cpp | 4 +- 11 files changed, 314 insertions(+), 13 deletions(-) create mode 100644 src/input/BBQ10Keyboard.cpp create mode 100644 src/input/BBQ10Keyboard.h diff --git a/src/configuration.h b/src/configuration.h index fb96430bc..e116854c2 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -101,6 +101,7 @@ along with this program. If not, see . // I2C Keyboards (M5Stack, RAK14004, T-Deck) #define CARDKB_ADDR 0x5F #define TDECK_KB_ADDR 0x55 +#define BBQ10_KB_ADDR 0x1F // ----------------------------------------------------------------------------- // SENSOR diff --git a/src/detect/ScanI2C.cpp b/src/detect/ScanI2C.cpp index 996bdf62a..bf206c190 100644 --- a/src/detect/ScanI2C.cpp +++ b/src/detect/ScanI2C.cpp @@ -30,8 +30,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const ScanI2C::FoundDevice ScanI2C::firstKeyboard() const { - ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, RAK14004}; - return firstOfOrNONE(3, types); + ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004}; + return firstOfOrNONE(4, types); } ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 418a6bf5e..15d9b1342 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -17,6 +17,7 @@ class ScanI2C RTC_PCF8563, CARDKB, TDECKKB, + BBQ10KB, RAK14004, PMU_AXP192_AXP2101, BME_680, diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 30f9e7b7c..ced1e34dd 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) break; SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n"); + SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n"); SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n"); #ifdef HAS_NCP5623 SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n"); diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp new file mode 100644 index 000000000..f0459d8f7 --- /dev/null +++ b/src/input/BBQ10Keyboard.cpp @@ -0,0 +1,177 @@ +// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd + +#include + +#include "BBQ10Keyboard.h" + +#define _REG_VER 1 +#define _REG_CFG 2 +#define _REG_INT 3 +#define _REG_KEY 4 +#define _REG_BKL 5 +#define _REG_DEB 6 +#define _REG_FRQ 7 +#define _REG_RST 8 +#define _REG_FIF 9 + +#define _WRITE_MASK (1 << 7) + +#define CFG_OVERFLOW_ON (1 << 0) +#define CFG_OVERFLOW_INT (1 << 1) +#define CFG_CAPSLOCK_INT (1 << 2) +#define CFG_NUMLOCK_INT (1 << 3) +#define CFG_KEY_INT (1 << 4) +#define CFG_PANIC_INT (1 << 5) + +#define INT_OVERFLOW (1 << 0) +#define INT_CAPSLOCK (1 << 1) +#define INT_NUMLOCK (1 << 2) +#define INT_KEY (1 << 3) +#define INT_PANIC (1 << 4) + +#define KEY_CAPSLOCK (1 << 5) +#define KEY_NUMLOCK (1 << 6) +#define KEY_COUNT_MASK (0x1F) + +BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(NULL), writeCallback(nullptr), readCallback(nullptr) {} + +void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire) +{ + m_addr = addr; + m_wire = wire; + + m_wire->begin(); + + reset(); +} + +void BBQ10Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr) +{ + m_addr = addr; + m_wire = nullptr; + writeCallback = w; + readCallback = r; + reset(); +} + +void BBQ10Keyboard::reset() +{ + if (m_wire) { + m_wire->beginTransmission(m_addr); + m_wire->write(_REG_RST); + m_wire->endTransmission(); + } + if (writeCallback) { + uint8_t data = 0; + writeCallback(m_addr, _REG_RST, &data, 0); + } + delay(100); +} + +void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const +{ + pinMode(pin, INPUT_PULLUP); + ::attachInterrupt(digitalPinToInterrupt(pin), func, RISING); +} + +void BBQ10Keyboard::detachInterrupt(uint8_t pin) const +{ + ::detachInterrupt(pin); +} + +void BBQ10Keyboard::clearInterruptStatus() +{ + writeRegister(_REG_INT, 0x00); +} + +uint8_t BBQ10Keyboard::status() const +{ + return readRegister8(_REG_KEY); +} + +uint8_t BBQ10Keyboard::keyCount() const +{ + return status() & KEY_COUNT_MASK; +} + +BBQ10Keyboard::KeyEvent BBQ10Keyboard::keyEvent() const +{ + KeyEvent event = {.key = '\0', .state = StateIdle}; + + if (keyCount() == 0) + return event; + + const uint16_t buf = readRegister16(_REG_FIF); + event.key = buf >> 8; + event.state = KeyState(buf & 0xFF); + + return event; +} + +float BBQ10Keyboard::backlight() const +{ + return readRegister8(_REG_BKL) / 255.0f; +} + +void BBQ10Keyboard::setBacklight(float value) +{ + writeRegister(_REG_BKL, value * 255); +} + +uint8_t BBQ10Keyboard::readRegister8(uint8_t reg) const +{ + if (m_wire) { + m_wire->beginTransmission(m_addr); + m_wire->write(reg); + m_wire->endTransmission(); + + m_wire->requestFrom(m_addr, (uint8_t)1); + if (m_wire->available() < 1) + return 0; + + return m_wire->read(); + } + if (readCallback) { + uint8_t data; + readCallback(m_addr, reg, &data, 1); + return data; + } + return 0; +} + +uint16_t BBQ10Keyboard::readRegister16(uint8_t reg) const +{ + uint8_t data[2] = {0}; + // uint8_t low = 0, high = 0; + if (m_wire) { + m_wire->beginTransmission(m_addr); + m_wire->write(reg); + m_wire->endTransmission(); + + m_wire->requestFrom(m_addr, (uint8_t)2); + if (m_wire->available() < 2) + return 0; + data[0] = m_wire->read(); + data[1] = m_wire->read(); + } + if (readCallback) { + readCallback(m_addr, reg, data, 2); + } + return (data[1] << 8) | data[0]; +} + +void BBQ10Keyboard::writeRegister(uint8_t reg, uint8_t value) +{ + uint8_t data[2]; + data[0] = reg | _WRITE_MASK; + data[1] = value; + + if (m_wire) { + m_wire->beginTransmission(m_addr); + m_wire->write(data, sizeof(uint8_t) * 2); + m_wire->endTransmission(); + } + if (writeCallback) { + writeCallback(m_addr, data[0], &(data[1]), 1); + } +} diff --git a/src/input/BBQ10Keyboard.h b/src/input/BBQ10Keyboard.h new file mode 100644 index 000000000..da6de71d7 --- /dev/null +++ b/src/input/BBQ10Keyboard.h @@ -0,0 +1,46 @@ +// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd + +#include "configuration.h" +#include + +class BBQ10Keyboard +{ + public: + typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len); + + enum KeyState { StateIdle = 0, StatePress, StateLongPress, StateRelease }; + + struct KeyEvent { + char key; + KeyState state; + }; + + BBQ10Keyboard(); + + void begin(uint8_t addr = BBQ10_KB_ADDR, TwoWire *wire = &Wire); + + void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = BBQ10_KB_ADDR); + + void reset(void); + + void attachInterrupt(uint8_t pin, void (*func)(void)) const; + void detachInterrupt(uint8_t pin) const; + void clearInterruptStatus(void); + + uint8_t status(void) const; + uint8_t keyCount(void) const; + KeyEvent keyEvent(void) const; + + float backlight() const; + void setBacklight(float value); + + uint8_t readRegister8(uint8_t reg) const; + uint16_t readRegister16(uint8_t reg) const; + void writeRegister(uint8_t reg, uint8_t value); + + private: + TwoWire *m_wire; + uint8_t m_addr; + i2c_com_fptr_t readCallback; + i2c_com_fptr_t writeCallback; +}; diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 44db1d952..e000f36eb 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {} void CardKbI2cImpl::init() { - if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) { + if (cardkb_found.address == 0x00) { disable(); return; } diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index f7fd62645..3289a665c 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -30,7 +30,7 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len int32_t KbI2cBase::runOnce() { - if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) { + if (cardkb_found.address == 0x00) { // Input device is not detected. return INT32_MAX; } @@ -41,11 +41,19 @@ int32_t KbI2cBase::runOnce() #ifdef I2C_SDA1 LOG_DEBUG("Using I2C Bus 1 (the second one)\n"); i2cBus = &Wire1; + if (cardkb_found.address == BBQ10_KB_ADDR) { + Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1); + Q10keyboard.setBacklight(0); + } break; #endif case ScanI2C::WIRE: LOG_DEBUG("Using I2C Bus 0 (the first one)\n"); i2cBus = &Wire; + if (cardkb_found.address == BBQ10_KB_ADDR) { + Q10keyboard.begin(BBQ10_KB_ADDR, &Wire); + Q10keyboard.setBacklight(0); + } break; case ScanI2C::NO_I2C: default: @@ -53,7 +61,60 @@ int32_t KbI2cBase::runOnce() } } - if (kb_model == 0x02) { + switch (kb_model) { + case 0x11: { // BB Q10 + int keyCount = Q10keyboard.keyCount(); + while (keyCount--) { + const BBQ10Keyboard::KeyEvent key = Q10keyboard.keyEvent(); + if ((key.key != 0x00) && (key.state == BBQ10Keyboard::StateRelease)) { + InputEvent e; + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; + e.source = this->_originName; + switch (key.key) { + case 0x1b: // ESC + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; + break; + case 0x08: // Back + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; + e.kbchar = key.key; + break; + case 0x12: // sym shift+2 + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; + break; + case 0x18: // sym shift+8 + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; + break; + case 0x14: // Left (sym shift+4) + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; + e.kbchar = 0x00; // tweak for destSelect + break; + case 0x16: // Right (sym shift+6) + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; + e.kbchar = 0x00; // tweak for destSelect + break; + case 0x0d: // Enter + case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; + break; + case 0x00: // nopress + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; + break; + default: // all other keys + e.inputEvent = ANYKEY; + e.kbchar = key.key; + break; + } + + if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) { + this->notifyObservers(&e); + } + } + } + break; + } + case 0x02: { // RAK14004 uint8_t rDataBuf[8] = {0}; uint8_t PrintDataBuf = 0; @@ -74,9 +135,12 @@ int32_t KbI2cBase::runOnce() e.kbchar = PrintDataBuf; this->notifyObservers(&e); } - } else if (kb_model == 0x00 || kb_model == 0x10) { - // m5 cardkb and T-Deck - i2cBus->requestFrom(kb_model == 0x00 ? CARDKB_ADDR : TDECK_KB_ADDR, 1); + break; + } + case 0x00: // CARDKB + case 0x10: { // T-DECK + + i2cBus->requestFrom((int)cardkb_found.address, 1); while (i2cBus->available()) { char c = i2cBus->read(); @@ -93,17 +157,19 @@ int32_t KbI2cBase::runOnce() break; case 0xb5: // Up e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; break; case 0xb6: // Down e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; break; case 0xb4: // Left e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = c; + e.kbchar = 0xb4; break; case 0xb7: // Right e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = c; + e.kbchar = 0xb7; break; case 0x0d: // Enter e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; @@ -121,7 +187,9 @@ int32_t KbI2cBase::runOnce() this->notifyObservers(&e); } } - } else { + break; + } + default: LOG_WARN("Unknown kb_model 0x%02x\n", kb_model); } return 300; diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h index a0a4dd608..59c26e16d 100644 --- a/src/input/kbI2cBase.h +++ b/src/input/kbI2cBase.h @@ -1,5 +1,6 @@ #pragma once +#include "BBQ10Keyboard.h" #include "InputBroker.h" #include "Wire.h" #include "concurrency/OSThread.h" @@ -16,4 +17,6 @@ class KbI2cBase : public Observable, public concurrency::OST const char *_originName; TwoWire *i2cBus = 0; + + BBQ10Keyboard Q10keyboard; }; diff --git a/src/main.cpp b/src/main.cpp index 5f0eaca30..09fa62896 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -387,6 +387,10 @@ void setup() // assign an arbitrary value to distinguish from other models kb_model = 0x10; break; + case ScanI2C::DeviceType::BBQ10KB: + // assign an arbitrary value to distinguish from other models + kb_model = 0x11; + break; default: // use this as default since it's also just zero LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type); diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 1e605656f..ad71a7112 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -65,8 +65,8 @@ CannedMessageModule::CannedMessageModule() { if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) { this->loadProtoForModule(); - if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address != CARDKB_ADDR) && - (cardkb_found.address != TDECK_KB_ADDR) && !INPUTBROKER_MATRIX_TYPE && !CANNED_MESSAGE_MODULE_ENABLE) { + if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address == 0x00) && !INPUTBROKER_MATRIX_TYPE && + !CANNED_MESSAGE_MODULE_ENABLE) { LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n"); this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED; disable(); From 364364263b3abd7bc05ad55102c67bffb696800d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 19 Aug 2023 09:44:40 -0500 Subject: [PATCH 06/97] Remove range_test goalie from drawing frames --- src/graphics/Screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 43635c441..9ccd28aba 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -365,7 +365,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta // Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled static bool shouldDrawMessage(const meshtastic_MeshPacket *packet) { - return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled; + return packet->from != 0 && !moduleConfig.store_forward.enabled; } /// Draw the last text message we received From f35c7be91709b39e1d57afa730509cdecf20cdf2 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 19 Aug 2023 09:45:48 -0500 Subject: [PATCH 07/97] Just putting back DELAYED_INTERVAL for reliability. Ran into problems --- src/modules/DetectionSensorModule.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index c8eb7793b..f1fc26244 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -46,10 +46,7 @@ int32_t DetectionSensorModule::runOnce() if ((millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) && hasDetectionEvent()) { sendDetectionMessage(); - return getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs < - moduleConfig.detection_sensor.state_broadcast_secs - ? moduleConfig.detection_sensor.minimum_broadcast_secs - : moduleConfig.detection_sensor.state_broadcast_secs); + return DELAYED_INTERVAL; } // Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort // of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state @@ -57,10 +54,7 @@ int32_t DetectionSensorModule::runOnce() else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 && (millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs)) { sendCurrentStateMessage(); - return getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs < - moduleConfig.detection_sensor.state_broadcast_secs - ? moduleConfig.detection_sensor.minimum_broadcast_secs - : moduleConfig.detection_sensor.state_broadcast_secs); + return DELAYED_INTERVAL; } return GPIO_POLLING_INTERVAL; } From 6fc76103a05924e653bb93c77dfa76cff4cad2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 19 Aug 2023 20:55:50 +0200 Subject: [PATCH 08/97] temporarily Enable debug print --- src/modules/CannedMessageModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index ad71a7112..091dee106 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -170,7 +170,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) if ((event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { - // LOG_DEBUG("Canned message event (%x)\n", event->kbchar); + LOG_DEBUG("Canned message event (%x)\n", event->kbchar); // tweak for left/right events generated via trackball/touch with empty kbchar if (!event->kbchar) { if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { @@ -649,4 +649,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor) return result; } -#endif \ No newline at end of file +#endif From ecceb109106241e67d4a5bc418436722d9edc44b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 19 Aug 2023 21:28:02 +0200 Subject: [PATCH 09/97] different debug print --- src/modules/CannedMessageModule.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 091dee106..8f59848d8 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -170,7 +170,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) if ((event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { - LOG_DEBUG("Canned message event (%x)\n", event->kbchar); + // LOG_DEBUG("Canned message event (%x)\n", event->kbchar); // tweak for left/right events generated via trackball/touch with empty kbchar if (!event->kbchar) { if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { @@ -195,6 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT; } // pass the pressed key + LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); this->payload = event->kbchar; this->lastTouchMillis = millis(); validEvent = true; From b47c9c165a6f9e0ff7fb1e51a753848ce0280d60 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 19 Aug 2023 18:06:33 -0500 Subject: [PATCH 10/97] [create-pull-request] automated change (#2733) Co-authored-by: thebentern Co-authored-by: Ben Meadors --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index f26bc2b58..ebc9a1191 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 2 +build = 3 From a55eac5c202fe95015add932c8dadc26e37ec9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 10:58:54 +0200 Subject: [PATCH 11/97] silence compiler warnings --- src/input/BBQ10Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index f0459d8f7..fa663d9b9 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -33,7 +33,7 @@ #define KEY_NUMLOCK (1 << 6) #define KEY_COUNT_MASK (0x1F) -BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(NULL), writeCallback(nullptr), readCallback(nullptr) {} +BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {} void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire) { From 0fcaaf39b0ad3ce6d9a46ecd79726f56c9c84bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 11:23:19 +0200 Subject: [PATCH 12/97] Try manual scancode for SYM --- src/input/BBQ10Keyboard.cpp | 4 +++ src/input/BBQ10Keyboard.h | 5 ++++ src/input/kbI2cBase.cpp | 51 ++++++++++++++++++++++++++++--------- src/input/kbI2cBase.h | 1 + 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index fa663d9b9..8f8399aef 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -22,6 +22,8 @@ #define CFG_NUMLOCK_INT (1 << 3) #define CFG_KEY_INT (1 << 4) #define CFG_PANIC_INT (1 << 5) +#define CFG_REPORT_MODS (1 << 6) +#define CFG_USE_MODS (1 << 7) #define INT_OVERFLOW (1 << 0) #define INT_CAPSLOCK (1 << 1) @@ -66,6 +68,8 @@ void BBQ10Keyboard::reset() writeCallback(m_addr, _REG_RST, &data, 0); } delay(100); + writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS); + delay(100); } void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const diff --git a/src/input/BBQ10Keyboard.h b/src/input/BBQ10Keyboard.h index da6de71d7..07d02308f 100644 --- a/src/input/BBQ10Keyboard.h +++ b/src/input/BBQ10Keyboard.h @@ -3,6 +3,11 @@ #include "configuration.h" #include +#define KEY_MOD_ALT (0x1A) +#define KEY_MOD_SHL (0x1B) +#define KEY_MOD_SHR (0x1C) +#define KEY_MOD_SYM (0x1D) + class BBQ10Keyboard { public: diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 3289a665c..56d065070 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -78,21 +78,48 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; - case 0x12: // sym shift+2 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + case 'e': // sym e + case '2': // sym shift+2 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x18: // sym shift+8 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + case 'x': // sym x + case '8': // sym shift+8 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x14: // Left (sym shift+4) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = 0x00; // tweak for destSelect + case 's': // sym s + case '4': // Left (sym shift+4) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x16: // Right (sym shift+6) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0x00; // tweak for destSelect + case 'f': // sym f + case '6': // Right (sym shift+6) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case KEY_MOD_SYM: // toggle SYM Key + is_sym = !is_sym; break; case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h index 59c26e16d..35b9b0901 100644 --- a/src/input/kbI2cBase.h +++ b/src/input/kbI2cBase.h @@ -19,4 +19,5 @@ class KbI2cBase : public Observable, public concurrency::OST TwoWire *i2cBus = 0; BBQ10Keyboard Q10keyboard; + bool is_sym = false; }; From 5f3a8b4924618f1566db2dc3181f9f3bcab2a7b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 15:43:21 +0200 Subject: [PATCH 13/97] fix crash and Debug logging in NeighbourInfo --- src/modules/NeighborInfoModule.cpp | 22 +++++++++++----------- src/modules/NeighborInfoModule.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index 804384cb6..a5bb671f0 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -15,12 +15,12 @@ NOTE: For debugging only */ void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np) { - LOG_DEBUG("%s NEIGHBORINFO PACKET from Node %d to Node %d (last sent by %d)\n", header, np->node_id, nodeDB.getNodeNum(), - np->last_sent_by_id); + LOG_DEBUG("%s NEIGHBORINFO PACKET from Node 0x%x to Node 0x%x (last sent by 0x%x)\n", header, np->node_id, + nodeDB.getNodeNum(), np->last_sent_by_id); LOG_DEBUG("----------------\n"); LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count); for (int i = 0; i < np->neighbors_count; i++) { - LOG_DEBUG("Neighbor %d: node_id=%d, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr); + LOG_DEBUG("Neighbor %d: node_id=0x%x, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr); } LOG_DEBUG("----------------\n"); } @@ -31,12 +31,12 @@ NOTE: for debugging only void NeighborInfoModule::printNodeDBNodes(const char *header) { int num_nodes = nodeDB.getNumMeshNodes(); - LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum()); + LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum()); LOG_DEBUG("----------------\n"); LOG_DEBUG("DB contains %d nodes\n", num_nodes); for (int i = 0; i < num_nodes; i++) { const meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i); - LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->num, dbEntry->snr); + LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->num, dbEntry->snr); } LOG_DEBUG("----------------\n"); } @@ -48,12 +48,12 @@ NOTE: for debugging only void NeighborInfoModule::printNodeDBNeighbors(const char *header) { int num_neighbors = getNumNeighbors(); - LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum()); + LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum()); LOG_DEBUG("----------------\n"); LOG_DEBUG("DB contains %d neighbors\n", num_neighbors); for (int i = 0; i < num_neighbors; i++) { const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i); - LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); + LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); } LOG_DEBUG("----------------\n"); } @@ -66,7 +66,7 @@ NOTE: For debugging only void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np) { int num_neighbors = getNumNeighbors(); - LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum()); + LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum()); LOG_DEBUG("----------------\n"); LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors); for (int i = 0; i < num_neighbors; i++) { @@ -78,9 +78,9 @@ void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtast } } if (!chosen) { - LOG_DEBUG(" Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); + LOG_DEBUG(" Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); } else { - LOG_DEBUG("---> Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); + LOG_DEBUG("---> Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr); } } LOG_DEBUG("----------------\n"); @@ -255,7 +255,7 @@ void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const } meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n, - uint32_t node_broadcast_interval_secs, int snr) + uint32_t node_broadcast_interval_secs, float snr) { // our node and the phone are the same node (not neighbors) if (n == 0) { diff --git a/src/modules/NeighborInfoModule.h b/src/modules/NeighborInfoModule.h index 20f68ca87..0e3ec09ca 100644 --- a/src/modules/NeighborInfoModule.h +++ b/src/modules/NeighborInfoModule.h @@ -49,7 +49,7 @@ class NeighborInfoModule : public ProtobufModule, priva meshtastic_NeighborInfo *allocateNeighborInfoPacket(); // Find a neighbor in our DB, create an empty neighbor if missing - meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, int snr); + meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, float snr); /* * Send info on our node's neighbors into the mesh From 8cfe130df3e62128458e7036bd9f1b841ac7717f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:11:19 +0200 Subject: [PATCH 14/97] update SYM Scancode --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 56d065070..2e8d04933 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,6 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 5c7c1cd25337d3e5d2f5f57790015632b281d279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 10:58:54 +0200 Subject: [PATCH 15/97] silence compiler warnings --- src/input/BBQ10Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index f0459d8f7..fa663d9b9 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -33,7 +33,7 @@ #define KEY_NUMLOCK (1 << 6) #define KEY_COUNT_MASK (0x1F) -BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(NULL), writeCallback(nullptr), readCallback(nullptr) {} +BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {} void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire) { From 7b1aeb60cd68f04f0ff82966acc729aef082acbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 11:23:19 +0200 Subject: [PATCH 16/97] Try manual scancode for SYM --- src/input/BBQ10Keyboard.cpp | 4 +++ src/input/BBQ10Keyboard.h | 5 ++++ src/input/kbI2cBase.cpp | 51 ++++++++++++++++++++++++++++--------- src/input/kbI2cBase.h | 1 + 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index fa663d9b9..8f8399aef 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -22,6 +22,8 @@ #define CFG_NUMLOCK_INT (1 << 3) #define CFG_KEY_INT (1 << 4) #define CFG_PANIC_INT (1 << 5) +#define CFG_REPORT_MODS (1 << 6) +#define CFG_USE_MODS (1 << 7) #define INT_OVERFLOW (1 << 0) #define INT_CAPSLOCK (1 << 1) @@ -66,6 +68,8 @@ void BBQ10Keyboard::reset() writeCallback(m_addr, _REG_RST, &data, 0); } delay(100); + writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS); + delay(100); } void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const diff --git a/src/input/BBQ10Keyboard.h b/src/input/BBQ10Keyboard.h index da6de71d7..07d02308f 100644 --- a/src/input/BBQ10Keyboard.h +++ b/src/input/BBQ10Keyboard.h @@ -3,6 +3,11 @@ #include "configuration.h" #include +#define KEY_MOD_ALT (0x1A) +#define KEY_MOD_SHL (0x1B) +#define KEY_MOD_SHR (0x1C) +#define KEY_MOD_SYM (0x1D) + class BBQ10Keyboard { public: diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 3289a665c..56d065070 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -78,21 +78,48 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; - case 0x12: // sym shift+2 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + case 'e': // sym e + case '2': // sym shift+2 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x18: // sym shift+8 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + case 'x': // sym x + case '8': // sym shift+8 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x14: // Left (sym shift+4) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = 0x00; // tweak for destSelect + case 's': // sym s + case '4': // Left (sym shift+4) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x16: // Right (sym shift+6) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0x00; // tweak for destSelect + case 'f': // sym f + case '6': // Right (sym shift+6) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case KEY_MOD_SYM: // toggle SYM Key + is_sym = !is_sym; break; case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h index 59c26e16d..35b9b0901 100644 --- a/src/input/kbI2cBase.h +++ b/src/input/kbI2cBase.h @@ -19,4 +19,5 @@ class KbI2cBase : public Observable, public concurrency::OST TwoWire *i2cBus = 0; BBQ10Keyboard Q10keyboard; + bool is_sym = false; }; From d6b629ae04694de4203487220c89df0688909d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:11:19 +0200 Subject: [PATCH 17/97] update SYM Scancode --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 56d065070..2e8d04933 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,6 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 7f1b58a222d79e86d2415cbb33d95e28937e625f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:23:37 +0200 Subject: [PATCH 18/97] trunk fmt --- src/input/kbI2cBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 2e8d04933..fd7bee074 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,7 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key - case 0x13: // Code scanner says the SYM key ias 0x13 + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 5453e4d1233da8a8a936e1261d3e92a66e1eb7be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:11:22 -0500 Subject: [PATCH 19/97] [create-pull-request] automated change (#2742) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index d3dd7cfbe..468ff2e24 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit d3dd7cfbe3bb7c0e406c055df58e6eccf94f1275 +Subproject commit 468ff2e2457d7534a907af0a21bdede9f4042cb7 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index f319c58b9..887e4d11e 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -111,6 +111,8 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_T_WATCH_S3 = 51, /* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */ meshtastic_HardwareModel_PICOMPUTER_S3 = 52, + /* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */ + meshtastic_HardwareModel_HELTEC_HT62 = 53, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ From 5bb207d88be146aa1778ebcabe254968a30f6b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 23 Aug 2023 09:44:20 +0200 Subject: [PATCH 20/97] reset sym after second keypress also remove debug print and non-working scancodes. --- src/input/kbI2cBase.cpp | 18 +++++++++++------- src/modules/CannedMessageModule.cpp | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index fd7bee074..106eed3a2 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -79,50 +79,53 @@ int32_t KbI2cBase::runOnce() e.kbchar = key.key; break; case 'e': // sym e - case '2': // sym shift+2 + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; e.kbchar = 0xb5; + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 'x': // sym x - case '8': // sym shift+8 + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; e.kbchar = 0xb6; + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 's': // sym s - case '4': // Left (sym shift+4) + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; e.kbchar = 0x00; // tweak for destSelect + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 'f': // sym f - case '6': // Right (sym shift+6) + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; e.kbchar = 0x00; // tweak for destSelect + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; - case KEY_MOD_SYM: // toggle SYM Key - case 0x13: // Code scanner says the SYM key ias 0x13 + + case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; break; - case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; break; @@ -132,6 +135,7 @@ int32_t KbI2cBase::runOnce() default: // all other keys e.inputEvent = ANYKEY; e.kbchar = key.key; + is_sym = false; // reset sym state after second keypress break; } diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 8f59848d8..ade9d0e5a 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -171,7 +171,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { // LOG_DEBUG("Canned message event (%x)\n", event->kbchar); - // tweak for left/right events generated via trackball/touch with empty kbchar + // tweak for left/right events generated via trackball/touch with empty kbchar if (!event->kbchar) { if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { this->payload = 0xb4; @@ -195,7 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT; } // pass the pressed key - LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); + // LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); this->payload = event->kbchar; this->lastTouchMillis = millis(); validEvent = true; From 00ffe73ebde7e24c55bb1853959017c6cf2b2362 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Wed, 23 Aug 2023 14:59:21 +0200 Subject: [PATCH 21/97] Heltec ESP32-C3 HT-CT62 support (#2741) * Add files via upload * Update platformio.ini * Update variant.h * Update platformio.ini * Switch to our new HW_MODEL --------- Co-authored-by: Ben Meadors Co-authored-by: Ben Meadors --- variants/heltec_esp32c3/pins_arduino.h | 32 +++++++++++++++++++++++ variants/heltec_esp32c3/platformio.ini | 12 +++++++++ variants/heltec_esp32c3/variant.h | 36 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 variants/heltec_esp32c3/pins_arduino.h create mode 100644 variants/heltec_esp32c3/platformio.ini create mode 100644 variants/heltec_esp32c3/variant.h diff --git a/variants/heltec_esp32c3/pins_arduino.h b/variants/heltec_esp32c3/pins_arduino.h new file mode 100644 index 000000000..db30a2f30 --- /dev/null +++ b/variants/heltec_esp32c3/pins_arduino.h @@ -0,0 +1,32 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define EXTERNAL_NUM_INTERRUPTS 22 +#define NUM_DIGITAL_PINS 22 +#define NUM_ANALOG_INPUTS 6 + +#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (esp32_adc2gpio[(p)]) : -1) +#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1) +#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS) + +static const uint8_t TX = 21; +static const uint8_t RX = 20; + +static const uint8_t SDA = 1; +static const uint8_t SCL = 0; + +static const uint8_t SS = 8; +static const uint8_t MOSI = 7; +static const uint8_t MISO = 6; +static const uint8_t SCK = 10; + +static const uint8_t A0 = 0; +static const uint8_t A1 = 1; +static const uint8_t A2 = 2; +static const uint8_t A3 = 3; +static const uint8_t A4 = 4; +static const uint8_t A5 = 5; + +#endif /* Pins_Arduino_h */ \ No newline at end of file diff --git a/variants/heltec_esp32c3/platformio.ini b/variants/heltec_esp32c3/platformio.ini new file mode 100644 index 000000000..a9843ef85 --- /dev/null +++ b/variants/heltec_esp32c3/platformio.ini @@ -0,0 +1,12 @@ +[env:heltec-ht62-esp32c3-sx1262] +extends = esp32c3_base +board = esp32-c3-devkitm-1 +board_level = extra +build_flags = + ${esp32_base.build_flags} + -D HELTEC_HT62 + -I variants/heltec_esp32c3 +monitor_speed = 115200 +upload_protocol = esptool +upload_port = /dev/ttyUSB0 +upload_speed = 921600 diff --git a/variants/heltec_esp32c3/variant.h b/variants/heltec_esp32c3/variant.h new file mode 100644 index 000000000..29ed88080 --- /dev/null +++ b/variants/heltec_esp32c3/variant.h @@ -0,0 +1,36 @@ +#define I2C_SDA 1 +#define I2C_SCL 0 + +#define BUTTON_PIN 9 +#define BUTTON_NEED_PULLUP + +// LED flashes brighter +// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf +#define LED_PIN 18 // LED +#define LED_INVERTED 1 + +#define HAS_SCREEN 0 +#define HAS_GPS 0 +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +#undef RF95_SCK +#undef RF95_MISO +#undef RF95_MOSI +#undef RF95_NSS + +#define USE_SX1262 +#define RF95_SCK 10 +#define RF95_MISO 6 +#define RF95_MOSI 7 +#define RF95_NSS 8 +#define LORA_DIO0 RADIOLIB_NC +#define LORA_RESET 5 +#define LORA_DIO1 3 +#define LORA_DIO2 RADIOLIB_NC +#define LORA_BUSY 4 +#define SX126X_CS RF95_NSS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_BUSY +#define SX126X_RESET LORA_RESET +#define SX126X_E22 From 2a1d8c40b4eb29f61a81f7ac8585180847ec3218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 24 Aug 2023 14:24:26 +0200 Subject: [PATCH 22/97] add TAB and ESC handling --- src/input/kbI2cBase.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 106eed3a2..cb94bed51 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -71,15 +71,30 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; e.source = this->_originName; switch (key.key) { - case 0x1b: // ESC - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; + case 'p': // TAB + if (is_sym) { + e.kbchar = 0x09; // TAB Scancode + is_sym = false; // reset sym state after second keypress + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case 'q': // ESC + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; + e.kbchar = 0x1b; + is_sym = false; // reset sym state after second keypress + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; case 0x08: // Back e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; case 'e': // sym e - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; e.kbchar = 0xb5; @@ -90,7 +105,6 @@ int32_t KbI2cBase::runOnce() } break; case 'x': // sym x - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; e.kbchar = 0xb6; @@ -101,7 +115,6 @@ int32_t KbI2cBase::runOnce() } break; case 's': // sym s - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; e.kbchar = 0x00; // tweak for destSelect @@ -112,7 +125,6 @@ int32_t KbI2cBase::runOnce() } break; case 'f': // sym f - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; e.kbchar = 0x00; // tweak for destSelect @@ -122,7 +134,6 @@ int32_t KbI2cBase::runOnce() e.kbchar = key.key; } break; - case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; break; From c2ae38405e9119258fe54a0f950e54702969aa3f Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Thu, 24 Aug 2023 14:58:24 +0200 Subject: [PATCH 23/97] Update architecture.h (#2746) --- src/platform/esp32/architecture.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 8f71bace6..da2295fb5 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -119,6 +119,8 @@ #define HW_VENDOR meshtastic_HardwareModel_BETAFPV_900_NANO_TX #elif defined(PICOMPUTER_S3) #define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3 +#elif defined(HELTEC_HT62) +#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62 #endif // @@ -149,4 +151,4 @@ #define RF95_NSS 18 #endif -#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 \ No newline at end of file +#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 From 03dc36ea1243d6958274ddd3e577823dd3221383 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 24 Aug 2023 10:55:49 -0500 Subject: [PATCH 24/97] Use fixed position regardless of gps lock (#2744) --- src/mesh/MeshService.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 96ea2f0a1..5fbd441b6 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -327,15 +327,15 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) // load data from GPS object, will add timestamp + battery further down pos = gps->p; } else { - // The GPS has lost lock, if we are fixed position we should just keep using - // the old position + // The GPS has lost lock #ifdef GPS_EXTRAVERBOSE LOG_DEBUG("onGPSchanged() - lost validLocation\n"); #endif - if (config.position.fixed_position) { - LOG_WARN("Using fixed position\n"); - pos = ConvertToPosition(node->position); - } + } + // Used fixed position if configured regalrdless of GPS lock + if (config.position.fixed_position) { + LOG_WARN("Using fixed position\n"); + pos = ConvertToPosition(node->position); } // Finally add a fresh timestamp and battery level reading From 312028b16136acfd4d85448e7cfee2625aaa1479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 25 Aug 2023 09:27:09 +0200 Subject: [PATCH 25/97] Possble fix ESC --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index cb94bed51..5cc829bac 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -73,6 +73,7 @@ int32_t KbI2cBase::runOnce() switch (key.key) { case 'p': // TAB if (is_sym) { + e.inputEvent = ANYKEY; e.kbchar = 0x09; // TAB Scancode is_sym = false; // reset sym state after second keypress } else { From 4ab67f36684d3275f2efbe4ca5b1c0efff3e9429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 25 Aug 2023 16:44:39 +0200 Subject: [PATCH 26/97] IGOR! Fetch me the brain! --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 5cc829bac..366e7fbb1 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -72,6 +72,7 @@ int32_t KbI2cBase::runOnce() e.source = this->_originName; switch (key.key) { case 'p': // TAB + case 't': // TAB as well if (is_sym) { e.inputEvent = ANYKEY; e.kbchar = 0x09; // TAB Scancode From a605c69eb4899ab2ccf51fe0f6194f64101baf89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 26 Aug 2023 07:36:04 -0500 Subject: [PATCH 27/97] [create-pull-request] automated change (#2748) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index ebc9a1191..830d7970e 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 3 +build = 4 From a42266f74bfdc94ebe3958c8cdf911d864b56032 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 28 Aug 2023 03:09:16 -0500 Subject: [PATCH 28/97] GPS: Fix checksum and remove spurious returns --- src/gps/GPS.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 27fe36fe5..ab5156fab 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -188,8 +188,8 @@ bool GPS::setupGPS() config.position.tx_gpio = GPS_TX_PIN; #endif -//#define BAUD_RATE 115200 -// ESP32 has a special set of parameters vs other arduino ports +// #define BAUD_RATE 115200 +// ESP32 has a special set of parameters vs other arduino ports #if defined(ARCH_ESP32) if (config.position.rx_gpio) { LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); @@ -267,7 +267,6 @@ bool GPS::setupGPS() LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands delay(750); - return true; } // Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board, @@ -535,7 +534,8 @@ bool GPS::setupGPS() _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); if (!getACK(0x06, 0x86)) { LOG_WARN("Unable to enable powersaving for GPS.\n"); - return true; + // T-beam doesn't support this mode. + // Don't bail from function early. } // We need save configuration to flash to make our config changes persistent @@ -675,6 +675,7 @@ void GPS::setAwake(bool on) if (isAwake != on) { LOG_DEBUG("WANT GPS=%d\n", on); if (on) { + clearBuffer(); // drop any old data waiting in the buffer lastWakeStartMsec = millis(); wake(); } else { @@ -858,7 +859,7 @@ GnssModel_t GPS::probe() { memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); // return immediately if the model is set by the variant.h file -//#ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info! +// #ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info! // return GNSS_MODEL_UBLOX; think about removing this macro and return) #if defined(GPS_L76K) return GNSS_MODEL_MTK; @@ -891,7 +892,8 @@ GnssModel_t GPS::probe() } } - uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30}; + uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; + UBXChecksum(cfg_rate, sizeof(cfg_rate)); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct if (!getAck(buffer, 384, 0x06, 0x08)) { From 2e3f762d3d24421da4c54d9053976cb27eaade45 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 28 Aug 2023 03:28:04 -0500 Subject: [PATCH 29/97] Catch a nullptr return rather than crash --- src/modules/PositionModule.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb49f0a8f..40dbf266e 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -11,8 +11,8 @@ PositionModule *positionModule; PositionModule::PositionModule() - : ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg), concurrency::OSThread( - "PositionModule") + : ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg), + concurrency::OSThread("PositionModule") { isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) @@ -65,7 +65,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes meshtastic_MeshPacket *PositionModule::allocReply() { if (ignoreRequest) { - return NULL; + return nullptr; } meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position @@ -142,6 +142,11 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha service.cancelSending(prevPacketId); meshtastic_MeshPacket *p = allocReply(); + if (p == nullptr) { + LOG_WARN("allocReply returned a nullptr"); + return; + } + p->to = dest; p->decoded.want_response = wantReplies; if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER) From 903f61960993c751de7334072649423f185b7bc6 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 28 Aug 2023 11:13:17 -0500 Subject: [PATCH 30/97] Add GPS serial speed scan --- src/gps/GPS.cpp | 64 +++++++++++++++++++++-------------------------- src/gps/GPS.h | 2 +- src/meshUtils.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++ src/meshUtils.h | 7 +++++- 4 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 src/meshUtils.cpp diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index ab5156fab..170304a61 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -4,6 +4,10 @@ #include "configuration.h" #include "sleep.h" +#ifdef ARCH_PORTDUINO +#include "meshUtils.h" +#endif + #ifndef GPS_RESET_MODE #define GPS_RESET_MODE HIGH #endif @@ -203,7 +207,17 @@ bool GPS::setupGPS() /* * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first */ - gnssModel = probe(); +#if defined(GPS_UC6580) + _serial_gps->updateBaudRate(115200); + gnssModel = GNSS_MODEL_UC6850; +#else + for (int serialSpeed : {9600, 4800, 38400, 57600, 115200}) { + LOG_DEBUG("Probing for GPS at %d \n", serialSpeed); + gnssModel = probe(serialSpeed); + if (gnssModel != GNSS_MODEL_UNKNOWN) + break; + } +#endif if (gnssModel == GNSS_MODEL_MTK) { /* @@ -262,7 +276,6 @@ bool GPS::setupGPS() // what is specified in the Ublox documentation. // There is also a possibility that the module may be GPS-only. LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); - return true; } else { LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands @@ -297,7 +310,6 @@ bool GPS::setupGPS() if (!getACK(0x06, 0x39)) { LOG_WARN("Unable to enable interference resistance.\n"); - return true; } // Configure navigation engine expert settings: @@ -343,7 +355,6 @@ bool GPS::setupGPS() if (!getACK(0x06, 0x23)) { LOG_WARN("Unable to configure extra settings.\n"); - return true; } /* @@ -384,7 +395,6 @@ bool GPS::setupGPS() if (!getACK(0x06, 0x08)) { LOG_WARN("Unable to set GPS update rate.\n"); - return true; } // Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical @@ -408,7 +418,6 @@ bool GPS::setupGPS() if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to disable NMEA GGL.\n"); - return true; } // Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and @@ -427,7 +436,6 @@ bool GPS::setupGPS() _serial_gps->write(_message_GSA, sizeof(_message_GSA)); if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to Enable NMEA GSA.\n"); - return true; } // Disable GSV. GSV - Satellites in view, details the number and location of satellites in view. @@ -445,7 +453,6 @@ bool GPS::setupGPS() _serial_gps->write(_message_GSV, sizeof(_message_GSV)); if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to disable NMEA GSV.\n"); - return true; } // Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to @@ -464,7 +471,6 @@ bool GPS::setupGPS() _serial_gps->write(_message_VTG, sizeof(_message_VTG)); if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to disable NMEA VTG.\n"); - return true; } // Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data. @@ -482,7 +488,6 @@ bool GPS::setupGPS() _serial_gps->write(_message_RMC, sizeof(_message_RMC)); if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to enable NMEA RMC.\n"); - return true; } // Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data. @@ -500,7 +505,6 @@ bool GPS::setupGPS() _serial_gps->write(_message_GGA, sizeof(_message_GGA)); if (!getACK(0x06, 0x01)) { LOG_WARN("Unable to enable NMEA GGA.\n"); - return true; } // The Power Management configuration allows the GPS module to operate in different power modes for optimized power @@ -534,8 +538,6 @@ bool GPS::setupGPS() _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); if (!getACK(0x06, 0x86)) { LOG_WARN("Unable to enable powersaving for GPS.\n"); - // T-beam doesn't support this mode. - // Don't bail from function early. } // We need save configuration to flash to make our config changes persistent @@ -558,10 +560,8 @@ bool GPS::setupGPS() if (!getACK(0x06, 0x09)) { LOG_WARN("Unable to save GNSS module configuration.\n"); - return true; } else { LOG_INFO("GNSS module configuration saved!\n"); - return true; } } } @@ -855,18 +855,15 @@ int GPS::prepareDeepSleep(void *unused) return 0; } -GnssModel_t GPS::probe() +GnssModel_t GPS::probe(int serialSpeed) { - memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); -// return immediately if the model is set by the variant.h file -// #ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info! -// return GNSS_MODEL_UBLOX; think about removing this macro and return) -#if defined(GPS_L76K) - return GNSS_MODEL_MTK; -#elif defined(GPS_UC6580) - _serial_gps->updateBaudRate(115200); - return GNSS_MODEL_UC6850; +#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) + _serial_gps->end(); + _serial_gps->begin(serialSpeed); #else + _serial_gps->updateBaudRate(serialSpeed); +#endif + memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); uint8_t buffer[384] = {0}; // Close all NMEA sentences , Only valid for MTK platform @@ -874,20 +871,17 @@ GnssModel_t GPS::probe() delay(20); // Get version information + clearBuffer(); _serial_gps->write("$PCAS06,0*1B\r\n"); uint32_t startTimeout = millis() + 500; while (millis() < startTimeout) { if (_serial_gps->available()) { - String ver = _serial_gps->readStringUntil('\r'); // Get module info , If the correct header is returned, // it can be determined that it is the MTK chip - int index = ver.indexOf("$"); - if (index != -1) { - ver = ver.substring(index); - if (ver.startsWith("$GPTXT,01,01,02,SW=")) { - LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n"); - return GNSS_MODEL_MTK; - } + int bytesRead = _serial_gps->readBytesUntil('\r', buffer, sizeof(buffer)); + if (strnstr((char *)buffer, "$GPTXT,01,01,02,SW=", bytesRead) != nullptr) { + LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n"); + return GNSS_MODEL_MTK; } } } @@ -897,9 +891,10 @@ GnssModel_t GPS::probe() _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct if (!getAck(buffer, 384, 0x06, 0x08)) { - LOG_WARN("Failed to find UBlox & MTK GNSS Module\n"); + LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; } + LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed); memset(buffer, 0, sizeof(buffer)); byte _message_MONVER[8] = { 0xB5, 0x62, // Sync message for UBX protocol @@ -971,7 +966,6 @@ GnssModel_t GPS::probe() } return GNSS_MODEL_UBLOX; -#endif } #if HAS_GPS diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 89f6c491d..9ad4a9c3e 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -172,7 +172,7 @@ class GPS : private concurrency::OSThread // Get GNSS model String getNMEA(); - GnssModel_t probe(); + GnssModel_t probe(int serialSpeed); int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID); diff --git a/src/meshUtils.cpp b/src/meshUtils.cpp new file mode 100644 index 000000000..cab05e54b --- /dev/null +++ b/src/meshUtils.cpp @@ -0,0 +1,58 @@ +#include "meshUtils.h" +#include + +/* + * Find the first occurrence of find in s, where the search is limited to the + * first slen characters of s. + * - + * Copyright (c) 2001 Mike Barcroft + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +char *strnstr(const char *s, const char *find, size_t slen) +{ + char c, sc; + size_t len; + + if ((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if (slen-- < 1 || (sc = *s++) == '\0') + return (NULL); + } while (sc != c); + if (len > slen) + return (NULL); + } while (strncmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} \ No newline at end of file diff --git a/src/meshUtils.h b/src/meshUtils.h index a725bf13c..a6436a8d5 100644 --- a/src/meshUtils.h +++ b/src/meshUtils.h @@ -4,4 +4,9 @@ template constexpr const T &clamp(const T &v, const T &lo, const T &hi) { return (v < lo) ? lo : (hi < v) ? hi : v; -} \ No newline at end of file +} + +#if (defined(ARCH_PORTDUINO) && !defined(STRNSTR)) +#define STRNSTR +char *strnstr(const char *s, const char *find, size_t slen); +#endif \ No newline at end of file From 3d2c419d0df59c298bbca4eb493785486a450861 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:24:56 -0400 Subject: [PATCH 31/97] Remove leftover debug msg --- src/gps/GPS.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 170304a61..281f32065 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -931,7 +931,6 @@ GnssModel_t GPS::probe(int serialSpeed) LOG_DEBUG("Module Info : \n"); LOG_DEBUG("Soft version: %s\n", info.swVersion); - LOG_DEBUG("first char is %c\n", (char)info.swVersion[0]); LOG_DEBUG("Hard version: %s\n", info.hwVersion); LOG_DEBUG("Extensions:%d\n", info.extensionNo); for (int i = 0; i < info.extensionNo; i++) { From cf762bbd42ed7bf37f382a61fbcb763d1b17a4a6 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Aug 2023 20:39:23 -0500 Subject: [PATCH 32/97] Cut down delay times for GPS probe and init --- src/gps/GPS.cpp | 55 ++++++++++++++++++++++++++----------------------- src/gps/GPS.h | 4 ++-- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 281f32065..8d80f8d42 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -47,7 +47,7 @@ void GPS::UBXChecksum(byte *message, size_t length) message[length - 1] = CK_B; } -bool GPS::getACK(uint8_t class_id, uint8_t msg_id) +bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) { uint8_t b; uint8_t ack = 0; @@ -66,15 +66,11 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id) buf[9] += buf[8]; } - while (1) { + while (millis() - startTime < waitMillis) { if (ack > 9) { - // LOG_INFO("Got ACK for class %02X message %02X\n", class_id, msg_id); + // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); return true; // ACK received } - if (millis() - startTime > 3000) { - LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); - return false; // No response received within 3 seconds - } if (_serial_gps->available()) { b = _serial_gps->read(); if (b == buf[ack]) { @@ -88,6 +84,8 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id) } } } + // LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); + return false; // No response received within timeout } /** @@ -99,14 +97,14 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id) * @param requestedID: request message ID constant * @retval length of payload message */ -int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID) +int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis) { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); uint16_t needRead; - while (millis() - startTime < 1200) { - while (_serial_gps->available()) { + while (millis() - startTime < waitMillis) { + if (_serial_gps->available()) { int c = _serial_gps->read(); switch (ubxFrameCounter) { case 0: @@ -159,6 +157,8 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t ubxFrameCounter = 0; } else { // return payload length + // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", requestedClass, requestedID, millis() - + // startTime); return needRead; } break; @@ -168,6 +168,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t } } } + // LOG_WARN("No response for class %02X message %02X\n", requestedClass, requestedID); return 0; } @@ -268,7 +269,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - if (!getACK(0x06, 0x3e)) { + if (!getACK(0x06, 0x3e, 300)) { // It's not critical if the module doesn't acknowledge this configuration. // The module should operate adequately with its factory or previously saved settings. // It appears that there is a firmware bug in some GPS modules: When an attempt is made @@ -308,7 +309,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_JAM, sizeof(_message_JAM)); - if (!getACK(0x06, 0x39)) { + if (!getACK(0x06, 0x39, 300)) { LOG_WARN("Unable to enable interference resistance.\n"); } @@ -353,7 +354,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_NAVX5, sizeof(_message_NAVX5)); - if (!getACK(0x06, 0x23)) { + if (!getACK(0x06, 0x23, 300)) { LOG_WARN("Unable to configure extra settings.\n"); } @@ -365,7 +366,7 @@ bool GPS::setupGPS() byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF}; _serial_gps->write(_message_nmea, sizeof(_message_nmea)); - if (!getACK(0x06, 0x00)) { + if (!getACK(0x06, 0x00, 300)) { LOG_WARN("Unable to enable NMEA Mode.\n"); return true; } @@ -393,7 +394,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_1Hz, sizeof(_message_1Hz)); - if (!getACK(0x06, 0x08)) { + if (!getACK(0x06, 0x08, 300)) { LOG_WARN("Unable to set GPS update rate.\n"); } @@ -416,7 +417,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_GGL, sizeof(_message_GGL)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to disable NMEA GGL.\n"); } @@ -434,7 +435,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GSA, sizeof(_message_GSA)); _serial_gps->write(_message_GSA, sizeof(_message_GSA)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to Enable NMEA GSA.\n"); } @@ -451,7 +452,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GSV, sizeof(_message_GSV)); _serial_gps->write(_message_GSV, sizeof(_message_GSV)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to disable NMEA GSV.\n"); } @@ -469,7 +470,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_VTG, sizeof(_message_VTG)); _serial_gps->write(_message_VTG, sizeof(_message_VTG)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to disable NMEA VTG.\n"); } @@ -486,7 +487,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_RMC, sizeof(_message_RMC)); _serial_gps->write(_message_RMC, sizeof(_message_RMC)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to enable NMEA RMC.\n"); } @@ -503,7 +504,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GGA, sizeof(_message_GGA)); _serial_gps->write(_message_GGA, sizeof(_message_GGA)); - if (!getACK(0x06, 0x01)) { + if (!getACK(0x06, 0x01, 300)) { LOG_WARN("Unable to enable NMEA GGA.\n"); } @@ -536,7 +537,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - if (!getACK(0x06, 0x86)) { + if (!getACK(0x06, 0x86, 300)) { LOG_WARN("Unable to enable powersaving for GPS.\n"); } @@ -558,7 +559,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_SAVE, sizeof(_message_SAVE)); - if (!getACK(0x06, 0x09)) { + if (!getACK(0x06, 0x09, 300)) { LOG_WARN("Unable to save GNSS module configuration.\n"); } else { LOG_INFO("GNSS module configuration saved!\n"); @@ -864,7 +865,7 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->updateBaudRate(serialSpeed); #endif memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); - uint8_t buffer[384] = {0}; + uint8_t buffer[768] = {0}; // Close all NMEA sentences , Only valid for MTK platform _serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n"); @@ -888,9 +889,10 @@ GnssModel_t GPS::probe(int serialSpeed) uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; UBXChecksum(cfg_rate, sizeof(cfg_rate)); + clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct - if (!getAck(buffer, 384, 0x06, 0x08)) { + if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 750)) { LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; } @@ -904,9 +906,10 @@ GnssModel_t GPS::probe(int serialSpeed) }; // Get Ublox gnss module hardware and software info UBXChecksum(_message_MONVER, sizeof(_message_MONVER)); + clearBuffer(); _serial_gps->write(_message_MONVER, sizeof(_message_MONVER)); - uint16_t len = getAck(buffer, 384, 0x0A, 0x04); + uint16_t len = getAck(buffer, sizeof(buffer), 0x0A, 0x04, 1200); if (len) { // LOG_DEBUG("monver reply size = %d\n", len); uint16_t position = 0; diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 9ad4a9c3e..1eb96f8cc 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -161,7 +161,7 @@ class GPS : private concurrency::OSThread */ uint32_t getSleepTime() const; - bool getACK(uint8_t c, uint8_t i); + bool getACK(uint8_t c, uint8_t i, int waitMillis); /** * Tell users we have new GPS readings @@ -174,7 +174,7 @@ class GPS : private concurrency::OSThread String getNMEA(); GnssModel_t probe(int serialSpeed); - int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID); + int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); // delay counter to allow more sats before fixed position stops GPS thread uint8_t fixeddelayCtr = 0; From 79cfc4b72546809688e750a02eb2273568d99c95 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Aug 2023 20:40:01 -0500 Subject: [PATCH 33/97] Avoid Serial output mangling with RTOS. --- src/RedirectablePrint.cpp | 15 ++++++++++++++- src/RedirectablePrint.h | 10 ++++++++-- src/SerialConsole.cpp | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 0e8e1c798..2d73c7c9b 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -18,6 +18,12 @@ NoopPrint noopPrint; #if HAS_WIFI || HAS_ETHERNET extern Syslog syslog; #endif +void RedirectablePrint::rpInit() +{ +#ifdef HAS_FREE_RTOS + inDebugPrint = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace); +#endif +} void RedirectablePrint::setDestination(Print *_dest) { @@ -66,9 +72,12 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) return 0; } size_t r = 0; - +#ifdef HAS_FREE_RTOS + if (inDebugPrint != nullptr && xSemaphoreTake(inDebugPrint, portMAX_DELAY) == pdTRUE) { +#else if (!inDebugPrint) { inDebugPrint = true; +#endif va_list arg; va_start(arg, format); @@ -141,7 +150,11 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) va_end(arg); isContinuationMessage = !hasNewline; +#ifdef HAS_FREE_RTOS + xSemaphoreGive(inDebugPrint); +#else inDebugPrint = false; +#endif } return r; diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index 560021972..31cc1b6ef 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -1,5 +1,6 @@ #pragma once +#include "../freertosinc.h" #include #include #include @@ -16,14 +17,19 @@ class RedirectablePrint : public Print /// Used to allow multiple logDebug messages to appear on a single log line bool isContinuationMessage = false; +#ifdef HAS_FREE_RTOS + SemaphoreHandle_t inDebugPrint = nullptr; + StaticSemaphore_t _MutexStorageSpace; +#else volatile bool inDebugPrint = false; - +#endif public: explicit RedirectablePrint(Print *_dest) : dest(_dest) {} /** * Set a new destination */ + void rpInit(); void setDestination(Print *dest); virtual size_t write(uint8_t c); @@ -54,4 +60,4 @@ class NoopPrint : public Print /** * A printer that doesn't go anywhere */ -extern NoopPrint noopPrint; +extern NoopPrint noopPrint; \ No newline at end of file diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index e827dcf3b..ed217c3ed 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -12,6 +12,7 @@ SerialConsole *console; void consoleInit() { new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread + DEBUG_PORT.rpInit(); // Simply sets up semaphore } void consolePrintf(const char *format, ...) From a61f969773de1606d5ad38b2cbedc2aba3f6c527 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Aug 2023 22:19:50 -0500 Subject: [PATCH 34/97] Increase GPS detection timeout slightly --- src/gps/GPS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 8d80f8d42..b14d31de4 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -892,7 +892,7 @@ GnssModel_t GPS::probe(int serialSpeed) clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct - if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 750)) { + if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 1000)) { LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; } From 6803fd7949505867a7aa0028c58b3dfeb460b079 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 1 Sep 2023 11:55:46 -0500 Subject: [PATCH 35/97] More fixes for GPS chips with unexpected baud --- src/gps/GPS.cpp | 77 +++++++++++++++++++++++++++++++------------------ src/gps/GPS.h | 5 ++-- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index b14d31de4..34352032f 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -47,6 +47,30 @@ void GPS::UBXChecksum(byte *message, size_t length) message[length - 1] = CK_B; } +bool GPS::getACK(const char *message, int waitMillis) +{ + uint8_t buffer[768] = {0}; + uint8_t b; + int bytesRead; + uint32_t startTimeout = millis() + waitMillis; + while (millis() < startTimeout) { + bytesRead = 0; + while ((_serial_gps->available()) && (millis() < startTimeout)) { + b = _serial_gps->read(); + buffer[bytesRead] = b; + bytesRead++; + if ((bytesRead == 768) || (b == '\r')) + break; + // Get module info , If the correct header is returned, + // it can be determined that it is the MTK chip + } + if (strnstr((char *)buffer, message, bytesRead) != nullptr) { + return true; + } + } + return false; +} + bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) { uint8_t b; @@ -68,7 +92,7 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) while (millis() - startTime < waitMillis) { if (ack > 9) { - // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); + LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); return true; // ACK received } if (_serial_gps->available()) { @@ -84,7 +108,7 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) } } } - // LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); + LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); return false; // No response received within timeout } @@ -358,20 +382,6 @@ bool GPS::setupGPS() LOG_WARN("Unable to configure extra settings.\n"); } - /* - tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after - setting will not output command messages in UART1, resulting in unrecognized module information - - // Set the UART port to output NMEA only - byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, - 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF}; - _serial_gps->write(_message_nmea, sizeof(_message_nmea)); - if (!getACK(0x06, 0x00, 300)) { - LOG_WARN("Unable to enable NMEA Mode.\n"); - return true; - } - */ - // ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid // Set GPS update rate to 1Hz @@ -874,17 +884,9 @@ GnssModel_t GPS::probe(int serialSpeed) // Get version information clearBuffer(); _serial_gps->write("$PCAS06,0*1B\r\n"); - uint32_t startTimeout = millis() + 500; - while (millis() < startTimeout) { - if (_serial_gps->available()) { - // Get module info , If the correct header is returned, - // it can be determined that it is the MTK chip - int bytesRead = _serial_gps->readBytesUntil('\r', buffer, sizeof(buffer)); - if (strnstr((char *)buffer, "$GPTXT,01,01,02,SW=", bytesRead) != nullptr) { - LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n"); - return GNSS_MODEL_MTK; - } - } + if (getACK("$GPTXT,01,01,02,SW=", 500)) { + LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n"); + return GNSS_MODEL_MTK; } uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; @@ -892,11 +894,30 @@ GnssModel_t GPS::probe(int serialSpeed) clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct - if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 1000)) { + if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 1500)) { LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; } LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed); + + // tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after + // 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}; + UBXChecksum(_message_prt, sizeof(_message_prt)); + _serial_gps->write(_message_prt, sizeof(_message_prt)); + delay(500); + serialSpeed = 9600; +#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) + _serial_gps->end(); + _serial_gps->begin(serialSpeed); +#else + _serial_gps->updateBaudRate(serialSpeed); +#endif + } + memset(buffer, 0, sizeof(buffer)); byte _message_MONVER[8] = { 0xB5, 0x62, // Sync message for UBX protocol diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 1eb96f8cc..0330151f3 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -161,8 +161,6 @@ class GPS : private concurrency::OSThread */ uint32_t getSleepTime() const; - bool getACK(uint8_t c, uint8_t i, int waitMillis); - /** * Tell users we have new GPS readings */ @@ -175,7 +173,8 @@ class GPS : private concurrency::OSThread GnssModel_t probe(int serialSpeed); int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); - + bool getACK(uint8_t c, uint8_t i, int waitMillis); + bool getACK(const char *message, int waitMillis); // delay counter to allow more sats before fixed position stops GPS thread uint8_t fixeddelayCtr = 0; From 6d93fab49537978cc0b3bc1b47b6d294f36b32a0 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Fri, 1 Sep 2023 21:35:57 +0200 Subject: [PATCH 36/97] Add neighbor IDs to MQTT JSON (#2756) * Add neighbor IDs to JSON * Limit #neighbors to what we can actually save * Put neighbor IDs in an array * Add SNR to neighbors in nested objects --- src/modules/NeighborInfoModule.cpp | 2 +- src/mqtt/MQTT.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index a5bb671f0..d6fb572a9 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -277,7 +277,7 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen } // otherwise, allocate one and assign data to it // TODO: max memory for the database should take neighbors into account, but currently doesn't - if (*numNeighbors < MAX_NUM_NODES) { + if (*numNeighbors < MAX_NUM_NEIGHBORS) { (*numNeighbors)++; } meshtastic_Neighbor *new_nbr = &neighbors[((*numNeighbors) - 1)]; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 7a1861756..7ff85d148 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -656,8 +656,18 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) &scratch)) { decoded = &scratch; msgPayload["node_id"] = new JSONValue((uint)decoded->node_id); + msgPayload["node_broadcast_interval_secs"] = new JSONValue((uint)decoded->node_broadcast_interval_secs); + msgPayload["last_sent_by_id"] = new JSONValue((uint)decoded->last_sent_by_id); msgPayload["neighbors_count"] = new JSONValue(decoded->neighbors_count); - msgPayload["neighbors"] = new JSONValue(decoded->neighbors); + JSONArray neighbors; + for (uint8_t i = 0; i < decoded->neighbors_count; i++) { + JSONObject neighborObj; + neighborObj["node_id"] = new JSONValue((uint)decoded->neighbors[i].node_id); + neighborObj["snr"] = new JSONValue((int)decoded->neighbors[i].snr); + neighbors.push_back(new JSONValue(neighborObj)); + } + msgPayload["neighbors"] = new JSONValue(neighbors); + jsonObj["payload"] = new JSONValue(msgPayload); } else { LOG_ERROR("Error decoding protobuf for neighborinfo message!\n"); } From 5d6f0ea6c4cec4e24bdfca1803f2bb23b9b6014e Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 1 Sep 2023 16:23:52 -0500 Subject: [PATCH 37/97] Fix possible edge case in GPS detection --- src/gps/GPS.cpp | 29 ++++++++++++++--------------- src/gps/GPS.h | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 34352032f..ec35930eb 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -51,21 +51,20 @@ bool GPS::getACK(const char *message, int waitMillis) { uint8_t buffer[768] = {0}; uint8_t b; - int bytesRead; + int bytesRead = 0; uint32_t startTimeout = millis() + waitMillis; while (millis() < startTimeout) { - bytesRead = 0; - while ((_serial_gps->available()) && (millis() < startTimeout)) { + if (_serial_gps->available()) { b = _serial_gps->read(); buffer[bytesRead] = b; bytesRead++; - if ((bytesRead == 768) || (b == '\r')) - break; - // Get module info , If the correct header is returned, - // it can be determined that it is the MTK chip - } - if (strnstr((char *)buffer, message, bytesRead) != nullptr) { - return true; + if ((bytesRead == 768) || (b == '\r')) { + if (strnstr((char *)buffer, message, bytesRead) != nullptr) { + return true; + } else { + bytesRead = 0; + } + } } } return false; @@ -92,7 +91,7 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) while (millis() - startTime < waitMillis) { if (ack > 9) { - LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); + // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); return true; // ACK received } if (_serial_gps->available()) { @@ -108,7 +107,7 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) } } } - LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); + // LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); return false; // No response received within timeout } @@ -121,7 +120,7 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) * @param requestedID: request message ID constant * @retval length of payload message */ -int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis) +int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis) { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); @@ -894,7 +893,7 @@ GnssModel_t GPS::probe(int serialSpeed) clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct - if (!getAck(buffer, sizeof(buffer), 0x06, 0x08, 1500)) { + if (!getACK(0x06, 0x08, 500)) { LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; } @@ -930,7 +929,7 @@ GnssModel_t GPS::probe(int serialSpeed) clearBuffer(); _serial_gps->write(_message_MONVER, sizeof(_message_MONVER)); - uint16_t len = getAck(buffer, sizeof(buffer), 0x0A, 0x04, 1200); + uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200); if (len) { // LOG_DEBUG("monver reply size = %d\n", len); uint16_t position = 0; diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 0330151f3..ff2ccf0e7 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -172,7 +172,7 @@ class GPS : private concurrency::OSThread String getNMEA(); GnssModel_t probe(int serialSpeed); - int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); + int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); bool getACK(uint8_t c, uint8_t i, int waitMillis); bool getACK(const char *message, int waitMillis); // delay counter to allow more sats before fixed position stops GPS thread From 1a178c7d33dd85e9b6dfd0ea182687fd68442cbb Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 2 Sep 2023 04:25:18 -0500 Subject: [PATCH 38/97] Add check for GPS Frame Errors message --- src/gps/GPS.cpp | 62 +++++++++++++++++++++++++++++++------------------ src/gps/GPS.h | 11 +++++++-- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index ec35930eb..d3bc23a21 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -47,7 +47,7 @@ void GPS::UBXChecksum(byte *message, size_t length) message[length - 1] = CK_B; } -bool GPS::getACK(const char *message, int waitMillis) +GPS_RESPONSE GPS::getACK(const char *message, int waitMillis) { uint8_t buffer[768] = {0}; uint8_t b; @@ -60,23 +60,25 @@ bool GPS::getACK(const char *message, int waitMillis) bytesRead++; if ((bytesRead == 768) || (b == '\r')) { if (strnstr((char *)buffer, message, bytesRead) != nullptr) { - return true; + return GNSS_RESPONSE_OK; } else { bytesRead = 0; } } } } - return false; + return GNSS_RESPONSE_NONE; } -bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) +GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) { uint8_t b; uint8_t ack = 0; const uint8_t ackP[2] = {class_id, msg_id}; uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned long startTime = millis(); + const char frame_errors[] = "More than 100 frame errors"; + int sCounter = 0; for (int j = 2; j < 6; j++) { buf[8] += buf[j]; @@ -92,23 +94,33 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) while (millis() - startTime < waitMillis) { if (ack > 9) { // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); - return true; // ACK received + return GNSS_RESPONSE_OK; // ACK received } if (_serial_gps->available()) { b = _serial_gps->read(); + if (b == frame_errors[sCounter]) { + sCounter++; + if (sCounter == 26) { + return GNSS_RESPONSE_FRAME_ERRORS; + } + } else { + sCounter = 0; + } + // LOG_DEBUG("%02X", b); if (b == buf[ack]) { ack++; } else { ack = 0; // Reset the acknowledgement counter if (buf[3] == 0x00) { // UBX-ACK-NAK message LOG_WARN("Got NAK for class %02X message %02X\n", class_id, msg_id); - return false; // NAK received + return GNSS_RESPONSE_NAK; // NAK received } } } } // LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); - return false; // No response received within timeout + // LOG_DEBUG("\n"); + return GNSS_RESPONSE_NONE; // No response received within timeout } /** @@ -292,7 +304,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - if (!getACK(0x06, 0x3e, 300)) { + if (getACK(0x06, 0x3e, 300) != GNSS_RESPONSE_OK) { // It's not critical if the module doesn't acknowledge this configuration. // The module should operate adequately with its factory or previously saved settings. // It appears that there is a firmware bug in some GPS modules: When an attempt is made @@ -332,7 +344,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_JAM, sizeof(_message_JAM)); - if (!getACK(0x06, 0x39, 300)) { + if (getACK(0x06, 0x39, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to enable interference resistance.\n"); } @@ -377,7 +389,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_NAVX5, sizeof(_message_NAVX5)); - if (!getACK(0x06, 0x23, 300)) { + if (getACK(0x06, 0x23, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to configure extra settings.\n"); } @@ -403,7 +415,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_1Hz, sizeof(_message_1Hz)); - if (!getACK(0x06, 0x08, 300)) { + if (getACK(0x06, 0x08, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to set GPS update rate.\n"); } @@ -426,7 +438,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_GGL, sizeof(_message_GGL)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to disable NMEA GGL.\n"); } @@ -444,7 +456,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GSA, sizeof(_message_GSA)); _serial_gps->write(_message_GSA, sizeof(_message_GSA)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to Enable NMEA GSA.\n"); } @@ -461,7 +473,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GSV, sizeof(_message_GSV)); _serial_gps->write(_message_GSV, sizeof(_message_GSV)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to disable NMEA GSV.\n"); } @@ -479,7 +491,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_VTG, sizeof(_message_VTG)); _serial_gps->write(_message_VTG, sizeof(_message_VTG)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to disable NMEA VTG.\n"); } @@ -496,7 +508,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_RMC, sizeof(_message_RMC)); _serial_gps->write(_message_RMC, sizeof(_message_RMC)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to enable NMEA RMC.\n"); } @@ -513,7 +525,7 @@ bool GPS::setupGPS() }; UBXChecksum(_message_GGA, sizeof(_message_GGA)); _serial_gps->write(_message_GGA, sizeof(_message_GGA)); - if (!getACK(0x06, 0x01, 300)) { + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to enable NMEA GGA.\n"); } @@ -546,7 +558,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - if (!getACK(0x06, 0x86, 300)) { + if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to enable powersaving for GPS.\n"); } @@ -568,7 +580,7 @@ bool GPS::setupGPS() // Send the message to the module _serial_gps->write(_message_SAVE, sizeof(_message_SAVE)); - if (!getACK(0x06, 0x09, 300)) { + if (getACK(0x06, 0x09, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to save GNSS module configuration.\n"); } else { LOG_INFO("GNSS module configuration saved!\n"); @@ -883,21 +895,25 @@ GnssModel_t GPS::probe(int serialSpeed) // Get version information clearBuffer(); _serial_gps->write("$PCAS06,0*1B\r\n"); - if (getACK("$GPTXT,01,01,02,SW=", 500)) { + if (getACK("$GPTXT,01,01,02,SW=", 500) == GNSS_RESPONSE_OK) { LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n"); return GNSS_MODEL_MTK; } uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; UBXChecksum(cfg_rate, sizeof(cfg_rate)); - clearBuffer(); + // clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct - if (!getACK(0x06, 0x08, 500)) { + GPS_RESPONSE response = getACK(0x06, 0x08, 750); + if (response == GNSS_RESPONSE_NONE) { LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed); return GNSS_MODEL_UNKNOWN; + } else if (response == GNSS_RESPONSE_FRAME_ERRORS) { + LOG_INFO("UBlox Frame Errors using baudrate %d\n", serialSpeed); + } else if (response == GNSS_RESPONSE_OK) { + LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed); } - LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed); // tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after // setting will not output command messages in UART1, resulting in unrecognized module information diff --git a/src/gps/GPS.h b/src/gps/GPS.h index ff2ccf0e7..485d53709 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -18,6 +18,13 @@ typedef enum { GNSS_MODEL_UNKNOWN, } GnssModel_t; +typedef enum { + GNSS_RESPONSE_NONE, + GNSS_RESPONSE_NAK, + GNSS_RESPONSE_FRAME_ERRORS, + GNSS_RESPONSE_OK, +} GPS_RESPONSE; + // Generate a string representation of DOP const char *getDOPString(uint32_t dop); @@ -173,8 +180,8 @@ class GPS : private concurrency::OSThread GnssModel_t probe(int serialSpeed); int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); - bool getACK(uint8_t c, uint8_t i, int waitMillis); - bool getACK(const char *message, int waitMillis); + GPS_RESPONSE getACK(uint8_t c, uint8_t i, int waitMillis); + GPS_RESPONSE getACK(const char *message, int waitMillis); // delay counter to allow more sats before fixed position stops GPS thread uint8_t fixeddelayCtr = 0; From b21368ecfa66a5d18b527da8518bc85dfa96b63b Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 2 Sep 2023 20:35:38 -0500 Subject: [PATCH 39/97] Add delay and debug code for GPS probe --- src/gps/GPS.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index d3bc23a21..35ac6e8e2 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -58,15 +58,21 @@ GPS_RESPONSE GPS::getACK(const char *message, int waitMillis) b = _serial_gps->read(); buffer[bytesRead] = b; bytesRead++; - if ((bytesRead == 768) || (b == '\r')) { + if ((bytesRead == 767) || (b == '\r')) { if (strnstr((char *)buffer, message, bytesRead) != nullptr) { return GNSS_RESPONSE_OK; } else { + buffer[bytesRead] = '\0'; + bytesRead++; + LOG_INFO("Bytes read:%s\n", (char*) buffer); bytesRead = 0; } } } } + buffer[bytesRead] = '\0'; + bytesRead++; + LOG_INFO("Bytes read:%s\n", (char*) buffer); return GNSS_RESPONSE_NONE; } @@ -887,6 +893,7 @@ GnssModel_t GPS::probe(int serialSpeed) #endif memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); uint8_t buffer[768] = {0}; + delay(100); // Close all NMEA sentences , Only valid for MTK platform _serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n"); From 7c98445ca34e23f0e859ccde444f31efce65f296 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 3 Sep 2023 01:50:11 -0500 Subject: [PATCH 40/97] Cleanup in prep for commiting Fix some compilation warnings gate debug code behind GPS_DEBUG minor fix in u-blox protocol detection Begin to gate GPS messages based on protover --- src/gps/GPS.cpp | 64 ++++++++++++++++++++++++++++--------------------- src/gps/GPS.h | 6 ++--- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 35ac6e8e2..650cefd57 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -47,7 +47,7 @@ void GPS::UBXChecksum(byte *message, size_t length) message[length - 1] = CK_B; } -GPS_RESPONSE GPS::getACK(const char *message, int waitMillis) +GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis) { uint8_t buffer[768] = {0}; uint8_t b; @@ -62,27 +62,31 @@ GPS_RESPONSE GPS::getACK(const char *message, int waitMillis) if (strnstr((char *)buffer, message, bytesRead) != nullptr) { return GNSS_RESPONSE_OK; } else { +#ifdef GPS_DEBUG buffer[bytesRead] = '\0'; bytesRead++; - LOG_INFO("Bytes read:%s\n", (char*) buffer); + LOG_INFO("Bytes read:%s\n", (char *)buffer); +#endif bytesRead = 0; } } } } +#ifdef GPS_DEBUG buffer[bytesRead] = '\0'; bytesRead++; - LOG_INFO("Bytes read:%s\n", (char*) buffer); + LOG_INFO("Bytes read:%s\n", (char *)buffer); +#endif return GNSS_RESPONSE_NONE; } -GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) +GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) { uint8_t b; uint8_t ack = 0; const uint8_t ackP[2] = {class_id, msg_id}; uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned long startTime = millis(); + uint32_t startTime = millis(); const char frame_errors[] = "More than 100 frame errors"; int sCounter = 0; @@ -99,7 +103,9 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) while (millis() - startTime < waitMillis) { if (ack > 9) { - // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); +#ifdef GPS_DEBUG + LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); +#endif return GNSS_RESPONSE_OK; // ACK received } if (_serial_gps->available()) { @@ -138,7 +144,7 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, int waitMillis) * @param requestedID: request message ID constant * @retval length of payload message */ -int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis) +int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis) { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); @@ -198,8 +204,10 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t ubxFrameCounter = 0; } else { // return payload length - // LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", requestedClass, requestedID, millis() - - // startTime); +#ifdef GPS_DEBUG + LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", requestedClass, requestedID, + millis() - startTime); +#endif return needRead; } break; @@ -548,26 +556,27 @@ bool GPS::setupGPS() // set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase and // must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, it must // be set to '0'. - byte UBX_CFG_PMS[14] = { - 0xB5, 0x62, // UBX sync characters - 0x06, 0x86, // Message class and ID (UBX-CFG-PMS) - 0x06, 0x00, // Length of payload (6 bytes) - 0x00, // Version (0) - 0x03, // Power setup value - 0x00, 0x00, // period: not applicable, set to 0 - 0x00, 0x00, // onTime: not applicable, set to 0 - 0x00, 0x00 // Placeholder for checksum, will be calculated next - }; + if (uBloxProtocolVersion >= 18) { + byte UBX_CFG_PMS[14] = { + 0xB5, 0x62, // UBX sync characters + 0x06, 0x86, // Message class and ID (UBX-CFG-PMS) + 0x06, 0x00, // Length of payload (6 bytes) + 0x00, // Version (0) + 0x03, // Power setup value + 0x00, 0x00, // period: not applicable, set to 0 + 0x00, 0x00, // onTime: not applicable, set to 0 + 0x00, 0x00 // Placeholder for checksum, will be calculated next + }; - // Calculate the checksum and update the message - UBXChecksum(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); + // Calculate the checksum and update the message + UBXChecksum(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - // Send the message to the module - _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving for GPS.\n"); + // Send the message to the module + _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); + if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving for GPS.\n"); + } } - // We need save configuration to flash to make our config changes persistent byte _message_SAVE[21] = { 0xB5, 0x62, // UBX protocol header @@ -938,6 +947,7 @@ GnssModel_t GPS::probe(int serialSpeed) #else _serial_gps->updateBaudRate(serialSpeed); #endif + delay(200); } memset(buffer, 0, sizeof(buffer)); @@ -995,7 +1005,7 @@ GnssModel_t GPS::probe(int serialSpeed) } else { LOG_INFO("UBlox GNSS init succeeded, using UBlox GNSS Module\n"); } - } else if (!strncmp(info.extension[i], "PROTVER=", 8)) { + } else if (!strncmp(info.extension[i], "PROTVER", 7)) { char *ptr = nullptr; memset(buffer, 0, sizeof(buffer)); strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer)); diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 485d53709..89ae7a916 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -179,9 +179,9 @@ class GPS : private concurrency::OSThread String getNMEA(); GnssModel_t probe(int serialSpeed); - int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, int waitMillis); - GPS_RESPONSE getACK(uint8_t c, uint8_t i, int waitMillis); - GPS_RESPONSE getACK(const char *message, int waitMillis); + int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis); + GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis); + GPS_RESPONSE getACK(const char *message, uint32_t waitMillis); // delay counter to allow more sats before fixed position stops GPS thread uint8_t fixeddelayCtr = 0; From ecdb75aae08ea3b059856e085f4b76f7796e9635 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 3 Sep 2023 02:16:29 -0500 Subject: [PATCH 41/97] Correct UBX-CFG-PMS message --- src/gps/GPS.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 650cefd57..4f1641617 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -557,14 +557,15 @@ bool GPS::setupGPS() // must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, it must // be set to '0'. if (uBloxProtocolVersion >= 18) { - byte UBX_CFG_PMS[14] = { + byte UBX_CFG_PMS[16] = { 0xB5, 0x62, // UBX sync characters 0x06, 0x86, // Message class and ID (UBX-CFG-PMS) - 0x06, 0x00, // Length of payload (6 bytes) + 0x08, 0x00, // Length of payload (6 bytes) 0x00, // Version (0) 0x03, // Power setup value 0x00, 0x00, // period: not applicable, set to 0 0x00, 0x00, // onTime: not applicable, set to 0 + 0x97, 0x6F, // reserved, generated by u-center 0x00, 0x00 // Placeholder for checksum, will be calculated next }; From 7ad94da1c6b2e77af7e8b931060e070615e41a1a Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 3 Sep 2023 16:20:01 -0500 Subject: [PATCH 42/97] Add more to GPS_DEBUG and fix ubx7 CFG-GNSS --- src/gps/GPS.cpp | 89 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 4f1641617..71e689b22 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -104,6 +104,7 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) while (millis() - startTime < waitMillis) { if (ack > 9) { #ifdef GPS_DEBUG + LOG_DEBUG("\n"); LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime); #endif return GNSS_RESPONSE_OK; // ACK received @@ -118,20 +119,27 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) } else { sCounter = 0; } - // LOG_DEBUG("%02X", b); +#ifdef GPS_DEBUG + LOG_DEBUG("%02X", b); +#endif if (b == buf[ack]) { ack++; } else { - ack = 0; // Reset the acknowledgement counter - if (buf[3] == 0x00) { // UBX-ACK-NAK message + if (ack == 3 && b == 0x00) { // UBX-ACK-NAK message +#ifdef GPS_DEBUG + LOG_DEBUG("\n"); +#endif LOG_WARN("Got NAK for class %02X message %02X\n", class_id, msg_id); return GNSS_RESPONSE_NAK; // NAK received } + ack = 0; // Reset the acknowledgement counter } } } - // LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); - // LOG_DEBUG("\n"); +#ifdef GPS_DEBUG + LOG_DEBUG("\n"); + LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id); +#endif return GNSS_RESPONSE_NONE; // No response received within timeout } @@ -267,6 +275,10 @@ bool GPS::setupGPS() if (gnssModel != GNSS_MODEL_UNKNOWN) break; } + if (gnssModel == GNSS_MODEL_UNKNOWN) { + LOG_DEBUG("No GPS found, retrying at 9600 baud.\n"); + gnssModel = probe(9600); + } #endif if (gnssModel == GNSS_MODEL_MTK) { @@ -297,28 +309,47 @@ bool GPS::setupGPS() // We need set it because by default it is GPS only, and we want to use GLONASS too // Also we need SBAS for better accuracy and extra features // ToDo: Dynamic configure GNSS systems depending of LoRa region - byte _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) - 0x00, // msgVer (0 for this version) - 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) - 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) - 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems - // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags - 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS - 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS - 0x00, 0x00 // Checksum (to be calculated below) - }; - // Calculate the checksum and update the message. - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + if (strncmp(info.hwVersion, "00070000", 8) == 0) { // Max7 seems to only support GPS *or* GLONASS + byte _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) + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, // SBAS + 0x00, 0x00 // Checksum (to be calculated below) + }; + // Calculate the checksum and update the message. + UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + // Send the message to the module + _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); + } else { + byte _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) + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS + 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS + 0x00, 0x00 // Checksum (to be calculated below) + }; + // Calculate the checksum and update the message. + UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + // Send the message to the module + _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); + } - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - - if (getACK(0x06, 0x3e, 300) != GNSS_RESPONSE_OK) { + if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) { // It's not critical if the module doesn't acknowledge this configuration. // The module should operate adequately with its factory or previously saved settings. // It appears that there is a firmware bug in some GPS modules: When an attempt is made @@ -327,7 +358,11 @@ bool GPS::setupGPS() // There is also a possibility that the module may be GPS-only. LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); } else { - LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); + if (strncmp(info.hwVersion, "00070000", 8) == 0) { + LOG_INFO("GNSS configured for GPS+SBAS. Pause for 0.75s before sending next command.\n"); + } else { + LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); + } // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands delay(750); } @@ -919,7 +954,7 @@ GnssModel_t GPS::probe(int serialSpeed) uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; UBXChecksum(cfg_rate, sizeof(cfg_rate)); - // clearBuffer(); + clearBuffer(); _serial_gps->write(cfg_rate, sizeof(cfg_rate)); // Check that the returned response class and message ID are correct GPS_RESPONSE response = getACK(0x06, 0x08, 750); From ac62330e1caaf0b4836d318f1b725338a013c730 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 3 Sep 2023 22:00:07 -0500 Subject: [PATCH 43/97] Found lost byte dropped from moduleinfo Attempt to fix CFG-GNSS for neo-6m --- src/gps/GPS.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 71e689b22..2eae287bf 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -201,8 +201,6 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t // Payload length msb needRead |= (c << 8); ubxFrameCounter++; - break; - case 6: // Check for buffer overflow if (needRead >= size) { ubxFrameCounter = 0; @@ -304,13 +302,31 @@ bool GPS::setupGPS() _serial_gps->write("$CFGSYS,h15\r\n"); delay(250); } else if (gnssModel == GNSS_MODEL_UBLOX) { + /* + uint8_t buffer[768] = {0}; + byte _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}; + UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + // Send the message to the module + _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); + int ackLen = getACK(buffer, sizeof(buffer), 0x06, 0x3e, 2000); + LOG_DEBUG("monver reply size = %d\n", ackLen); + LOG_DEBUG("Ack: "); + for (int i = 0; i < ackLen; i++) { + LOG_DEBUG("%02X", buffer[i]); + } + LOG_DEBUG("\n"); */ // Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command) // We need set it because by default it is GPS only, and we want to use GLONASS too // Also we need SBAS for better accuracy and extra features // ToDo: Dynamic configure GNSS systems depending of LoRa region - if (strncmp(info.hwVersion, "00070000", 8) == 0) { // Max7 seems to only support GPS *or* GLONASS + if ((strncmp(info.hwVersion, "00070000", 8) == 0) || // Max7 seems to only support GPS *or* GLONASS + (strncmp(info.hwVersion, "00040007", 8) == 0)) { + LOG_DEBUG("Setting GPS+SBAS\n"); byte _message_GNSS[28] = { 0xb5, 0x62, // Sync message for UBX protocol 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) @@ -1007,13 +1023,13 @@ GnssModel_t GPS::probe(int serialSpeed) position++; } for (int i = 0; i < 10; i++) { - info.hwVersion[i] = buffer[position - 1]; + info.hwVersion[i] = buffer[position]; position++; } while (len >= position + 30) { for (int i = 0; i < 30; i++) { - info.extension[info.extensionNo][i] = buffer[position - 1]; + info.extension[info.extensionNo][i] = buffer[position]; position++; } info.extensionNo++; From ad40493a39a83cd06e5a8bbe8ffe05edf985a714 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 4 Sep 2023 06:46:27 -0500 Subject: [PATCH 44/97] Add speed, heading, and DOP to default position flags (#2759) * Add speed and heading * Add DOP --- src/mesh/NodeDB.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 196874d48..5774eb084 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -190,7 +190,9 @@ void NodeDB::installDefaultConfig() : meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN; // for backward compat, default position flags are ALT+MSL config.position.position_flags = - (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL); + (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL | + meshtastic_Config_PositionConfig_PositionFlags_SPEED | meshtastic_Config_PositionConfig_PositionFlags_HEADING | + meshtastic_Config_PositionConfig_PositionFlags_DOP); #ifdef T_WATCH_S3 config.display.screen_on_secs = 30; From bb1fe7cad35e22ef53801486d9e0ac2c8297f83f Mon Sep 17 00:00:00 2001 From: tropho23 <71199294+tropho23@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:16:39 -0400 Subject: [PATCH 45/97] GPS toggle for RAK4631 (patch 1 of 2) (#2763) * Added triple-press GPS toggle button changes * Revert edits to extensions.json * comma'd * Update platformio.ini Added line: -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. --------- Co-authored-by: Ben Meadors Co-authored-by: code8buster --- variants/rak4631/platformio.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index 34eed88dd..b9789166f 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -4,6 +4,7 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631 -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" + -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + + + lib_deps = ${nrf52840_base.lib_deps} @@ -13,4 +14,4 @@ lib_deps = rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) -;upload_protocol = jlink \ No newline at end of file +;upload_protocol = jlink From ffcb131171b56e2ce18aebee2744599fc74be9d4 Mon Sep 17 00:00:00 2001 From: tropho23 <71199294+tropho23@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:17:01 -0400 Subject: [PATCH 46/97] GPS toggle for RAK4631 (patch 2 of 2) (#2764) * Added triple-press GPS toggle button changes * Revert edits to extensions.json * comma'd * Update variant.h Added the line: // Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press #define PIN_GPS_EN 34 // GPS power enable pin --------- Co-authored-by: Ben Meadors Co-authored-by: code8buster --- variants/rak4631/variant.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index 258e4eb3c..88a396e69 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -227,6 +227,9 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG #define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_TX_PIN PIN_SERIAL1_TX +// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press +#define PIN_GPS_EN 34 // GPS power enable pin + // RAK12002 RTC Module #define RV3028_RTC (uint8_t)0b1010010 @@ -273,4 +276,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif From e943fffe8cf45cf4876a3b98116e5a0003f2dafc Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 4 Sep 2023 14:18:27 -0500 Subject: [PATCH 47/97] GPS fixes Work aroung Serial reset issue on ESP32 Don't send unsupported command to G60xx GPS --- src/gps/GPS.cpp | 137 ++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 2eae287bf..e0b3e2e01 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -60,11 +60,14 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis) bytesRead++; if ((bytesRead == 767) || (b == '\r')) { if (strnstr((char *)buffer, message, bytesRead) != nullptr) { +#ifdef GPS_DEBUG + buffer[bytesRead] = '\0'; + LOG_DEBUG("%s\r", (char *)buffer); +#endif return GNSS_RESPONSE_OK; } else { #ifdef GPS_DEBUG buffer[bytesRead] = '\0'; - bytesRead++; LOG_INFO("Bytes read:%s\n", (char *)buffer); #endif bytesRead = 0; @@ -74,7 +77,6 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis) } #ifdef GPS_DEBUG buffer[bytesRead] = '\0'; - bytesRead++; LOG_INFO("Bytes read:%s\n", (char *)buffer); #endif return GNSS_RESPONSE_NONE; @@ -305,11 +307,11 @@ bool GPS::setupGPS() /* uint8_t buffer[768] = {0}; byte _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}; + 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) + 0x00, 0x00, // Length of payload (28 bytes) + 0x00, 0x00}; UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module + // Send the message to the module _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); int ackLen = getACK(buffer, sizeof(buffer), 0x06, 0x3e, 2000); LOG_DEBUG("monver reply size = %d\n", ackLen); @@ -324,63 +326,66 @@ bool GPS::setupGPS() // Also we need SBAS for better accuracy and extra features // ToDo: Dynamic configure GNSS systems depending of LoRa region - if ((strncmp(info.hwVersion, "00070000", 8) == 0) || // Max7 seems to only support GPS *or* GLONASS - (strncmp(info.hwVersion, "00040007", 8) == 0)) { - LOG_DEBUG("Setting GPS+SBAS\n"); - byte _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) - 0x00, // msgVer (0 for this version) - 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) - 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) - 0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems - // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags - 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, // SBAS - 0x00, 0x00 // Checksum (to be calculated below) - }; - // Calculate the checksum and update the message. - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - } else { - byte _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) - 0x00, // msgVer (0 for this version) - 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) - 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) - 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems - // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags - 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS - 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS - 0x00, 0x00 // Checksum (to be calculated below) - }; - // Calculate the checksum and update the message. - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - } - - if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) { - // It's not critical if the module doesn't acknowledge this configuration. - // The module should operate adequately with its factory or previously saved settings. - // It appears that there is a firmware bug in some GPS modules: When an attempt is made - // to overwrite a saved state with identical values, no ACK/NAK is received, contrary to - // what is specified in the Ublox documentation. - // There is also a possibility that the module may be GPS-only. - LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); - } else { - if (strncmp(info.hwVersion, "00070000", 8) == 0) { - LOG_INFO("GNSS configured for GPS+SBAS. Pause for 0.75s before sending next command.\n"); + if (strncmp(info.hwVersion, "00040007", 8) != + 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] = { + 0xb5, 0x62, // Sync message for UBX protocol + 0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS) + 0x14, 0x00, // Length of payload (28 bytes) + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, // SBAS + 0x00, 0x00 // Checksum (to be calculated below) + }; + // Calculate the checksum and update the message. + UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + // Send the message to the module + _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); } else { - LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); + byte _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) + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS + 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS + 0x00, 0x00 // Checksum (to be calculated below) + }; + // Calculate the checksum and update the message. + UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); + // Send the message to the module + _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); + } + + if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) { + // It's not critical if the module doesn't acknowledge this configuration. + // The module should operate adequately with its factory or previously saved settings. + // It appears that there is a firmware bug in some GPS modules: When an attempt is made + // to overwrite a saved state with identical values, no ACK/NAK is received, contrary to + // what is specified in the Ublox documentation. + // There is also a possibility that the module may be GPS-only. + LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); + } else { + if (strncmp(info.hwVersion, "00070000", 8) == 0) { + LOG_INFO("GNSS configured for GPS+SBAS. Pause for 0.75s before sending next command.\n"); + } else { + LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); + } + // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next + // commands + delay(750); } - // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands - delay(750); } // Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board, @@ -950,7 +955,15 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->end(); _serial_gps->begin(serialSpeed); #else - _serial_gps->updateBaudRate(serialSpeed); + if (_serial_gps->baudRate() != serialSpeed) { + LOG_DEBUG("Setting Baud to %i\n", serialSpeed); + _serial_gps->updateBaudRate(serialSpeed); + } +#endif +#ifdef GPS_DEBUG + for (int i = 0; i < 20; i++) { + getACK("$GP", 200); + } #endif memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); uint8_t buffer[768] = {0}; From 97f0c734e0ae02f10cea9d495cfe7aed6fc814cb Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 4 Sep 2023 17:47:24 -0500 Subject: [PATCH 48/97] Fix Neighborinfo crash neighbors object wasn't initialized when module disabled, this initializes it to a safe, empty object. --- src/modules/NeighborInfoModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index d6fb572a9..e83436552 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -99,6 +99,7 @@ NeighborInfoModule::NeighborInfoModule() setIntervalFromNow(35 * 1000); } else { LOG_DEBUG("NeighborInfoModule is disabled\n"); + neighborState = meshtastic_NeighborInfo_init_zero; disable(); } } From 17617ce031c6e2c521be5450966edce4399e45d6 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Tue, 5 Sep 2023 01:38:16 +0200 Subject: [PATCH 49/97] Fix possible memory leak in NeighborInfo Module (#2765) Co-authored-by: Ben Meadors --- src/modules/NeighborInfoModule.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index e83436552..a0e9843ed 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -104,16 +104,6 @@ NeighborInfoModule::NeighborInfoModule() } } -/* -Allocate a zeroed neighbor info packet -*/ -meshtastic_NeighborInfo *NeighborInfoModule::allocateNeighborInfoPacket() -{ - meshtastic_NeighborInfo *neighborInfo = (meshtastic_NeighborInfo *)malloc(sizeof(meshtastic_NeighborInfo)); - memset(neighborInfo, 0, sizeof(meshtastic_NeighborInfo)); - return neighborInfo; -} - /* Collect neighbor info from the nodeDB's history, capping at a maximum number of entries and max time Assumes that the neighborInfo packet has been allocated @@ -185,14 +175,14 @@ size_t NeighborInfoModule::cleanUpNeighbors() /* Send neighbor info to the mesh */ void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies) { - meshtastic_NeighborInfo *neighborInfo = allocateNeighborInfoPacket(); - collectNeighborInfo(neighborInfo); - meshtastic_MeshPacket *p = allocDataProtobuf(*neighborInfo); + meshtastic_NeighborInfo neighborInfo = meshtastic_NeighborInfo_init_zero; + collectNeighborInfo(&neighborInfo); + meshtastic_MeshPacket *p = allocDataProtobuf(neighborInfo); // send regardless of whether or not we have neighbors in our DB, // because we want to get neighbors for the next cycle p->to = dest; p->decoded.want_response = wantReplies; - printNeighborInfo("SENDING", neighborInfo); + printNeighborInfo("SENDING", &neighborInfo); service.sendToMesh(p, RX_SRC_LOCAL, true); } From 3bcab0e223986e86a8deec4af5fca9db2ae3ef9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 18:38:58 -0500 Subject: [PATCH 50/97] [create-pull-request] automated change (#2768) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/protobufs b/protobufs index 468ff2e24..826dfb760 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 468ff2e2457d7534a907af0a21bdede9f4042cb7 +Subproject commit 826dfb760450a4225384da6316582e93138102ba diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index ef9d09a19..1114ea99b 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -51,8 +51,9 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode { } meshtastic_Config_DeviceConfig_RebroadcastMode; /* Bit field of boolean configuration options, indicating which optional - fields to include when assembling POSITION messages - Longitude and latitude are always included (also time if GPS-synced) + fields to include when assembling POSITION messages. + Longitude, latitude, altitude, speed, heading, and DOP + are always included (also time if GPS-synced) NOTE: the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss */ typedef enum _meshtastic_Config_PositionConfig_PositionFlags { From 5a6169501668b0d90c364047a4abc0e7234390fa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:45:46 -0500 Subject: [PATCH 51/97] [create-pull-request] automated change (#2769) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 830d7970e..66e2e5f1d 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 4 +build = 5 From fb23e479ac163cc8ef88ee4938ce93dd4f086546 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 4 Sep 2023 20:20:20 -0500 Subject: [PATCH 52/97] Update ESP32 platform (#2770) --- arch/esp32/esp32.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 5853baf76..d8ee50f45 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -1,7 +1,7 @@ ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] extends = arduino_base -platform = platformio/espressif32@^6.3.2 +platform = platformio/espressif32@^6.4.0 build_src_filter = ${arduino_base.build_src_filter} - - - - 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 53/97] 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 54/97] 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 55/97] 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 From cfb6a1394c77d99addd6b6d7466e76347b0b97d1 Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Tue, 5 Sep 2023 19:56:42 +0200 Subject: [PATCH 56/97] Only update neighbors when module is enabled --- src/modules/NeighborInfoModule.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index a0e9843ed..a58525de4 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -203,8 +203,10 @@ Pass it to an upper client; do not persist this data on the mesh */ bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np) { - printNeighborInfo("RECEIVED", np); - updateNeighbors(mp, np); + if (enabled) { + printNeighborInfo("RECEIVED", np); + updateNeighbors(mp, np); + } // Allow others to handle this packet return false; } @@ -307,4 +309,4 @@ bool NeighborInfoModule::saveProtoForModule() okay &= nodeDB.saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState); return okay; -} \ No newline at end of file +} From 9af4ecf48faa40deae0fa5dbdd85c0aeff04248b Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Tue, 5 Sep 2023 21:42:39 +0200 Subject: [PATCH 57/97] Remove unnecessary line when disabled --- src/modules/NeighborInfoModule.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index a58525de4..cf2276f0e 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -99,7 +99,6 @@ NeighborInfoModule::NeighborInfoModule() setIntervalFromNow(35 * 1000); } else { LOG_DEBUG("NeighborInfoModule is disabled\n"); - neighborState = meshtastic_NeighborInfo_init_zero; disable(); } } @@ -309,4 +308,4 @@ bool NeighborInfoModule::saveProtoForModule() okay &= nodeDB.saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState); return okay; -} +} \ No newline at end of file From 0fa3685161f4468ac13d74c087fc2c6ec57ca719 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 6 Sep 2023 12:02:23 -0500 Subject: [PATCH 58/97] Fix crash in GPS setup when GPS is disabled --- src/gps/GPS.cpp | 3 ++- src/main.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 8f2ce35d0..8436c3f60 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -661,6 +661,8 @@ bool GPS::setupGPS() if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to enable powersaving for GPS.\n"); } + } else { + // use cfg-rxm } // We need save configuration to flash to make our config changes persistent uint8_t _message_SAVE[21] = { @@ -721,7 +723,6 @@ bool GPS::setup() if (config.position.gps_enabled == false && config.position.fixed_position == false) { setAwake(false); - doGPSpowersave(false); } return ok; } diff --git a/src/main.cpp b/src/main.cpp index 09fa62896..3ca3b50f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -562,6 +562,9 @@ void setup() if (gps) { gpsStatus->observe(&gps->newStatus); + if (config.position.gps_enabled == false && config.position.fixed_position == false) { + doGPSpowersave(false); + } } else { LOG_WARN("No GPS found - running without GPS\n"); } From fd563e41f14c8c49a46b3ed62e61c1803a3b2db1 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 7 Sep 2023 12:24:21 -0500 Subject: [PATCH 59/97] Add ubx-cfg-rxm and cfg-pm2 for ublock 6 powersave (#2777) --- src/gps/GPS.cpp | 27 +++++++++++++++++++-------- src/gps/GPS.h | 4 +++- src/gps/ubx.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 src/gps/ubx.h diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 8436c3f60..91efbdf0d 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -3,6 +3,7 @@ #include "RTC.h" #include "configuration.h" #include "sleep.h" +#include "ubx.h" #ifdef ARCH_PORTDUINO #include "meshUtils.h" @@ -32,13 +33,6 @@ static bool didSerialInit; struct uBloxGnssModelInfo info; uint8_t uBloxProtocolVersion; -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; @@ -662,7 +656,24 @@ bool GPS::setupGPS() LOG_WARN("Unable to enable powersaving for GPS.\n"); } } else { - // use cfg-rxm + if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode has only been tested on this hardware + int msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving mode for GPS.\n"); + } + msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving details for GPS.\n"); + } + } else { + int msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving ECO mode for GPS.\n"); + } + } } // We need save configuration to flash to make our config changes persistent uint8_t _message_SAVE[21] = { diff --git a/src/gps/GPS.h b/src/gps/GPS.h index f6b4e95c8..f5254890d 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -63,7 +63,9 @@ class GPS : private concurrency::OSThread static HardwareSerial *_serial_gps; static const uint8_t _message_PMREQ[8]; - + static const uint8_t _message_CFG_RXM_PSM[2]; + static const uint8_t _message_CFG_RXM_ECO[2]; + static const uint8_t _message_CFG_PM2[44]; meshtastic_Position p = meshtastic_Position_init_default; GPS() : concurrency::OSThread("GPS") {} diff --git a/src/gps/ubx.h b/src/gps/ubx.h new file mode 100644 index 000000000..a81b52e80 --- /dev/null +++ b/src/gps/ubx.h @@ -0,0 +1,31 @@ +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 +}; + +const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = { + 0x08, // Reserved + 0x01 // Power save mode +}; + +const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = { + 0x08, // Reserved + 0x04 // eco mode +}; + +const uint8_t GPS::_message_CFG_PM2[] PROGMEM = { + 0x01, 0x06, 0x00, 0x00, // version, Reserved + 0x0e, 0x81, 0x42, 0x01, // flags + 0xE8, 0x03, 0x00, 0x00, // update period 1000 ms + 0x10, 0x27, 0x00, 0x00, // search period 10s + 0x00, 0x00, 0x00, 0x00, // Grod offset 0 + 0x01, 0x00, // onTime 1 second + 0x00, 0x00, // min search time 0 + 0x2C, 0x01, // reserved + 0x00, 0x00, 0x4F, 0xC1, // reserved + 0x03, 0x00, 0x87, 0x02, // reserved + 0x00, 0x00, 0xFF, 0x00, // reserved + 0x01, 0x00, 0xD6, 0x4D // reserved +}; \ No newline at end of file From dcdf9b64de7ba93f480bfbe43da51aac1c11ab02 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 7 Sep 2023 12:24:47 -0500 Subject: [PATCH 60/97] Ambient lighting (#2779) * This was already defined and throwing a ton of warnings * Ambient lighting module feature * Use local instance type --- src/AmbientLightingThread.h | 75 ++++++++++++++++++++++ src/graphics/RAKled.h | 2 - src/main.cpp | 16 ++--- src/mesh/NodeDB.cpp | 7 ++ src/modules/ExternalNotificationModule.cpp | 1 - variants/rak4631/variant.h | 3 +- 6 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 src/AmbientLightingThread.h diff --git a/src/AmbientLightingThread.h b/src/AmbientLightingThread.h new file mode 100644 index 000000000..0dd0fdf4a --- /dev/null +++ b/src/AmbientLightingThread.h @@ -0,0 +1,75 @@ +#include "configuration.h" + +#ifdef HAS_NCP5623 +#include +NCP5623 rgb; +#endif + +namespace concurrency +{ +class AmbientLightingThread : public concurrency::OSThread +{ + public: + AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread") + { + // Uncomment to test module + // moduleConfig.ambient_lighting.led_state = true; + // moduleConfig.ambient_lighting.current = 10; + // // Default to a color based on our node number + // moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16; + // moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8; + // moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF; + +#ifdef HAS_NCP5623 + _type = type; + if (_type == ScanI2C::DeviceType::NONE) { + LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n"); + disable(); + return; + } + if (!moduleConfig.ambient_lighting.led_state) { + LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n"); + disable(); + return; + } + LOG_DEBUG("AmbientLightingThread initializing\n"); + if (_type == ScanI2C::NCP5623) { + rgb.begin(); + setLighting(); + } +#endif + } + + protected: + int32_t runOnce() override + { +#ifdef HAS_NCP5623 + if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) { + setLighting(); + return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification + } else { + return disable(); + } +#else + return disable(); +#endif + } + + private: + ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE; + + void setLighting() + { +#ifdef HAS_NCP5623 + rgb.setCurrent(moduleConfig.ambient_lighting.current); + rgb.setRed(moduleConfig.ambient_lighting.red); + rgb.setGreen(moduleConfig.ambient_lighting.green); + rgb.setBlue(moduleConfig.ambient_lighting.blue); + LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n", + moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, + moduleConfig.ambient_lighting.blue); +#endif + } +}; + +} // namespace concurrency \ No newline at end of file diff --git a/src/graphics/RAKled.h b/src/graphics/RAKled.h index 2e36b874a..659ea9b72 100644 --- a/src/graphics/RAKled.h +++ b/src/graphics/RAKled.h @@ -1,5 +1,3 @@ -#include "main.h" - #ifdef HAS_NCP5623 #include extern NCP5623 rgb; diff --git a/src/main.cpp b/src/main.cpp index 3ca3b50f3..2ae17225f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,6 +73,7 @@ NRF52Bluetooth *nrf52Bluetooth; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #include "AccelerometerThread.h" +#include "AmbientLightingThread.h" #endif using namespace concurrency; @@ -169,6 +170,7 @@ static OSThread *buttonThread; uint32_t ButtonThread::longPressTime = 0; #endif static OSThread *accelerometerThread; +static OSThread *ambientLightingThread; SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); RadioInterface *rIf = NULL; @@ -409,14 +411,6 @@ void setup() // Only one supported RGB LED currently #ifdef HAS_NCP5623 rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623); - - // Start the RGB LED at 50% - - if (rgb_found.type == ScanI2C::NCP5623) { - rgb.begin(); - rgb.setCurrent(10); - rgb.setColor(128, 128, 128); - } #endif #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) @@ -521,6 +515,12 @@ void setup() } #endif +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) + if (rgb_found.type != ScanI2C::DeviceType::NONE) { + ambientLightingThread = new AmbientLightingThread(rgb_found.type); + } +#endif + #ifdef T_WATCH_S3 drv.begin(); drv.selectLibrary(1); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5774eb084..2bbc4b779 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -255,6 +255,13 @@ void NodeDB::installDefaultModuleConfig() moduleConfig.detection_sensor.detection_triggered_high = true; moduleConfig.detection_sensor.minimum_broadcast_secs = 45; + moduleConfig.has_ambient_lighting = true; + moduleConfig.ambient_lighting.current = 10; + // Default to a color based on our node number + moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16; + moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8; + moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF; + initModuleConfigIntervals(); } diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 20191e706..1e0e8250d 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -27,7 +27,6 @@ #ifdef HAS_NCP5623 #include -NCP5623 rgb; uint8_t red = 0; uint8_t green = 0; diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index 88a396e69..c4061037d 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -228,7 +228,6 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG #define GPS_TX_PIN PIN_SERIAL1_TX // Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press -#define PIN_GPS_EN 34 // GPS power enable pin // RAK12002 RTC Module #define RV3028_RTC (uint8_t)0b1010010 @@ -276,4 +275,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif +#endif \ No newline at end of file From fcf798df984d09653618d59613c75d9c4d3a6831 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 7 Sep 2023 16:01:35 -0500 Subject: [PATCH 61/97] Experiment with moving gps init (#2780) * Move it move it * Moving to the end of the main setup method * NimBLE version --- arch/esp32/esp32.ini | 2 +- src/main.cpp | 42 ++++++++++++++++++++---------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index d8ee50f45..ccad60858 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -38,7 +38,7 @@ lib_deps = ${networking_base.lib_deps} ${environmental_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 - h2zero/NimBLE-Arduino@^1.4.0 + h2zero/NimBLE-Arduino@^1.4.1 jgromes/RadioLib@^6.1.0 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f diff --git a/src/main.cpp b/src/main.cpp index 2ae17225f..e67603c64 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -558,17 +558,6 @@ void setup() readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) - gps = createGps(); - - if (gps) { - gpsStatus->observe(&gps->newStatus); - if (config.position.gps_enabled == false && config.position.fixed_position == false) { - doGPSpowersave(false); - } - } else { - LOG_WARN("No GPS found - running without GPS\n"); - } - nodeStatus->observe(&nodeDB.newStatus); service.init(); @@ -593,17 +582,6 @@ void setup() screen->print("Started...\n"); - // We have now loaded our saved preferences from flash - - // ONCE we will factory reset the GPS for bug #327 - if (gps && !devicestate.did_gps_reset) { - LOG_WARN("GPS FactoryReset requested\n"); - if (gps->factoryReset()) { // If we don't succeed try again next time - devicestate.did_gps_reset = true; - nodeDB.saveToDisk(SEGMENT_DEVICESTATE); - } - } - #ifdef SX126X_ANT_SW // make analog PA vs not PA switch on SX126x eval board work properly pinMode(SX126X_ANT_SW, OUTPUT); @@ -758,6 +736,26 @@ void setup() PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS powerFSMthread = new PowerFSMThread(); + gps = createGps(); + + if (gps) { + gpsStatus->observe(&gps->newStatus); + if (config.position.gps_enabled == false && config.position.fixed_position == false) { + doGPSpowersave(false); + } + } else { + LOG_WARN("No GPS found - running without GPS\n"); + } + // We have now loaded our saved preferences from flash + + // ONCE we will factory reset the GPS for bug #327 + if (gps && !devicestate.did_gps_reset) { + LOG_WARN("GPS FactoryReset requested\n"); + if (gps->factoryReset()) { // If we don't succeed try again next time + devicestate.did_gps_reset = true; + nodeDB.saveToDisk(SEGMENT_DEVICESTATE); + } + } // setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state setCPUFast(false); // 80MHz is fine for our slow peripherals } From e2565203366bdf12a70929ebd0fe46bd6bf3d583 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:34:58 -0500 Subject: [PATCH 62/97] [create-pull-request] automated change (#2782) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/module_config.pb.h | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/protobufs b/protobufs index 826dfb760..82ce9448a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 826dfb760450a4225384da6316582e93138102ba +Subproject commit 82ce9448a0d89899ba01786c05d8f73e6a5005b7 diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index 828a44cc7..28a11ffcd 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -313,13 +313,14 @@ Initially created for the RAK14001 RGB LED module. */ typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig { /* Sets LED to on or off. */ bool led_state; - /* Sets the overall current for the LED, firmware side range for the RAK14001 is 1-31, but users should be given a range of 0-100% */ + /* Sets the current for the LED output. Default is 10. */ uint8_t current; - uint8_t red; /* Red level */ - /* Sets the green level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */ - uint8_t green; /* Green level */ - /* Sets the blue level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */ - uint8_t blue; /* Blue level */ + /* Sets the red LED level. Values are 0-255. */ + uint8_t red; + /* Sets the green LED level. Values are 0-255. */ + uint8_t green; + /* Sets the blue LED level. Values are 0-255. */ + uint8_t blue; } meshtastic_ModuleConfig_AmbientLightingConfig; /* A GPIO pin definition for remote hardware module */ From d7a98519f4014a9b8e04108322b4bf26d09bb61d Mon Sep 17 00:00:00 2001 From: Ric In New Mexico <78682404+RicInNewMexico@users.noreply.github.com> Date: Sat, 9 Sep 2023 18:37:35 -0600 Subject: [PATCH 63/97] Update variant.h (#2778) * Update variant.h Add second i2c channel on external connector for Station G1 * Create trunk-check.yml --------- Co-authored-by: Ben Meadors --- .github/workflows/trunk-check.yml | 22 ++++++++++++++++++++++ variants/station-g1/variant.h | 5 ++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/trunk-check.yml diff --git a/.github/workflows/trunk-check.yml b/.github/workflows/trunk-check.yml new file mode 100644 index 000000000..e35b91cb9 --- /dev/null +++ b/.github/workflows/trunk-check.yml @@ -0,0 +1,22 @@ +name: Pull Request +on: [pull_request] +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: read-all + +jobs: + trunk_check: + name: Trunk Check Runner + runs-on: ubuntu-latest + permissions: + checks: write # For trunk to post annotations + contents: read # For repo checkout + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Trunk Check + uses: trunk-io/trunk-action@v1 diff --git a/variants/station-g1/variant.h b/variants/station-g1/variant.h index 3439cb125..f49dbe854 100644 --- a/variants/station-g1/variant.h +++ b/variants/station-g1/variant.h @@ -3,6 +3,9 @@ #define I2C_SDA 21 #define I2C_SCL 22 +#define I2C_SDA1 14 // Second i2c channel on external IO connector +#define I2C_SCL1 15 // Second i2c channel on external IO connector + #define BUTTON_PIN 36 // The middle button GPIO on the Nano G1 //#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented // anywhere. @@ -42,4 +45,4 @@ #define BAT_NOBATVOLT 6690 // different screen -#define USE_SH1106 \ No newline at end of file +#define USE_SH1106 From 8255128eae444d023d432d8089c67883f282385c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 9 Sep 2023 19:40:57 -0500 Subject: [PATCH 64/97] Trunk finally spilled the beans about what it's upset about --- variants/station-g1/variant.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/variants/station-g1/variant.h b/variants/station-g1/variant.h index f49dbe854..1017f23c7 100644 --- a/variants/station-g1/variant.h +++ b/variants/station-g1/variant.h @@ -7,8 +7,8 @@ #define I2C_SCL1 15 // Second i2c channel on external IO connector #define BUTTON_PIN 36 // The middle button GPIO on the Nano G1 -//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented -// anywhere. +// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented +// anywhere. #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. // common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if @@ -27,9 +27,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -//#define SX126X_E22 // Not really an E22 -// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface -// code) +// #define SX126X_E22 // Not really an E22 +// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface +// code) #define SX126X_MAX_POWER \ 16 // Ensure the PA does not exceed the saturation output power. More // Info:https://uniteng.com/wiki/doku.php?id=meshtastic:station#rf_design_-_lora_station_edition_g1 From 44a77a10e1717e86da7ebaa1458bfdad616dad10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 10 Sep 2023 06:34:48 -0500 Subject: [PATCH 65/97] [create-pull-request] automated change (#2785) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 66e2e5f1d..d0c8a646f 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 5 +build = 6 From d6d51bc3f4ae0758b15fb8d69f6ed4ff5d968d04 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Sun, 10 Sep 2023 13:54:25 +0200 Subject: [PATCH 66/97] T-Deck/T-Watch: enhancements/fixes (#2786) * T-Deck: enhancements/fixes * trunk fmt * T-Watch board update --------- Co-authored-by: Ben Meadors --- boards/t-deck.json | 5 +++-- boards/t-watch-s3.json | 10 ++++++---- src/PowerFSM.cpp | 9 +++++++++ variants/t-deck/platformio.ini | 2 +- variants/t-deck/variant.h | 6 +++--- variants/t-watch-s3/platformio.ini | 4 +--- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/boards/t-deck.json b/boards/t-deck.json index 9d74834e9..d62ec48e6 100644 --- a/boards/t-deck.json +++ b/boards/t-deck.json @@ -1,7 +1,8 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld" + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi" }, "core": "esp32", "extra_flags": [ @@ -13,7 +14,7 @@ ], "f_cpu": "240000000L", "f_flash": "80000000L", - "flash_mode": "dio", + "flash_mode": "qio", "hwids": [["0x303A", "0x1001"]], "mcu": "esp32s3", "variant": "t-deck" diff --git a/boards/t-watch-s3.json b/boards/t-watch-s3.json index e86917df6..080389f39 100644 --- a/boards/t-watch-s3.json +++ b/boards/t-watch-s3.json @@ -1,7 +1,8 @@ { "build": { "arduino": { - "ldscript": "esp32s3_out.ld" + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi" }, "core": "esp32", "extra_flags": [ @@ -14,7 +15,7 @@ ], "f_cpu": "240000000L", "f_flash": "80000000L", - "flash_mode": "dio", + "flash_mode": "qio", "hwids": [["0x303A", "0x1001"]], "mcu": "esp32s3", "variant": "t-watch-s3" @@ -31,8 +32,9 @@ "maximum_size": 8388608, "require_upload_port": true, "use_1200bps_touch": true, - "wait_for_upload_port": true + "wait_for_upload_port": true, + "speed": 921600 }, - "url": "http://www.lilygo.cn/", + "url": "https://www.lilygo.cc/en-pl/products/t-watch-s3", "vendor": "LilyGo" } diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 827720d1f..da8759c3c 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -158,6 +158,9 @@ static void darkEnter() { setBluetoothEnable(true); screen->setOn(false); +#ifdef KB_POWERON + digitalWrite(KB_POWERON, LOW); +#endif } static void serialEnter() @@ -185,6 +188,9 @@ static void powerEnter() } else { screen->setOn(true); setBluetoothEnable(true); +#ifdef KB_POWERON + digitalWrite(KB_POWERON, HIGH); +#endif // within enter() the function getState() returns the state we came from if (strcmp(powerFSM.getState()->name, "BOOT") != 0 && strcmp(powerFSM.getState()->name, "POWER") != 0 && strcmp(powerFSM.getState()->name, "DARK") != 0) { @@ -215,6 +221,9 @@ static void onEnter() LOG_DEBUG("Enter state: ON\n"); screen->setOn(true); setBluetoothEnable(true); +#ifdef KB_POWERON + digitalWrite(KB_POWERON, HIGH); +#endif } static void onIdle() diff --git a/variants/t-deck/platformio.ini b/variants/t-deck/platformio.ini index c3c508a0f..abf545f44 100644 --- a/variants/t-deck/platformio.ini +++ b/variants/t-deck/platformio.ini @@ -11,4 +11,4 @@ build_flags = ${esp32_base.build_flags} -Ivariants/t-deck lib_deps = ${esp32s3_base.lib_deps} - lovyan03/LovyanGFX@^1.1.8 \ No newline at end of file + lovyan03/LovyanGFX@^1.1.9 \ No newline at end of file diff --git a/variants/t-deck/variant.h b/variants/t-deck/variant.h index 2f4643fde..b732b90cb 100644 --- a/variants/t-deck/variant.h +++ b/variants/t-deck/variant.h @@ -27,8 +27,8 @@ #define BUTTON_PIN 0 // #define BUTTON_NEED_PULLUP -#undef GPS_RX_PIN -#undef GPS_TX_PIN +#define GPS_RX_PIN 44 +#define GPS_TX_PIN 43 // Have SPI interface SD card slot #define HAS_SDCARD 1 @@ -41,7 +41,7 @@ #define BATTERY_PIN 4 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage // ratio of voltage divider = 2.0 (RD2=100k, RD3=100k) #define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage. -#define ADC_CHANNEL ADC1_GPIO1_CHANNEL +#define ADC_CHANNEL ADC1_GPIO4_CHANNEL // keyboard #define I2C_SDA 18 // I2C pins for this board diff --git a/variants/t-watch-s3/platformio.ini b/variants/t-watch-s3/platformio.ini index 08751d463..162384bfd 100644 --- a/variants/t-watch-s3/platformio.ini +++ b/variants/t-watch-s3/platformio.ini @@ -3,8 +3,6 @@ extends = esp32s3_base board = t-watch-s3 upload_protocol = esptool -upload_speed = 115200 -#upload_port = /dev/tty.usbmodem3485188D636C1 build_flags = ${esp32_base.build_flags} -DT_WATCH_S3 @@ -12,6 +10,6 @@ build_flags = ${esp32_base.build_flags} -DPCF8563_RTC=0x51 lib_deps = ${esp32s3_base.lib_deps} - lovyan03/LovyanGFX@^1.1.8 + lovyan03/LovyanGFX@^1.1.9 lewisxhe/PCF8563_Library@1.0.1 adafruit/Adafruit DRV2605 Library@^1.2.2 \ No newline at end of file From e1839e33f2cf308186a68fb55828c2826a002fc5 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 10 Sep 2023 22:21:14 -0500 Subject: [PATCH 67/97] Lazy probe of GPS (#2781) * First attempt at lazy config of GPS * More GPS rework Break GPS init into smaller, interruptable steps Move more GPS commands into ubx.h Combine Setup functions * Move the rest of UBX messages to ubs.h --- src/gps/GPS.cpp | 717 +++++++++++++++----------------------------- src/gps/GPS.h | 39 ++- src/gps/NMEAGPS.cpp | 24 -- src/gps/NMEAGPS.h | 2 - src/gps/ubx.h | 161 ++++++++++ src/main.cpp | 22 +- src/sleep.cpp | 4 +- 7 files changed, 431 insertions(+), 538 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 91efbdf0d..1ee61d592 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -251,462 +251,23 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t return 0; } -bool GPS::setupGPS() -{ - if (_serial_gps && !didSerialInit) { - didSerialInit = true; - -#ifdef ARCH_ESP32 - // In esp32 framework, setRxBufferSize needs to be initialized before Serial - _serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 -#endif - - // if the overrides are not dialled in, set them from the board definitions, if they exist - -#if defined(GPS_RX_PIN) - if (!config.position.rx_gpio) - config.position.rx_gpio = GPS_RX_PIN; -#endif -#if defined(GPS_TX_PIN) - if (!config.position.tx_gpio) - config.position.tx_gpio = GPS_TX_PIN; -#endif - -// #define BAUD_RATE 115200 -// ESP32 has a special set of parameters vs other arduino ports -#if defined(ARCH_ESP32) - if (config.position.rx_gpio) { - LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); - LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio); - _serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio); - } -#else - _serial_gps->begin(GPS_BAUDRATE); -#endif - - /* - * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first - */ -#if defined(GPS_UC6580) - _serial_gps->updateBaudRate(115200); - gnssModel = GNSS_MODEL_UC6850; -#else - for (int serialSpeed : {9600, 4800, 38400, 57600, 115200}) { - LOG_DEBUG("Probing for GPS at %d \n", serialSpeed); - gnssModel = probe(serialSpeed); - if (gnssModel != GNSS_MODEL_UNKNOWN) - break; - } - if (gnssModel == GNSS_MODEL_UNKNOWN) { - LOG_DEBUG("No GPS found, retrying at 9600 baud.\n"); - gnssModel = probe(9600); - } -#endif - - if (gnssModel == GNSS_MODEL_MTK) { - /* - * t-beam-s3-core uses the same L76K GNSS module as t-echo. - * Unlike t-echo, L76K uses 9600 baud rate for communication by default. - * */ - // _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line - // is the redundant part delay(250); - - // Initialize the L76K Chip, use GPS + GLONASS + BEIDOU - _serial_gps->write("$PCAS04,7*1E\r\n"); - delay(250); - // only ask for RMC and GGA - _serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n"); - delay(250); - // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g - _serial_gps->write("$PCAS11,3*1E\r\n"); - delay(250); - } else if (gnssModel == GNSS_MODEL_UC6850) { - - // use GPS + GLONASS - _serial_gps->write("$CFGSYS,h15\r\n"); - delay(250); - } else if (gnssModel == GNSS_MODEL_UBLOX) { - /* - uint8_t buffer[768] = {0}; - 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}; - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - int ackLen = getACK(buffer, sizeof(buffer), 0x06, 0x3e, 2000); - LOG_DEBUG("monver reply size = %d\n", ackLen); - LOG_DEBUG("Ack: "); - for (int i = 0; i < ackLen; i++) { - LOG_DEBUG("%02X", buffer[i]); - } - LOG_DEBUG("\n"); */ - - // Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command) - // We need set it because by default it is GPS only, and we want to use GLONASS too - // Also we need SBAS for better accuracy and extra features - // ToDo: Dynamic configure GNSS systems depending of LoRa region - - if (strncmp(info.hwVersion, "00040007", 8) != - 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"); - 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) - 0x00, // msgVer (0 for this version) - 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) - 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) - 0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems - // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags - 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, // SBAS - 0x00, 0x00 // Checksum (to be calculated below) - }; - // Calculate the checksum and update the message. - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - } else { - 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) - 0x00, // msgVer (0 for this version) - 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) - 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) - 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems - // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags - 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS - 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS - 0x00, 0x00 // Checksum (to be calculated below) - }; - // Calculate the checksum and update the message. - UBXChecksum(_message_GNSS, sizeof(_message_GNSS)); - // Send the message to the module - _serial_gps->write(_message_GNSS, sizeof(_message_GNSS)); - } - - if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) { - // It's not critical if the module doesn't acknowledge this configuration. - // The module should operate adequately with its factory or previously saved settings. - // It appears that there is a firmware bug in some GPS modules: When an attempt is made - // to overwrite a saved state with identical values, no ACK/NAK is received, contrary to - // what is specified in the Ublox documentation. - // There is also a possibility that the module may be GPS-only. - LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); - } else { - if (strncmp(info.hwVersion, "00070000", 8) == 0) { - LOG_INFO("GNSS configured for GPS+SBAS. Pause for 0.75s before sending next command.\n"); - } else { - LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); - } - // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next - // commands - delay(750); - } - } - - // Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board, - // and we need to reduce interference from them - 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) - // bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal) - // cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal) - // algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended - // enable (Enable interference detection) is set to 1 (enabled) - 0x3F, 0x10, 0xB1, 0x56, // config: Interference config word - // generalBits (General settings) is set to 0x31E as recommended - // antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown) - // ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info - // enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1 - // (enabled) - 0x1E, 0x03, 0x00, 0x01, // config2: Extra settings for jamming/interference monitor - 0x00, 0x00 // Checksum (calculated below) - }; - - // Calculate the checksum and update the message. - UBXChecksum(_message_JAM, sizeof(_message_JAM)); - - // Send the message to the module - _serial_gps->write(_message_JAM, sizeof(_message_JAM)); - - if (getACK(0x06, 0x39, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable interference resistance.\n"); - } - - // Configure navigation engine expert settings: - 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) - 0x00, 0x00, // msgVer (0 for this version) - // minMax flag = 1: apply min/max SVs settings - // minCno flag = 1: apply minimum C/N0 setting - // initial3dfix flag = 0: apply initial 3D fix settings - // aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous) - 0x1B, 0x00, // mask1 (First parameters bitmask) - // adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag) - // If firmware is not ADR/UDR, enabling this flag will fail configuration - // ToDo: check this with UBX-MON-VER - 0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask) - 0x00, 0x00, // Reserved - 0x03, // minSVs (Minimum number of satellites for navigation) = 3 - 0x10, // maxSVs (Maximum number of satellites for navigation) = 16 - 0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz - 0x00, // Reserved - 0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled) - 0x00, 0x00, // Reserved - 0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled) - 0x00, 0x00, // Reserved - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved - 0x00, // Reserved - 0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled) - 0x00, 0x00, // Reserved - 0x00, 0x00, // Reserved - 0x00, 0x00, 0x00, 0x00, // Reserved - 0x00, 0x00, 0x00, // Reserved - 0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled) - 0x00, 0x00 // Checksum (calculated below) - }; - - // Calculate the checksum and update the message. - UBXChecksum(_message_NAVX5, sizeof(_message_NAVX5)); - - // Send the message to the module - _serial_gps->write(_message_NAVX5, sizeof(_message_NAVX5)); - - if (getACK(0x06, 0x23, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to configure extra settings.\n"); - } - - // ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid - - // Set GPS update rate to 1Hz - // 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. - 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) - 0xE8, 0x03, // Measurement Rate (1000ms for 1Hz) - 0x01, 0x00, // Navigation rate, always 1 in GPS mode - 0x01, 0x00, // Time reference - 0x00, 0x00 // Placeholder for checksum, will be calculated next - }; - - // Calculate the checksum and update the message. - UBXChecksum(_message_1Hz, sizeof(_message_1Hz)); - - // Send the message to the module - _serial_gps->write(_message_1Hz, sizeof(_message_1Hz)); - - if (getACK(0x06, 0x08, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to set GPS update rate.\n"); - } - - // Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical - // coordinates. - 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) - 0xF0, 0x01, // NMEA ID for GLL - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x00, // Disable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - - // Calculate the checksum and update the message. - UBXChecksum(_message_GGL, sizeof(_message_GGL)); - - // Send the message to the module - _serial_gps->write(_message_GGL, sizeof(_message_GGL)); - - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA GGL.\n"); - } - - // Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and - // the DOP (Dilution of Precision) - 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) - 0xF0, 0x02, // NMEA ID for GSA - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x01, // Enable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - UBXChecksum(_message_GSA, sizeof(_message_GSA)); - _serial_gps->write(_message_GSA, sizeof(_message_GSA)); - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to Enable NMEA GSA.\n"); - } - - // Disable GSV. GSV - Satellites in view, details the number and location of satellites in view. - 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) - 0xF0, 0x03, // NMEA ID for GSV - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x00, // Disable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - UBXChecksum(_message_GSV, sizeof(_message_GSV)); - _serial_gps->write(_message_GSV, sizeof(_message_GSV)); - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA GSV.\n"); - } - - // Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to - // the ground. - 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) - 0xF0, 0x05, // NMEA ID for VTG - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x00, // Disable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - UBXChecksum(_message_VTG, sizeof(_message_VTG)); - _serial_gps->write(_message_VTG, sizeof(_message_VTG)); - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA VTG.\n"); - } - - // Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data. - 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) - 0xF0, 0x04, // NMEA ID for RMC - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x01, // Enable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - UBXChecksum(_message_RMC, sizeof(_message_RMC)); - _serial_gps->write(_message_RMC, sizeof(_message_RMC)); - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable NMEA RMC.\n"); - } - - // Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data. - 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) - 0xF0, 0x00, // NMEA ID for GGA - 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI - 0x01, // Enable - 0x01, 0x01, 0x01, 0x01, // Reserved - 0x00, 0x00 // CK_A and CK_B (Checksum) - }; - UBXChecksum(_message_GGA, sizeof(_message_GGA)); - _serial_gps->write(_message_GGA, sizeof(_message_GGA)); - if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable NMEA GGA.\n"); - } - - // The Power Management configuration allows the GPS module to operate in different power modes for optimized power - // consumption. - // The modes supported are: - // 0x00 = Full power: The module operates at full power with no power saving. - // 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption. - // 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states. - // 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate. - // 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate. - // 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate. - // The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue is - // set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase and - // must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, it must - // be set to '0'. - if (uBloxProtocolVersion >= 18) { - byte UBX_CFG_PMS[16] = { - 0xB5, 0x62, // UBX sync characters - 0x06, 0x86, // Message class and ID (UBX-CFG-PMS) - 0x08, 0x00, // Length of payload (6 bytes) - 0x00, // Version (0) - 0x03, // Power setup value - 0x00, 0x00, // period: not applicable, set to 0 - 0x00, 0x00, // onTime: not applicable, set to 0 - 0x97, 0x6F, // reserved, generated by u-center - 0x00, 0x00 // Placeholder for checksum, will be calculated next - }; - - // Calculate the checksum and update the message - UBXChecksum(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - - // Send the message to the module - _serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS)); - if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving for GPS.\n"); - } - } else { - if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode has only been tested on this hardware - int msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving mode for GPS.\n"); - } - msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving details for GPS.\n"); - } - } else { - int msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving ECO mode for GPS.\n"); - } - } - } - // We need save configuration to flash to make our config changes persistent - 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) - 0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared - 0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections - 0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded - 0x0F, // deviceMask: BBR, Flash, EEPROM, and SPI Flash - 0x00, 0x00 // Checksum (calculated below) - }; - - // Calculate the checksum and update the message. - UBXChecksum(_message_SAVE, sizeof(_message_SAVE)); - - // Send the message to the module - _serial_gps->write(_message_SAVE, sizeof(_message_SAVE)); - - if (getACK(0x06, 0x09, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to save GNSS module configuration.\n"); - } else { - LOG_INFO("GNSS module configuration saved!\n"); - } - } - } - - return true; -} - bool GPS::setup() { + int msglen = 0; // Master power for the GPS +#ifdef PIN_GPS_PPS + // pulse per second + pinMode(PIN_GPS_PPS, INPUT); +#endif + +// Currently disabled per issue #525 (TinyGPS++ crash bug) +// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + // see NMEAGPS.h + gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2); + gsapdop.begin(reader, NMEA_MSG_GXGSA, 15); + LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n"); +#endif #if defined(HAS_PMU) || defined(PIN_GPS_EN) if (config.position.gps_enabled) { @@ -724,18 +285,214 @@ bool GPS::setup() digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE); #endif setAwake(true); // Wake GPS power before doing any init - bool ok = setupGPS(); - if (ok) { - notifySleepObserver.observe(¬ifySleep); - notifyDeepSleepObserver.observe(¬ifyDeepSleep); - notifyGPSSleepObserver.observe(¬ifyGPSSleep); + if (_serial_gps && !didSerialInit) { + if (!GPSInitStarted) { + GPSInitStarted = true; +#ifdef ARCH_ESP32 + // In esp32 framework, setRxBufferSize needs to be initialized before Serial + _serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 +#endif + + // if the overrides are not dialled in, set them from the board definitions, if they exist + +#if defined(GPS_RX_PIN) + if (!config.position.rx_gpio) + config.position.rx_gpio = GPS_RX_PIN; +#endif +#if defined(GPS_TX_PIN) + if (!config.position.tx_gpio) + config.position.tx_gpio = GPS_TX_PIN; +#endif + +// #define BAUD_RATE 115200 +// ESP32 has a special set of parameters vs other arduino ports +#if defined(ARCH_ESP32) + if (config.position.rx_gpio) { + LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); + LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio); + _serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio); + } +#else + _serial_gps->begin(GPS_BAUDRATE); +#endif + + /* + * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first + */ +#if defined(GPS_UC6580) + _serial_gps->updateBaudRate(115200); + gnssModel = GNSS_MODEL_UC6850; +#else + } + LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]); + gnssModel = probe(serialSpeeds[speedSelect]); + if (gnssModel == GNSS_MODEL_UNKNOWN) { + if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) { + speedSelect = 0; + if (--probeTries == 0) { + LOG_WARN("Giving up on GPS probe and setting to 9600.\n"); + return true; + } + } + return false; +#endif + } + + if (gnssModel == GNSS_MODEL_MTK) { + /* + * t-beam-s3-core uses the same L76K GNSS module as t-echo. + * Unlike t-echo, L76K uses 9600 baud rate for communication by default. + * */ + + // Initialize the L76K Chip, use GPS + GLONASS + BEIDOU + _serial_gps->write("$PCAS04,7*1E\r\n"); + delay(250); + // only ask for RMC and GGA + _serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n"); + delay(250); + // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g + _serial_gps->write("$PCAS11,3*1E\r\n"); + delay(250); + } else if (gnssModel == GNSS_MODEL_UC6850) { + + // use GPS + GLONASS + _serial_gps->write("$CFGSYS,h15\r\n"); + delay(250); + } else if (gnssModel == GNSS_MODEL_UBLOX) { + // Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command) + // We need set it because by default it is GPS only, and we want to use GLONASS too + // Also we need SBAS for better accuracy and extra features + // ToDo: Dynamic configure GNSS systems depending of LoRa region + + if (strncmp(info.hwVersion, "00040007", 8) != + 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"); + msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7); + _serial_gps->write(UBXscratch, msglen); + } else { + msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS), _message_GNSS); + _serial_gps->write(UBXscratch, msglen); + } + + if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) { + // It's not critical if the module doesn't acknowledge this configuration. + LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n"); + } else { + if (strncmp(info.hwVersion, "00070000", 8) == 0) { + LOG_INFO("GNSS configured for GPS+SBAS. Pause for 0.75s before sending next command.\n"); + } else { + LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n"); + } + // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next + // commands + delay(750); + } + } + + msglen = makeUBXPacket(0x06, 0x39, sizeof(_message_JAM), _message_JAM); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x39, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable interference resistance.\n"); + } + + msglen = makeUBXPacket(0x06, 0x23, sizeof(_message_NAVX5), _message_NAVX5); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x23, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to configure extra settings.\n"); + } + + // ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid + + msglen = makeUBXPacket(0x06, 0x08, sizeof(_message_1HZ), _message_1HZ); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x08, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to set GPS update rate.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GGL), _message_GGL); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to disable NMEA GGL.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GSA), _message_GSA); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to Enable NMEA GSA.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GSV), _message_GSV); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to disable NMEA GSV.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_VTG), _message_VTG); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to disable NMEA VTG.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_RMC), _message_RMC); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable NMEA RMC.\n"); + } + + msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GGA), _message_GGA); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable NMEA GGA.\n"); + } + + if (uBloxProtocolVersion >= 18) { + msglen = makeUBXPacket(0x06, 0x86, sizeof(_message_PMS), _message_PMS); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving for GPS.\n"); + } + } else { + if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode has only been tested on this hardware + msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving mode for GPS.\n"); + } + msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving details for GPS.\n"); + } + } else { + msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to enable powersaving ECO mode for GPS.\n"); + } + } + } + + msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x09, 300) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to save GNSS module configuration.\n"); + } else { + LOG_INFO("GNSS module configuration saved!\n"); + } + } + didSerialInit = true; } + notifySleepObserver.observe(¬ifySleep); + notifyDeepSleepObserver.observe(¬ifyDeepSleep); + notifyGPSSleepObserver.observe(¬ifyGPSSleep); + if (config.position.gps_enabled == false && config.position.fixed_position == false) { setAwake(false); } - return ok; + return true; } GPS::~GPS() @@ -865,6 +622,28 @@ void GPS::publishUpdate() int32_t GPS::runOnce() { + if (!GPSInitFinished) { + if (!setup()) + return 2000; // Setup failed, re-run in two seconds + gpsStatus->observe(&gps->newStatus); + + // We have now loaded our saved preferences from flash + + // ONCE we will factory reset the GPS for bug #327 + if (gps && !devicestate.did_gps_reset) { + LOG_WARN("GPS FactoryReset requested\n"); + if (gps->factoryReset()) { // If we don't succeed try again next time + devicestate.did_gps_reset = true; + nodeDB.saveToDisk(SEGMENT_DEVICESTATE); + } + } + GPSInitFinished = true; + if (config.position.gps_enabled == false) { + doGPSpowersave(false); + return 0; + } + } + // Repeaters have no need for GPS if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) disable(); @@ -1138,24 +917,6 @@ GPS *createGps() #if !HAS_GPS return nullptr; #else - if (config.position.gps_enabled) { -#ifdef GPS_ALTITUDE_HAE - LOG_DEBUG("Using HAE altitude model\n"); -#else - LOG_DEBUG("Using MSL altitude model\n"); -#endif - if (GPS::_serial_gps) { - // Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. - // Just assume NMEA at 9600 baud. - GPS *new_gps = new NMEAGPS(); - new_gps->setup(); - return new_gps; - } - } else { - GPS *new_gps = new NMEAGPS(); - new_gps->setup(); - return new_gps; - } - return nullptr; + return new NMEAGPS(); #endif } \ No newline at end of file diff --git a/src/gps/GPS.h b/src/gps/GPS.h index f5254890d..67ff69068 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -37,6 +37,10 @@ class GPS : private concurrency::OSThread { private: uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0; + const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600}; + + int speedSelect = 0; + int probeTries = 2; /** * hasValidLocation - indicates that the position variables contain a complete @@ -52,6 +56,9 @@ class GPS : private concurrency::OSThread bool hasGPS = false; // Do we have a GPS we are talking to + bool GPSInitFinished = false; // Init thread finished? + bool GPSInitStarted = false; // Init thread finished? + uint8_t numSatellites = 0; CallbackObserver notifySleepObserver = CallbackObserver(this, &GPS::prepareSleep); @@ -62,10 +69,24 @@ 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]; - static const uint8_t _message_CFG_RXM_PSM[2]; - static const uint8_t _message_CFG_RXM_ECO[2]; - static const uint8_t _message_CFG_PM2[44]; + static const uint8_t _message_PMREQ[]; + static const uint8_t _message_CFG_RXM_PSM[]; + static const uint8_t _message_CFG_RXM_ECO[]; + static const uint8_t _message_CFG_PM2[]; + static const uint8_t _message_GNSS_7[]; + static const uint8_t _message_GNSS[]; + static const uint8_t _message_JAM[]; + static const uint8_t _message_NAVX5[]; + static const uint8_t _message_1HZ[]; + static const uint8_t _message_GGL[]; + static const uint8_t _message_GSA[]; + static const uint8_t _message_GSV[]; + static const uint8_t _message_VTG[]; + static const uint8_t _message_RMC[]; + static const uint8_t _message_GGA[]; + static const uint8_t _message_PMS[]; + static const uint8_t _message_SAVE[]; + meshtastic_Position p = meshtastic_Position_init_default; GPS() : concurrency::OSThread("GPS") {} @@ -111,10 +132,11 @@ class GPS : private concurrency::OSThread // scratch space for creating ublox packets uint8_t UBXscratch[250] = {0}; - protected: - /// Do gps chipset specific init, return true for success - virtual bool setupGPS(); + int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis); + GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis); + GPS_RESPONSE getACK(const char *message, uint32_t waitMillis); + protected: /// If possible force the GPS into sleep/low power mode virtual void sleep(); @@ -189,9 +211,6 @@ class GPS : private concurrency::OSThread String getNMEA(); GnssModel_t probe(int serialSpeed); - int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis); - GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis); - GPS_RESPONSE getACK(const char *message, uint32_t waitMillis); // delay counter to allow more sats before fixed position stops GPS thread uint8_t fixeddelayCtr = 0; diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp index 202185a3b..f62a1aee8 100644 --- a/src/gps/NMEAGPS.cpp +++ b/src/gps/NMEAGPS.cpp @@ -36,30 +36,6 @@ bool NMEAGPS::factoryReset() return true; } -bool NMEAGPS::setupGPS() -{ - GPS::setupGPS(); - -#ifdef PIN_GPS_PPS - // pulse per second - // FIXME - move into shared GPS code - pinMode(PIN_GPS_PPS, INPUT); -#endif - -// Currently disabled per issue #525 (TinyGPS++ crash bug) -// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - // see NMEAGPS.h - gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2); - gsapdop.begin(reader, NMEA_MSG_GXGSA, 15); - LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n"); -#else - LOG_DEBUG("GxGSA NOT available\n"); -#endif - - return true; -} - /** * Perform any processing that should be done only while the GPS is awake and looking for a fix. * Override this method to check for new locations diff --git a/src/gps/NMEAGPS.h b/src/gps/NMEAGPS.h index 85521077a..ea918de66 100644 --- a/src/gps/NMEAGPS.h +++ b/src/gps/NMEAGPS.h @@ -24,8 +24,6 @@ class NMEAGPS : public GPS #endif public: - virtual bool setupGPS() override; - virtual bool factoryReset() override; protected: diff --git a/src/gps/ubx.h b/src/gps/ubx.h index a81b52e80..6493b2ce7 100644 --- a/src/gps/ubx.h +++ b/src/gps/ubx.h @@ -28,4 +28,165 @@ const uint8_t GPS::_message_CFG_PM2[] PROGMEM = { 0x03, 0x00, 0x87, 0x02, // reserved 0x00, 0x00, 0xFF, 0x00, // reserved 0x01, 0x00, 0xD6, 0x4D // reserved +}; + +const uint8_t GPS::_message_GNSS_7[] = { + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01 // SBAS +}; + +// It's not critical if the module doesn't acknowledge this configuration. +// The module should operate adequately with its factory or previously saved settings. +// It appears that there is a firmware bug in some GPS modules: When an attempt is made +// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to +// what is specified in the Ublox documentation. +// There is also a possibility that the module may be GPS-only. +const uint8_t GPS::_message_GNSS[] = { + 0x00, // msgVer (0 for this version) + 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0) + 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) + 0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems + // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags + 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS + 0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01 // GLONASS +}; + +// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board, +// and we need to reduce interference from them +const uint8_t GPS::_message_JAM[] = { + // bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal) + // cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal) + // algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended + // enable (Enable interference detection) is set to 1 (enabled) + 0x3F, 0x10, 0xB1, 0x56, // config: Interference config word + // generalBits (General settings) is set to 0x31E as recommended + // antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown) + // ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info + // enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1 + // (enabled) + 0x1E, 0x03, 0x00, 0x01 // config2: Extra settings for jamming/interference monitor +}; + +// Configure navigation engine expert settings: +const uint8_t GPS::_message_NAVX5[] = { + 0x00, 0x00, // msgVer (0 for this version) + // minMax flag = 1: apply min/max SVs settings + // minCno flag = 1: apply minimum C/N0 setting + // initial3dfix flag = 0: apply initial 3D fix settings + // aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous) + 0x1B, 0x00, // mask1 (First parameters bitmask) + // adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag) + // If firmware is not ADR/UDR, enabling this flag will fail configuration + // ToDo: check this with UBX-MON-VER + 0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask) + 0x00, 0x00, // Reserved + 0x03, // minSVs (Minimum number of satellites for navigation) = 3 + 0x10, // maxSVs (Maximum number of satellites for navigation) = 16 + 0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz + 0x00, // Reserved + 0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled) + 0x00, 0x00, // Reserved + 0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled) + 0x00, 0x00, // Reserved + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved + 0x00, // Reserved + 0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled) + 0x00, 0x00, // Reserved + 0x00, 0x00, // Reserved + 0x00, 0x00, 0x00, 0x00, // Reserved + 0x00, 0x00, 0x00, // Reserved + 0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled) +}; + +// Set GPS update rate to 1Hz +// 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. +const uint8_t GPS::_message_1HZ[] = { + 0xE8, 0x03, // Measurement Rate (1000ms for 1Hz) + 0x01, 0x00, // Navigation rate, always 1 in GPS mode + 0x01, 0x00, // Time reference +}; + +// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical +// coordinates. +const uint8_t GPS::_message_GGL[] = { + 0xF0, 0x01, // NMEA ID for GLL + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x00, // Disable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and +// the DOP (Dilution of Precision) +const uint8_t GPS::_message_GSA[] = { + 0xF0, 0x02, // NMEA ID for GSA + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x01, // Enable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view. +const uint8_t GPS::_message_GSV[] = { + 0xF0, 0x03, // NMEA ID for GSV + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x00, // Disable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to +// the ground. +const uint8_t GPS::_message_VTG[] = { + 0xF0, 0x05, // NMEA ID for VTG + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x00, // Disable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data. +const uint8_t GPS::_message_RMC[] = { + 0xF0, 0x04, // NMEA ID for RMC + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x01, // Enable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data. +const uint8_t GPS::_message_GGA[] = { + 0xF0, 0x00, // NMEA ID for GGA + 0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI + 0x01, // Enable + 0x01, 0x01, 0x01, 0x01 // Reserved +}; + +// The Power Management configuration allows the GPS module to operate in different power modes for optimized +// power consumption. The modes supported are: 0x00 = Full power: The module operates at full power with no power +// saving. 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption. +// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states. +// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate. +// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate. +// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate. +// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue +// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase +// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, +// it must be set to '0'. +const uint8_t GPS::_message_PMS[] = { + 0x00, // Version (0) + 0x03, // Power setup value + 0x00, 0x00, // period: not applicable, set to 0 + 0x00, 0x00, // onTime: not applicable, set to 0 + 0x97, 0x6F // reserved, generated by u-center +}; + +const uint8_t GPS::_message_SAVE[] = { + 0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared + 0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections + 0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded + 0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e67603c64..d31ec3dba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -559,6 +559,7 @@ void setup() readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) nodeStatus->observe(&nodeDB.newStatus); + gps = createGps(); service.init(); @@ -736,27 +737,6 @@ void setup() PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS powerFSMthread = new PowerFSMThread(); - gps = createGps(); - - if (gps) { - gpsStatus->observe(&gps->newStatus); - if (config.position.gps_enabled == false && config.position.fixed_position == false) { - doGPSpowersave(false); - } - } else { - LOG_WARN("No GPS found - running without GPS\n"); - } - // We have now loaded our saved preferences from flash - - // ONCE we will factory reset the GPS for bug #327 - if (gps && !devicestate.did_gps_reset) { - LOG_WARN("GPS FactoryReset requested\n"); - if (gps->factoryReset()) { // If we don't succeed try again next time - devicestate.did_gps_reset = true; - nodeDB.saveToDisk(SEGMENT_DEVICESTATE); - } - } - // setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state setCPUFast(false); // 80MHz is fine for our slow peripherals } diff --git a/src/sleep.cpp b/src/sleep.cpp index 891cce228..9df5da686 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -209,9 +209,7 @@ void doGPSpowersave(bool 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); - } + gps->_serial_gps->write(gps->UBXscratch, msglen); } else { gps->forceWake(1); gps->_serial_gps->write(0xFF); From c608f0ba81169aaec814e070446ba2567b7f8560 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 12 Sep 2023 15:54:50 -0500 Subject: [PATCH 68/97] Fix time=0 bug for fixed_position nodes (#2789) --- src/mesh/MeshService.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 5fbd441b6..9d2ecdcee 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -338,10 +338,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) pos = ConvertToPosition(node->position); } - // Finally add a fresh timestamp and battery level reading - // I KNOW this is redundant with refreshLocalMeshNode() above, but these are - // inexpensive nonblocking calls and can be refactored in due course - pos.time = getValidTime(RTCQualityGPS); + // Add a fresh timestamp + pos.time = getValidTime(RTCQualityFromNet); // In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB) LOG_DEBUG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i, From b02dd0e964247a117a0796008fa36f662bf83f99 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 12 Sep 2023 16:46:46 -0500 Subject: [PATCH 69/97] Move partial GPS initialization earlier in boot (#2788) Co-authored-by: Ben Meadors --- src/gps/GPS.cpp | 146 ++++++++++++++++++++++++------------------------ src/gps/GPS.h | 14 ++--- src/main.cpp | 5 +- 3 files changed, 84 insertions(+), 81 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 1ee61d592..d457cfcf3 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -254,77 +254,9 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t bool GPS::setup() { int msglen = 0; - // Master power for the GPS -#ifdef PIN_GPS_PPS - // pulse per second - pinMode(PIN_GPS_PPS, INPUT); -#endif - -// Currently disabled per issue #525 (TinyGPS++ crash bug) -// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - // see NMEAGPS.h - gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2); - gsapdop.begin(reader, NMEA_MSG_GXGSA, 15); - LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n"); -#endif - -#if defined(HAS_PMU) || defined(PIN_GPS_EN) - if (config.position.gps_enabled) { -#ifdef PIN_GPS_EN - pinMode(PIN_GPS_EN, OUTPUT); -#endif - setGPSPower(true); - } -#endif - -#ifdef PIN_GPS_RESET - digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms - pinMode(PIN_GPS_RESET, OUTPUT); - delay(10); - digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE); -#endif - setAwake(true); // Wake GPS power before doing any init if (_serial_gps && !didSerialInit) { - if (!GPSInitStarted) { - GPSInitStarted = true; -#ifdef ARCH_ESP32 - // In esp32 framework, setRxBufferSize needs to be initialized before Serial - _serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 -#endif - - // if the overrides are not dialled in, set them from the board definitions, if they exist - -#if defined(GPS_RX_PIN) - if (!config.position.rx_gpio) - config.position.rx_gpio = GPS_RX_PIN; -#endif -#if defined(GPS_TX_PIN) - if (!config.position.tx_gpio) - config.position.tx_gpio = GPS_TX_PIN; -#endif - -// #define BAUD_RATE 115200 -// ESP32 has a special set of parameters vs other arduino ports -#if defined(ARCH_ESP32) - if (config.position.rx_gpio) { - LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); - LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio); - _serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio); - } -#else - _serial_gps->begin(GPS_BAUDRATE); -#endif - - /* - * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first - */ -#if defined(GPS_UC6580) - _serial_gps->updateBaudRate(115200); - gnssModel = GNSS_MODEL_UC6850; -#else - } +#if !defined(GPS_UC6580) LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]); gnssModel = probe(serialSpeeds[speedSelect]); if (gnssModel == GNSS_MODEL_UNKNOWN) { @@ -336,8 +268,10 @@ bool GPS::setup() } } return false; -#endif } +#else + gnssModel = GNSS_MODEL_UC6850; +#endif if (gnssModel == GNSS_MODEL_MTK) { /* @@ -625,7 +559,6 @@ int32_t GPS::runOnce() if (!GPSInitFinished) { if (!setup()) return 2000; // Setup failed, re-run in two seconds - gpsStatus->observe(&gps->newStatus); // We have now loaded our saved preferences from flash @@ -917,6 +850,75 @@ GPS *createGps() #if !HAS_GPS return nullptr; #else - return new NMEAGPS(); + GPS *new_gps = new NMEAGPS(); + // Master power for the GPS +#ifdef PIN_GPS_PPS + // pulse per second + pinMode(PIN_GPS_PPS, INPUT); +#endif + +// Currently disabled per issue #525 (TinyGPS++ crash bug) +// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + // see NMEAGPS.h + gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2); + gsapdop.begin(reader, NMEA_MSG_GXGSA, 15); + LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n"); +#endif + +#if defined(HAS_PMU) || defined(PIN_GPS_EN) + if (config.position.gps_enabled) { +#ifdef PIN_GPS_EN + pinMode(PIN_GPS_EN, OUTPUT); +#endif + setGPSPower(true); + } +#endif + +#ifdef PIN_GPS_RESET + digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms + pinMode(PIN_GPS_RESET, OUTPUT); + delay(10); + digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE); +#endif + new_gps->setAwake(true); // Wake GPS power before doing any init + + if (new_gps->_serial_gps) { +#ifdef ARCH_ESP32 + // In esp32 framework, setRxBufferSize needs to be initialized before Serial + new_gps->_serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 +#endif + + // if the overrides are not dialled in, set them from the board definitions, if they exist + +#if defined(GPS_RX_PIN) + if (!config.position.rx_gpio) + config.position.rx_gpio = GPS_RX_PIN; +#endif +#if defined(GPS_TX_PIN) + if (!config.position.tx_gpio) + config.position.tx_gpio = GPS_TX_PIN; +#endif + +// #define BAUD_RATE 115200 +// ESP32 has a special set of parameters vs other arduino ports +#if defined(ARCH_ESP32) + if (config.position.rx_gpio) { + LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); + LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio); + new_gps->_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio); + } +#else + new_gps->_serial_gps->begin(GPS_BAUDRATE); +#endif + + /* + * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first + */ +#if defined(GPS_UC6580) + new_gps->_serial_gps->updateBaudRate(115200); +#endif + } + return new_gps; #endif } \ No newline at end of file diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 67ff69068..eaf6cc224 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -136,6 +136,13 @@ class GPS : private concurrency::OSThread GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis); GPS_RESPONSE getACK(const char *message, uint32_t waitMillis); + /** + * Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode + * + * calls sleep/wake + */ + void setAwake(bool on); + protected: /// If possible force the GPS into sleep/low power mode virtual void sleep(); @@ -185,13 +192,6 @@ class GPS : private concurrency::OSThread // Calculate checksum 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 - * - * calls sleep/wake - */ - void setAwake(bool on); - /** Get how long we should stay looking for each aquisition */ uint32_t getWakeTime() const; diff --git a/src/main.cpp b/src/main.cpp index d31ec3dba..031f65356 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -557,9 +557,10 @@ void setup() screen = new graphics::Screen(screen_found, screen_model, screen_geometry); readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) - - nodeStatus->observe(&nodeDB.newStatus); gps = createGps(); + if (gps) + gpsStatus->observe(&gps->newStatus); + nodeStatus->observe(&nodeDB.newStatus); service.init(); From b53cb38a09ec25d9dc101732ecf820f0d73bee07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:50:52 -0500 Subject: [PATCH 70/97] [create-pull-request] automated change (#2790) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 5 ++--- src/mesh/generated/meshtastic/telemetry.pb.h | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/protobufs b/protobufs index 82ce9448a..e9feb6424 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 82ce9448a0d89899ba01786c05d8f73e6a5005b7 +Subproject commit e9feb6424aaa00915db33a25f4153ebc8c14735b diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 887e4d11e..c32f55aab 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -299,9 +299,8 @@ typedef struct _meshtastic_Position { /* In meters above MSL (but see issue #359) */ int32_t altitude; /* This is usually not sent over the mesh (to save space), but it is sent - from the phone so that the local device can set its RTC If it is sent over - the mesh (because there are devices on the mesh without GPS), it will only - be sent by devices which has a hardware GPS clock. + from the phone so that the local device can set its time if it is sent over + the mesh (because there are devices on the mesh without GPS or RTC). seconds since 1970 */ uint32_t time; /* TODO: REPLACE */ diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 4a9efc337..760286598 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -101,11 +101,7 @@ typedef struct _meshtastic_AirQualityMetrics { /* Types of Measurements the telemetry module is equipped to handle */ typedef struct _meshtastic_Telemetry { - /* This is usually not sent over the mesh (to save space), but it is sent - from the phone so that the local device can set its RTC If it is sent over - the mesh (because there are devices on the mesh without GPS), it will only - be sent by devices which has a hardware GPS clock (IE Mobile Phone). - seconds since 1970 */ + /* Seconds since 1970 - or 0 for unknown/unset */ uint32_t time; pb_size_t which_variant; union { From 073190274486dda9c5fae0aba4e9749e73625df2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:00:29 -0500 Subject: [PATCH 71/97] [create-pull-request] automated change (#2791) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index d0c8a646f..4754257e1 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 6 +build = 7 From 822c150e0da417a728896a16acdc8b8261369f65 Mon Sep 17 00:00:00 2001 From: Ric In New Mexico <78682404+RicInNewMexico@users.noreply.github.com> Date: Sat, 16 Sep 2023 14:24:59 -0600 Subject: [PATCH 72/97] Fixing typo in src/mesh/mesh-pb-constants.cpp logging (#2800) * Update variant.h Add second i2c channel on external connector for Station G1 * Create trunk-check.yml * Fix typo in logging Corrected typo in pb_msgdesc logging for packets failing to be decoded. --------- Co-authored-by: Ben Meadors --- src/mesh/mesh-pb-constants.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/mesh-pb-constants.cpp b/src/mesh/mesh-pb-constants.cpp index 994fab61f..93dbf0178 100644 --- a/src/mesh/mesh-pb-constants.cpp +++ b/src/mesh/mesh-pb-constants.cpp @@ -25,7 +25,7 @@ bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msg { pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize); if (!pb_decode(&stream, fields, dest_struct)) { - LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields); + LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc %p\n", PB_GET_ERROR(&stream), fields); return false; } else { return true; From 8b82ae6fe3f36fbadc0dee87a82fc7e5c520a6f3 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 16 Sep 2023 23:10:10 -0500 Subject: [PATCH 73/97] refactor and avoid needless probe (#2799) * Use UINT32_MAX to indicate no configured GPS * Refactor GPS to not probe if pins not defined * Minor cleanups related to rework * Use Named Constructor to clean up code * Actually disable the GPS thread * Don't actually disable the GPS thread * Move doGPSPowerSave to GPS class * Make sure to set GPS awake on triple-click --------- Co-authored-by: Ben Meadors --- src/ButtonThread.h | 14 +- src/gps/GPS.cpp | 385 +++++++++++++++++++++++++----- src/gps/GPS.h | 53 +++- src/gps/NMEAGPS.cpp | 248 ------------------- src/gps/NMEAGPS.h | 55 ----- src/main.cpp | 8 +- src/platform/esp32/architecture.h | 18 +- src/sleep.cpp | 35 --- src/sleep.h | 2 +- variants/heltec_v3/variant.h | 4 +- variants/rak11310/variant.h | 2 - variants/rpipico/variant.h | 2 - variants/rpipicow/variant.h | 2 - variants/station-g1/variant.h | 4 + variants/tbeam/variant.h | 8 +- 15 files changed, 397 insertions(+), 443 deletions(-) delete mode 100644 src/gps/NMEAGPS.cpp delete mode 100644 src/gps/NMEAGPS.h diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 255ab5162..944a7adf0 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -165,13 +165,15 @@ class ButtonThread : public concurrency::OSThread static void userButtonMultiPressed() { #if defined(GPS_POWER_TOGGLE) - if (config.position.gps_enabled) { - LOG_DEBUG("Flag set to false for gps power\n"); - } else { - LOG_DEBUG("Flag set to true to restore power\n"); + if (gps != nullptr) { + if (config.position.gps_enabled) { + LOG_DEBUG("Flag set to false for gps power\n"); + } else { + LOG_DEBUG("Flag set to true to restore power\n"); + } + config.position.gps_enabled = !(config.position.gps_enabled); + gps->doGPSpowersave(config.position.gps_enabled); } - config.position.gps_enabled = !(config.position.gps_enabled); - doGPSpowersave(config.position.gps_enabled); #endif } diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index d457cfcf3..43869a72e 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -13,12 +13,7 @@ #define GPS_RESET_MODE HIGH #endif -// If we have a serial GPS port it will not be null -#ifdef GPS_SERIAL_NUM -HardwareSerial _serial_gps_real(GPS_SERIAL_NUM); -HardwareSerial *GPS::_serial_gps = &_serial_gps_real; -#elif defined(NRF52840_XXAA) || defined(NRF52833_XXAA) -// Assume NRF52840 +#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) HardwareSerial *GPS::_serial_gps = &Serial1; #else HardwareSerial *GPS::_serial_gps = NULL; @@ -32,6 +27,8 @@ static bool didSerialInit; struct uBloxGnssModelInfo info; uint8_t uBloxProtocolVersion; +#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway +#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc) void GPS::UBXChecksum(uint8_t *message, size_t length) { @@ -257,17 +254,21 @@ bool GPS::setup() if (_serial_gps && !didSerialInit) { #if !defined(GPS_UC6580) - LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]); - gnssModel = probe(serialSpeeds[speedSelect]); - if (gnssModel == GNSS_MODEL_UNKNOWN) { - if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) { - speedSelect = 0; - if (--probeTries == 0) { - LOG_WARN("Giving up on GPS probe and setting to 9600.\n"); - return true; + if (tx_gpio) { + LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]); + gnssModel = probe(serialSpeeds[speedSelect]); + if (gnssModel == GNSS_MODEL_UNKNOWN) { + if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) { + speedSelect = 0; + if (--probeTries == 0) { + LOG_WARN("Giving up on GPS probe and setting to 9600.\n"); + return true; + } } + return false; } - return false; + } else { + gnssModel = GNSS_MODEL_UNKNOWN; } #else gnssModel = GNSS_MODEL_UC6850; @@ -437,16 +438,6 @@ GPS::~GPS() notifyGPSSleepObserver.observe(¬ifyGPSSleep); } -bool GPS::hasLock() -{ - return hasValidLocation; -} - -bool GPS::hasFlow() -{ - return hasGPS; -} - // Allow defining the polarity of the WAKE output. default is active high #ifndef GPS_WAKE_ACTIVE #define GPS_WAKE_ACTIVE 1 @@ -563,7 +554,7 @@ int32_t GPS::runOnce() // We have now loaded our saved preferences from flash // ONCE we will factory reset the GPS for bug #327 - if (gps && !devicestate.did_gps_reset) { + if (!devicestate.did_gps_reset) { LOG_WARN("GPS FactoryReset requested\n"); if (gps->factoryReset()) { // If we don't succeed try again next time devicestate.did_gps_reset = true; @@ -576,6 +567,8 @@ int32_t GPS::runOnce() return 0; } } + if (config.position.gps_enabled == false) + return 0; // Repeaters have no need for GPS if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) @@ -840,18 +833,30 @@ GnssModel_t GPS::probe(int serialSpeed) return GNSS_MODEL_UBLOX; } -#if HAS_GPS -#include "NMEAGPS.h" -#endif - -GPS *createGps() +// GPS::GPS(uint32_t _rx_gpio, uint32_t _tx_gpio) : concurrency::OSThread("GPS") +GPS *GPS::createGps() { + int8_t _rx_gpio = config.position.rx_gpio; + int8_t _tx_gpio = config.position.tx_gpio; +#if defined(HAS_GPS) && !defined(ARCH_ESP32) + _rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags. + _tx_gpio = 1; +#endif +#if defined(GPS_RX_PIN) + if (!_rx_gpio) + _rx_gpio = GPS_RX_PIN; +#endif +#if defined(GPS_TX_PIN) + if (!_tx_gpio) + _tx_gpio = GPS_TX_PIN; +#endif + if (!_rx_gpio) // Configured to have no GPS at all + return nullptr; + + GPS *new_gps = new GPS; + new_gps->rx_gpio = _rx_gpio; + new_gps->tx_gpio = _tx_gpio; -#if !HAS_GPS - return nullptr; -#else - GPS *new_gps = new NMEAGPS(); - // Master power for the GPS #ifdef PIN_GPS_PPS // pulse per second pinMode(PIN_GPS_PPS, INPUT); @@ -883,42 +888,308 @@ GPS *createGps() #endif new_gps->setAwake(true); // Wake GPS power before doing any init - if (new_gps->_serial_gps) { + if (_serial_gps) { #ifdef ARCH_ESP32 // In esp32 framework, setRxBufferSize needs to be initialized before Serial - new_gps->_serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 + _serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256 #endif - // if the overrides are not dialled in, set them from the board definitions, if they exist - -#if defined(GPS_RX_PIN) - if (!config.position.rx_gpio) - config.position.rx_gpio = GPS_RX_PIN; -#endif -#if defined(GPS_TX_PIN) - if (!config.position.tx_gpio) - config.position.tx_gpio = GPS_TX_PIN; -#endif - -// #define BAUD_RATE 115200 // ESP32 has a special set of parameters vs other arduino ports #if defined(ARCH_ESP32) - if (config.position.rx_gpio) { - LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio); - LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio); - new_gps->_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio); - } + LOG_DEBUG("Using GPIO%d for GPS RX\n", new_gps->rx_gpio); + LOG_DEBUG("Using GPIO%d for GPS TX\n", new_gps->tx_gpio); + _serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, new_gps->rx_gpio, new_gps->tx_gpio); + #else - new_gps->_serial_gps->begin(GPS_BAUDRATE); + _serial_gps->begin(GPS_BAUDRATE); #endif /* * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first */ #if defined(GPS_UC6580) - new_gps->_serial_gps->updateBaudRate(115200); + _serial_gps->updateBaudRate(115200); #endif } return new_gps; +} + +static int32_t toDegInt(RawDegrees d) +{ + int32_t degMult = 10000000; // 1e7 + int32_t r = d.deg * degMult + d.billionths / 100; + if (d.negative) + r *= -1; + return r; +} + +bool GPS::factoryReset() +{ +#ifdef PIN_GPS_REINIT + // The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW + digitalWrite(PIN_GPS_REINIT, 0); + pinMode(PIN_GPS_REINIT, OUTPUT); + delay(150); // The L76K datasheet calls for at least 100MS delay + digitalWrite(PIN_GPS_REINIT, 1); +#endif + + // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX. + // Factory Reset + byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; + _serial_gps->write(_message_reset, sizeof(_message_reset)); + delay(1000); + return true; +} + +/** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a new location + */ +bool GPS::lookForTime() +{ + auto ti = reader.time; + auto d = reader.date; + if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed + /* Convert to unix time +The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 +(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). +*/ + struct tm t; + t.tm_sec = ti.second(); + t.tm_min = ti.minute(); + t.tm_hour = ti.hour(); + t.tm_mday = d.day(); + t.tm_mon = d.month() - 1; + t.tm_year = d.year() - 1900; + t.tm_isdst = false; + if (t.tm_mon > -1) { + LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec); + perhapsSetRTC(RTCQualityGPS, t); + return true; + } else + return false; + } else + return false; +} + +/** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a new location + */ +bool GPS::lookForLocation() +{ + // By default, TinyGPS++ does not parse GPGSA lines, which give us + // the 2D/3D fixType (see NMEAGPS.h) + // At a minimum, use the fixQuality indicator in GPGGA (FIXME?) + fixQual = reader.fixQuality(); + +#ifndef TINYGPS_OPTION_NO_STATISTICS + if (reader.failedChecksum() > lastChecksumFailCount) { + LOG_WARN("Warning, %u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount, + reader.failedChecksum()); + lastChecksumFailCount = reader.failedChecksum(); + } +#endif + +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + fixType = atoi(gsafixtype.value()); // will set to zero if no data + // LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType); +#endif + + // check if GPS has an acceptable lock + if (!hasLock()) + return false; + +#ifdef GPS_EXTRAVERBOSE + LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(), +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + gsafixtype.age(), +#else + 0, +#endif + reader.date.age(), reader.time.age()); +#endif // GPS_EXTRAVERBOSE + + // check if a complete GPS solution set is available for reading + // tinyGPSDatum::age() also includes isValid() test + // FIXME + if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) && +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + (gsafixtype.age() < GPS_SOL_EXPIRY_MS) && +#endif + (reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) { + LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age()); + return false; + } + + // Is this a new point or are we re-reading the previous one? + if (!reader.location.isUpdated()) + return false; + + // We know the solution is fresh and valid, so just read the data + auto loc = reader.location.value(); + + // Bail out EARLY to avoid overwriting previous good data (like #857) + if (toDegInt(loc.lat) > 900000000) { +#ifdef GPS_EXTRAVERBOSE + LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat)); +#endif + return false; + } + if (toDegInt(loc.lng) > 1800000000) { +#ifdef GPS_EXTRAVERBOSE + LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng)); +#endif + return false; + } + + p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL; + + // Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + p.HDOP = reader.hdop.value(); + p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value()); + // LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP); +#else + // FIXME! naive PDOP emulation (assumes VDOP==HDOP) + // correct formula is PDOP = SQRT(HDOP^2 + VDOP^2) + p.HDOP = reader.hdop.value(); + p.PDOP = 1.41 * reader.hdop.value(); +#endif + + // Discard incomplete or erroneous readings + if (reader.hdop.value() == 0) { + LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value()); + return false; + } + + p.latitude_i = toDegInt(loc.lat); + p.longitude_i = toDegInt(loc.lng); + + p.altitude_geoidal_separation = reader.geoidHeight.meters(); + p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation; + p.altitude = reader.altitude.meters(); + + p.fix_quality = fixQual; +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + p.fix_type = fixType; +#endif + + // positional timestamp + struct tm t; + t.tm_sec = reader.time.second(); + t.tm_min = reader.time.minute(); + t.tm_hour = reader.time.hour(); + t.tm_mday = reader.date.day(); + t.tm_mon = reader.date.month() - 1; + t.tm_year = reader.date.year() - 1900; + t.tm_isdst = false; + p.timestamp = mktime(&t); + + // Nice to have, if available + if (reader.satellites.isUpdated()) { + p.sats_in_view = reader.satellites.value(); + } + + if (reader.course.isUpdated() && reader.course.isValid()) { + if (reader.course.value() < 36000) { // sanity check + p.ground_track = + reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5 + } else { + LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value()); + } + } + + if (reader.speed.isUpdated() && reader.speed.isValid()) { + p.ground_speed = reader.speed.kmph(); + } + + return true; +} + +bool GPS::hasLock() +{ + // Using GPGGA fix quality indicator + if (fixQual >= 1 && fixQual <= 5) { +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + // Use GPGSA fix type 2D/3D (better) if available + if (fixType == 3 || fixType == 0) // zero means "no data received" +#endif + return true; + } + + return false; +} + +bool GPS::hasFlow() +{ + return reader.passedChecksum() > 0; +} + +bool GPS::whileIdle() +{ + bool isValid = false; +#ifdef SERIAL_BUFFER_SIZE + if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) { + LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available()); + clearBuffer(); + } +#endif + // if (_serial_gps->available() > 0) + // LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available()); + // First consume any chars that have piled up at the receiver + while (_serial_gps->available() > 0) { + int c = _serial_gps->read(); + // LOG_DEBUG("%c", c); + isValid |= reader.encode(c); + } + + return isValid; +} + +void GPS::doGPSpowersave(bool on) +{ +#if defined(HAS_PMU) || defined(PIN_GPS_EN) + if (on) { + LOG_INFO("Turning GPS back on\n"); + gps->forceWake(1); + setGPSPower(1); + setAwake(1); + } else { + LOG_INFO("Turning off GPS chip\n"); + notifyGPSSleep.notifyObservers(NULL); + setGPSPower(0); + } +#endif +#ifdef PIN_GPS_WAKE + if (on) { + LOG_INFO("Waking GPS"); + gps->forceWake(1); + setAwake(1); + } else { + LOG_INFO("GPS entering sleep"); + notifyGPSSleep.notifyObservers(NULL); + } +#endif +#if !(defined(HAS_PMU) || defined(PIN_GPS_EN) || defined(PIN_GPS_WAKE)) + if (!on) { + notifyGPSSleep.notifyObservers(NULL); + if (gnssModel == GNSS_MODEL_UBLOX) { + uint8_t msglen; + msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ); + gps->_serial_gps->write(gps->UBXscratch, msglen); + } + setAwake(1); + } else { + gps->forceWake(1); + if (gnssModel == GNSS_MODEL_UBLOX) + gps->_serial_gps->write(0xFF); + } #endif } \ No newline at end of file diff --git a/src/gps/GPS.h b/src/gps/GPS.h index eaf6cc224..6ee62a283 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -2,6 +2,7 @@ #include "GPSStatus.h" #include "Observer.h" +#include "TinyGPS++.h" #include "concurrency/OSThread.h" struct uBloxGnssModelInfo { @@ -35,10 +36,24 @@ const char *getDOPString(uint32_t dop); */ class GPS : private concurrency::OSThread { + TinyGPSPlus reader; + uint8_t fixQual = 0; // fix quality from GPGGA + uint32_t lastChecksumFailCount = 0; + +#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS + // (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field + // via optional feature "custom fields", currently disabled (bug #525) + TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA + TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA + uint8_t fixType = 0; // fix type from GPGSA +#endif private: uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0; const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600}; + uint32_t rx_gpio = 0; + uint32_t tx_gpio = 0; + int speedSelect = 0; int probeTries = 2; @@ -120,9 +135,6 @@ class GPS : private concurrency::OSThread * */ void forceWake(bool on); - // Some GPS modules (ublock) require factory reset - virtual bool factoryReset() { return true; } - // Empty the input buffer as quickly as possible void clearBuffer(); @@ -142,6 +154,12 @@ class GPS : private concurrency::OSThread * calls sleep/wake */ void setAwake(bool on); + void doGPSpowersave(bool on); + virtual bool factoryReset(); + + // Creates an instance of the GPS class. + // Returns the new instance or null if the GPS is not present. + static GPS *createGps(); protected: /// If possible force the GPS into sleep/low power mode @@ -154,7 +172,6 @@ class GPS : private concurrency::OSThread * * Return true if we received a valid message from the GPS */ - virtual bool whileIdle() = 0; /** Idle processing while GPS is looking for lock, called once per secondish */ virtual void whileActive() {} @@ -165,7 +182,6 @@ class GPS : private concurrency::OSThread * * @return true if we've acquired a time */ - virtual bool lookForTime() = 0; /** * Perform any processing that should be done only while the GPS is awake and looking for a fix. @@ -173,13 +189,34 @@ class GPS : private concurrency::OSThread * * @return true if we've acquired a new location */ - virtual bool lookForLocation() = 0; /// Record that we have a GPS void setConnected(); void setNumSatellites(uint8_t n); + /** Subclasses should look for serial rx characters here and feed it to their GPS parser + * + * Return true if we received a valid message from the GPS + */ + virtual bool whileIdle(); + + /** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a time + */ + virtual bool lookForTime(); + + /** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a new location + */ + virtual bool lookForLocation(); + 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 @@ -218,8 +255,4 @@ class GPS : private concurrency::OSThread GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN; }; -// Creates an instance of the GPS class. -// Returns the new instance or null if the GPS is not present. -GPS *createGps(); - extern GPS *gps; \ No newline at end of file diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp deleted file mode 100644 index f62a1aee8..000000000 --- a/src/gps/NMEAGPS.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include "NMEAGPS.h" -#include "RTC.h" -#include "configuration.h" - -#include - -// GPS solutions older than this will be rejected - see TinyGPSDatum::age() -#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway -#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc) - -static int32_t toDegInt(RawDegrees d) -{ - int32_t degMult = 10000000; // 1e7 - int32_t r = d.deg * degMult + d.billionths / 100; - if (d.negative) - r *= -1; - return r; -} - -bool NMEAGPS::factoryReset() -{ -#ifdef PIN_GPS_REINIT - // The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW - digitalWrite(PIN_GPS_REINIT, 0); - pinMode(PIN_GPS_REINIT, OUTPUT); - delay(150); // The L76K datasheet calls for at least 100MS delay - digitalWrite(PIN_GPS_REINIT, 1); -#endif - - // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX. - // Factory Reset - byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; - _serial_gps->write(_message_reset, sizeof(_message_reset)); - delay(1000); - return true; -} - -/** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a new location - */ -bool NMEAGPS::lookForTime() -{ - auto ti = reader.time; - auto d = reader.date; - if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed - /* Convert to unix time -The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 -(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). -*/ - struct tm t; - t.tm_sec = ti.second(); - t.tm_min = ti.minute(); - t.tm_hour = ti.hour(); - t.tm_mday = d.day(); - t.tm_mon = d.month() - 1; - t.tm_year = d.year() - 1900; - t.tm_isdst = false; - if (t.tm_mon > -1) { - LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec); - perhapsSetRTC(RTCQualityGPS, t); - return true; - } else - return false; - } else - return false; -} - -/** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a new location - */ -bool NMEAGPS::lookForLocation() -{ - // By default, TinyGPS++ does not parse GPGSA lines, which give us - // the 2D/3D fixType (see NMEAGPS.h) - // At a minimum, use the fixQuality indicator in GPGGA (FIXME?) - fixQual = reader.fixQuality(); - -#ifndef TINYGPS_OPTION_NO_STATISTICS - if (reader.failedChecksum() > lastChecksumFailCount) { - LOG_WARN("Warning, %u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount, - reader.failedChecksum()); - lastChecksumFailCount = reader.failedChecksum(); - } -#endif - -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - fixType = atoi(gsafixtype.value()); // will set to zero if no data - // LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType); -#endif - - // check if GPS has an acceptable lock - if (!hasLock()) - return false; - -#ifdef GPS_EXTRAVERBOSE - LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(), -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - gsafixtype.age(), -#else - 0, -#endif - reader.date.age(), reader.time.age()); -#endif // GPS_EXTRAVERBOSE - - // check if a complete GPS solution set is available for reading - // tinyGPSDatum::age() also includes isValid() test - // FIXME - if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) && -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - (gsafixtype.age() < GPS_SOL_EXPIRY_MS) && -#endif - (reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) { - LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age()); - return false; - } - - // Is this a new point or are we re-reading the previous one? - if (!reader.location.isUpdated()) - return false; - - // We know the solution is fresh and valid, so just read the data - auto loc = reader.location.value(); - - // Bail out EARLY to avoid overwriting previous good data (like #857) - if (toDegInt(loc.lat) > 900000000) { -#ifdef GPS_EXTRAVERBOSE - LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat)); -#endif - return false; - } - if (toDegInt(loc.lng) > 1800000000) { -#ifdef GPS_EXTRAVERBOSE - LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng)); -#endif - return false; - } - - p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL; - - // Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - p.HDOP = reader.hdop.value(); - p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value()); - // LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP); -#else - // FIXME! naive PDOP emulation (assumes VDOP==HDOP) - // correct formula is PDOP = SQRT(HDOP^2 + VDOP^2) - p.HDOP = reader.hdop.value(); - p.PDOP = 1.41 * reader.hdop.value(); -#endif - - // Discard incomplete or erroneous readings - if (reader.hdop.value() == 0) { - LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value()); - return false; - } - - p.latitude_i = toDegInt(loc.lat); - p.longitude_i = toDegInt(loc.lng); - - p.altitude_geoidal_separation = reader.geoidHeight.meters(); - p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation; - p.altitude = reader.altitude.meters(); - - p.fix_quality = fixQual; -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - p.fix_type = fixType; -#endif - - // positional timestamp - struct tm t; - t.tm_sec = reader.time.second(); - t.tm_min = reader.time.minute(); - t.tm_hour = reader.time.hour(); - t.tm_mday = reader.date.day(); - t.tm_mon = reader.date.month() - 1; - t.tm_year = reader.date.year() - 1900; - t.tm_isdst = false; - p.timestamp = mktime(&t); - - // Nice to have, if available - if (reader.satellites.isUpdated()) { - p.sats_in_view = reader.satellites.value(); - } - - if (reader.course.isUpdated() && reader.course.isValid()) { - if (reader.course.value() < 36000) { // sanity check - p.ground_track = - reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5 - } else { - LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value()); - } - } - - if (reader.speed.isUpdated() && reader.speed.isValid()) { - p.ground_speed = reader.speed.kmph(); - } - - return true; -} - -bool NMEAGPS::hasLock() -{ - // Using GPGGA fix quality indicator - if (fixQual >= 1 && fixQual <= 5) { -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - // Use GPGSA fix type 2D/3D (better) if available - if (fixType == 3 || fixType == 0) // zero means "no data received" -#endif - return true; - } - - return false; -} - -bool NMEAGPS::hasFlow() -{ - return reader.passedChecksum() > 0; -} - -bool NMEAGPS::whileIdle() -{ - bool isValid = false; -#ifdef SERIAL_BUFFER_SIZE - if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) { - LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available()); - clearBuffer(); - } -#endif - // if (_serial_gps->available() > 0) - // LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available()); - // First consume any chars that have piled up at the receiver - while (_serial_gps->available() > 0) { - int c = _serial_gps->read(); - // LOG_DEBUG("%c", c); - isValid |= reader.encode(c); - } - - return isValid; -} \ No newline at end of file diff --git a/src/gps/NMEAGPS.h b/src/gps/NMEAGPS.h deleted file mode 100644 index ea918de66..000000000 --- a/src/gps/NMEAGPS.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include "GPS.h" -#include "Observer.h" -#include "TinyGPS++.h" - -/** - * A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading) - * - * When new data is available it will notify observers. - */ -class NMEAGPS : public GPS -{ - TinyGPSPlus reader; - uint8_t fixQual = 0; // fix quality from GPGGA - uint32_t lastChecksumFailCount = 0; - -#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS - // (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field - // via optional feature "custom fields", currently disabled (bug #525) - TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA - TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA - uint8_t fixType = 0; // fix type from GPGSA -#endif - - public: - virtual bool factoryReset() override; - - protected: - /** Subclasses should look for serial rx characters here and feed it to their GPS parser - * - * Return true if we received a valid message from the GPS - */ - virtual bool whileIdle() override; - - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a time - */ - virtual bool lookForTime() override; - - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a new location - */ - virtual bool lookForLocation() override; - - virtual bool hasLock() override; - - virtual bool hasFlow() override; -}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 031f65356..8ce365358 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -557,9 +557,13 @@ void setup() screen = new graphics::Screen(screen_found, screen_model, screen_geometry); readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) - gps = createGps(); - if (gps) + + gps = GPS::createGps(); + if (gps) { gpsStatus->observe(&gps->newStatus); + } else { + LOG_DEBUG("Running without GPS.\n"); + } nodeStatus->observe(&nodeDB.newStatus); service.init(); diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index da2295fb5..163cc8b84 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -123,22 +123,6 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62 #endif -// -// Standard definitions for ESP32 targets -// - -#define GPS_SERIAL_NUM 1 -#ifndef GPS_RX_PIN -#define GPS_RX_PIN 34 -#endif -#ifndef GPS_TX_PIN -#ifdef USE_JTAG -#define GPS_TX_PIN -1 -#else -#define GPS_TX_PIN 12 -#endif -#endif - // ----------------------------------------------------------------------------- // LoRa SPI // ----------------------------------------------------------------------------- @@ -151,4 +135,4 @@ #define RF95_NSS 18 #endif -#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 +#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 \ No newline at end of file diff --git a/src/sleep.cpp b/src/sleep.cpp index 9df5da686..ed89b926d 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -182,41 +182,6 @@ static void waitEnterSleep() notifySleep.notifyObservers(NULL); } -void doGPSpowersave(bool on) -{ -#if defined(HAS_PMU) || defined(PIN_GPS_EN) - if (on) { - LOG_INFO("Turning GPS back on\n"); - gps->forceWake(1); - setGPSPower(1); - } else { - LOG_INFO("Turning off GPS chip\n"); - notifyGPSSleep.notifyObservers(NULL); - setGPSPower(0); - } -#endif -#ifdef PIN_GPS_WAKE - if (on) { - LOG_INFO("Waking GPS"); - gps->forceWake(1); - } else { - LOG_INFO("GPS entering sleep"); - 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); - gps->_serial_gps->write(gps->UBXscratch, msglen); - } else { - gps->forceWake(1); - gps->_serial_gps->write(0xFF); - } -#endif -} - void doDeepSleep(uint32_t msecToWake) { if (INCLUDE_vTaskSuspend && (msecToWake == portMAX_DELAY)) { diff --git a/src/sleep.h b/src/sleep.h index 856d8d6b1..366aa1621 100644 --- a/src/sleep.h +++ b/src/sleep.h @@ -19,7 +19,7 @@ extern XPowersLibInterface *PMU; #endif void setGPSPower(bool on); -void doGPSpowersave(bool on); + // Perform power on init that we do on each wake from deep sleep void initDeepSleep(); diff --git a/variants/heltec_v3/variant.h b/variants/heltec_v3/variant.h index cb26ba0a3..3e2227e15 100644 --- a/variants/heltec_v3/variant.h +++ b/variants/heltec_v3/variant.h @@ -11,8 +11,6 @@ #define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost #define BUTTON_PIN 0 -#define PIN_GPS_EN 46 // GPS power enable pin - #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider @@ -35,4 +33,4 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 +#define SX126X_E22 \ No newline at end of file diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h index 1d1577cfd..f103447fb 100644 --- a/variants/rak11310/variant.h +++ b/variants/rak11310/variant.h @@ -11,8 +11,6 @@ #undef ECB #define ECB 0 -#undef GPS_SERIAL_NUM - #define LED_CONN PIN_LED2 #define LED_PIN LED_BUILTIN diff --git a/variants/rpipico/variant.h b/variants/rpipico/variant.h index 71d1bd159..9deeeadf8 100644 --- a/variants/rpipico/variant.h +++ b/variants/rpipico/variant.h @@ -11,9 +11,7 @@ #undef ECB #define ECB 0 -#define NO_GPS 1 #define USE_SH1106 1 -#undef GPS_SERIAL_NUM // default I2C pins: // SDA = 4 diff --git a/variants/rpipicow/variant.h b/variants/rpipicow/variant.h index ac393d4d3..d714e2534 100644 --- a/variants/rpipicow/variant.h +++ b/variants/rpipicow/variant.h @@ -11,9 +11,7 @@ #undef ECB #define ECB 0 -#define NO_GPS 1 #define USE_SH1106 1 -#undef GPS_SERIAL_NUM // default I2C pins: // SDA = 4 diff --git a/variants/station-g1/variant.h b/variants/station-g1/variant.h index 1017f23c7..a1d549d42 100644 --- a/variants/station-g1/variant.h +++ b/variants/station-g1/variant.h @@ -46,3 +46,7 @@ // different screen #define USE_SH1106 + +// Station may not have GPS installed, but it has a labeled GPS pinout +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 \ No newline at end of file diff --git a/variants/tbeam/variant.h b/variants/tbeam/variant.h index 642e3721c..62a864636 100644 --- a/variants/tbeam/variant.h +++ b/variants/tbeam/variant.h @@ -4,8 +4,8 @@ #define I2C_SCL 22 #define BUTTON_PIN 38 // The middle button GPIO on the T-Beam -//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented -// anywhere. +// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented +// anywhere. #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. #define LED_INVERTED 1 @@ -37,4 +37,6 @@ // and waking from light sleep // #define PMU_IRQ 35 #define HAS_AXP192 -#define GPS_UBLOX \ No newline at end of file +#define GPS_UBLOX +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 \ No newline at end of file From a1514b8b64f037eeee8984bd6e9287e4b27bdb07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 18 Sep 2023 11:38:33 +0200 Subject: [PATCH 74/97] Enable (new) ADC and GPS capability. (#2792) * Enable (new) ADC and GPS capability. * Make Picomputer a canon device and define ADC for new board revision --- variants/picomputer-s3/platformio.ini | 2 +- variants/picomputer-s3/variant.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/variants/picomputer-s3/platformio.ini b/variants/picomputer-s3/platformio.ini index e7093697a..202cd05e7 100644 --- a/variants/picomputer-s3/platformio.ini +++ b/variants/picomputer-s3/platformio.ini @@ -1,7 +1,7 @@ [env:picomputer-s3] extends = esp32s3_base board = bpi_picow_esp32_s3 -board_level = extra + ;OpenOCD flash method ;upload_protocol = esp-builtin ;Normal method diff --git a/variants/picomputer-s3/variant.h b/variants/picomputer-s3/variant.h index 716f2779d..732be4bcf 100644 --- a/variants/picomputer-s3/variant.h +++ b/variants/picomputer-s3/variant.h @@ -5,9 +5,14 @@ #define PIN_BUZZER 43 -#define HAS_GPS 0 #define HAS_WIRE 0 +#define BATTERY_PIN ADC1_CHANNEL_1_GPIO_NUM // 2 +// A battery voltage measurement pin, voltage divider connected here to measure battery voltage +// ratio of voltage divider = 3.0 (R11=200k, R7=100k) +#define ADC_MULTIPLIER 3.1 // 3.0 with correction of display undervoltage. +#define ADC_CHANNEL ADC1_GPIO2_CHANNEL + #define USE_RF95 // RFM95/SX127x #define RF95_SCK SCK // 21 From 1bae92657639696a942ef38327ff8f34b4de6e37 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:16:37 +0200 Subject: [PATCH 75/97] fix: nodenum 4 (#2798) * tryfix: nodenum 4 * trunk fmt * rename vars and fix brackets * purge invalid db entries * trunk fmt --- src/mesh/NodeDB.cpp | 33 +++++++++++++++++++++------------ src/mesh/NodeDB.h | 3 +++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2bbc4b779..ff58ca407 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -304,6 +304,19 @@ void NodeDB::resetNodes() neighborInfoModule->resetNeighbors(); } +void NodeDB::cleanupMeshDB() +{ + int newPos = 0, removed = 0; + for (int i = 0; i < *numMeshNodes; i++) { + if (meshNodes[i].has_user) + meshNodes[newPos++] = meshNodes[i]; + else + removed++; + } + *numMeshNodes -= removed; + LOG_DEBUG("cleanupMeshDB purged %d entries\n", removed); +} + void NodeDB::installDefaultDeviceState() { LOG_INFO("Installing default DeviceState\n"); @@ -333,6 +346,7 @@ void NodeDB::init() { LOG_INFO("Initializing NodeDB\n"); loadFromDisk(); + cleanupMeshDB(); uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate)); uint32_t configCRC = crc32Buffer(&config, sizeof(config)); @@ -388,25 +402,20 @@ void NodeDB::init() */ void NodeDB::pickNewNodeNum() { - NodeNum r = myNodeInfo.my_node_num; - getMacAddr(ourMacAddr); // Make sure ourMacAddr is set // Pick an initial nodenum based on the macaddr - r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5]; - - if (r == NODENUM_BROADCAST || r < NUM_RESERVED) - r = NUM_RESERVED; // don't pick a reserved node number + NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5]; meshtastic_NodeInfoLite *found; - while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) { - // FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1 - NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice - LOG_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n); - r = n; + while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) || + ((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0)) { + NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice + LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate); + nodeNum = candidate; } - myNodeInfo.my_node_num = r; + myNodeInfo.my_node_num = nodeNum; } static const char *prefFileName = "/prefs/db.proto"; diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index ab0ec8288..0f43376ba 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -146,6 +146,9 @@ class NodeDB /// read our db from flash void loadFromDisk(); + /// purge db entries without user info + void cleanupMeshDB(); + /// Reinit device state from scratch (not loading from disk) void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig(); }; From 6d211815d93041174149e2f0c9e7772c409a8878 Mon Sep 17 00:00:00 2001 From: Ric In New Mexico <78682404+RicInNewMexico@users.noreply.github.com> Date: Mon, 18 Sep 2023 06:26:19 -0600 Subject: [PATCH 76/97] Temp fix for S3 bluetooth (#2809) Need to roll back espressif to v6.3.2 --- arch/esp32/esp32.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index ccad60858..aa31db13e 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -1,7 +1,7 @@ ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] extends = arduino_base -platform = platformio/espressif32@^6.4.0 +platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch. build_src_filter = ${arduino_base.build_src_filter} - - - - @@ -57,4 +57,4 @@ lib_ignore = ; customize the partition table ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables -board_build.partitions = partition-table.csv \ No newline at end of file +board_build.partitions = partition-table.csv From f737ee59ec2f706d492fc251fc4e0cc92106d971 Mon Sep 17 00:00:00 2001 From: code8buster <20384924+code8buster@users.noreply.github.com> Date: Mon, 18 Sep 2023 17:58:09 +0000 Subject: [PATCH 77/97] Deny maxhops to anyone who sets >7 (#2808) * Deny maxhops to anyone who sets >7 * Use reliable hop count instead of 3 --- src/mesh/RadioInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 61b6b85d0..0d2238396 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -534,8 +534,8 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) h->id = p->id; h->channel = p->channel; if (p->hop_limit > HOP_MAX) { - LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_MAX); - p->hop_limit = HOP_MAX; + LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_RELIABLE); + p->hop_limit = HOP_RELIABLE; } h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0); From e8970ad66b3bfbed1a4257c9f9671e382bd86c42 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:26:09 -0500 Subject: [PATCH 78/97] [create-pull-request] automated change (#2810) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/protobufs b/protobufs index e9feb6424..ce55381ec 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit e9feb6424aaa00915db33a25f4153ebc8c14735b +Subproject commit ce55381ecfd6017f52229db0c8085e6f88d6af44 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 1114ea99b..6dbcc7353 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -399,7 +399,8 @@ typedef struct _meshtastic_Config_LoRaConfig { /* The region code for the radio (US, CN, EU433, etc...) */ meshtastic_Config_LoRaConfig_RegionCode region; /* Maximum number of hops. This can't be greater than 7. - Default of 3 */ + Default of 3 + Attempting to set a value > 7 results in the default */ uint32_t hop_limit; /* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests. Defaults to false */ From 4e9bf753409617c9c23bc61565b802d1d1c5be18 Mon Sep 17 00:00:00 2001 From: thebentern Date: Mon, 18 Sep 2023 19:49:42 +0000 Subject: [PATCH 79/97] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 4754257e1..51e5a5acf 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 7 +build = 8 From 0a12d67d19a3af5222c2c4b221d98230a650609c Mon Sep 17 00:00:00 2001 From: caveman99 Date: Tue, 19 Sep 2023 10:45:28 +0000 Subject: [PATCH 80/97] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 24 ++++++++++++------- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/protobufs b/protobufs index ce55381ec..524819fac 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit ce55381ecfd6017f52229db0c8085e6f88d6af44 +Subproject commit 524819facebc70ad381f765fedc36003f6994783 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 6dbcc7353..24662b7af 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -237,6 +237,8 @@ typedef struct _meshtastic_Config_DeviceConfig { /* If true, device is considered to be "managed" by a mesh administrator Clients should then limit available configuration and administrative options inside the user interface */ bool is_managed; + /* Enables the triple-press of user button to enable or disable GPS */ + bool enable_triple_click; } meshtastic_Config_DeviceConfig; /* Position Config */ @@ -272,6 +274,8 @@ typedef struct _meshtastic_Config_PositionConfig { uint32_t broadcast_smart_minimum_distance; /* The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */ uint32_t broadcast_smart_minimum_interval_secs; + /* (Re)define PIN_GPS_EN for your board. */ + uint32_t gps_en_gpio; } meshtastic_Config_PositionConfig; /* Power Config\ @@ -531,8 +535,8 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} -#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0} -#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0} +#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0} @@ -540,8 +544,8 @@ extern "C" { #define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} #define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} -#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0} -#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0} +#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0} @@ -559,6 +563,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7 #define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8 #define meshtastic_Config_DeviceConfig_is_managed_tag 9 +#define meshtastic_Config_DeviceConfig_enable_triple_click_tag 10 #define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1 #define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define meshtastic_Config_PositionConfig_fixed_position_tag 3 @@ -570,6 +575,7 @@ extern "C" { #define meshtastic_Config_PositionConfig_tx_gpio_tag 9 #define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10 #define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11 +#define meshtastic_Config_PositionConfig_gps_en_gpio_tag 12 #define meshtastic_Config_PowerConfig_is_power_saving_tag 1 #define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2 #define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3 @@ -654,7 +660,8 @@ X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \ X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \ X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \ X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \ -X(a, STATIC, SINGULAR, BOOL, is_managed, 9) +X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ +X(a, STATIC, SINGULAR, BOOL, enable_triple_click, 10) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL @@ -669,7 +676,8 @@ X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \ X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \ X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \ X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \ -X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) +X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \ +X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) #define meshtastic_Config_PositionConfig_CALLBACK NULL #define meshtastic_Config_PositionConfig_DEFAULT NULL @@ -769,12 +777,12 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; /* Maximum encoded size of messages (where known) */ #define meshtastic_Config_BluetoothConfig_size 10 -#define meshtastic_Config_DeviceConfig_size 30 +#define meshtastic_Config_DeviceConfig_size 32 #define meshtastic_Config_DisplayConfig_size 28 #define meshtastic_Config_LoRaConfig_size 77 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 #define meshtastic_Config_NetworkConfig_size 195 -#define meshtastic_Config_PositionConfig_size 54 +#define meshtastic_Config_PositionConfig_size 60 #define meshtastic_Config_PowerConfig_size 40 #define meshtastic_Config_size 198 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 143bd4482..c554074a2 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg; #define meshtastic_DeviceState_size 16854 #define meshtastic_NodeInfoLite_size 151 #define meshtastic_NodeRemoteHardwarePin_size 29 -#define meshtastic_OEMStore_size 3210 +#define meshtastic_OEMStore_size 3218 #define meshtastic_PositionLite_size 28 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 471074948..f672d865c 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -174,7 +174,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; #define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg /* Maximum encoded size of messages (where known) */ -#define meshtastic_LocalConfig_size 455 +#define meshtastic_LocalConfig_size 463 #define meshtastic_LocalModuleConfig_size 609 #ifdef __cplusplus From 17207681ef6e62c459ccf0cc79ef753b13e90316 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 19 Sep 2023 10:55:14 -0500 Subject: [PATCH 81/97] Remove GPS pins from devices lacking built-in GPS (#2812) --- variants/tlora_t3s3_v1/variant.h | 5 ----- variants/tlora_v1/variant.h | 5 +---- variants/tlora_v1_3/variant.h | 5 ----- variants/tlora_v2/variant.h | 5 ----- variants/tlora_v2_1_16/variant.h | 7 ------- variants/tlora_v2_1_18/variant.h | 3 --- 6 files changed, 1 insertion(+), 29 deletions(-) diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h index 7f914c055..3d500633f 100644 --- a/variants/tlora_t3s3_v1/variant.h +++ b/variants/tlora_t3s3_v1/variant.h @@ -1,8 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN - -#define PIN_GPS_EN 42 // GPS power enable pin - #define HAS_SDCARD #define SDCARD_USE_SPI1 diff --git a/variants/tlora_v1/variant.h b/variants/tlora_v1/variant.h index b4365a443..08fefa809 100644 --- a/variants/tlora_v1/variant.h +++ b/variants/tlora_v1/variant.h @@ -1,6 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN - #define I2C_SDA 4 // I2C pins for this board #define I2C_SCL 15 @@ -16,4 +13,4 @@ #define LORA_DIO0 26 // a No connect on the SX1262 module #define LORA_RESET 14 #define LORA_DIO1 33 // Must be manually wired: https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436 -#define LORA_DIO2 32 // Not really used +#define LORA_DIO2 32 // Not really used \ No newline at end of file diff --git a/variants/tlora_v1_3/variant.h b/variants/tlora_v1_3/variant.h index 50041f296..73cb31f27 100644 --- a/variants/tlora_v1_3/variant.h +++ b/variants/tlora_v1_3/variant.h @@ -1,8 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN -#define GPS_RX_PIN 36 -#define GPS_TX_PIN 13 // per @eugene - #define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO35_CHANNEL diff --git a/variants/tlora_v2/variant.h b/variants/tlora_v2/variant.h index b9b521771..8a7cf89ec 100644 --- a/variants/tlora_v2/variant.h +++ b/variants/tlora_v2/variant.h @@ -1,8 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN -#define GPS_RX_PIN 36 -#define GPS_TX_PIN 13 // per @eugene - #define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO35_CHANNEL diff --git a/variants/tlora_v2_1_16/variant.h b/variants/tlora_v2_1_16/variant.h index 30a176e4c..b8c43e557 100644 --- a/variants/tlora_v2_1_16/variant.h +++ b/variants/tlora_v2_1_16/variant.h @@ -1,10 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN -#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick -#define GPS_TX_PIN 13 - -#define PIN_GPS_EN 19 // GPS power enable pin - #define BATTERY_PIN 35 #define ADC_CHANNEL ADC1_GPIO35_CHANNEL #define BATTERY_SENSE_SAMPLES 30 diff --git a/variants/tlora_v2_1_18/variant.h b/variants/tlora_v2_1_18/variant.h index e8f0a9659..efc676992 100644 --- a/variants/tlora_v2_1_18/variant.h +++ b/variants/tlora_v2_1_18/variant.h @@ -1,6 +1,3 @@ -#undef GPS_RX_PIN -#undef GPS_TX_PIN - #define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage // ratio of voltage divider = 2.0 (R42=100k, R43=100k) #define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage. From 7eff5e7bcb2084499b723c5e3846c15ee089e36d Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 20 Sep 2023 19:34:45 -0500 Subject: [PATCH 82/97] Fix for Pi Pico hang (#2817) * Fix for Pi Pico hang * Pi Pico fix part 2: Electric Boogaloo --- src/gps/GPS.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 43869a72e..519da24e6 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -252,7 +252,7 @@ bool GPS::setup() { int msglen = 0; - if (_serial_gps && !didSerialInit) { + if (!didSerialInit) { #if !defined(GPS_UC6580) if (tx_gpio) { LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]); @@ -548,6 +548,8 @@ void GPS::publishUpdate() int32_t GPS::runOnce() { if (!GPSInitFinished) { + if (!_serial_gps) + return disable(); if (!setup()) return 2000; // Setup failed, re-run in two seconds @@ -850,7 +852,7 @@ GPS *GPS::createGps() if (!_tx_gpio) _tx_gpio = GPS_TX_PIN; #endif - if (!_rx_gpio) // Configured to have no GPS at all + if (!_rx_gpio || !_serial_gps) // Configured to have no GPS at all return nullptr; GPS *new_gps = new GPS; From 1a2c7f00e16d75ed51dd0a4ca54abc25a3137c92 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 23 Sep 2023 23:45:35 -0500 Subject: [PATCH 83/97] Gps cleanup and powersave (#2807) * Refactor GPS to not probe if pins not defined * Use Named Constructor to clean up code * Move doGPSPowerSave to GPS class * Make sure to set GPS awake on triple-click * Cleanup and remove dead code * Rename GPS_PIN_WAKE to GPS_PIN_STANDBY * Actually put GPS to sleep between fixes * add GPS_POWER_TOGGLE for heltec-tracker and t-deck * Change GPS_THREAD_INTERVAL to 200 ms * More dead code, compiler warnings, and add returns * Add Number of sats to log output * Add pgs enable and triple-click config * Track average GPS fix time to judge low-power time * Feed PositionModule on GPS fix * Don't turn off the 3v3_s line on RAK4631 when the rotary is present. * Add GPS power standbyOnly option * Delay setting time currentQuality to avoid strange log message. * Typos, comments, and remove unused variable * Short-circuit the setAwake logic on GPS disable * heltec-tracker 0.3 GPS power saving * set en_gpio to defined state * Fix fixed_position logic with GPS disabled * Don't process GPS serial when not isAwake * Add quirk for Heltec Tracker GPS powersave --------- Co-authored-by: Ben Meadors Co-authored-by: mverch67 Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com> --- protobufs | 2 +- src/ButtonThread.h | 18 +- src/PowerFSM.cpp | 4 - src/concurrency/OSThread.h | 4 +- src/configuration.h | 2 +- src/gps/GPS.cpp | 271 +++++++++--------- src/gps/GPS.h | 53 ++-- src/gps/RTC.cpp | 7 +- src/input/RotaryEncoderInterruptImpl1.cpp | 7 +- src/input/RotaryEncoderInterruptImpl1.h | 2 +- src/input/UpDownInterruptImpl1.cpp | 7 +- src/input/UpDownInterruptImpl1.h | 4 +- src/main.cpp | 5 - src/mesh/NodeDB.cpp | 8 + src/mesh/generated/meshtastic/config.pb.h | 10 +- src/modules/Modules.cpp | 10 +- src/modules/PositionModule.cpp | 37 +++ src/modules/PositionModule.h | 2 + src/sleep.cpp | 29 +- src/sleep.h | 2 - .../heltec_wireless_tracker/platformio.ini | 1 + variants/heltec_wireless_tracker/variant.h | 2 + variants/lora_relay_v2/variant.h | 4 +- variants/nano-g2-ultra/variant.h | 16 +- variants/t-deck/platformio.ini | 1 + variants/t-echo/variant.h | 8 +- 26 files changed, 262 insertions(+), 254 deletions(-) diff --git a/protobufs b/protobufs index 524819fac..60f1f1574 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 524819facebc70ad381f765fedc36003f6994783 +Subproject commit 60f1f15743f5232cdcae6c160e8fa52951f62880 diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 944a7adf0..a8a89e82e 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -164,17 +164,17 @@ class ButtonThread : public concurrency::OSThread static void userButtonMultiPressed() { -#if defined(GPS_POWER_TOGGLE) - if (gps != nullptr) { - if (config.position.gps_enabled) { - LOG_DEBUG("Flag set to false for gps power\n"); - } else { - LOG_DEBUG("Flag set to true to restore power\n"); - } + if (!config.device.disable_triple_click && (gps != nullptr)) { config.position.gps_enabled = !(config.position.gps_enabled); - gps->doGPSpowersave(config.position.gps_enabled); + if (config.position.gps_enabled) { + LOG_DEBUG("Flag set to true to restore power\n"); + gps->enable(); + + } else { + LOG_DEBUG("Flag set to false for gps power\n"); + gps->disable(); + } } -#endif } static void userButtonPressedLongStart() diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index da8759c3c..d9cd88126 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -8,7 +8,6 @@ * actions to be taken upon entering or exiting each state. */ #include "PowerFSM.h" -#include "GPS.h" #include "MeshService.h" #include "NodeDB.h" #include "configuration.h" @@ -137,9 +136,6 @@ static void lsIdle() static void lsExit() { LOG_INFO("Exit state: LS\n"); - // setGPSPower(true); // restore GPS power - if (gps) - gps->forceWake(true); } static void nbEnter() diff --git a/src/concurrency/OSThread.h b/src/concurrency/OSThread.h index aa8e3e2d8..7957ee952 100644 --- a/src/concurrency/OSThread.h +++ b/src/concurrency/OSThread.h @@ -53,7 +53,7 @@ class OSThread : public Thread static void setup(); - int32_t disable(); + virtual int32_t disable(); /** * Wait a specified number msecs starting from the current time (rather than the last time we were run) @@ -87,4 +87,4 @@ extern bool hasBeenSetup; void assertIsSetup(); -} // namespace concurrency +} // namespace concurrency \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index e116854c2..2640b1572 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -145,7 +145,7 @@ along with this program. If not, see . #define GPS_BAUDRATE 9600 #ifndef GPS_THREAD_INTERVAL -#define GPS_THREAD_INTERVAL 100 +#define GPS_THREAD_INTERVAL 200 #endif // convert 24-bit color to 16-bit (56K) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 519da24e6..13afaa3e6 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -2,6 +2,7 @@ #include "NodeDB.h" #include "RTC.h" #include "configuration.h" +#include "main.h" // pmu_found #include "sleep.h" #include "ubx.h" @@ -420,43 +421,77 @@ bool GPS::setup() didSerialInit = true; } - notifySleepObserver.observe(¬ifySleep); notifyDeepSleepObserver.observe(¬ifyDeepSleep); notifyGPSSleepObserver.observe(¬ifyGPSSleep); - - if (config.position.gps_enabled == false && config.position.fixed_position == false) { - setAwake(false); - } return true; } GPS::~GPS() { // we really should unregister our sleep observer - notifySleepObserver.unobserve(¬ifySleep); notifyDeepSleepObserver.unobserve(¬ifyDeepSleep); notifyGPSSleepObserver.observe(¬ifyGPSSleep); } -// Allow defining the polarity of the WAKE output. default is active high -#ifndef GPS_WAKE_ACTIVE -#define GPS_WAKE_ACTIVE 1 -#endif - -void GPS::wake() +void GPS::setGPSPower(bool on, bool standbyOnly) { -#ifdef PIN_GPS_WAKE - digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE); - pinMode(PIN_GPS_WAKE, OUTPUT); + LOG_INFO("Setting GPS power=%d\n", on); + if (on) { + clearBuffer(); // drop any old data waiting in the buffer before re-enabling + if (en_gpio) + digitalWrite(en_gpio, on ? GPS_EN_ACTIVE : !GPS_EN_ACTIVE); // turn this on if defined, every time + } + isInPowersave = !on; + if (!standbyOnly && en_gpio != 0 && + !(HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))) { + LOG_DEBUG("GPS powerdown using GPS_EN_ACTIVE\n"); + digitalWrite(en_gpio, on ? GPS_EN_ACTIVE : !GPS_EN_ACTIVE); + return; + } +#ifdef HAS_PMU // We only have PMUs on the T-Beam, and that board has a tiny battery to save GPS ephemera, so treat as a standby. + if (pmu_found && PMU) { + uint8_t model = PMU->getChipModel(); + if (model == XPOWERS_AXP2101) { + if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) { + // t-beam v1.2 GNSS power channel + on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3); + } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) { + // t-beam-s3-core GNSS power channel + on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4); + } + } else if (model == XPOWERS_AXP192) { + // t-beam v1.1 GNSS power channel + on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3); + } + return; + } #endif -} - -void GPS::sleep() -{ -#ifdef PIN_GPS_WAKE - digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE ? 0 : 1); - pinMode(PIN_GPS_WAKE, OUTPUT); +#ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones + if (on) { + LOG_INFO("Waking GPS"); + digitalWrite(PIN_GPS_STANDBY, 1); + pinMode(PIN_GPS_STANDBY, OUTPUT); + return; + } else { + LOG_INFO("GPS entering sleep"); + // notifyGPSSleep.notifyObservers(NULL); + digitalWrite(PIN_GPS_STANDBY, 0); + pinMode(PIN_GPS_STANDBY, OUTPUT); + return; + } #endif + if (!on) { + if (gnssModel == GNSS_MODEL_UBLOX) { + uint8_t msglen; + msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ); + gps->_serial_gps->write(gps->UBXscratch, msglen); + } + } else { + if (gnssModel == GNSS_MODEL_UBLOX) { + gps->_serial_gps->write(0xFF); + clearBuffer(); // This often returns old data, so drop it + } + } } /// Record that we have a GPS @@ -468,14 +503,6 @@ void GPS::setConnected() } } -void GPS::setNumSatellites(uint8_t n) -{ - if (n != numSatellites) { - numSatellites = n; - shouldPublish = true; - } -} - /** * Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode * @@ -483,23 +510,38 @@ void GPS::setNumSatellites(uint8_t n) */ void GPS::setAwake(bool on) { - if (!wakeAllowed && on) { - LOG_WARN("Inhibiting because !wakeAllowed\n"); - on = false; - } - if (isAwake != on) { LOG_DEBUG("WANT GPS=%d\n", on); - if (on) { - clearBuffer(); // drop any old data waiting in the buffer - lastWakeStartMsec = millis(); - wake(); - } else { - lastSleepStartMsec = millis(); - sleep(); + isAwake = on; + if (!enabled) { // short circuit if the user has disabled GPS + setGPSPower(false, false); + return; } - isAwake = on; + if (on) { + lastWakeStartMsec = millis(); + } else { + lastSleepStartMsec = millis(); + if (GPSCycles == 1) { // Skipping initial lock time, as it will likely be much longer than average + averageLockTime = lastSleepStartMsec - lastWakeStartMsec; + } else if (GPSCycles > 1) { + averageLockTime += ((int32_t)(lastSleepStartMsec - lastWakeStartMsec) - averageLockTime) / (int32_t)GPSCycles; + } + GPSCycles++; + LOG_DEBUG("GPS Lock took %d, average %d\n", (lastSleepStartMsec - lastWakeStartMsec) / 1000, averageLockTime / 1000); + } + if ((int32_t)getSleepTime() - averageLockTime > + 15 * 60 * 1000) { // 15 minutes is probably long enough to make a complete poweroff worth it. + setGPSPower(on, false); + } else if ((int32_t)getSleepTime() - averageLockTime > 10000) { // 10 seconds is enough for standby +#ifdef GPS_UC6580 + setGPSPower(on, false); +#else + setGPSPower(on, true); +#endif + } else if (averageLockTime > 20000) { + averageLockTime -= 1000; // eventually want to sleep again. + } } } @@ -519,10 +561,9 @@ uint32_t GPS::getWakeTime() const uint32_t GPS::getSleepTime() const { uint32_t t = config.position.gps_update_interval; - bool gps_enabled = config.position.gps_enabled; // We'll not need the GPS thread to wake up again after first acq. with fixed position. - if (!gps_enabled || config.position.fixed_position) + if (!config.position.gps_enabled || config.position.fixed_position) t = UINT32_MAX; // Sleep forever now if (t == UINT32_MAX) @@ -537,11 +578,14 @@ void GPS::publishUpdate() shouldPublish = false; // In debug logs, identify position by @timestamp:stage (stage 2 = publish) - LOG_DEBUG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock()); + LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, p.sats_in_view, + hasLock()); // Notify any status instances that are observing us const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p); newStatus.notifyObservers(&status); + if (config.position.gps_enabled) + positionModule->handleNewPosition(); } } @@ -554,7 +598,9 @@ int32_t GPS::runOnce() return 2000; // Setup failed, re-run in two seconds // We have now loaded our saved preferences from flash - + if (config.position.gps_enabled == false && config.position.fixed_position == false) { + return disable(); + } // ONCE we will factory reset the GPS for bug #327 if (!devicestate.did_gps_reset) { LOG_WARN("GPS FactoryReset requested\n"); @@ -564,17 +610,12 @@ int32_t GPS::runOnce() } } GPSInitFinished = true; - if (config.position.gps_enabled == false) { - doGPSpowersave(false); - return 0; - } } - if (config.position.gps_enabled == false) - return 0; // Repeaters have no need for GPS - if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) - disable(); + if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) { + return disable(); + } if (whileIdle()) { // if we have received valid NMEA claim we are connected @@ -582,20 +623,22 @@ int32_t GPS::runOnce() } else { if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) { // reset the GPS on next bootup - if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) { + if (devicestate.did_gps_reset && (millis() - lastWakeStartMsec > 60000) && !hasFlow()) { LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n"); devicestate.did_gps_reset = false; nodeDB.saveDeviceStateToDisk(); - disable(); // Stop the GPS thread as it can do nothing useful until next reboot. + return disable(); // Stop the GPS thread as it can do nothing useful until next reboot. } } } // If we are overdue for an update, turn on the GPS and at least publish the current status uint32_t now = millis(); + uint32_t timeAsleep = now - lastSleepStartMsec; auto sleepTime = getSleepTime(); - if (!isAwake && sleepTime != UINT32_MAX && (now - lastSleepStartMsec) > sleepTime) { + if (!isAwake && (sleepTime != UINT32_MAX) && + ((timeAsleep > sleepTime) || (isInPowersave && timeAsleep > (sleepTime - averageLockTime)))) { // We now want to be awake - so wake up the GPS setAwake(true); } @@ -603,11 +646,6 @@ int32_t GPS::runOnce() // While we are awake if (isAwake) { // LOG_DEBUG("looking for location\n"); - if ((now - lastWhileActiveMsec) > 5000) { - lastWhileActiveMsec = now; - whileActive(); - } - // If we've already set time from the GPS, no need to ask the GPS bool gotTime = (getRTCQuality() >= RTCQualityGPS); if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time @@ -622,7 +660,6 @@ int32_t GPS::runOnce() shouldPublish = true; } - // We've been awake too long - force sleep now = millis(); auto wakeTime = getWakeTime(); bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime; @@ -647,26 +684,15 @@ int32_t GPS::runOnce() // If state has changed do a publish publishUpdate(); + + if (config.position.gps_enabled == false) // This should trigger if GPS is disabled but fixed_position is true + return disable(); + // 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms // if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake. return isAwake ? GPS_THREAD_INTERVAL : 5000; } -void GPS::forceWake(bool on) -{ - if (on) { - LOG_DEBUG("Allowing GPS lock\n"); - // lastSleepStartMsec = 0; // Force an update ASAP - wakeAllowed = true; - } else { - wakeAllowed = false; - - // Note: if the gps was already awake, we DO NOT shut it down, because we want to allow it to complete its lock - // attempt even if we are in light sleep. Once the attempt succeeds (or times out) we'll then shut it down. - // setAwake(false); - } -} - // clear the GPS rx buffer as quickly as possible void GPS::clearBuffer() { @@ -675,22 +701,11 @@ void GPS::clearBuffer() _serial_gps->read(); } -/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs -int GPS::prepareSleep(void *unused) -{ - LOG_INFO("GPS prepare sleep!\n"); - forceWake(false); - - return 0; -} - /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs int GPS::prepareDeepSleep(void *unused) { LOG_INFO("GPS deep sleep!\n"); - // For deep sleep we also want abandon any lock attempts (because we want minimum power) - getSleepTime(); setAwake(false); return 0; @@ -835,11 +850,11 @@ GnssModel_t GPS::probe(int serialSpeed) return GNSS_MODEL_UBLOX; } -// GPS::GPS(uint32_t _rx_gpio, uint32_t _tx_gpio) : concurrency::OSThread("GPS") GPS *GPS::createGps() { int8_t _rx_gpio = config.position.rx_gpio; int8_t _tx_gpio = config.position.tx_gpio; + int8_t _en_gpio = config.position.gps_en_gpio; #if defined(HAS_GPS) && !defined(ARCH_ESP32) _rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags. _tx_gpio = 1; @@ -851,6 +866,10 @@ GPS *GPS::createGps() #if defined(GPS_TX_PIN) if (!_tx_gpio) _tx_gpio = GPS_TX_PIN; +#endif +#if defined(PIN_GPS_EN) + if (!_en_gpio) + _en_gpio = PIN_GPS_EN; #endif if (!_rx_gpio || !_serial_gps) // Configured to have no GPS at all return nullptr; @@ -858,6 +877,13 @@ GPS *GPS::createGps() GPS *new_gps = new GPS; new_gps->rx_gpio = _rx_gpio; new_gps->tx_gpio = _tx_gpio; + new_gps->en_gpio = _en_gpio; + + if (_en_gpio != 0) { + LOG_DEBUG("Setting %d to output.\n", _en_gpio); + digitalWrite(_en_gpio, !GPS_EN_ACTIVE); + pinMode(_en_gpio, OUTPUT); + } #ifdef PIN_GPS_PPS // pulse per second @@ -873,14 +899,9 @@ GPS *GPS::createGps() LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n"); #endif -#if defined(HAS_PMU) || defined(PIN_GPS_EN) if (config.position.gps_enabled) { -#ifdef PIN_GPS_EN - pinMode(PIN_GPS_EN, OUTPUT); -#endif - setGPSPower(true); + new_gps->setGPSPower(true, false); } -#endif #ifdef PIN_GPS_RESET digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms @@ -1137,6 +1158,10 @@ bool GPS::hasFlow() bool GPS::whileIdle() { bool isValid = false; + if (!isAwake) { + clearBuffer(); + return isAwake; + } #ifdef SERIAL_BUFFER_SIZE if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) { LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available()); @@ -1154,44 +1179,18 @@ bool GPS::whileIdle() return isValid; } - -void GPS::doGPSpowersave(bool on) +void GPS::enable() { -#if defined(HAS_PMU) || defined(PIN_GPS_EN) - if (on) { - LOG_INFO("Turning GPS back on\n"); - gps->forceWake(1); - setGPSPower(1); - setAwake(1); - } else { - LOG_INFO("Turning off GPS chip\n"); - notifyGPSSleep.notifyObservers(NULL); - setGPSPower(0); - } -#endif -#ifdef PIN_GPS_WAKE - if (on) { - LOG_INFO("Waking GPS"); - gps->forceWake(1); - setAwake(1); - } else { - LOG_INFO("GPS entering sleep"); - notifyGPSSleep.notifyObservers(NULL); - } -#endif -#if !(defined(HAS_PMU) || defined(PIN_GPS_EN) || defined(PIN_GPS_WAKE)) - if (!on) { - notifyGPSSleep.notifyObservers(NULL); - if (gnssModel == GNSS_MODEL_UBLOX) { - uint8_t msglen; - msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ); - gps->_serial_gps->write(gps->UBXscratch, msglen); - } - setAwake(1); - } else { - gps->forceWake(1); - if (gnssModel == GNSS_MODEL_UBLOX) - gps->_serial_gps->write(0xFF); - } -#endif + enabled = true; + setInterval(GPS_THREAD_INTERVAL); + setAwake(true); +} + +int32_t GPS::disable() +{ + enabled = false; + setInterval(INT32_MAX); + setAwake(false); + + return INT32_MAX; } \ No newline at end of file diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 6ee62a283..4269acf2d 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -4,6 +4,14 @@ #include "Observer.h" #include "TinyGPS++.h" #include "concurrency/OSThread.h" +#include "input/RotaryEncoderInterruptImpl1.h" +#include "input/UpDownInterruptImpl1.h" +#include "modules/PositionModule.h" + +// Allow defining the polarity of the ENABLE output. default is active high +#ifndef GPS_EN_ACTIVE +#define GPS_EN_ACTIVE 1 +#endif struct uBloxGnssModelInfo { char swVersion[30]; @@ -48,11 +56,14 @@ class GPS : private concurrency::OSThread uint8_t fixType = 0; // fix type from GPGSA #endif private: - uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0; + uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0; const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600}; uint32_t rx_gpio = 0; uint32_t tx_gpio = 0; + uint32_t en_gpio = 0; + int32_t averageLockTime = 0; + uint32_t GPSCycles = 0; int speedSelect = 0; int probeTries = 2; @@ -65,7 +76,7 @@ class GPS : private concurrency::OSThread bool isAwake = false; // true if we want a location right now - bool wakeAllowed = true; // false if gps must be forced to sleep regardless of what time it is + bool isInPowersave = false; bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop() @@ -76,7 +87,6 @@ class GPS : private concurrency::OSThread uint8_t numSatellites = 0; - CallbackObserver notifySleepObserver = CallbackObserver(this, &GPS::prepareSleep); CallbackObserver notifyDeepSleepObserver = CallbackObserver(this, &GPS::prepareDeepSleep); CallbackObserver notifyGPSSleepObserver = CallbackObserver(this, &GPS::prepareDeepSleep); @@ -116,6 +126,14 @@ class GPS : private concurrency::OSThread */ virtual bool setup(); + // re-enable the thread + void enable(); + + // Disable the thread + int32_t disable() override; + + void setGPSPower(bool on, bool standbyOnly); + /// Returns true if we have acquired GPS lock. virtual bool hasLock(); @@ -127,14 +145,6 @@ class GPS : private concurrency::OSThread bool isPowerSaving() const { return !config.position.gps_enabled; } - /** - * Restart our lock attempt - try to get and broadcast a GPS reading ASAP - * called after the CPU wakes from light-sleep state - * - * Or set to false, to disallow any sort of waking - * */ - void forceWake(bool on); - // Empty the input buffer as quickly as possible void clearBuffer(); @@ -154,7 +164,6 @@ class GPS : private concurrency::OSThread * calls sleep/wake */ void setAwake(bool on); - void doGPSpowersave(bool on); virtual bool factoryReset(); // Creates an instance of the GPS class. @@ -162,20 +171,6 @@ class GPS : private concurrency::OSThread static GPS *createGps(); protected: - /// If possible force the GPS into sleep/low power mode - virtual void sleep(); - - /// wake the GPS into normal operation mode - virtual void wake(); - - /** Subclasses should look for serial rx characters here and feed it to their GPS parser - * - * Return true if we received a valid message from the GPS - */ - - /** Idle processing while GPS is looking for lock, called once per secondish */ - virtual void whileActive() {} - /** * Perform any processing that should be done only while the GPS is awake and looking for a fix. * Override this method to check for new locations @@ -193,8 +188,6 @@ class GPS : private concurrency::OSThread /// Record that we have a GPS void setConnected(); - void setNumSatellites(uint8_t n); - /** Subclasses should look for serial rx characters here and feed it to their GPS parser * * Return true if we received a valid message from the GPS @@ -218,10 +211,6 @@ class GPS : private concurrency::OSThread virtual bool lookForLocation(); 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 - int prepareSleep(void *unused); - /// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs /// always returns 0 to indicate okay to sleep int prepareDeepSleep(void *unused); diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 2bfb66e12..ef438a7dd 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -103,9 +103,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) bool shouldSet; if (q > currentQuality) { - currentQuality = q; shouldSet = true; - LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q); + LOG_DEBUG("Upgrading time to quality %d\n", q); } else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { // Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift shouldSet = true; @@ -114,12 +113,12 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) shouldSet = false; if (shouldSet) { + currentQuality = q; lastSetMsec = now; // This delta value works on all platforms timeStartMsec = now; zeroOffsetSecs = tv->tv_sec; - // If this platform has a setable RTC, set it #ifdef RV3028_RTC if (rtc_found.address == RV3028_RTC) { @@ -209,4 +208,4 @@ uint32_t getTime() uint32_t getValidTime(RTCQuality minQuality) { return (currentQuality >= minQuality) ? getTime() : 0; -} +} \ No newline at end of file diff --git a/src/input/RotaryEncoderInterruptImpl1.cpp b/src/input/RotaryEncoderInterruptImpl1.cpp index 7bf66ac55..7e79289e5 100644 --- a/src/input/RotaryEncoderInterruptImpl1.cpp +++ b/src/input/RotaryEncoderInterruptImpl1.cpp @@ -5,12 +5,12 @@ RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1; RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {} -void RotaryEncoderInterruptImpl1::init() +bool RotaryEncoderInterruptImpl1::init() { if (!moduleConfig.canned_message.rotary1_enabled) { // Input device is disabled. disable(); - return; + return false; } uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a; @@ -25,6 +25,7 @@ void RotaryEncoderInterruptImpl1::init() RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB, RotaryEncoderInterruptImpl1::handleIntPressed); inputBroker->registerSource(this); + return true; } void RotaryEncoderInterruptImpl1::handleIntA() @@ -38,4 +39,4 @@ void RotaryEncoderInterruptImpl1::handleIntB() void RotaryEncoderInterruptImpl1::handleIntPressed() { rotaryEncoderInterruptImpl1->intPressHandler(); -} +} \ No newline at end of file diff --git a/src/input/RotaryEncoderInterruptImpl1.h b/src/input/RotaryEncoderInterruptImpl1.h index 1bdb3a5a5..22ecba37a 100644 --- a/src/input/RotaryEncoderInterruptImpl1.h +++ b/src/input/RotaryEncoderInterruptImpl1.h @@ -12,7 +12,7 @@ class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase { public: RotaryEncoderInterruptImpl1(); - void init(); + bool init(); static void handleIntA(); static void handleIntB(); static void handleIntPressed(); diff --git a/src/input/UpDownInterruptImpl1.cpp b/src/input/UpDownInterruptImpl1.cpp index c22152f82..7dd1f76b2 100644 --- a/src/input/UpDownInterruptImpl1.cpp +++ b/src/input/UpDownInterruptImpl1.cpp @@ -5,12 +5,12 @@ UpDownInterruptImpl1 *upDownInterruptImpl1; UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {} -void UpDownInterruptImpl1::init() +bool UpDownInterruptImpl1::init() { if (!moduleConfig.canned_message.updown1_enabled) { // Input device is disabled. - return; + return false; } uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a; @@ -24,6 +24,7 @@ void UpDownInterruptImpl1::init() UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown, UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed); inputBroker->registerSource(this); + return true; } void UpDownInterruptImpl1::handleIntDown() @@ -37,4 +38,4 @@ void UpDownInterruptImpl1::handleIntUp() void UpDownInterruptImpl1::handleIntPressed() { upDownInterruptImpl1->intPressHandler(); -} +} \ No newline at end of file diff --git a/src/input/UpDownInterruptImpl1.h b/src/input/UpDownInterruptImpl1.h index 17420db95..4739cd2ff 100644 --- a/src/input/UpDownInterruptImpl1.h +++ b/src/input/UpDownInterruptImpl1.h @@ -5,10 +5,10 @@ class UpDownInterruptImpl1 : public UpDownInterruptBase { public: UpDownInterruptImpl1(); - void init(); + bool init(); static void handleIntDown(); static void handleIntUp(); static void handleIntPressed(); }; -extern UpDownInterruptImpl1 *upDownInterruptImpl1; +extern UpDownInterruptImpl1 *upDownInterruptImpl1; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8ce365358..a4caad3fd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -221,11 +221,6 @@ void setup() digitalWrite(VEXT_ENABLE, 0); // turn on the display power #endif -#ifdef VGNSS_CTRL - pinMode(VGNSS_CTRL, OUTPUT); - digitalWrite(VGNSS_CTRL, LOW); -#endif - #if defined(VTFT_CTRL) pinMode(VTFT_CTRL, OUTPUT); digitalWrite(VTFT_CTRL, LOW); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index ff58ca407..d7fd84fb7 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -169,6 +169,14 @@ void NodeDB::installDefaultConfig() config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET; config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; config.lora.hop_limit = HOP_RELIABLE; +#ifdef PIN_GPS_EN + config.position.gps_en_gpio = PIN_GPS_EN; +#endif +#ifdef GPS_POWER_TOGGLE + config.device.disable_triple_click = false; +#else + config.device.disable_triple_click = true; +#endif config.position.gps_enabled = true; config.position.position_broadcast_smart_enabled = true; config.position.broadcast_smart_minimum_distance = 100; diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 24662b7af..3c4adf41d 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -237,8 +237,8 @@ typedef struct _meshtastic_Config_DeviceConfig { /* If true, device is considered to be "managed" by a mesh administrator Clients should then limit available configuration and administrative options inside the user interface */ bool is_managed; - /* Enables the triple-press of user button to enable or disable GPS */ - bool enable_triple_click; + /* Disables the triple-press of user button to enable or disable GPS */ + bool disable_triple_click; } meshtastic_Config_DeviceConfig; /* Position Config */ @@ -563,7 +563,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7 #define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8 #define meshtastic_Config_DeviceConfig_is_managed_tag 9 -#define meshtastic_Config_DeviceConfig_enable_triple_click_tag 10 +#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10 #define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1 #define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define meshtastic_Config_PositionConfig_fixed_position_tag 3 @@ -661,7 +661,7 @@ X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \ X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \ X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \ X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ -X(a, STATIC, SINGULAR, BOOL, enable_triple_click, 10) +X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL @@ -790,4 +790,4 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; } /* extern "C" */ #endif -#endif +#endif \ No newline at end of file diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index bcb33c640..ba291d018 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -60,9 +60,15 @@ void setupModules() new ReplyModule(); #if HAS_BUTTON rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); - rotaryEncoderInterruptImpl1->init(); + if (!rotaryEncoderInterruptImpl1->init()) { + delete rotaryEncoderInterruptImpl1; + rotaryEncoderInterruptImpl1 = nullptr; + } upDownInterruptImpl1 = new UpDownInterruptImpl1(); - upDownInterruptImpl1->init(); + if (!upDownInterruptImpl1->init()) { + delete upDownInterruptImpl1; + upDownInterruptImpl1 = nullptr; + } cardKbI2cImpl = new CardKbI2cImpl(); cardKbI2cImpl->init(); #ifdef INPUTBROKER_MATRIX_TYPE diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 40dbf266e..937625cec 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -230,4 +230,41 @@ int32_t PositionModule::runOnce() } return 5000; // to save power only wake for our callback occasionally +} + +void PositionModule::handleNewPosition() +{ + meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum()); + const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position + // We limit our GPS broadcasts to a max rate + uint32_t now = millis(); + uint32_t msSinceLastSend = now - lastGpsSend; + + if (hasValidPosition(node2)) { + // The minimum distance to travel before we are able to send a new position packet. + const uint32_t distanceTravelThreshold = + config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; + + // Determine the distance in meters between two points on the globe + float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( + lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7); + + if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold)) { + bool requestReplies = currentGeneration != radioGeneration; + currentGeneration = radioGeneration; + + LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims)\n", + localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, msSinceLastSend); + sendOurPosition(NODENUM_BROADCAST, requestReplies); + + // Set the current coords as our last ones, after we've compared distance with current and decided to send + lastGpsLatitude = node->position.latitude_i; + lastGpsLongitude = node->position.longitude_i; + + /* Update lastGpsSend to now. This means if the device is stationary, then + getPref_position_broadcast_secs will still apply. + */ + lastGpsSend = now; + } + } } \ No newline at end of file diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h index aaa5c76c5..8f7047432 100644 --- a/src/modules/PositionModule.h +++ b/src/modules/PositionModule.h @@ -31,6 +31,8 @@ class PositionModule : public ProtobufModule, private concu */ void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0); + void handleNewPosition(); + protected: /** Called to handle a particular incoming message diff --git a/src/sleep.cpp b/src/sleep.cpp index ed89b926d..62ce0064f 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -90,33 +90,6 @@ void setLed(bool ledOn) #endif } -void setGPSPower(bool on) -{ - LOG_INFO("Setting GPS power=%d\n", on); - -#ifdef PIN_GPS_EN - digitalWrite(PIN_GPS_EN, on ? 1 : 0); -#endif - -#ifdef HAS_PMU - if (pmu_found && PMU) { - uint8_t model = PMU->getChipModel(); - if (model == XPOWERS_AXP2101) { - if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) { - // t-beam v1.2 GNSS power channel - on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3); - } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) { - // t-beam-s3-core GNSS power channel - on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4); - } - } else if (model == XPOWERS_AXP192) { - // t-beam v1.1 GNSS power channel - on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3); - } - } -#endif -} - // Perform power on init that we do on each wake from deep sleep void initDeepSleep() { @@ -200,7 +173,7 @@ void doDeepSleep(uint32_t msecToWake) nodeDB.saveToDisk(); // Kill GPS power completely (even if previously we just had it in sleep mode) - setGPSPower(false); + gps->setGPSPower(false, false); setLed(false); diff --git a/src/sleep.h b/src/sleep.h index 366aa1621..8ff81035c 100644 --- a/src/sleep.h +++ b/src/sleep.h @@ -18,8 +18,6 @@ extern esp_sleep_source_t wakeCause; extern XPowersLibInterface *PMU; #endif -void setGPSPower(bool on); - // Perform power on init that we do on each wake from deep sleep void initDeepSleep(); diff --git a/variants/heltec_wireless_tracker/platformio.ini b/variants/heltec_wireless_tracker/platformio.ini index 45be3bf98..fa79eeb6a 100644 --- a/variants/heltec_wireless_tracker/platformio.ini +++ b/variants/heltec_wireless_tracker/platformio.ini @@ -5,6 +5,7 @@ upload_protocol = esp-builtin build_flags = ${esp32s3_base.build_flags} -I variants/heltec_wireless_tracker + -DGPS_POWER_TOGGLE lib_deps = ${esp32s3_base.lib_deps} diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index 83f41ecdf..f3915e350 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -38,6 +38,8 @@ #define PIN_GPS_RESET 35 #define PIN_GPS_PPS 36 #define VGNSS_CTRL 37 // Heltec Tracker needs this pulled low for GPS +#define PIN_GPS_EN VGNSS_CTRL +#define GPS_EN_ACTIVE LOW #define GPS_RESET_MODE LOW #define GPS_UC6580 diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h index bc1f0714a..16286210f 100644 --- a/variants/lora_relay_v2/variant.h +++ b/variants/lora_relay_v2/variant.h @@ -164,8 +164,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define ST7735_SDA (39) // actually spi MOSI #define ST7735_SCK (37) // actually spi clk -#define PIN_GPS_WAKE 36 // Just kill GPS power when we want it to sleep? FIXME -#define GPS_WAKE_ACTIVE 0 // GPS Power output is active low +#define PIN_GPS_EN 36 // Just kill GPS power when we want it to sleep? FIXME +#define GPS_EN_ACTIVE 0 // GPS Power output is active low // #define LORA_DISABLE_SENDING // The board can brownout during lora TX if you don't have a battery connected. Disable sending // to allow USB power only based debugging diff --git a/variants/nano-g2-ultra/variant.h b/variants/nano-g2-ultra/variant.h index 4c1720af8..9474b6cce 100644 --- a/variants/nano-g2-ultra/variant.h +++ b/variants/nano-g2-ultra/variant.h @@ -23,7 +23,7 @@ #define VARIANT_MCK (64000000ul) #define USE_LFXO // Board uses 32khz crystal for LF -//#define USE_LFRC // Board uses 32khz RC for LF +// #define USE_LFRC // Board uses 32khz RC for LF /*---------------------------------------------------------------------------- * Headers @@ -54,7 +54,7 @@ extern "C" { #define LED_CONN PIN_GREEN #define LED_STATE_ON 0 // State when LED is lit -//#define LED_INVERTED 1 +// #define LED_INVERTED 1 /* * Buttons @@ -114,7 +114,7 @@ External serial flash W25Q16JV_IQ #define SX126X_CS (32 + 13) // FIXME - we really should define LORA_CS instead #define SX126X_DIO1 (32 + 10) // Note DIO2 is attached internally to the module to an analog switch for TX/RX switching -//#define SX1262_DIO3 (0 + 21) +// #define SX1262_DIO3 (0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main CPU? #define SX126X_BUSY (32 + 11) #define SX126X_RESET (32 + 15) @@ -130,11 +130,11 @@ External serial flash W25Q16JV_IQ #define GPS_L76K -#define PIN_GPS_WAKE (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake -#define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU -#define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS +#define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY +#define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU +#define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS -//#define GPS_THREAD_INTERVAL 50 +// #define GPS_THREAD_INTERVAL 50 #define PIN_SERIAL1_RX PIN_GPS_TX #define PIN_SERIAL1_TX PIN_GPS_RX @@ -152,7 +152,7 @@ External serial flash W25Q16JV_IQ #define PIN_SPI_MOSI (0 + 11) #define PIN_SPI_SCK (0 + 12) -//#define PIN_PWR_EN (0 + 6) +// #define PIN_PWR_EN (0 + 6) // To debug via the segger JLINK console rather than the CDC-ACM serial device // #define USE_SEGGER diff --git a/variants/t-deck/platformio.ini b/variants/t-deck/platformio.ini index abf545f44..38e334a30 100644 --- a/variants/t-deck/platformio.ini +++ b/variants/t-deck/platformio.ini @@ -8,6 +8,7 @@ debug_tool = esp-builtin build_flags = ${esp32_base.build_flags} -DT_DECK -DBOARD_HAS_PSRAM + -DGPS_POWER_TOGGLE -Ivariants/t-deck lib_deps = ${esp32s3_base.lib_deps} diff --git a/variants/t-echo/variant.h b/variants/t-echo/variant.h index bd8dd838f..f955285ae 100644 --- a/variants/t-echo/variant.h +++ b/variants/t-echo/variant.h @@ -85,9 +85,9 @@ static const uint8_t A0 = PIN_A0; /* No longer populated on PCB */ -//#define PIN_SERIAL2_RX (0 + 6) -//#define PIN_SERIAL2_TX (0 + 8) -// #define PIN_SERIAL2_EN (0 + 17) +// #define PIN_SERIAL2_RX (0 + 6) +// #define PIN_SERIAL2_TX (0 + 8) +// #define PIN_SERIAL2_EN (0 + 17) /** Wire Interfaces @@ -171,7 +171,7 @@ External serial flash WP25R1635FZUIL0 #define GPS_L76K #define PIN_GPS_REINIT (32 + 5) // An output to reset L76K GPS. As per datasheet, low for > 100ms will reset the L76K -#define PIN_GPS_WAKE (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake +#define PIN_GPS_STANDBY (32 + 2) // An output to wake GPS, low means allow sleep, high means force wake // Seems to be missing on this new board // #define PIN_GPS_PPS (32 + 4) // Pulse per second input from the GPS #define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU From cdac643749ac3b8d91190bec3d1c4b3b539bf156 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sun, 24 Sep 2023 13:49:21 +0200 Subject: [PATCH 84/97] Fix compression (#2806) (#2819) * Fix compression: encode to bytes after `decoded` is modified * Change payload size to decompressed length --------- Co-authored-by: Ben Meadors --- src/mesh/Router.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 03aa57351..b4c456158 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -359,6 +359,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // LOG_DEBUG("\n\n**\n\nDecompressed length - %d \n", decompressed_len); memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len); + p->decoded.payload.size = decompressed_len; // Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP; @@ -382,9 +383,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) // If the packet is not yet encrypted, do so now if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { - size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); - - // Only allow encryption on the text message app. + // Only allow compression on the text message app. // TODO: Allow modules to opt into compression. if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) { @@ -396,17 +395,12 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) int compressed_len; compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out); - LOG_DEBUG("Original length - %d \n", p->decoded.payload.size); - LOG_DEBUG("Compressed length - %d \n", compressed_len); + LOG_DEBUG("Length - %d, compressed length - %d \n", p->decoded.payload.size, compressed_len); LOG_DEBUG("Original message - %s \n", p->decoded.payload.bytes); // If the compressed length is greater than or equal to the original size, don't use the compressed form if (compressed_len >= p->decoded.payload.size) { - LOG_DEBUG("Not using compressing message.\n"); - // Set the uncompressed payload variant anyway. Shouldn't hurt? - // p->decoded.which_payloadVariant = Data_payload_tag; - // Otherwise we use the compressor } else { LOG_DEBUG("Using compressed message.\n"); @@ -419,6 +413,8 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) } } + size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); + if (numbytes > MAX_RHPACKETLEN) return meshtastic_Routing_Error_TOO_LARGE; From 350090ec0d29626b942983f1f118a6b8422156dd Mon Sep 17 00:00:00 2001 From: Andre K Date: Sun, 24 Sep 2023 08:49:35 -0300 Subject: [PATCH 85/97] remove residual code for `mesh_sds_timeout_secs` (#2821) Co-authored-by: Ben Meadors --- src/PowerFSM.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index d9cd88126..eceb545fe 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -370,10 +370,6 @@ void PowerFSM_setup() getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout"); } - - if (config.power.sds_secs != UINT32_MAX) - powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL, - "mesh timeout"); #endif powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state From db7b77c76e6fdc701b4bd7ed5556d09781e3da58 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 24 Sep 2023 07:01:46 -0500 Subject: [PATCH 86/97] [create-pull-request] automated change (#2823) Co-authored-by: thebentern --- src/mesh/generated/meshtastic/config.pb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 3c4adf41d..4b8bef8a1 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -790,4 +790,4 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; } /* extern "C" */ #endif -#endif \ No newline at end of file +#endif From 61f6fb22c5de371783a86a5a7db7ea446e6202e7 Mon Sep 17 00:00:00 2001 From: Andre K Date: Sun, 24 Sep 2023 09:22:54 -0300 Subject: [PATCH 87/97] move `STATE_SEND_METADATA` to beginning of wantConfig (#2820) Co-authored-by: Ben Meadors --- src/mesh/PhoneAPI.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index c91f2e815..672c6871e 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -155,11 +155,18 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) // app not to send locations on our behalf. fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag; fromRadioScratch.my_info = myNodeInfo; - state = STATE_SEND_NODEINFO; + state = STATE_SEND_METADATA; service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon. break; + case STATE_SEND_METADATA: + LOG_INFO("getFromRadio=STATE_SEND_METADATA\n"); + fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag; + fromRadioScratch.metadata = getDeviceMetadata(); + state = STATE_SEND_NODEINFO; + break; + case STATE_SEND_NODEINFO: { LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n"); @@ -294,15 +301,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) config_state++; // Advance when we have sent all of our ModuleConfig objects if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) { - state = STATE_SEND_METADATA; + state = STATE_SEND_COMPLETE_ID; config_state = 0; } break; - case STATE_SEND_METADATA: - fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag; - fromRadioScratch.metadata = getDeviceMetadata(); - state = STATE_SEND_COMPLETE_ID; - break; + case STATE_SEND_COMPLETE_ID: LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n"); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag; From e96ba7cbcf3e7716f4dbee585838cefbefe4042f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 06:31:22 -0500 Subject: [PATCH 88/97] [create-pull-request] automated change (#2827) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 51e5a5acf..1a080d923 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 8 +build = 9 From 04b2ab82dc2fa2f4bc534e1dab2d7d1a03a8f959 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 26 Sep 2023 05:44:08 -0500 Subject: [PATCH 89/97] Add GPS pin definitions missed in revamp (#2834) --- variants/nano-g1-explorer/variant.h | 7 +++++-- variants/nano-g1/variant.h | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/variants/nano-g1-explorer/variant.h b/variants/nano-g1-explorer/variant.h index fb3fc72d1..1cc3b4103 100644 --- a/variants/nano-g1-explorer/variant.h +++ b/variants/nano-g1-explorer/variant.h @@ -4,8 +4,8 @@ #define I2C_SCL 22 #define BUTTON_PIN 36 // The user button (information button) GPIO on the Nano G1 explorer -//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented -// anywhere. +// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented +// anywhere. #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. // common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if @@ -13,6 +13,9 @@ #define USE_RF95 #define USE_SX1262 +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 + #define LORA_DIO0 26 // a No connect on the SX1262 module #define LORA_RESET 23 #define LORA_DIO1 33 // SX1262 IRQ diff --git a/variants/nano-g1/variant.h b/variants/nano-g1/variant.h index eec6e8a07..53adffa01 100644 --- a/variants/nano-g1/variant.h +++ b/variants/nano-g1/variant.h @@ -4,8 +4,8 @@ #define I2C_SCL 22 #define BUTTON_PIN 36 // The middle button GPIO on the Nano G1 -//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented -// anywhere. +// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented +// anywhere. #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. // common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if @@ -13,6 +13,9 @@ #define USE_RF95 #define USE_SX1262 +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 + #define LORA_DIO0 26 // a No connect on the SX1262 module #define LORA_RESET 23 #define LORA_DIO1 33 // SX1262 IRQ @@ -30,4 +33,4 @@ #endif // different screen -#define USE_SH1106 +#define USE_SH1106 \ No newline at end of file From a1c433748afd8a6b888295f1119cca8e833ce7d0 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:45:34 +0200 Subject: [PATCH 90/97] RP2040: Add SerialModule support (#2830) * Support for SerialModule on RP2040 * Remove one !defined too many * Increase serial RX_BUFFER: more reliable for long packets Even results into an error for ESP32 --------- Co-authored-by: Ben Meadors --- src/modules/Modules.cpp | 5 +++-- src/modules/SerialModule.cpp | 12 +++++++++--- src/modules/SerialModule.h | 5 +++-- variants/rpipico/variant.h | 4 ++++ variants/rpipicow/variant.h | 4 ++++ 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index ba291d018..1780a8528 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -31,7 +31,7 @@ #if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) #include "modules/ExternalNotificationModule.h" #include "modules/RangeTestModule.h" -#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) +#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) #include "modules/SerialModule.h" #endif #endif @@ -92,7 +92,8 @@ void setupModules() new AirQualityTelemetryModule(); } #endif -#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \ + !defined(CONFIG_IDF_TARGET_ESP32C3) new SerialModule(); #endif #ifdef ARCH_ESP32 diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 16cd3a263..42b109050 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -44,9 +44,10 @@ */ -#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \ + !defined(CONFIG_IDF_TARGET_ESP32C3) -#define RX_BUFFER 128 +#define RX_BUFFER 256 #define TIMEOUT 250 #define BAUD 38400 #define ACK 1 @@ -141,7 +142,12 @@ int32_t SerialModule::runOnce() } #elif !defined(TTGO_T_ECHO) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { +#ifdef ARCH_RP2040 + Serial2.setFIFOSize(RX_BUFFER); + Serial2.setPinout(moduleConfig.serial.txd, moduleConfig.serial.rxd); +#else Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd); +#endif Serial2.begin(baud, SERIAL_8N1); Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } else { @@ -182,7 +188,7 @@ int32_t SerialModule::runOnce() } } } -#ifndef TTGO_T_ECHO +#if !defined(TTGO_T_ECHO) else { while (Serial2.available()) { serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); diff --git a/src/modules/SerialModule.h b/src/modules/SerialModule.h index 562ccd42b..18ad8a1ba 100644 --- a/src/modules/SerialModule.h +++ b/src/modules/SerialModule.h @@ -8,7 +8,8 @@ #include #include -#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \ + !defined(CONFIG_IDF_TARGET_ESP32C3) class SerialModule : public StreamAPI, private concurrency::OSThread { @@ -74,4 +75,4 @@ class SerialModuleRadio : public MeshModule extern SerialModuleRadio *serialModuleRadio; -#endif +#endif \ No newline at end of file diff --git a/variants/rpipico/variant.h b/variants/rpipico/variant.h index 9deeeadf8..52e748ee8 100644 --- a/variants/rpipico/variant.h +++ b/variants/rpipico/variant.h @@ -17,6 +17,10 @@ // SDA = 4 // SCL = 5 +// Recommended pins for SerialModule: +// txd = 8 +// rxd = 9 + #define EXT_NOTIFY_OUT 22 #define BUTTON_PIN 17 diff --git a/variants/rpipicow/variant.h b/variants/rpipicow/variant.h index d714e2534..a9111db6b 100644 --- a/variants/rpipicow/variant.h +++ b/variants/rpipicow/variant.h @@ -17,6 +17,10 @@ // SDA = 4 // SCL = 5 +// Recommended pins for SerialModule: +// txd = 8 +// rxd = 9 + #define EXT_NOTIFY_OUT 22 #define BUTTON_PIN 17 From b5e952db243c264be99ad15efca3e47b404ef03f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 26 Sep 2023 06:19:17 -0500 Subject: [PATCH 91/97] No more goober traffic on public mqtt (#2831) * No more goober traffic on public mqtt * Oops --- src/mqtt/MQTT.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 7ff85d148..791a4194b 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -455,6 +455,13 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, ChannelIndex chIndex) { auto &ch = channels.getByIndex(chIndex); + if (&mp.decoded && strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 && + (mp.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || + mp.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) { + LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n"); + return; + } + if (ch.settings.uplink_enabled) { const char *channelId = channels.getGlobalId(chIndex); // FIXME, for now we just use the human name for the channel From 0d023ea215f2ff21668fe1ae78f9473ac5c9c576 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 26 Sep 2023 07:02:06 -0500 Subject: [PATCH 92/97] Revert "Fix compression (#2806) (#2819)" (#2835) This reverts commit cdac643749ac3b8d91190bec3d1c4b3b539bf156. --- src/mesh/Router.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index b4c456158..03aa57351 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -359,7 +359,6 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // LOG_DEBUG("\n\n**\n\nDecompressed length - %d \n", decompressed_len); memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len); - p->decoded.payload.size = decompressed_len; // Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP; @@ -383,7 +382,9 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) // If the packet is not yet encrypted, do so now if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { - // Only allow compression on the text message app. + size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); + + // Only allow encryption on the text message app. // TODO: Allow modules to opt into compression. if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) { @@ -395,12 +396,17 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) int compressed_len; compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out); - LOG_DEBUG("Length - %d, compressed length - %d \n", p->decoded.payload.size, compressed_len); + LOG_DEBUG("Original length - %d \n", p->decoded.payload.size); + LOG_DEBUG("Compressed length - %d \n", compressed_len); LOG_DEBUG("Original message - %s \n", p->decoded.payload.bytes); // If the compressed length is greater than or equal to the original size, don't use the compressed form if (compressed_len >= p->decoded.payload.size) { + LOG_DEBUG("Not using compressing message.\n"); + // Set the uncompressed payload variant anyway. Shouldn't hurt? + // p->decoded.which_payloadVariant = Data_payload_tag; + // Otherwise we use the compressor } else { LOG_DEBUG("Using compressed message.\n"); @@ -413,8 +419,6 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) } } - size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); - if (numbytes > MAX_RHPACKETLEN) return meshtastic_Routing_Error_TOO_LARGE; From 47301a5ac090d2733353ed412e672e7e31dbede2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:11:54 -0500 Subject: [PATCH 93/97] [create-pull-request] automated change (#2836) Co-authored-by: thebentern --- protobufs | 2 +- src/mesh/generated/meshtastic/portnums.pb.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/protobufs b/protobufs index 60f1f1574..fb28d5935 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 60f1f15743f5232cdcae6c160e8fa52951f62880 +Subproject commit fb28d593526467977cf353959a66e11373928282 diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h index d354b7a42..c94349d47 100644 --- a/src/mesh/generated/meshtastic/portnums.pb.h +++ b/src/mesh/generated/meshtastic/portnums.pb.h @@ -69,7 +69,8 @@ typedef enum _meshtastic_PortNum { NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */ meshtastic_PortNum_AUDIO_APP = 9, - /* Same as Text Message but originating from Detection Sensor Module. */ + /* Same as Text Message but originating from Detection Sensor Module. + NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */ meshtastic_PortNum_DETECTION_SENSOR_APP = 10, /* Provides a 'ping' service that replies to any packet it receives. Also serves as a small example module. @@ -90,7 +91,8 @@ typedef enum _meshtastic_PortNum { ENCODING: Protobuf */ meshtastic_PortNum_STORE_FORWARD_APP = 65, /* Optional port for messages for the range test module. - ENCODING: ASCII Plaintext */ + ENCODING: ASCII Plaintext + NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */ meshtastic_PortNum_RANGE_TEST_APP = 66, /* Provides a format to send and receive telemetry data from the Meshtastic network. Maintained by Charles Crossan (crossan007) : crossan007@gmail.com From 07d51a2ca4a8f4c0f23b0dc25b2d80781745bbd1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:54:35 -0500 Subject: [PATCH 94/97] [create-pull-request] automated change (#2837) --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 1a080d923..fc48509e1 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 2 -build = 9 +build = 10 From ad529924f1a8ce35a18eeae1752ec3c972493903 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 27 Sep 2023 10:32:35 -0500 Subject: [PATCH 95/97] Code duplication cleanup for smart position logic (#2840) --- src/mesh/NodeDB.h | 8 +++++++ src/modules/PositionModule.cpp | 40 +++++++++++++++++----------------- src/modules/PositionModule.h | 9 ++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 0f43376ba..51c1b3043 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -212,6 +212,14 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d return defaultInterval * 1000; } +inline uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue) +{ + if (configured > 0) + return configured; + + return defaultValue; +} + /// Sometimes we will have Position objects that only have a time, so check for /// valid lat/lon static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 937625cec..5292ba209 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -193,26 +193,19 @@ int32_t PositionModule::runOnce() const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position if (hasValidPosition(node2)) { - // The minimum distance to travel before we are able to send a new position packet. - const uint32_t distanceTravelThreshold = - config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; - // The minimum time (in seconds) that would pass before we are able to send a new position packet. const uint32_t minimumTimeThreshold = getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30); - // Determine the distance in meters between two points on the globe - float distanceTraveledSinceLastSend = - GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, - node->position.longitude_i * 1e-7); + auto smartPosition = getDistanceTraveledSinceLastSend(node->position); - if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) { + if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) { bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, " "minTimeInterval=%ims)\n", - localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, + localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend, minimumTimeThreshold); sendOurPosition(NODENUM_BROADCAST, requestReplies); @@ -232,6 +225,20 @@ int32_t PositionModule::runOnce() return 5000; // to save power only wake for our callback occasionally } +struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition) +{ + // The minimum distance to travel before we are able to send a new position packet. + const uint32_t distanceTravelThreshold = getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100); + + // Determine the distance in meters between two points on the globe + float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( + lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7); + + return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend), + .distanceThreshold = distanceTravelThreshold, + .hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold}; +} + void PositionModule::handleNewPosition() { meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum()); @@ -241,20 +248,13 @@ void PositionModule::handleNewPosition() uint32_t msSinceLastSend = now - lastGpsSend; if (hasValidPosition(node2)) { - // The minimum distance to travel before we are able to send a new position packet. - const uint32_t distanceTravelThreshold = - config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; - - // Determine the distance in meters between two points on the globe - float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( - lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7); - - if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold)) { + auto smartPosition = getDistanceTraveledSinceLastSend(node->position); + if (smartPosition.hasTraveledOverThreshold) { bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims)\n", - localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, msSinceLastSend); + localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend); sendOurPosition(NODENUM_BROADCAST, requestReplies); // Set the current coords as our last ones, after we've compared distance with current and decided to send diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h index 8f7047432..3114f31e1 100644 --- a/src/modules/PositionModule.h +++ b/src/modules/PositionModule.h @@ -46,6 +46,15 @@ class PositionModule : public ProtobufModule, private concu /** Does our periodic broadcast */ virtual int32_t runOnce() override; + + private: + struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition); +}; + +struct SmartPosition { + float distanceTraveled; + uint32_t distanceThreshold; + bool hasTraveledOverThreshold; }; extern PositionModule *positionModule; From 98290e5d7be9550e5a3e842982ea62fb274ac6bc Mon Sep 17 00:00:00 2001 From: Tavis Date: Wed, 27 Sep 2023 11:00:56 -1000 Subject: [PATCH 96/97] Re issue: #2496 Populate the position log entries from PositionModule with data fields (#2839) * Populate the position log entries with data fields includes datafields with no data as 0 * trunk check formatted. --------- Co-authored-by: Ben Meadors --- src/modules/PositionModule.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 5292ba209..39e467cda 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -33,12 +33,12 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes // return false; } - // Log packet size and list of fields - LOG_INFO("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size, - p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "", - p.altitude_geoidal_separation ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "", - p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.timestamp ? "PTS " : "", - p.time ? "TIME " : ""); + // Log packet size and data fields + LOG_INFO("POSITION node=%08x l=%d latI=%d lonI=%d msl=%d hae=%d geo=%d pdop=%d hdop=%d vdop=%d siv=%d fxq=%d fxt=%d pts=%d " + "time=%d\n", + getFrom(&mp), mp.decoded.payload.size, p.latitude_i, p.longitude_i, p.altitude, p.altitude_hae, + p.altitude_geoidal_separation, p.PDOP, p.HDOP, p.VDOP, p.sats_in_view, p.fix_quality, p.fix_type, p.timestamp, + p.time); if (p.time) { struct timeval tv; From 4e3576ae4899c403ed7c8458fd313bfc0e323665 Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Wed, 27 Sep 2023 22:01:40 +0100 Subject: [PATCH 97/97] Simplify SX126x variant configuration (#2813) * Update SX126xInterface.cpp * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update SX126xInterface.cpp * Update SX126xInterface.cpp * Update variant.h * Update variant.h * trunk fmt * trunk fmt * Update variant.h * trunk fmt * trunk fmt * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update pins_arduino.h * Update pins_arduino.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h * trunk fmt * Update variant.h * Update variant.h * Update variant.h * Update variant.h * trunk fmt * trunk fmt * Update variant.h * Update variant.h * Update variant.h * Update variant.h Specify behavior * Update variant.h Maintain behavior * trunk fmt * Update variant.h * Update variant.h * Update variant.h * Update variant.h * Update variant.h --------- Co-authored-by: Ben Meadors --- src/mesh/SX126xInterface.cpp | 93 ++++++++++--------- .../Dongle_nRF52840-pca10059-v1/variant.h | 13 +-- variants/MakePython_nRF52840_eink/variant.h | 8 +- variants/MakePython_nRF52840_oled/variant.h | 4 +- variants/ai-c3/variant.h | 4 +- variants/bpi_picow_esp32_s3/pins_arduino.h | 12 +-- variants/bpi_picow_esp32_s3/variant.h | 33 +++---- variants/diy/dr-dev/variant.h | 24 +++-- variants/diy/hydra/variant.h | 5 +- variants/diy/v1/variant.h | 4 +- variants/diy/v1_1/variant.h | 2 +- variants/feather_diy/variant.h | 2 +- variants/heltec_esp32c3/variant.h | 3 +- variants/heltec_v3/variant.h | 4 +- variants/heltec_wireless_paper/variant.h | 4 +- variants/heltec_wireless_tracker/variant.h | 4 +- variants/heltec_wsl_v3/variant.h | 4 +- variants/lora_isp4520/variant.h | 5 +- variants/lora_relay_v1/variant.h | 3 +- variants/lora_relay_v2/variant.h | 3 +- variants/m5stack-stamp-c3/variant.h | 79 ++++++++-------- variants/m5stack_core/variant.h | 2 +- variants/m5stack_coreink/variant.h | 6 +- variants/monteops_hw1/variant.h | 10 +- variants/my_esp32s3_diy_eink/pins_arduino.h | 10 +- variants/my_esp32s3_diy_eink/variant.h | 14 +-- variants/my_esp32s3_diy_oled/pins_arduino.h | 10 +- variants/my_esp32s3_diy_oled/variant.h | 26 +++--- variants/nano-g1-explorer/variant.h | 6 +- variants/nano-g1/variant.h | 4 +- variants/nano-g2-ultra/variant.h | 6 +- variants/pca10056-rc-clock/variant.h | 1 + variants/portduino/variant.h | 1 + variants/ppr/variant.h | 11 ++- variants/ppr1/variant.h | 7 +- variants/rak11200/variant.h | 4 +- variants/rak11310/variant.h | 6 +- variants/rak4631/variant.h | 6 +- variants/rak4631_epaper/variant.h | 6 +- variants/rak4631_epaper_onrxtx/variant.h | 48 +++++----- variants/rpipico/variant.h | 5 +- variants/rpipicow/variant.h | 5 +- variants/station-g1/variant.h | 6 +- variants/t-deck/variant.h | 6 +- variants/t-echo/variant.h | 4 +- variants/t-watch-s3/variant.h | 8 +- variants/tbeam-s3-core/variant.h | 12 ++- variants/tbeam/variant.h | 6 +- variants/tlora_t3s3_v1/variant.h | 5 +- variants/xiao_ble/variant.h | 8 +- 50 files changed, 311 insertions(+), 251 deletions(-) diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index fa158c22b..0e94bff93 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -3,7 +3,8 @@ #include "error.h" #include "mesh/NodeDB.h" -// Particular boards might define a different max power based on what their hardware can do +// Particular boards might define a different max power based on what their hardware can do, default to max power output if not +// specified (may be dangerous if using external PA and SX126x power config forgotten) #ifndef SX126X_MAX_POWER #define SX126X_MAX_POWER 22 #endif @@ -26,20 +27,23 @@ template bool SX126xInterface::init() pinMode(SX126X_POWER_EN, OUTPUT); #endif -#ifndef SX126X_E22 - float tcxoVoltage = 0; // None - we use an XTAL +// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE +#if !defined(SX126X_DIO3_TCXO_VOLTAGE) + float tcxoVoltage = + 0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per + // https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.h#L471C26-L471C104 + // (DIO3 is free to be used as an IRQ) + LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n"); #else - // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 - float tcxoVoltage = 1.8; + float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; + LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", SX126X_DIO3_TCXO_VOLTAGE); + // (DIO3 is not free to be used as an IRQ) #endif + // FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? RadioLibInterface::init(); - - if (power == 0) - power = SX126X_MAX_POWER; - - if (power > SX126X_MAX_POWER) // This chip has lower power limits than some + if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level power = SX126X_MAX_POWER; limitPower(); @@ -54,49 +58,50 @@ template bool SX126xInterface::init() LOG_INFO("Bandwidth set to %f\n", bw); LOG_INFO("Power output set to %d\n", power); - // current limit was removed from module' ctor - // override default value (60 mA) + // Overriding current limit + // (https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.cpp#L85) using + // value in SX126xInterface.h (currently 140 mA) It may or may not be neccessary, depending on how RadioLib functions, from + // SX1261/2 datasheet: OCP after setting DeviceSel with SetPaConfig(): SX1261 - 60 mA, SX1262 - 140 mA For the SX1268 the IC + // defaults to 140mA no matter the set power level, but RadioLib set it lower, this would need further checking Default values + // are: SX1262, SX1268: 0x38 (140 mA), SX1261: 0x18 (60 mA) + // FIXME: Not ideal to increase SX1261 current limit above 60mA as it can only transmit max 15dBm, should probably only do it + // if using SX1262 or SX1268 res = lora.setCurrentLimit(currentLimit); LOG_DEBUG("Current limit set to %f\n", currentLimit); LOG_DEBUG("Current limit set result %d\n", res); -#if defined(SX126X_E22) - // E22 Emulation explicitly requires DIO2 as RF switch, so set it to TRUE again for good measure. In case somebody defines - // SX126X_TX for an E22 Module - if (res == RADIOLIB_ERR_NONE) { - LOG_DEBUG("SX126X_E22 mode enabled. Setting DIO2 as RF Switch\n"); - res = lora.setDio2AsRfSwitch(true); - } +#ifdef SX126X_DIO2_AS_RF_SWITCH + LOG_DEBUG("Setting DIO2 as RF switch\n"); + bool dio2AsRfSwitch = true; +#else + LOG_DEBUG("Setting DIO2 as not RF switch\n"); + bool dio2AsRfSwitch = false; #endif + if (res == RADIOLIB_ERR_NONE) { + res = lora.setDio2AsRfSwitch(dio2AsRfSwitch); + } -#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC) - // If SX126X_TXEN is connected to the MCU, we are manually controlling RX and TX. - // But lora.begin (called above) sets Dio2 as RF switch control, which is not true here, so set it back to false. - if (res == RADIOLIB_ERR_NONE) { - LOG_DEBUG("SX126X_TXEN pin defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN); - res = lora.setDio2AsRfSwitch(false); - lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN); - } -#elif defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC && defined(E22_TXEN_CONNECTED_TO_DIO2)) - // Otherwise, if SX126X_RXEN is connected to the MCU, and E22_TXEN_CONNECTED_TO_DIO2 is defined, we are letting the - // E22 control RX and TX via DIO2. In this configuration, the E22's TXEN and DIO2 pins are connected to each other, - // but not to the MCU. - // However, we must still connect the E22's RXEN pin to the MCU, define SX126X_RXEN accordingly, and then call - // setRfSwitchPins, otherwise RX sensitivity (observed via RSSI) is greatly diminished. - LOG_DEBUG("SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are defined; value of res: %d", res); - if (res == RADIOLIB_ERR_NONE) { - LOG_DEBUG("SX126X_TXEN is RADIOLIB_NC, but SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are both defined; calling " - "lora.setRfSwitchPins."); - lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN); - } + // If a pin isn't defined, we set it to RADIOLIB_NC, it is safe to always do external RF switching with RADIOLIB_NC as it has + // no effect +#ifndef SX126X_RXEN +#define SX126X_RXEN RADIOLIB_NC + LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC\n"); #endif +#ifndef SX126X_TXEN +#define SX126X_TXEN RADIOLIB_NC + LOG_DEBUG("SX126X_TXEN not defined, defaulting to RADIOLIB_NC\n"); +#endif + if (res == RADIOLIB_ERR_NONE) { + LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", SX126X_RXEN, SX126X_TXEN); + lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN); + } if (config.lora.sx126x_rx_boosted_gain) { uint16_t result = lora.setRxBoostedGainMode(true); - LOG_INFO("Set Rx Boosted Gain mode; result: %d\n", result); + LOG_INFO("Set RX gain to boosted mode; result: %d\n", result); } else { uint16_t result = lora.setRxBoostedGainMode(false); - LOG_INFO("Set Rx Power Saving Gain mode; result: %d\n", result); + LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", result); } #if 0 @@ -265,7 +270,7 @@ template bool SX126xInterface::isChannelActive() /** Could we send right now (i.e. either not actively receiving or transmitting)? */ template bool SX126xInterface::isActivelyReceiving() { - // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet + // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet // received and handled the interrupt for reading the packet/handling errors. uint16_t irq = lora.getIrqStatus(); @@ -296,7 +301,7 @@ template bool SX126xInterface::sleep() { // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet // \todo Display actual typename of the adapter, not just `SX126x` - LOG_DEBUG("sx126x entering sleep mode (FIXME, don't keep config)\n"); + LOG_DEBUG("SX126x entering sleep mode (FIXME, don't keep config)\n"); setStandby(); // Stop any pending operations // turn off TCXO if it was powered @@ -312,4 +317,4 @@ template bool SX126xInterface::sleep() #endif return true; -} \ No newline at end of file +} diff --git a/variants/Dongle_nRF52840-pca10059-v1/variant.h b/variants/Dongle_nRF52840-pca10059-v1/variant.h index d165d6bdc..81e2ad995 100644 --- a/variants/Dongle_nRF52840-pca10059-v1/variant.h +++ b/variants/Dongle_nRF52840-pca10059-v1/variant.h @@ -47,12 +47,12 @@ extern "C" { #define PIN_LED2 (0 + 6) // Built in Green P0.06 // Green Built in LED1 -//#define PIN_LED1 (0 + 6) // LED1 P1.15 +// #define PIN_LED1 (0 + 6) // LED1 P1.15 // RGB NeoPixel LED2 -//#define PIN_LED1 (0 + 8) Red -//#define PIN_LED1 (32 + 9) Green -//#define PIN_LED1 (0 + 12) Blue +// #define PIN_LED1 (0 + 8) Red +// #define PIN_LED1 (32 + 9) Green +// #define PIN_LED1 (0 + 12) Blue #define LED_BUILTIN PIN_LED1 #define LED_CONN PIN_LED2 @@ -113,7 +113,7 @@ static const uint8_t SCK = PIN_SPI_SCK; * eink display pins */ -//#define PIN_EINK_EN (-1) +// #define PIN_EINK_EN (-1) #define PIN_EINK_EN (0 + 6) // Turn on the Green built in LED #define PIN_EINK_CS (32) // EPD_CS #define PIN_EINK_BUSY (20) // EPD_BUSY @@ -140,7 +140,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_RESET (32 + 15) // LORA_RESET P1.15 #define SX126X_TXEN (32 + 13) // TXEN P1.13 NiceRF 868 dont use #define SX126X_RXEN (32 + 10) // RXEN P1.10 NiceRF 868 dont use -#define SX126X_E22 + +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define PIN_GPS_EN (-1) #define PIN_GPS_PPS (-1) // Pulse per second input from the GPS diff --git a/variants/MakePython_nRF52840_eink/variant.h b/variants/MakePython_nRF52840_eink/variant.h index 8cf1f7dd9..2ff9c76fd 100644 --- a/variants/MakePython_nRF52840_eink/variant.h +++ b/variants/MakePython_nRF52840_eink/variant.h @@ -73,7 +73,7 @@ static const uint8_t AREF = PIN_AREF; */ #define SPI_INTERFACES_COUNT 2 // here -//#define SPI_INTERFACES_COUNT 1 +// #define SPI_INTERFACES_COUNT 1 #define PIN_SPI_MISO (0 + 31) // MISO P0.31 #define PIN_SPI_MOSI (0 + 30) // MOSI P0.30 @@ -94,7 +94,7 @@ static const uint8_t SCK = PIN_SPI_SCK; * eink display pins */ -//#define PIN_EINK_EN (-1) +// #define PIN_EINK_EN (-1) #define PIN_EINK_CS (0 + 3) // EPD_CS #define PIN_EINK_BUSY (32 + 11) // EPD_BUSY #define PIN_EINK_DC (32 + 13) // EPD_D/C @@ -118,8 +118,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX128X_CS (0 + 23) #define SX128X_DIO1 (0 + 4) #define SX128X_BUSY (0 + 7) -//#define SX128X_TXEN (32 + 9) -//#define SX128X_RXEN (0 + 12) +// #define SX128X_TXEN (32 + 9) +// #define SX128X_RXEN (0 + 12) #define SX128X_RESET LORA_RESET #define PIN_GPS_EN (-1) diff --git a/variants/MakePython_nRF52840_oled/variant.h b/variants/MakePython_nRF52840_oled/variant.h index 2f4323dd8..e7375a610 100644 --- a/variants/MakePython_nRF52840_oled/variant.h +++ b/variants/MakePython_nRF52840_oled/variant.h @@ -96,8 +96,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX128X_CS (0 + 23) #define SX128X_DIO1 (0 + 4) #define SX128X_BUSY (0 + 7) -//#define SX128X_TXEN (32 + 9) -//#define SX128X_RXEN (0 + 12) +// #define SX128X_TXEN (32 + 9) +// #define SX128X_RXEN (0 + 12) #define SX128X_RESET LORA_RESET #define PIN_GPS_EN (-1) diff --git a/variants/ai-c3/variant.h b/variants/ai-c3/variant.h index 352d189f1..254f5fd36 100644 --- a/variants/ai-c3/variant.h +++ b/variants/ai-c3/variant.h @@ -23,7 +23,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY 10 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // use DIO2 as RF switch + +#define SX126X_DIO2_AS_RF_SWITCH // use DIO2 as RF switch +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define HAS_GPS 0 #undef GPS_RX_PIN diff --git a/variants/bpi_picow_esp32_s3/pins_arduino.h b/variants/bpi_picow_esp32_s3/pins_arduino.h index ee0e34ebf..af03bf28a 100644 --- a/variants/bpi_picow_esp32_s3/pins_arduino.h +++ b/variants/bpi_picow_esp32_s3/pins_arduino.h @@ -27,11 +27,11 @@ static const uint8_t SCK = 21; static const uint8_t MOSI = 38; static const uint8_t SS = 17; -//#define SPI_MOSI (11) -//#define SPI_SCK (14) -//#define SPI_MISO (2) -//#define SPI_CS (13) +// #define SPI_MOSI (11) +// #define SPI_SCK (14) +// #define SPI_MISO (2) +// #define SPI_CS (13) -//#define SDCARD_CS SPI_CS +// #define SDCARD_CS SPI_CS -#endif /* Pins_Arduino_h */ \ No newline at end of file +#endif /* Pins_Arduino_h */ diff --git a/variants/bpi_picow_esp32_s3/variant.h b/variants/bpi_picow_esp32_s3/variant.h index 78eae1dad..8114b9ea3 100644 --- a/variants/bpi_picow_esp32_s3/variant.h +++ b/variants/bpi_picow_esp32_s3/variant.h @@ -2,10 +2,10 @@ #undef GPS_RX_PIN #undef GPS_TX_PIN -//#define HAS_SCREEN 0 +// #define HAS_SCREEN 0 -//#define HAS_SDCARD -//#define SDCARD_USE_SPI1 +// #define HAS_SDCARD +// #define SDCARD_USE_SPI1 #define USE_SSD1306 #define I2C_SDA 12 @@ -14,13 +14,13 @@ #define LED_PIN 46 #define LED_STATE_ON 0 // State when LED is litted -//#define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17) +// #define BUTTON_PIN 15 // Pico OLED 1.3 User key 0 - removed User key 1 (17) #define BUTTON_PIN 40 -//#define BUTTON_PIN 0 // This is the BOOT button pad at the moment -//#define BUTTON_NEED_PULLUP +// #define BUTTON_PIN 0 // This is the BOOT button pad at the moment +// #define BUTTON_NEED_PULLUP -//#define USE_RF95 // RFM95/SX127x +// #define USE_RF95 // RFM95/SX127x #undef RF95_SCK #undef RF95_MISO @@ -43,10 +43,11 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_BUSY #define SX126X_RESET LORA_RESET -#define SX126X_E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #endif -//#define USE_SX1280 +// #define USE_SX1280 #ifdef USE_SX1280 #define RF95_MISO 1 #define RF95_SCK 3 @@ -61,13 +62,13 @@ #define SX128X_RESET LORA_RESET #endif -//#define USE_EINK +// #define USE_EINK /* * eink display pins */ -//#define PIN_EINK_CS -//#define PIN_EINK_BUSY -//#define PIN_EINK_DC -//#define PIN_EINK_RES (-1) -//#define PIN_EINK_SCLK 3 -//#define PIN_EINK_MOSI 4 \ No newline at end of file +// #define PIN_EINK_CS +// #define PIN_EINK_BUSY +// #define PIN_EINK_DC +// #define PIN_EINK_RES (-1) +// #define PIN_EINK_SCLK 3 +// #define PIN_EINK_MOSI 4 diff --git a/variants/diy/dr-dev/variant.h b/variants/diy/dr-dev/variant.h index b9c82a9c8..08d57eec9 100644 --- a/variants/diy/dr-dev/variant.h +++ b/variants/diy/dr-dev/variant.h @@ -31,10 +31,13 @@ // PINS FOR THE 900M22S -#define LORA_DIO1 26 // IRQ for SX1262/SX1268 -#define LORA_DIO2 22 // BUSY for SX1262/SX1268 -#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level -#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level +#define LORA_DIO1 26 // IRQ for SX1262/SX1268 +#define LORA_DIO2 22 // BUSY for SX1262/SX1268 +// NOT_A_PIN is treated as RADIOLIB_NC due to how they are defined, best to use RADIOLIB_NC directly +#define LORA_TXEN RADIOLIB_NC // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level +// E22_TXEN_CONNECTED_TO_DIO2 wasn't defined, so RXEN wasn't controlled. Commented it out to maintain behavior, but shouldn't be. +// Need to comment out defining SX126X_RXEN as LORA_RXEN too +// #define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level #undef RF95_NSS #define RF95_NSS 16 #define SX126X_BUSY 22 @@ -53,7 +56,7 @@ */ // RX/TX for RFM95/SX127x -#define RF95_RXEN LORA_RXEN +// #define RF95_RXEN LORA_RXEN #define RF95_TXEN LORA_TXEN // #define RF95_TCXO @@ -61,12 +64,13 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_RESET LORA_RESET -#define SX126X_RXEN LORA_RXEN +// #define SX126X_RXEN LORA_RXEN #define SX126X_TXEN LORA_TXEN // supported modules list -//#define USE_RF95 // RFM95/SX127x +// #define USE_RF95 // RFM95/SX127x #define USE_SX1262 -//#define USE_SX1268 -//#define USE_LLCC68 -#define SX126X_E22 \ No newline at end of file +// #define USE_SX1268 +// #define USE_LLCC68 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/diy/hydra/variant.h b/variants/diy/hydra/variant.h index 65bf839fd..98c1c2ae1 100644 --- a/variants/diy/hydra/variant.h +++ b/variants/diy/hydra/variant.h @@ -37,8 +37,9 @@ #define SX126X_RESET LORA_RESET #define SX126X_RXEN 14 #define SX126X_TXEN RADIOLIB_NC -#define E22_TXEN_CONNECTED_TO_DIO2 1 +#define SX126X_DIO2_AS_RF_SWITCH // Set lora.tx_power to 13 for Hydra or other E22 900M30S target due to PA #define SX126X_MAX_POWER 13 -#define SX126X_E22 + +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/diy/v1/variant.h b/variants/diy/v1/variant.h index a1083f9bb..48906515b 100644 --- a/variants/diy/v1/variant.h +++ b/variants/diy/v1/variant.h @@ -52,5 +52,5 @@ #ifdef EBYTE_E22 // Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch // (which is the default for the sx1262interface code) -#define SX126X_E22 -#endif \ No newline at end of file +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif diff --git a/variants/diy/v1_1/variant.h b/variants/diy/v1_1/variant.h index a550b9d1c..fd5276ced 100644 --- a/variants/diy/v1_1/variant.h +++ b/variants/diy/v1_1/variant.h @@ -53,5 +53,5 @@ #ifdef EBYTE_E22 // Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch // (which is the default for the sx1262interface code) -#define SX126X_E22 +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #endif diff --git a/variants/feather_diy/variant.h b/variants/feather_diy/variant.h index 85614d9b5..5e889b04e 100644 --- a/variants/feather_diy/variant.h +++ b/variants/feather_diy/variant.h @@ -105,7 +105,7 @@ extern "C" { #ifdef EBYTE_E22 // Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch // (which is the default for the sx1262interface code) -#define SX126X_E22 +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #endif #ifdef __cplusplus diff --git a/variants/heltec_esp32c3/variant.h b/variants/heltec_esp32c3/variant.h index 29ed88080..7d113720d 100644 --- a/variants/heltec_esp32c3/variant.h +++ b/variants/heltec_esp32c3/variant.h @@ -33,4 +33,5 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_BUSY #define SX126X_RESET LORA_RESET -#define SX126X_E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/heltec_v3/variant.h b/variants/heltec_v3/variant.h index 3e2227e15..4ce47996b 100644 --- a/variants/heltec_v3/variant.h +++ b/variants/heltec_v3/variant.h @@ -33,4 +33,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 \ No newline at end of file + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/heltec_wireless_paper/variant.h b/variants/heltec_wireless_paper/variant.h index eb67ea816..b73596f50 100644 --- a/variants/heltec_wireless_paper/variant.h +++ b/variants/heltec_wireless_paper/variant.h @@ -40,4 +40,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 \ No newline at end of file + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index f3915e350..cfb752d03 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -59,4 +59,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 \ No newline at end of file + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index 40671e4fb..240a482f7 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -32,4 +32,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h index ce0c48297..30b8fc169 100644 --- a/variants/lora_isp4520/variant.h +++ b/variants/lora_isp4520/variant.h @@ -28,7 +28,7 @@ #define USE_LFXO -//#define USE_SEGGER +// #define USE_SEGGER // Number of pins defined in PinDescription array #define PINS_COUNT (16) @@ -88,6 +88,7 @@ #define BATTERY_PIN 3 #define ADC_MULTIPLIER 1.436 -#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Not really an E22 but this board clones using DIO3 for tcxo control #endif diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h index 3ee0406ae..b310223d7 100644 --- a/variants/lora_relay_v1/variant.h +++ b/variants/lora_relay_v1/variant.h @@ -134,7 +134,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_TXEN (31) #define SX126X_POWER_EN \ (15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino -#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define ST7735_RESET (11) // Output #define ST7735_CS (12) diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h index 16286210f..172da17f7 100644 --- a/variants/lora_relay_v2/variant.h +++ b/variants/lora_relay_v2/variant.h @@ -154,7 +154,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_TXEN (31) #define SX126X_POWER_EN \ (15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino -#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // ST7565 SPI #define ST7735_RESET (11) // Output diff --git a/variants/m5stack-stamp-c3/variant.h b/variants/m5stack-stamp-c3/variant.h index b1a192af5..87adbc226 100644 --- a/variants/m5stack-stamp-c3/variant.h +++ b/variants/m5stack-stamp-c3/variant.h @@ -4,7 +4,7 @@ #define BUTTON_PIN 3 // M5Stack STAMP C3 built in button #define BUTTON_NEED_PULLUP -//#define HAS_SCREEN 0 +// #define HAS_SCREEN 0 #define HAS_GPS 0 #undef GPS_RX_PIN #undef GPS_TX_PIN @@ -28,45 +28,46 @@ // WaveShare Core1262-868M OK // https://www.waveshare.com/wiki/Core1262-868M -//#define USE_SX1262 -//#define RF95_SCK 4 -//#define RF95_MISO 5 -//#define RF95_MOSI 6 -//#define RF95_NSS 7 -//#define LORA_DIO0 RADIOLIB_NC -//#define LORA_RESET 8 -//#define LORA_DIO1 10 -//#define LORA_DIO2 RADIOLIB_NC -//#define LORA_BUSY 18 -//#define SX126X_CS RF95_NSS -//#define SX126X_DIO1 LORA_DIO1 -//#define SX126X_BUSY LORA_BUSY -//#define SX126X_RESET LORA_RESET -//#define SX126X_E22 +// #define USE_SX1262 +// #define RF95_SCK 4 +// #define RF95_MISO 5 +// #define RF95_MOSI 6 +// #define RF95_NSS 7 +// #define LORA_DIO0 RADIOLIB_NC +// #define LORA_RESET 8 +// #define LORA_DIO1 10 +// #define LORA_DIO2 RADIOLIB_NC +// #define LORA_BUSY 18 +// #define SX126X_CS RF95_NSS +// #define SX126X_DIO1 LORA_DIO1 +// #define SX126X_BUSY LORA_BUSY +// #define SX126X_RESET LORA_RESET +// #define SX126X_DIO2_AS_RF_SWITCH +// #define SX126X_DIO3_TCXO_VOLTAGE 1.8 // SX128X 2.4 Ghz LoRa module Not OK - RadioLib issue ? still to confirm -//#define USE_SX1280 -//#define RF95_SCK 4 -//#define RF95_MISO 5 -//#define RF95_MOSI 6 -//#define RF95_NSS 7 -//#define LORA_DIO0 -1 -//#define LORA_DIO1 10 -//#define LORA_DIO2 21 -//#define LORA_RESET 8 -//#define LORA_BUSY 1 -//#define SX128X_CS RF95_NSS -//#define SX128X_DIO1 LORA_DIO1 -//#define SX128X_BUSY LORA_BUSY -//#define SX128X_RESET LORA_RESET -//#define SX128X_MAX_POWER 10 +// #define USE_SX1280 +// #define RF95_SCK 4 +// #define RF95_MISO 5 +// #define RF95_MOSI 6 +// #define RF95_NSS 7 +// #define LORA_DIO0 -1 +// #define LORA_DIO1 10 +// #define LORA_DIO2 21 +// #define LORA_RESET 8 +// #define LORA_BUSY 1 +// #define SX128X_CS RF95_NSS +// #define SX128X_DIO1 LORA_DIO1 +// #define SX128X_BUSY LORA_BUSY +// #define SX128X_RESET LORA_RESET +// #define SX128X_MAX_POWER 10 // Not yet tested -//#define USE_EINK -//#define PIN_EINK_EN -1 // N/C -//#define PIN_EINK_CS 9 // EPD_CS -//#define PIN_EINK_BUSY 18 // EPD_BUSY -//#define PIN_EINK_DC 19 // EPD_D/C -//#define PIN_EINK_RES -1 // Connected but not needed -//#define PIN_EINK_SCLK 4 // EPD_SCLK -//#define PIN_EINK_MOSI 6 // EPD_MOSI \ No newline at end of file +// #define USE_EINK +// #define PIN_EINK_EN -1 // N/C +// #define PIN_EINK_CS 9 // EPD_CS +// #define PIN_EINK_BUSY 18 // EPD_BUSY +// #define PIN_EINK_DC 19 // EPD_D/C +// #define PIN_EINK_RES -1 // Connected but not needed +// #define PIN_EINK_SCLK 4 // EPD_SCLK +// #define PIN_EINK_MOSI 6 // EPD_MOSI diff --git a/variants/m5stack_core/variant.h b/variants/m5stack_core/variant.h index 22fa323d7..c671d77fa 100644 --- a/variants/m5stack_core/variant.h +++ b/variants/m5stack_core/variant.h @@ -4,7 +4,7 @@ #define I2C_SCL 22 // #define BUTTON_PIN 39 // 38, 37 -//#define BUTTON_PIN 0 +// #define BUTTON_PIN 0 #define BUTTON_NEED_PULLUP // #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin. diff --git a/variants/m5stack_coreink/variant.h b/variants/m5stack_coreink/variant.h index 5ec1a81a3..90ce41334 100644 --- a/variants/m5stack_coreink/variant.h +++ b/variants/m5stack_coreink/variant.h @@ -3,8 +3,8 @@ #define I2C_SCL 22 // 7-07-2023 Or enable Secondary I2C Bus -//#define I2C_SDA1 32 -//#define I2C_SCL1 33 +// #define I2C_SDA1 32 +// #define I2C_SCL1 33 #define HAS_GPS 1 #undef GPS_RX_PIN @@ -39,7 +39,7 @@ #undef RF95_MOSI #undef RF95_NSS #define USE_RF95 -//#define USE_SX1280 +// #define USE_SX1280 #ifdef USE_RF95 #define RF95_SCK 18 diff --git a/variants/monteops_hw1/variant.h b/variants/monteops_hw1/variant.h index 866ddf471..f7df0688b 100644 --- a/variants/monteops_hw1/variant.h +++ b/variants/monteops_hw1/variant.h @@ -64,7 +64,7 @@ extern "C" { * Buttons */ -//#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion +// #define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion #define BUTTON_NEED_PULLUP #define PIN_BUTTON2 12 #define PIN_BUTTON3 24 @@ -191,7 +191,9 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG // #define SX126X_TXEN (39) // #define SX126X_RXEN (37) #define SX126X_POWER_EN (37) -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 + +#define SX126X_DIO2_AS_RF_SWITCH // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define PIN_GPS_RESET (34) // Must be P1.02 // #define PIN_GPS_EN @@ -220,7 +222,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG #define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB #define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x) -//#define HAS_RTC 1 +// #define HAS_RTC 1 #define HAS_ETHERNET 1 @@ -237,4 +239,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/my_esp32s3_diy_eink/pins_arduino.h b/variants/my_esp32s3_diy_eink/pins_arduino.h index 1f276899c..39e316624 100644 --- a/variants/my_esp32s3_diy_eink/pins_arduino.h +++ b/variants/my_esp32s3_diy_eink/pins_arduino.h @@ -24,11 +24,11 @@ static const uint8_t SCK = 5; static const uint8_t MOSI = 6; static const uint8_t SS = 7; -//#define SPI_MOSI (11) -//#define SPI_SCK (14) -//#define SPI_MISO (2) -//#define SPI_CS (13) +// #define SPI_MOSI (11) +// #define SPI_SCK (14) +// #define SPI_MISO (2) +// #define SPI_CS (13) -//#define SDCARD_CS SPI_CS +// #define SDCARD_CS SPI_CS #endif /* Pins_Arduino_h */ diff --git a/variants/my_esp32s3_diy_eink/variant.h b/variants/my_esp32s3_diy_eink/variant.h index 288daf9ff..7e4fe2756 100644 --- a/variants/my_esp32s3_diy_eink/variant.h +++ b/variants/my_esp32s3_diy_eink/variant.h @@ -2,22 +2,22 @@ #undef GPS_RX_PIN #undef GPS_TX_PIN -//#define HAS_SCREEN 0 -//#define HAS_SDCARD -//#define SDCARD_USE_SPI1 +// #define HAS_SCREEN 0 +// #define HAS_SDCARD +// #define SDCARD_USE_SPI1 -//#define USE_SSD1306 +// #define USE_SSD1306 #define I2C_SDA 18 // 1 // I2C pins for this board #define I2C_SCL 17 // 2 -//#define LED_PIN 38 // This is a RGB LED not a standard LED +// #define LED_PIN 38 // This is a RGB LED not a standard LED #define BUTTON_PIN 0 // This is the BOOT button #define BUTTON_NEED_PULLUP -//#define USE_RF95 // RFM95/SX127x -//#define USE_SX1262 +// #define USE_RF95 // RFM95/SX127x +// #define USE_SX1262 #define USE_SX1280 #define RF95_MISO 3 diff --git a/variants/my_esp32s3_diy_oled/pins_arduino.h b/variants/my_esp32s3_diy_oled/pins_arduino.h index 1f276899c..39e316624 100644 --- a/variants/my_esp32s3_diy_oled/pins_arduino.h +++ b/variants/my_esp32s3_diy_oled/pins_arduino.h @@ -24,11 +24,11 @@ static const uint8_t SCK = 5; static const uint8_t MOSI = 6; static const uint8_t SS = 7; -//#define SPI_MOSI (11) -//#define SPI_SCK (14) -//#define SPI_MISO (2) -//#define SPI_CS (13) +// #define SPI_MOSI (11) +// #define SPI_SCK (14) +// #define SPI_MISO (2) +// #define SPI_CS (13) -//#define SDCARD_CS SPI_CS +// #define SDCARD_CS SPI_CS #endif /* Pins_Arduino_h */ diff --git a/variants/my_esp32s3_diy_oled/variant.h b/variants/my_esp32s3_diy_oled/variant.h index 9eda00791..bb9657c5b 100644 --- a/variants/my_esp32s3_diy_oled/variant.h +++ b/variants/my_esp32s3_diy_oled/variant.h @@ -2,22 +2,22 @@ #undef GPS_RX_PIN #undef GPS_TX_PIN -//#define HAS_SCREEN 0 -//#define HAS_SDCARD -//#define SDCARD_USE_SPI1 +// #define HAS_SCREEN 0 +// #define HAS_SDCARD +// #define SDCARD_USE_SPI1 #define USE_SSD1306 #define I2C_SDA 18 // 1 // I2C pins for this board #define I2C_SCL 17 // 2 -//#define LED_PIN 38 // This is a RGB LED not a standard LED +// #define LED_PIN 38 // This is a RGB LED not a standard LED #define BUTTON_PIN 0 // This is the BOOT button #define BUTTON_NEED_PULLUP -//#define USE_RF95 // RFM95/SX127x -//#define USE_SX1262 +// #define USE_RF95 // RFM95/SX127x +// #define USE_SX1262 #define USE_SX1280 #define RF95_MISO 3 @@ -44,13 +44,13 @@ #define SX128X_RESET LORA_RESET #endif -//#define USE_EINK +// #define USE_EINK /* * eink display pins */ -//#define PIN_EINK_CS 13 -//#define PIN_EINK_BUSY 2 -//#define PIN_EINK_DC 1 -//#define PIN_EINK_RES (-1) -//#define PIN_EINK_SCLK 5 -//#define PIN_EINK_MOSI 6 +// #define PIN_EINK_CS 13 +// #define PIN_EINK_BUSY 2 +// #define PIN_EINK_DC 1 +// #define PIN_EINK_RES (-1) +// #define PIN_EINK_SCLK 5 +// #define PIN_EINK_MOSI 6 diff --git a/variants/nano-g1-explorer/variant.h b/variants/nano-g1-explorer/variant.h index 1cc3b4103..71dd49f05 100644 --- a/variants/nano-g1-explorer/variant.h +++ b/variants/nano-g1-explorer/variant.h @@ -27,7 +27,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 +// Not really an E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) #endif @@ -37,4 +39,4 @@ #define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity. #define ADC_MULTIPLIER 2 -#define USE_SH1107_128_64 \ No newline at end of file +#define USE_SH1107_128_64 diff --git a/variants/nano-g1/variant.h b/variants/nano-g1/variant.h index 53adffa01..5ceb96f0c 100644 --- a/variants/nano-g1/variant.h +++ b/variants/nano-g1/variant.h @@ -27,7 +27,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 +// Not really an E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) #endif diff --git a/variants/nano-g2-ultra/variant.h b/variants/nano-g2-ultra/variant.h index 9474b6cce..d69235fd4 100644 --- a/variants/nano-g2-ultra/variant.h +++ b/variants/nano-g2-ultra/variant.h @@ -118,7 +118,9 @@ External serial flash W25Q16JV_IQ // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main CPU? #define SX126X_BUSY (32 + 11) #define SX126X_RESET (32 + 15) -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) @@ -193,4 +195,4 @@ External serial flash W25Q16JV_IQ * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/pca10056-rc-clock/variant.h b/variants/pca10056-rc-clock/variant.h index 20aed8cb6..032e1de2b 100644 --- a/variants/pca10056-rc-clock/variant.h +++ b/variants/pca10056-rc-clock/variant.h @@ -146,6 +146,7 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_BUSY (32 + 4) // P1.04 #define SX126X_RESET (0 + 3) // P0.03 #define SX126X_ANT_SW (32 + 10) // P1.10 +#define SX126X_DIO2_AS_RF_SWITCH // To debug via the segger JLINK console rather than the CDC-ACM serial device // #define USE_SEGGER diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h index e6269a38b..81dfd3885 100644 --- a/variants/portduino/variant.h +++ b/variants/portduino/variant.h @@ -20,5 +20,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH // HOPE RFM90 does not have a TCXO therefore not SX126X_E22 #endif diff --git a/variants/ppr/variant.h b/variants/ppr/variant.h index 4b37970a4..4c6cc015c 100644 --- a/variants/ppr/variant.h +++ b/variants/ppr/variant.h @@ -89,8 +89,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (0xff) -//#define PIN_NFC1 (9) -//#define PIN_NFC2 (10) +// #define PIN_NFC1 (9) +// #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -103,8 +103,8 @@ static const uint8_t AREF = PIN_AREF; #define PIN_SERIAL1_TX (9) // Connected to Jlink CDC -//#define PIN_SERIAL2_RX (8) -//#define PIN_SERIAL2_TX (6) +// #define PIN_SERIAL2_RX (8) +// #define PIN_SERIAL2_TX (6) /* * SPI Interfaces @@ -138,7 +138,8 @@ static const uint8_t SCK = PIN_SPI_SCK; // #define SX126X_ANT_SW (32 + 10) #define SX126X_RXEN (22) #define SX126X_TXEN (24) -#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +// Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // ERC12864-10 LCD #define ERC12864_CS (32 + 4) diff --git a/variants/ppr1/variant.h b/variants/ppr1/variant.h index 635614da0..ba3a25c2a 100644 --- a/variants/ppr1/variant.h +++ b/variants/ppr1/variant.h @@ -89,8 +89,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (0xff) -//#define PIN_NFC1 (9) -//#define PIN_NFC2 (10) +// #define PIN_NFC1 (9) +// #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -158,7 +158,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_RESET (0 + 17) #define SX126X_TXEN (0 + 24) #define SX126X_RXEN (0 + 22) -#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control +// Not really an E22 but this board clones using DIO3 for tcxo control +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // FIXME, to prevent burning out parts I've set the power level super low, because I don't have // an antenna wired up diff --git a/variants/rak11200/variant.h b/variants/rak11200/variant.h index 7f2c24082..b6d9c4229 100644 --- a/variants/rak11200/variant.h +++ b/variants/rak11200/variant.h @@ -81,4 +81,6 @@ static const uint8_t SCK = 33; #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET #define SX126X_POWER_EN WB_IO3 -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h index f103447fb..c2ab3628d 100644 --- a/variants/rak11310/variant.h +++ b/variants/rak11310/variant.h @@ -48,5 +48,7 @@ #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET #define SX126X_POWER_EN 25 -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 -#endif \ No newline at end of file +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index c4061037d..7b5f6b14d 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -209,7 +209,9 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG // #define SX126X_TXEN (39) // #define SX126X_RXEN (37) #define SX126X_POWER_EN (37) -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // enables 3.3V periphery like GPS or IO Module #define PIN_3V3_EN (34) @@ -275,4 +277,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak4631_epaper/variant.h b/variants/rak4631_epaper/variant.h index ad3e4b87f..0253ec14d 100644 --- a/variants/rak4631_epaper/variant.h +++ b/variants/rak4631_epaper/variant.h @@ -186,7 +186,9 @@ static const uint8_t SCK = PIN_SPI_SCK; // #define SX126X_TXEN (39) // #define SX126X_RXEN (37) #define SX126X_POWER_EN (37) -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // enables 3.3V periphery like GPS or IO Module #define PIN_3V3_EN (34) @@ -239,4 +241,4 @@ static const uint8_t SCK = PIN_SPI_SCK; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak4631_epaper_onrxtx/variant.h b/variants/rak4631_epaper_onrxtx/variant.h index e4d7c7d45..6fc6da373 100644 --- a/variants/rak4631_epaper_onrxtx/variant.h +++ b/variants/rak4631_epaper_onrxtx/variant.h @@ -43,7 +43,7 @@ extern "C" { #define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion #define BUTTON_NEED_PULLUP -//#define PIN_BUTTON2 12 +// #define PIN_BUTTON2 12 /* * Analog pins @@ -69,8 +69,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) -//#define PIN_NFC1 (9) -//#define PIN_NFC2 (10) +// #define PIN_NFC1 (9) +// #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -111,7 +111,7 @@ static const uint8_t SCK = PIN_SPI_SCK; #define PIN_EINK_CS (0 + 16) // TX1 #define PIN_EINK_BUSY (0 + 15) // RX1 #define PIN_EINK_DC (0 + 17) // IO1 -//#define PIN_EINK_RES (-1) //first try without RESET then connect it to AIN (AIN0 5 ) +// #define PIN_EINK_RES (-1) //first try without RESET then connect it to AIN (AIN0 5 ) #define PIN_EINK_RES (0 + 5) // 2.13 BN Display needs RESET #define PIN_EINK_SCLK (0 + 14) // SCL #define PIN_EINK_MOSI (0 + 13) // SDA @@ -155,7 +155,9 @@ static const uint8_t SCK = PIN_SPI_SCK; // #define SX126X_TXEN (39) // #define SX126X_RXEN (37) #define SX126X_POWER_EN (37) -#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // enables 3.3V periphery like GPS or IO Module #define PIN_3V3_EN (34) @@ -171,36 +173,36 @@ static const uint8_t SCK = PIN_SPI_SCK; // Therefore must be 1 to keep peripherals powered // Power is on the controllable 3V3_S rail // #define PIN_GPS_RESET (34) -//#define PIN_GPS_EN PIN_3V3_EN -//#define PIN_GPS_PPS (17) // Pulse per second input from the GPS +// #define PIN_GPS_EN PIN_3V3_EN +// #define PIN_GPS_PPS (17) // Pulse per second input from the GPS -//#define GPS_RX_PIN PIN_SERIAL1_RX -//#define GPS_TX_PIN PIN_SERIAL1_TX +// #define GPS_RX_PIN PIN_SERIAL1_RX +// #define GPS_TX_PIN PIN_SERIAL1_TX // RAK12002 RTC Module #define RV3028_RTC (uint8_t)0b1010010 // Battery // The battery sense is hooked to pin A0 (5) -//#define BATTERY_PIN PIN_A0 +// #define BATTERY_PIN PIN_A0 // and has 12 bit resolution -//#define BATTERY_SENSE_RESOLUTION_BITS 12 -//#define BATTERY_SENSE_RESOLUTION 4096.0 +// #define BATTERY_SENSE_RESOLUTION_BITS 12 +// #define BATTERY_SENSE_RESOLUTION 4096.0 // Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 -//#define VBAT_MV_PER_LSB (0.73242188F) +// #define VBAT_MV_PER_LSB (0.73242188F) // Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) -//#define VBAT_DIVIDER (0.4F) +// #define VBAT_DIVIDER (0.4F) // Compensation factor for the VBAT divider -//#define VBAT_DIVIDER_COMP (1.73) +// #define VBAT_DIVIDER_COMP (1.73) // Fixed calculation of milliVolt from compensation value -//#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) -//#undef AREF_VOLTAGE -//#define AREF_VOLTAGE 3.0 -//#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 -//#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB -//#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x) +// #define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) +// #undef AREF_VOLTAGE +// #define AREF_VOLTAGE 3.0 +// #define VBAT_AR_INTERNAL AR_INTERNAL_3_0 +// #define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB +// #define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x) -//#define HAS_RTC 1 +// #define HAS_RTC 1 #ifdef __cplusplus } @@ -210,4 +212,4 @@ static const uint8_t SCK = PIN_SPI_SCK; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rpipico/variant.h b/variants/rpipico/variant.h index 52e748ee8..5c92dec59 100644 --- a/variants/rpipico/variant.h +++ b/variants/rpipico/variant.h @@ -53,5 +53,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 -#endif \ No newline at end of file +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif diff --git a/variants/rpipicow/variant.h b/variants/rpipicow/variant.h index a9111db6b..6de2f7bd4 100644 --- a/variants/rpipicow/variant.h +++ b/variants/rpipicow/variant.h @@ -51,5 +51,6 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 -#endif \ No newline at end of file +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif diff --git a/variants/station-g1/variant.h b/variants/station-g1/variant.h index a1d549d42..79a49fc96 100644 --- a/variants/station-g1/variant.h +++ b/variants/station-g1/variant.h @@ -27,9 +27,7 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -// #define SX126X_E22 // Not really an E22 -// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface -// code) +#define SX126X_DIO2_AS_RF_SWITCH // Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch #define SX126X_MAX_POWER \ 16 // Ensure the PA does not exceed the saturation output power. More // Info:https://uniteng.com/wiki/doku.php?id=meshtastic:station#rf_design_-_lora_station_edition_g1 @@ -49,4 +47,4 @@ // Station may not have GPS installed, but it has a labeled GPS pinout #define GPS_RX_PIN 34 -#define GPS_TX_PIN 12 \ No newline at end of file +#define GPS_TX_PIN 12 diff --git a/variants/t-deck/variant.h b/variants/t-deck/variant.h index b732b90cb..b1673d338 100644 --- a/variants/t-deck/variant.h +++ b/variants/t-deck/variant.h @@ -84,6 +84,8 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that +// Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface -// code) \ No newline at end of file +// code) diff --git a/variants/t-echo/variant.h b/variants/t-echo/variant.h index f955285ae..6bd5091dd 100644 --- a/variants/t-echo/variant.h +++ b/variants/t-echo/variant.h @@ -133,7 +133,9 @@ External serial flash WP25R1635FZUIL0 // CPU? #define SX126X_BUSY (0 + 17) #define SX126X_RESET (0 + 25) -#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that +// Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) diff --git a/variants/t-watch-s3/variant.h b/variants/t-watch-s3/variant.h index dc363603b..c87845afa 100644 --- a/variants/t-watch-s3/variant.h +++ b/variants/t-watch-s3/variant.h @@ -63,6 +63,8 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that - // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for - // the sx1262interface code) \ No newline at end of file +// Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for +// the sx1262interface code) diff --git a/variants/tbeam-s3-core/variant.h b/variants/tbeam-s3-core/variant.h index 532b5b85c..5e9894cc6 100644 --- a/variants/tbeam-s3-core/variant.h +++ b/variants/tbeam-s3-core/variant.h @@ -7,9 +7,9 @@ #define I2C_SCL 18 // For QMC6310 sensors and screens #define BUTTON_PIN 0 // The middle button GPIO on the T-Beam S3 -//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented -// anywhere. -// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. +// #define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented +// anywhere. +// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. #define LED_INVERTED 1 @@ -29,7 +29,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that +// Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) #endif @@ -64,4 +66,4 @@ // has 32768 Hz crystal #define HAS_32768HZ -#define USE_SH1106 \ No newline at end of file +#define USE_SH1106 diff --git a/variants/tbeam/variant.h b/variants/tbeam/variant.h index 62a864636..84a3477d4 100644 --- a/variants/tbeam/variant.h +++ b/variants/tbeam/variant.h @@ -28,7 +28,9 @@ #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that +// Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) #endif @@ -39,4 +41,4 @@ #define HAS_AXP192 #define GPS_UBLOX #define GPS_RX_PIN 34 -#define GPS_TX_PIN 12 \ No newline at end of file +#define GPS_TX_PIN 12 diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h index 3d500633f..6e1d1d0eb 100644 --- a/variants/tlora_t3s3_v1/variant.h +++ b/variants/tlora_t3s3_v1/variant.h @@ -44,7 +44,8 @@ #define SX126X_DIO1 33 #define SX126X_BUSY 34 #define SX126X_RESET LORA_RESET -#define SX126X_E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #endif // per SX128x_Receive_Interrupt/utilities.h @@ -58,4 +59,4 @@ #define SX128X_RXEN 21 #define SX128X_TXEN 10 #define SX128X_MAX_POWER 3 -#endif \ No newline at end of file +#endif diff --git a/variants/xiao_ble/variant.h b/variants/xiao_ble/variant.h index ae7d37458..e2b8eb613 100644 --- a/variants/xiao_ble/variant.h +++ b/variants/xiao_ble/variant.h @@ -5,7 +5,7 @@ #define VARIANT_MCK (64000000ul) #define USE_LFXO // Board uses 32khz crystal for LF -//#define USE_LFRC // Board uses RC for LF +// #define USE_LFRC // Board uses RC for LF /*---------------------------------------------------------------------------- * Headers @@ -125,7 +125,6 @@ static const uint8_t SCK = PIN_SPI_SCK; #define SX126X_TXEN RADIOLIB_NC #define SX126X_RXEN D7 -#define E22_TXEN_CONNECTED_TO_DIO2 // ------------------------------ OR ------------------------------ @@ -141,7 +140,8 @@ static const uint8_t SCK = PIN_SPI_SCK; #ifdef EBYTE_E22 // Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch // (which is the default for the sx1262interface code) -#define SX126X_E22 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #endif /* @@ -198,4 +198,4 @@ static const uint8_t SCL = PIN_WIRE_SCL; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif