From c1569b0f702e3f565f3920c8879914d45004f1e6 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Mon, 19 Aug 2024 10:03:40 -0700 Subject: [PATCH 001/252] add draft contributing.md file --- CONTRIBUTING.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..229166c4a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to Meshtastic Firmware + +We're excited that you're interested in contributing to the Meshtastic firmware! This document provides a high-level overview of how you can get involved. + +## Important First Steps + +Before you begin, please: + +1. **Read our documentation**: Our [official documentation](https://meshtastic.org/docs/) is a crucial resource. It contains essential information about the project, including setup guides, feature explanations, and contribution guidelines. + +2. **Check out the firmware build guide**: For specific instructions on setting up your development environment and building the firmware, refer to our [Firmware Build Guide](https://meshtastic.org/docs/development/firmware/build/). + +3. Read our [Code of Conduct](CODE_OF_CONDUCT.md) + +4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with other contributors and get help + +## Getting Help and Discussing Ideas + +We encourage open communication and discussion before diving into code changes: + +1. **Use GitHub Discussions**: For new ideas, questions, or to discuss potential changes, start a conversation in our [GitHub Discussions](https://github.com/meshtastic/firmware/discussions) first. This helps us collaborate and avoid duplicate work. + +2. **Join our Discord**: For real-time chat and quick questions, join our [Discord server](https://discord.com/invite/ktMAKGBnBs). It's a great place to get help and connect with the community. + +3. **Reporting Issues**: If you've identified a bug, please use our bug report template when creating a new issue in the [issue tracker](https://github.com/meshtastic/firmware/issues). Ensure you've searched existing issues to avoid duplicates. + +## Making Contributions + +1. Fork the repository +2. Create a new branch for your feature or bug fix +3. Make your changes +4. Test your changes thoroughly +5. Create a pull request with a clear description of your changes + +## Coding Standards + +[Placeholder for coding standards] + +Thank you for contributing to Meshtastic! \ No newline at end of file From 2a664e01b0c7a75b49ac1d4ab351ff42ba680707 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Mon, 19 Aug 2024 10:06:33 -0700 Subject: [PATCH 002/252] update code of conduct link --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 229166c4a..7d642f1f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ Before you begin, please: 2. **Check out the firmware build guide**: For specific instructions on setting up your development environment and building the firmware, refer to our [Firmware Build Guide](https://meshtastic.org/docs/development/firmware/build/). -3. Read our [Code of Conduct](CODE_OF_CONDUCT.md) +3. Read our [Code of Conduct](https://meshtastic.org/docs/legal/conduct/) 4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with other contributors and get help From 9d323a3832dae5264f9ef545c59a9e721a8bd108 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Mon, 19 Aug 2024 10:08:43 -0700 Subject: [PATCH 003/252] verbiage changes --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d642f1f5..f0976554f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ Before you begin, please: 3. Read our [Code of Conduct](https://meshtastic.org/docs/legal/conduct/) -4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with other contributors and get help +4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with developers and other contributors to get help. ## Getting Help and Discussing Ideas @@ -20,7 +20,7 @@ We encourage open communication and discussion before diving into code changes: 1. **Use GitHub Discussions**: For new ideas, questions, or to discuss potential changes, start a conversation in our [GitHub Discussions](https://github.com/meshtastic/firmware/discussions) first. This helps us collaborate and avoid duplicate work. -2. **Join our Discord**: For real-time chat and quick questions, join our [Discord server](https://discord.com/invite/ktMAKGBnBs). It's a great place to get help and connect with the community. +2. **Join our Discord**: For real-time chat and quick questions, join our [Discord server](https://discord.com/invite/ktMAKGBnBs). It's a great place to get help and connect with other developers and the community. 3. **Reporting Issues**: If you've identified a bug, please use our bug report template when creating a new issue in the [issue tracker](https://github.com/meshtastic/firmware/issues). Ensure you've searched existing issues to avoid duplicates. @@ -30,7 +30,7 @@ We encourage open communication and discussion before diving into code changes: 2. Create a new branch for your feature or bug fix 3. Make your changes 4. Test your changes thoroughly -5. Create a pull request with a clear description of your changes +5. Create a pull request with a clear description, using the provided template, of your changes ## Coding Standards From 33b12126e00b8bab1b66c5f0825d5f0d115ca3ef Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Mon, 19 Aug 2024 10:10:32 -0700 Subject: [PATCH 004/252] more verbiage --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0976554f..c4cdd3bcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ We're excited that you're interested in contributing to the Meshtastic firmware! Before you begin, please: -1. **Read our documentation**: Our [official documentation](https://meshtastic.org/docs/) is a crucial resource. It contains essential information about the project, including setup guides, feature explanations, and contribution guidelines. +1. **Read our documentation**: Our [official documentation](https://meshtastic.org/docs/) is a crucial resource. It contains essential information about the project. 2. **Check out the firmware build guide**: For specific instructions on setting up your development environment and building the firmware, refer to our [Firmware Build Guide](https://meshtastic.org/docs/development/firmware/build/). From 9014058935053416cdcfaf6133a8ad30f9510950 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Tue, 20 Aug 2024 13:09:39 -0700 Subject: [PATCH 005/252] add CLA admonition --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4cdd3bcb..ddcec12ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,6 +26,9 @@ We encourage open communication and discussion before diving into code changes: ## Making Contributions +> [!IMPORTANT] "Sign our CLA agreement" +> Before making any contributions, you must sign our Contributor License Agreement (CLA). You can do this by visiting https://cla-assistant.io/meshtastic/firmware. Be sure to use the GitHub account you will use to submit your contributions when signing. + 1. Fork the repository 2. Create a new branch for your feature or bug fix 3. Make your changes From ba771ae50707f1cc2327f54680504a66c42868a6 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Tue, 20 Aug 2024 13:11:03 -0700 Subject: [PATCH 006/252] fix --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ddcec12ba..736e2ba5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ We encourage open communication and discussion before diving into code changes: ## Making Contributions -> [!IMPORTANT] "Sign our CLA agreement" +> [!IMPORTANT] > Before making any contributions, you must sign our Contributor License Agreement (CLA). You can do this by visiting https://cla-assistant.io/meshtastic/firmware. Be sure to use the GitHub account you will use to submit your contributions when signing. 1. Fork the repository From bb9ddcf2b56dd113bec2077189920c13e83aaf71 Mon Sep 17 00:00:00 2001 From: gitbisector Date: Wed, 4 Sep 2024 06:31:30 -0700 Subject: [PATCH 007/252] Same priority packets processed in enqueue order (#4608) * Same priority packets processed in enqueue order * Prefer same prio pkts on mesh over new ones. --------- Co-authored-by: Ben Meadors --- src/mesh/MeshPacketQueue.cpp | 54 ++++++++++++++---------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/src/mesh/MeshPacketQueue.cpp b/src/mesh/MeshPacketQueue.cpp index 6581b1ce4..da49ecb61 100644 --- a/src/mesh/MeshPacketQueue.cpp +++ b/src/mesh/MeshPacketQueue.cpp @@ -1,4 +1,5 @@ #include "MeshPacketQueue.h" +#include "NodeDB.h" #include "configuration.h" #include @@ -16,13 +17,9 @@ bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_Mes { assert(p1 && p2); auto p1p = getPriority(p1), p2p = getPriority(p2); - // If priorities differ, use that - // for equal priorities, order by id (older packets have higher priority - this will briefly be wrong when IDs roll over but - // no big deal) - return (p1p != p2p) - ? (p1p < p2p) // prefer bigger priorities - : ((p1->id & ID_COUNTER_MASK) >= (p2->id & ID_COUNTER_MASK)); // Mask to counter portion, prefer smaller packet ids + // for equal priorities, prefer packets already on mesh. + return (p1p != p2p) ? (p1p > p2p) : (getFrom(p1) != nodeDB->getNodeNum() && getFrom(p2) == nodeDB->getNodeNum()); } MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {} @@ -69,8 +66,9 @@ bool MeshPacketQueue::enqueue(meshtastic_MeshPacket *p) return replaceLowerPriorityPacket(p); } - queue.push_back(p); - std::push_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); + // Find the correct position using upper_bound to maintain a stable order + auto it = std::upper_bound(queue.begin(), queue.end(), p, CompareMeshPacketFunc); + queue.insert(it, p); // Insert packet at the found position return true; } @@ -81,9 +79,7 @@ meshtastic_MeshPacket *MeshPacketQueue::dequeue() } auto *p = queue.front(); - std::pop_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); - queue.pop_back(); - + queue.erase(queue.begin()); // Remove the highest-priority packet return p; } @@ -104,7 +100,6 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id) auto p = (*it); if (getFrom(p) == from && p->id == id) { queue.erase(it); - std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); return p; } } @@ -115,28 +110,21 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id) /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p) { - std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127) - // find first packet which does not compare less (in priority) than parameter packet - auto low = std::lower_bound(queue.begin(), queue.end(), p, &CompareMeshPacketFunc); - - if (low == queue.begin()) { // if already at start, there are no packets with lower priority - return false; + if (queue.empty()) { + return false; // No packets to replace + } + // Check if the packet at the back has a lower priority than the new packet + auto &backPacket = queue.back(); + if (backPacket->priority < p->priority) { + // Remove the back packet + packetPool.release(backPacket); + queue.pop_back(); + // Insert the new packet in the correct order + enqueue(p); + return true; } - if (low == queue.end()) { - // all priorities in the vector are smaller than the incoming packet. Replace the lowest priority (first) element - low = queue.begin(); - } else { - // 'low' iterator points to first packet which does not compare less than parameter - --low; // iterate to lower priority packet - } - - if (getPriority(p) > getPriority(*low)) { - packetPool.release(*low); // deallocate and drop the packet we're replacing - *low = p; // replace low-pri packet at this position with incoming packet with higher priority - } - - std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); - return true; + // If the back packet's priority is not lower, no replacement occurs + return false; } \ No newline at end of file From 8d29ce939d458876087a20d0a2bd7e30161114a1 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Wed, 4 Sep 2024 15:27:00 -0700 Subject: [PATCH 008/252] changes from feedback --- CONTRIBUTING.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 736e2ba5b..d802c385e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,10 +33,15 @@ We encourage open communication and discussion before diving into code changes: 2. Create a new branch for your feature or bug fix 3. Make your changes 4. Test your changes thoroughly -5. Create a pull request with a clear description, using the provided template, of your changes +5. Create a pull request with a clear description, using the provided template, of your changes. Be sure to enable "Allow edits from maintainers". ## Coding Standards -[Placeholder for coding standards] +To ensure consistent code formatting across the project: -Thank you for contributing to Meshtastic! \ No newline at end of file +1. Install the [Trunk](https://marketplace.visualstudio.com/items?itemName=Trunk.io) extension for Visual Studio Code. +2. Before submitting your changes, run trunk fmt to automatically format your code according to our standards. + +Adhering to these formatting guidelines helps maintain code consistency and makes the review process smoother. + +Thank you for contributing to Meshtastic! From 4d57c99ad11b497fd00fed73ea66951542bff404 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Wed, 4 Sep 2024 15:28:17 -0700 Subject: [PATCH 009/252] add ticks --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d802c385e..a3659e2a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ We encourage open communication and discussion before diving into code changes: To ensure consistent code formatting across the project: 1. Install the [Trunk](https://marketplace.visualstudio.com/items?itemName=Trunk.io) extension for Visual Studio Code. -2. Before submitting your changes, run trunk fmt to automatically format your code according to our standards. +2. Before submitting your changes, run `trunk fmt` to automatically format your code according to our standards. Adhering to these formatting guidelines helps maintain code consistency and makes the review process smoother. From 1d3d44061b9885f49ce0444bf8e94149ce395709 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Wed, 4 Sep 2024 15:33:28 -0700 Subject: [PATCH 010/252] lol of course trunk fmt --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3659e2a9..f579a7fe0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ We encourage open communication and discussion before diving into code changes: 2. Create a new branch for your feature or bug fix 3. Make your changes 4. Test your changes thoroughly -5. Create a pull request with a clear description, using the provided template, of your changes. Be sure to enable "Allow edits from maintainers". +5. Create a pull request with a clear description, using the provided template, of your changes. Be sure to enable "Allow edits from maintainers". ## Coding Standards From 9e55e6befbfb9438204d4e35aeeb7797eceb98f8 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Thu, 5 Sep 2024 19:16:06 +0800 Subject: [PATCH 011/252] Minor GPS fixes (#4630) 1. Remove unused line in GPS::probe 2. update new PositionModule::hasQualityTimeSource to handle MESHTASTIC_EXCLUDE_GPS --- src/gps/GPS.cpp | 5 +---- src/modules/PositionModule.cpp | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 12ef34c52..da9b5b1a8 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1252,9 +1252,6 @@ GnssModel_t GPS::probe(int serialSpeed) LOG_INFO("Aioha AG3335 detected, using AG3335 Module\n"); return GNSS_MODEL_AG3335; } - // Get version information for Airoha AG3335 - clearBuffer(); - _serial_gps->write("$PMTK605*31\r\n"); // Get version information clearBuffer(); @@ -1843,4 +1840,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 7c08835bc..cb6a58b2e 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -146,7 +146,11 @@ bool PositionModule::hasQualityTimesource() { bool setFromPhoneOrNtpToday = lastSetFromPhoneNtpOrGps == 0 ? false : (millis() - lastSetFromPhoneNtpOrGps) <= (SEC_PER_DAY * 1000UL); +#if MESHTASTIC_EXCLUDE_GPS + bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address); +#else bool hasGpsOrRtc = (gps && gps->isConnected()) || (rtc_found.address != ScanI2C::ADDRESS_NONE.address); +#endif return hasGpsOrRtc || setFromPhoneOrNtpToday; } From 7c6454f171014106dbcd946ac81f493ab14b6aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 5 Sep 2024 22:49:08 +0200 Subject: [PATCH 012/252] bring 2.4G back in line with preset bandwidth (#4634) --- src/mesh/RadioInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index eacd49644..7b6b4f5fa 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -420,7 +420,7 @@ void RadioInterface::applyModemConfig() switch (loraConfig.modem_preset) { case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: - bw = (myRegion->wideLora) ? 812.5 : 500; + bw = (myRegion->wideLora) ? 1625.0 : 500; cr = 5; sf = 7; break; From 972a5d57798d9045500b3fc93d814b0156b16154 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:25:34 -0700 Subject: [PATCH 013/252] Update Pull Request Template --- .github/pull_request_template.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 512dea311..6ccb4a105 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,9 @@ +### ❌ (Please delete all these tips and replace them with your text) ❌ + ## Thank you for sending in a pull request, here's some tips to get started! -(Please delete all these tips and replace with your text) - - Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first - to say "hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback + to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... - Please do not check in files that don't have real changes - Please do not reformat lines that you didn't have to change the code on @@ -12,3 +12,4 @@ - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your other co-developers have comments on your PR please tweak as needed. - Please also enable "Allow edits by maintainers". +- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord From bcdc36c07c270b8a5394adcd6a430d89f2be6b3f Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Fri, 6 Sep 2024 11:25:41 +1200 Subject: [PATCH 014/252] Refresh E-Ink to show changes in GPS icon --- src/graphics/Screen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 04fe73e44..68fdba207 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1766,6 +1766,11 @@ void Screen::forceDisplay(bool forceUiUpdate) #ifdef USE_EINK // If requested, make sure queued commands are run, and UI has rendered a new frame if (forceUiUpdate) { + // Force a display refresh, in addition to the UI update + // Changing the GPS status bar icon apparently doesn't register as a change in image + // (False negative of the image hashing algorithm used to skip identical frames) + EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); + // No delay between UI frame rendering setFastFramerate(); From e4e1ea971f12e203180bbc42378916c0f3ebc493 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 6 Sep 2024 08:45:57 +0800 Subject: [PATCH 015/252] Add missing linefeeds to gps code As reported by @caveman99, the required CRLFs were missing from the AG3335 setup code. --- src/gps/GPS.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index da9b5b1a8..6e6228d03 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -507,19 +507,19 @@ bool GPS::setup() delay(250); } else if (gnssModel == GNSS_MODEL_AG3335) { - _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B"); // Enable GPS+GALILEO+NAVIC + _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC // Configure NMEA (sentences will output once per fix) - _serial_gps->write("$PAIR062,0,0*3F"); // GGA ON - _serial_gps->write("$PAIR062,1,0*3F"); // GLL OFF - _serial_gps->write("$PAIR062,2,1*3D"); // GSA ON - _serial_gps->write("$PAIR062,3,0*3D"); // GSV OFF - _serial_gps->write("$PAIR062,4,0*3B"); // RMC ON - _serial_gps->write("$PAIR062,5,0*3B"); // VTG OFF - _serial_gps->write("$PAIR062,6,1*39"); // ZDA ON + _serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON + _serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF + _serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON + _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF + _serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON + _serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF + _serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON delay(250); - _serial_gps->write("$PAIR513*3D"); // save configuration + _serial_gps->write("$PAIR513*3D\r\n"); // save configuration } else if (gnssModel == GNSS_MODEL_UBLOX) { // Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command) From 011e640e951ef8369c6d7da1f78be1258c1ae531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 6 Sep 2024 09:47:43 +0200 Subject: [PATCH 016/252] Add LR11x0 firmware version to init. --- src/mesh/LR11x0Interface.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index 8f0dc062e..c0742f241 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -104,6 +104,13 @@ template bool LR11x0Interface::init() if (res == RADIOLIB_ERR_CHIP_NOT_FOUND) return false; + LR11x0VersionInfo_t version; + res = lora.getVersionInfo(&version); + if (res == RADIOLIB_ERR_NONE) + LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d\n", version.device, version.hardware, + version.fwMajor, version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS, + version.almanacGNSS); + LOG_INFO("Frequency set to %f\n", getFreq()); LOG_INFO("Bandwidth set to %f\n", bw); LOG_INFO("Power output set to %d\n", power); From d72a836e072b9bc2183699f6bc62c2f113744e31 Mon Sep 17 00:00:00 2001 From: zerolint <179066619+zerolint@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:04:37 -0400 Subject: [PATCH 017/252] RAK13800 Ethernet improvements Fixes (#3618) by allowing more time for slower requests. Resolve Syslog not maintaining client causing issues on RAK13800. Resolve Ethernet static IP setting subnet as gateway IP. Reduce comment and log message ambiguity around API. Remove duplicate #if !MESHTASTIC_EXCLUDE_WEBSERVER block. --- src/DebugConfiguration.cpp | 4 +++- src/mesh/api/ServerAPI.cpp | 15 ++++++++++++++- src/mesh/api/ServerAPI.h | 6 +++++- src/mesh/api/ethServerAPI.h | 2 +- src/mesh/eth/ethClient.cpp | 7 ++++--- src/mesh/wifi/WiFiAPClient.cpp | 6 ++---- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/DebugConfiguration.cpp b/src/DebugConfiguration.cpp index 23b140daf..1c081ae29 100644 --- a/src/DebugConfiguration.cpp +++ b/src/DebugConfiguration.cpp @@ -97,12 +97,14 @@ Syslog &Syslog::logMask(uint8_t priMask) void Syslog::enable() { + this->_client->begin(this->_port); this->_enabled = true; } void Syslog::disable() { this->_enabled = false; + this->_client->stop(); } bool Syslog::isEnabled() @@ -193,4 +195,4 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess return true; } -#endif \ No newline at end of file +#endif diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 140567ad2..3a483aac1 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -5,7 +5,7 @@ template ServerAPI::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client) { - LOG_INFO("Incoming wifi connection\n"); + LOG_INFO("Incoming API connection\n"); } template ServerAPI::~ServerAPI() @@ -49,6 +49,16 @@ template int32_t APIServerPort::runOnce() if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { +#if RAK_4631 + // RAK13800 Ethernet requests periodically take more time + // This backoff addresses most cases keeping max wait < 1s + // Reconnections are delayed by full wait time + if (waitTime < 400) { + waitTime *= 2; + LOG_INFO("Previous TCP connection still open, trying again in %dms\n", waitTime); + return waitTime; + } +#endif LOG_INFO("Force closing previous TCP connection\n"); delete openAPI; } @@ -56,5 +66,8 @@ template int32_t APIServerPort::runOnce() openAPI = new T(client); } +#if RAK_4631 + waitTime = 100; +#endif return 100; // only check occasionally for incoming connections } diff --git a/src/mesh/api/ServerAPI.h b/src/mesh/api/ServerAPI.h index dd2a767c9..5b84fddd7 100644 --- a/src/mesh/api/ServerAPI.h +++ b/src/mesh/api/ServerAPI.h @@ -31,7 +31,7 @@ template class ServerAPI : public StreamAPI, private concurrency::OSTh }; /** - * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed + * Listens for incoming connections and does accepts and creates instances of ServerAPI as needed */ template class APIServerPort : public U, private concurrency::OSThread { @@ -41,6 +41,10 @@ template class APIServerPort : public U, private concurrency: * delegate to the worker. Once coroutines are implemented we can relax this restriction. */ T *openAPI = NULL; +#if RAK_4631 + // Track wait time for RAK13800 Ethernet requests + int32_t waitTime = 100; +#endif public: explicit APIServerPort(int port); diff --git a/src/mesh/api/ethServerAPI.h b/src/mesh/api/ethServerAPI.h index 59673a684..6f214c75a 100644 --- a/src/mesh/api/ethServerAPI.h +++ b/src/mesh/api/ethServerAPI.h @@ -14,7 +14,7 @@ class ethServerAPI : public ServerAPI }; /** - * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed + * Listens for incoming connections and does accepts and creates instances of EthernetServerAPI as needed */ class ethServerPort : public APIServerPort { diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp index 9f3bb8ab7..1c97f3bed 100644 --- a/src/mesh/eth/ethClient.cpp +++ b/src/mesh/eth/ethClient.cpp @@ -38,7 +38,7 @@ static int32_t reconnectETH() Ethernet.maintain(); if (!ethStartupComplete) { // Start web server - LOG_INFO("... Starting network services\n"); + LOG_INFO("Starting Ethernet network services\n"); #ifndef DISABLE_NTP LOG_INFO("Starting NTP time client\n"); @@ -131,7 +131,8 @@ bool initEthernet() status = Ethernet.begin(mac); } else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) { LOG_INFO("starting Ethernet Static\n"); - Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet); + Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway, + config.network.ipv4_config.subnet); status = 1; } else { LOG_INFO("Ethernet Disabled\n"); @@ -186,4 +187,4 @@ bool isEthernetAvailable() } } -#endif \ No newline at end of file +#endif diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index e733d1801..07b03222e 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -15,10 +15,8 @@ #include #ifdef ARCH_ESP32 #if !MESHTASTIC_EXCLUDE_WEBSERVER -#if !MESHTASTIC_EXCLUDE_WEBSERVER #include "mesh/http/WebServer.h" #endif -#endif #include #include static void WiFiEvent(WiFiEvent_t event); @@ -58,7 +56,7 @@ static void onNetworkConnected() { if (!APStartupComplete) { // Start web server - LOG_INFO("Starting network services\n"); + LOG_INFO("Starting WiFi network services\n"); #ifdef ARCH_ESP32 // start mdns @@ -422,4 +420,4 @@ uint8_t getWifiDisconnectReason() { return wifiDisconnectReason; } -#endif \ No newline at end of file +#endif From 8e0a342f065f8ecec55d67614e3c3d43fd8a6466 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Wed, 4 Sep 2024 06:20:26 -0400 Subject: [PATCH 018/252] Gather canned message magic numbers into header defines. --- src/input/LinuxInput.cpp | 5 ++-- src/input/SerialKeyboard.cpp | 3 ++- src/input/kbI2cBase.cpp | 40 +++++++++++++++-------------- src/modules/CannedMessageModule.cpp | 36 +++++++++++++------------- src/modules/CannedMessageModule.h | 14 ++++++++++ 5 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/input/LinuxInput.cpp b/src/input/LinuxInput.cpp index 6194195ed..d6bd4333b 100644 --- a/src/input/LinuxInput.cpp +++ b/src/input/LinuxInput.cpp @@ -1,6 +1,7 @@ #include "configuration.h" #if ARCH_PORTDUINO #include "LinuxInput.h" +#include "modules/CannedMessageModule.h" #include "platform/portduino/PortduinoGlue.h" #include #include @@ -147,11 +148,11 @@ int32_t LinuxInput::runOnce() case KEY_LEFT: // Left e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; break; - e.kbchar = 0xb4; + e.kbchar = CANNED_MESSAGE_KEY_LEFT; case KEY_RIGHT: // Right e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; break; - e.kbchar = 0xb7; + e.kbchar = CANNED_MESSAGE_KEY_RIGHT; case KEY_ENTER: // Enter e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; break; diff --git a/src/input/SerialKeyboard.cpp b/src/input/SerialKeyboard.cpp index fa3eb2528..e705ac550 100644 --- a/src/input/SerialKeyboard.cpp +++ b/src/input/SerialKeyboard.cpp @@ -1,5 +1,6 @@ #include "SerialKeyboard.h" #include "configuration.h" +#include "modules/CannedMessageModule.h" #ifdef INPUTBROKER_SERIAL_TYPE #define CANNED_MESSAGE_MODULE_ENABLE 1 // in case it's not set in the variant file @@ -87,7 +88,7 @@ int32_t SerialKeyboard::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; } else if (!(shiftRegister2 & (1 << 2))) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0xb7; + e.kbchar = CANNED_MESSAGE_KEY_RIGHT; } else if (!(shiftRegister2 & (1 << 1))) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; } else if (!(shiftRegister2 & (1 << 0))) { diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 024b16b9e..f9d9f4748 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -2,6 +2,7 @@ #include "configuration.h" #include "detect/ScanI2C.h" #include "detect/ScanI2CTwoWire.h" +#include "modules/CannedMessageModule.h" extern ScanI2C::DeviceAddress cardkb_found; extern uint8_t kb_model; @@ -94,7 +95,7 @@ int32_t KbI2cBase::runOnce() case 'e': // sym e if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + e.kbchar = CANNED_MESSAGE_KEY_UP; is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; @@ -104,7 +105,7 @@ int32_t KbI2cBase::runOnce() case 'x': // sym x if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + e.kbchar = CANNED_MESSAGE_KEY_DOWN; is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; @@ -134,8 +135,8 @@ int32_t KbI2cBase::runOnce() case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; e.inputEvent = ANYKEY; - e.kbchar = - is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active + e.kbchar = is_sym ? CANNED_MESSAGE_KEY_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that + : CANNED_MESSAGE_KEY_FN_SYMBOL_OFF; // the modifier key is active break; case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; @@ -214,7 +215,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = 0xac; // mute notifications + e.kbchar = CANNED_MESSAGE_KEY_MUTE_TOGGLE; // mute notifications } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -224,7 +225,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = 0x11; // Increase Brightness code + e.kbchar = CANNED_MESSAGE_KEY_BRIGHTNESS_UP; // Increase Brightness code } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -234,7 +235,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = 0x12; // Decrease Brightness code + e.kbchar = CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN; // Decrease Brightness code } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -244,7 +245,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = 0xaf; // (fn + space) + e.kbchar = CANNED_MESSAGE_KEY_SEND_PING; // (fn + space) } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -254,7 +255,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = 0x9e; + e.kbchar = CANNED_MESSAGE_KEY_GPS_TOGGLE; } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -269,32 +270,33 @@ int32_t KbI2cBase::runOnce() break; case 0xb5: // Up e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + e.kbchar = CANNED_MESSAGE_KEY_UP; break; case 0xb6: // Down e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + e.kbchar = CANNED_MESSAGE_KEY_DOWN; break; case 0xb4: // Left e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = 0xb4; + e.kbchar = CANNED_MESSAGE_KEY_LEFT; break; case 0xb7: // Right e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0xb7; + e.kbchar = CANNED_MESSAGE_KEY_RIGHT; break; case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker)) // toggle moddifiers button. is_sym = !is_sym; e.inputEvent = ANYKEY; - e.kbchar = is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active + e.kbchar = is_sym ? CANNED_MESSAGE_KEY_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that the + : CANNED_MESSAGE_KEY_FN_SYMBOL_OFF; // modifier key is active break; - case 0x90: // fn+r + case 0x90: // fn+r CANNED_MESSAGE_KEY_REBOOT case 0x91: // fn+t - case 0x9b: // fn+s - case 0xac: // fn+m - case 0x9e: // fn+g - case 0xaf: // fn+space + case 0x9b: // fn+s CANNED_MESSAGE_KEY_SHUTDOWN + case 0xac: // fn+m CANNED_MESSAGE_KEY_MUTE_TOGGLE + case 0x9e: // fn+g CANNED_MESSAGE_KEY_GPS_TOGGLE + case 0xaf: // fn+space CANNED_MESSAGE_KEY_SEND_PING // just pass those unmodified e.inputEvent = ANYKEY; e.kbchar = c; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 4df5a03fc..6f8739a01 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -190,17 +190,17 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) #if defined(T_WATCH_S3) || defined(RAK14014) if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { - this->payload = 0xb4; + this->payload = CANNED_MESSAGE_KEY_LEFT; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { - this->payload = 0xb7; + this->payload = CANNED_MESSAGE_KEY_RIGHT; } #else // 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; + this->payload = CANNED_MESSAGE_KEY_LEFT; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { - this->payload = 0xb7; + this->payload = CANNED_MESSAGE_KEY_RIGHT; } } else { // pass the pressed key @@ -222,26 +222,26 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) // Run modifier key code below, (doesnt inturrupt typing or reset to start screen page) switch (event->kbchar) { - case 0x11: // make screen brighter + case CANNED_MESSAGE_KEY_BRIGHTNESS_UP: // make screen brighter if (screen) screen->increaseBrightness(); LOG_DEBUG("increasing Screen Brightness\n"); break; - case 0x12: // make screen dimmer + case CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN: // make screen dimmer if (screen) screen->decreaseBrightness(); LOG_DEBUG("Decreasing Screen Brightness\n"); break; - case 0xf1: // draw modifier (function) symbal + case CANNED_MESSAGE_KEY_FN_SYMBOL_ON: // draw modifier (function) symbal if (screen) screen->setFunctionSymbal("Fn"); break; - case 0xf2: // remove modifier (function) symbal + case CANNED_MESSAGE_KEY_FN_SYMBOL_OFF: // remove modifier (function) symbal if (screen) screen->removeFunctionSymbal("Fn"); break; // mute (switch off/toggle) external notifications on fn+m - case 0xac: + case CANNED_MESSAGE_KEY_MUTE_TOGGLE: if (moduleConfig.external_notification.enabled == true) { if (externalNotificationModule->getMute()) { externalNotificationModule->setMute(false); @@ -257,7 +257,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) } } break; - case 0x9e: // toggle GPS like triple press does + case CANNED_MESSAGE_KEY_GPS_TOGGLE: // toggle GPS like triple press does #if !MESHTASTIC_EXCLUDE_GPS if (gps != nullptr) { gps->toggleGpsMode(); @@ -267,7 +267,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) showTemporaryMessage("GPS Toggled"); #endif break; - case 0xaf: // fn+space send network ping like double press does + case CANNED_MESSAGE_KEY_SEND_PING: // fn+space send network ping like double press does service->refreshLocalMeshNode(); if (service->trySendPosition(NODENUM_BROADCAST, true)) { showTemporaryMessage("Position \nUpdate Sent"); @@ -283,7 +283,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) validEvent = true; break; } - if (screen && (event->kbchar != 0xf1)) { + if (screen && (event->kbchar != CANNED_MESSAGE_KEY_FN_SYMBOL_ON)) { screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal } } @@ -505,7 +505,7 @@ int32_t CannedMessageModule::runOnce() } } else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { switch (this->payload) { - case 0xb4: // left + case CANNED_MESSAGE_KEY_LEFT: if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB->getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { @@ -540,7 +540,7 @@ int32_t CannedMessageModule::runOnce() } } break; - case 0xb7: // right + case CANNED_MESSAGE_KEY_RIGHT: if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB->getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { @@ -602,19 +602,19 @@ int32_t CannedMessageModule::runOnce() this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; } break; - case 0xb4: // left - case 0xb7: // right + case CANNED_MESSAGE_KEY_LEFT: + case CANNED_MESSAGE_KEY_RIGHT: // already handled above break; // handle fn+s for shutdown - case 0x9b: + case CANNED_MESSAGE_KEY_SHUTDOWN: if (screen) screen->startAlert("Shutting down..."); shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000; runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; break; // and fn+r for reboot - case 0x90: + case CANNED_MESSAGE_KEY_REBOOT: if (screen) screen->startAlert("Rebooting..."); rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000; diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 9e6af8890..9ff1ec192 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -43,6 +43,20 @@ struct Letter { #define CANNED_MESSAGE_MODULE_ENABLE 0 #endif +#define CANNED_MESSAGE_KEY_BRIGHTNESS_UP 0x11 +#define CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN 0x12 +#define CANNED_MESSAGE_KEY_REBOOT 0x90 +#define CANNED_MESSAGE_KEY_SHUTDOWN 0x9b +#define CANNED_MESSAGE_KEY_GPS_TOGGLE 0x9e +#define CANNED_MESSAGE_KEY_MUTE_TOGGLE 0xac +#define CANNED_MESSAGE_KEY_SEND_PING 0xaf +#define CANNED_MESSAGE_KEY_LEFT 0xb4 +#define CANNED_MESSAGE_KEY_UP 0xb5 +#define CANNED_MESSAGE_KEY_DOWN 0xb6 +#define CANNED_MESSAGE_KEY_RIGHT 0xb7 +#define CANNED_MESSAGE_KEY_FN_SYMBOL_ON 0xf1 +#define CANNED_MESSAGE_KEY_FN_SYMBOL_OFF 0xf2 + class CannedMessageModule : public SinglePortModule, public Observable, private concurrency::OSThread { CallbackObserver inputObserver = From 962d9ff2207dce18b6828d42acd1fb97889e1905 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Thu, 5 Sep 2024 22:32:24 -0400 Subject: [PATCH 019/252] Move defines to input broker --- src/input/InputBroker.h | 14 ++++++++++ src/input/LinuxInput.cpp | 5 ++-- src/input/SerialKeyboard.cpp | 3 +-- src/input/kbI2cBase.cpp | 41 ++++++++++++++--------------- src/modules/CannedMessageModule.cpp | 36 ++++++++++++------------- src/modules/CannedMessageModule.h | 16 +---------- 6 files changed, 56 insertions(+), 59 deletions(-) diff --git a/src/input/InputBroker.h b/src/input/InputBroker.h index 57c25af4b..082268f0a 100644 --- a/src/input/InputBroker.h +++ b/src/input/InputBroker.h @@ -4,6 +4,20 @@ #define ANYKEY 0xFF #define MATRIXKEY 0xFE +#define INPUT_BROKER_MSG_BRIGHTNESS_UP 0x11 +#define INPUT_BROKER_MSG_BRIGHTNESS_DOWN 0x12 +#define INPUT_BROKER_MSG_REBOOT 0x90 +#define INPUT_BROKER_MSG_SHUTDOWN 0x9b +#define INPUT_BROKER_MSG_GPS_TOGGLE 0x9e +#define INPUT_BROKER_MSG_MUTE_TOGGLE 0xac +#define INPUT_BROKER_MSG_SEND_PING 0xaf +#define INPUT_BROKER_MSG_LEFT 0xb4 +#define INPUT_BROKER_MSG_UP 0xb5 +#define INPUT_BROKER_MSG_DOWN 0xb6 +#define INPUT_BROKER_MSG_RIGHT 0xb7 +#define INPUT_BROKER_MSG_FN_SYMBOL_ON 0xf1 +#define INPUT_BROKER_MSG_FN_SYMBOL_OFF 0xf2 + typedef struct _InputEvent { const char *source; char inputEvent; diff --git a/src/input/LinuxInput.cpp b/src/input/LinuxInput.cpp index d6bd4333b..57a87b0ef 100644 --- a/src/input/LinuxInput.cpp +++ b/src/input/LinuxInput.cpp @@ -1,7 +1,6 @@ #include "configuration.h" #if ARCH_PORTDUINO #include "LinuxInput.h" -#include "modules/CannedMessageModule.h" #include "platform/portduino/PortduinoGlue.h" #include #include @@ -148,11 +147,11 @@ int32_t LinuxInput::runOnce() case KEY_LEFT: // Left e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; break; - e.kbchar = CANNED_MESSAGE_KEY_LEFT; + e.kbchar = INPUT_BROKER_MSG_LEFT; case KEY_RIGHT: // Right e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; break; - e.kbchar = CANNED_MESSAGE_KEY_RIGHT; + e.kbchar = INPUT_BROKER_MSG_RIGHT; case KEY_ENTER: // Enter e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; break; diff --git a/src/input/SerialKeyboard.cpp b/src/input/SerialKeyboard.cpp index e705ac550..7b7a2f3ec 100644 --- a/src/input/SerialKeyboard.cpp +++ b/src/input/SerialKeyboard.cpp @@ -1,6 +1,5 @@ #include "SerialKeyboard.h" #include "configuration.h" -#include "modules/CannedMessageModule.h" #ifdef INPUTBROKER_SERIAL_TYPE #define CANNED_MESSAGE_MODULE_ENABLE 1 // in case it's not set in the variant file @@ -88,7 +87,7 @@ int32_t SerialKeyboard::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; } else if (!(shiftRegister2 & (1 << 2))) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = CANNED_MESSAGE_KEY_RIGHT; + e.kbchar = INPUT_BROKER_MSG_RIGHT; } else if (!(shiftRegister2 & (1 << 1))) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; } else if (!(shiftRegister2 & (1 << 0))) { diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index f9d9f4748..2692fc80d 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -2,7 +2,6 @@ #include "configuration.h" #include "detect/ScanI2C.h" #include "detect/ScanI2CTwoWire.h" -#include "modules/CannedMessageModule.h" extern ScanI2C::DeviceAddress cardkb_found; extern uint8_t kb_model; @@ -95,7 +94,7 @@ int32_t KbI2cBase::runOnce() case 'e': // sym e if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = CANNED_MESSAGE_KEY_UP; + e.kbchar = INPUT_BROKER_MSG_UP; is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; @@ -105,7 +104,7 @@ int32_t KbI2cBase::runOnce() case 'x': // sym x if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = CANNED_MESSAGE_KEY_DOWN; + e.kbchar = INPUT_BROKER_MSG_DOWN; is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; @@ -135,8 +134,8 @@ int32_t KbI2cBase::runOnce() case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; e.inputEvent = ANYKEY; - e.kbchar = is_sym ? CANNED_MESSAGE_KEY_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that - : CANNED_MESSAGE_KEY_FN_SYMBOL_OFF; // the modifier key is active + e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that + : INPUT_BROKER_MSG_FN_SYMBOL_OFF; // the modifier key is active break; case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; @@ -215,7 +214,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = CANNED_MESSAGE_KEY_MUTE_TOGGLE; // mute notifications + e.kbchar = INPUT_BROKER_MSG_MUTE_TOGGLE; // mute notifications } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -225,7 +224,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = CANNED_MESSAGE_KEY_BRIGHTNESS_UP; // Increase Brightness code + e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_UP; // Increase Brightness code } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -235,7 +234,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN; // Decrease Brightness code + e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_DOWN; // Decrease Brightness code } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -245,7 +244,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = CANNED_MESSAGE_KEY_SEND_PING; // (fn + space) + e.kbchar = INPUT_BROKER_MSG_SEND_PING; // (fn + space) } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -255,7 +254,7 @@ int32_t KbI2cBase::runOnce() if (is_sym) { is_sym = false; e.inputEvent = ANYKEY; - e.kbchar = CANNED_MESSAGE_KEY_GPS_TOGGLE; + e.kbchar = INPUT_BROKER_MSG_GPS_TOGGLE; } else { e.inputEvent = ANYKEY; e.kbchar = c; @@ -270,33 +269,33 @@ int32_t KbI2cBase::runOnce() break; case 0xb5: // Up e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = CANNED_MESSAGE_KEY_UP; + e.kbchar = INPUT_BROKER_MSG_UP; break; case 0xb6: // Down e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = CANNED_MESSAGE_KEY_DOWN; + e.kbchar = INPUT_BROKER_MSG_DOWN; break; case 0xb4: // Left e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = CANNED_MESSAGE_KEY_LEFT; + e.kbchar = INPUT_BROKER_MSG_LEFT; break; case 0xb7: // Right e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = CANNED_MESSAGE_KEY_RIGHT; + e.kbchar = INPUT_BROKER_MSG_RIGHT; break; case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker)) // toggle moddifiers button. is_sym = !is_sym; e.inputEvent = ANYKEY; - e.kbchar = is_sym ? CANNED_MESSAGE_KEY_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that the - : CANNED_MESSAGE_KEY_FN_SYMBOL_OFF; // modifier key is active + e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that the + : INPUT_BROKER_MSG_FN_SYMBOL_OFF; // modifier key is active break; - case 0x90: // fn+r CANNED_MESSAGE_KEY_REBOOT + case 0x90: // fn+r INPUT_BROKER_MSG_REBOOT case 0x91: // fn+t - case 0x9b: // fn+s CANNED_MESSAGE_KEY_SHUTDOWN - case 0xac: // fn+m CANNED_MESSAGE_KEY_MUTE_TOGGLE - case 0x9e: // fn+g CANNED_MESSAGE_KEY_GPS_TOGGLE - case 0xaf: // fn+space CANNED_MESSAGE_KEY_SEND_PING + case 0x9b: // fn+s INPUT_BROKER_MSG_SHUTDOWN + case 0xac: // fn+m INPUT_BROKER_MSG_MUTE_TOGGLE + case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE + case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING // just pass those unmodified e.inputEvent = ANYKEY; e.kbchar = c; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 6f8739a01..87a3e8927 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -190,17 +190,17 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) #if defined(T_WATCH_S3) || defined(RAK14014) if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { - this->payload = CANNED_MESSAGE_KEY_LEFT; + this->payload = INPUT_BROKER_MSG_LEFT; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { - this->payload = CANNED_MESSAGE_KEY_RIGHT; + this->payload = INPUT_BROKER_MSG_RIGHT; } #else // 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 = CANNED_MESSAGE_KEY_LEFT; + this->payload = INPUT_BROKER_MSG_LEFT; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { - this->payload = CANNED_MESSAGE_KEY_RIGHT; + this->payload = INPUT_BROKER_MSG_RIGHT; } } else { // pass the pressed key @@ -222,26 +222,26 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) // Run modifier key code below, (doesnt inturrupt typing or reset to start screen page) switch (event->kbchar) { - case CANNED_MESSAGE_KEY_BRIGHTNESS_UP: // make screen brighter + case INPUT_BROKER_MSG_BRIGHTNESS_UP: // make screen brighter if (screen) screen->increaseBrightness(); LOG_DEBUG("increasing Screen Brightness\n"); break; - case CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN: // make screen dimmer + case INPUT_BROKER_MSG_BRIGHTNESS_DOWN: // make screen dimmer if (screen) screen->decreaseBrightness(); LOG_DEBUG("Decreasing Screen Brightness\n"); break; - case CANNED_MESSAGE_KEY_FN_SYMBOL_ON: // draw modifier (function) symbal + case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal if (screen) screen->setFunctionSymbal("Fn"); break; - case CANNED_MESSAGE_KEY_FN_SYMBOL_OFF: // remove modifier (function) symbal + case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal if (screen) screen->removeFunctionSymbal("Fn"); break; // mute (switch off/toggle) external notifications on fn+m - case CANNED_MESSAGE_KEY_MUTE_TOGGLE: + case INPUT_BROKER_MSG_MUTE_TOGGLE: if (moduleConfig.external_notification.enabled == true) { if (externalNotificationModule->getMute()) { externalNotificationModule->setMute(false); @@ -257,7 +257,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) } } break; - case CANNED_MESSAGE_KEY_GPS_TOGGLE: // toggle GPS like triple press does + case INPUT_BROKER_MSG_GPS_TOGGLE: // toggle GPS like triple press does #if !MESHTASTIC_EXCLUDE_GPS if (gps != nullptr) { gps->toggleGpsMode(); @@ -267,7 +267,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) showTemporaryMessage("GPS Toggled"); #endif break; - case CANNED_MESSAGE_KEY_SEND_PING: // fn+space send network ping like double press does + case INPUT_BROKER_MSG_SEND_PING: // fn+space send network ping like double press does service->refreshLocalMeshNode(); if (service->trySendPosition(NODENUM_BROADCAST, true)) { showTemporaryMessage("Position \nUpdate Sent"); @@ -283,7 +283,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) validEvent = true; break; } - if (screen && (event->kbchar != CANNED_MESSAGE_KEY_FN_SYMBOL_ON)) { + if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) { screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal } } @@ -505,7 +505,7 @@ int32_t CannedMessageModule::runOnce() } } else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { switch (this->payload) { - case CANNED_MESSAGE_KEY_LEFT: + case INPUT_BROKER_MSG_LEFT: if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB->getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { @@ -540,7 +540,7 @@ int32_t CannedMessageModule::runOnce() } } break; - case CANNED_MESSAGE_KEY_RIGHT: + case INPUT_BROKER_MSG_RIGHT: if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB->getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { @@ -602,19 +602,19 @@ int32_t CannedMessageModule::runOnce() this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; } break; - case CANNED_MESSAGE_KEY_LEFT: - case CANNED_MESSAGE_KEY_RIGHT: + case INPUT_BROKER_MSG_LEFT: + case INPUT_BROKER_MSG_RIGHT: // already handled above break; // handle fn+s for shutdown - case CANNED_MESSAGE_KEY_SHUTDOWN: + case INPUT_BROKER_MSG_SHUTDOWN: if (screen) screen->startAlert("Shutting down..."); shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000; runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; break; // and fn+r for reboot - case CANNED_MESSAGE_KEY_REBOOT: + case INPUT_BROKER_MSG_REBOOT: if (screen) screen->startAlert("Rebooting..."); rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000; diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 9ff1ec192..368574c40 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -43,20 +43,6 @@ struct Letter { #define CANNED_MESSAGE_MODULE_ENABLE 0 #endif -#define CANNED_MESSAGE_KEY_BRIGHTNESS_UP 0x11 -#define CANNED_MESSAGE_KEY_BRIGHTNESS_DOWN 0x12 -#define CANNED_MESSAGE_KEY_REBOOT 0x90 -#define CANNED_MESSAGE_KEY_SHUTDOWN 0x9b -#define CANNED_MESSAGE_KEY_GPS_TOGGLE 0x9e -#define CANNED_MESSAGE_KEY_MUTE_TOGGLE 0xac -#define CANNED_MESSAGE_KEY_SEND_PING 0xaf -#define CANNED_MESSAGE_KEY_LEFT 0xb4 -#define CANNED_MESSAGE_KEY_UP 0xb5 -#define CANNED_MESSAGE_KEY_DOWN 0xb6 -#define CANNED_MESSAGE_KEY_RIGHT 0xb7 -#define CANNED_MESSAGE_KEY_FN_SYMBOL_ON 0xf1 -#define CANNED_MESSAGE_KEY_FN_SYMBOL_OFF 0xf2 - class CannedMessageModule : public SinglePortModule, public Observable, private concurrency::OSThread { CallbackObserver inputObserver = @@ -237,4 +223,4 @@ class CannedMessageModule : public SinglePortModule, public Observable Date: Fri, 6 Sep 2024 13:55:56 +0200 Subject: [PATCH 020/252] tryfix #4384 (#4642) * tryfix #4384 - don't assume we want that functionality if the Accelerometer was found. This is only for T-Watch * Add config.display.wake_on_tap_or_motion default to RAK --------- Co-authored-by: Ben Meadors --- src/main.cpp | 2 -- src/mesh/NodeDB.cpp | 5 ++++- src/modules/AdminModule.cpp | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e7261c5fa..83758d5ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -635,8 +635,6 @@ void setup() #if !MESHTASTIC_EXCLUDE_I2C #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR if (acc_info.type != ScanI2C::DeviceType::NONE) { - config.display.wake_on_tap_or_motion = true; - moduleConfig.external_notification.enabled = true; accelerometerThread = new AccelerometerThread(acc_info.type); } #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index fa3667f32..6613ad3c3 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -362,6 +362,9 @@ void NodeDB::installDefaultConfig() #ifdef DISPLAY_FLIP_SCREEN config.display.flip_screen = true; #endif +#ifdef RAK4630 + config.display.wake_on_tap_or_motion = true; +#endif #ifdef T_WATCH_S3 config.display.screen_on_secs = 30; config.display.wake_on_tap_or_motion = true; @@ -1190,4 +1193,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co LOG_ERROR("A critical failure occurred, portduino is exiting..."); exit(2); #endif -} \ No newline at end of file +} diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index bfe3a9ba5..d88f17a86 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -406,7 +406,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) LOG_INFO("Setting config: Device\n"); config.has_device = true; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true) { + if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true && + accelerometerThread->enabled == false) { accelerometerThread->start(); } #endif @@ -484,7 +485,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) requiresReboot = false; } #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true) { + if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true && + accelerometerThread->enabled == false) { accelerometerThread->start(); } #endif From b8cee51e84ed967e3cdfd1b22d00dbc7274991b0 Mon Sep 17 00:00:00 2001 From: caveman99 <25002+caveman99@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:27:28 +0000 Subject: [PATCH 021/252] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/apponly.pb.h | 2 +- src/mesh/generated/meshtastic/config.pb.h | 12 ++++++++---- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 15 ++++++++++----- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/protobufs b/protobufs index 5f7c91adb..96b10c036 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 5f7c91adb97187e0cb2140de7057344d93444bd1 +Subproject commit 96b10c0364c3f13940df30ddabc74488ff1ba76e diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h index f5bacea52..31211a91b 100644 --- a/src/mesh/generated/meshtastic/apponly.pb.h +++ b/src/mesh/generated/meshtastic/apponly.pb.h @@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size -#define meshtastic_ChannelSet_size 676 +#define meshtastic_ChannelSet_size 679 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index eb03ddc58..66ffa0a4b 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -510,6 +510,8 @@ typedef struct _meshtastic_Config_LoRaConfig { uint32_t ignore_incoming[3]; /* If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. */ bool ignore_mqtt; + /* Sets the ok_to_mqtt bit on outgoing packets */ + bool config_ok_to_mqtt; } meshtastic_Config_LoRaConfig; typedef struct _meshtastic_Config_BluetoothConfig { @@ -656,7 +658,7 @@ extern "C" { #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} #define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} -#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, 0}, 0} +#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, 0}, 0, 0} #define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} #define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_default {0} @@ -667,7 +669,7 @@ extern "C" { #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} #define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} -#define meshtastic_Config_LoRaConfig_init_zero {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, 0}, 0} +#define meshtastic_Config_LoRaConfig_init_zero {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, 0}, 0, 0} #define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} #define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_zero {0} @@ -746,6 +748,7 @@ extern "C" { #define meshtastic_Config_LoRaConfig_pa_fan_disabled_tag 15 #define meshtastic_Config_LoRaConfig_ignore_incoming_tag 103 #define meshtastic_Config_LoRaConfig_ignore_mqtt_tag 104 +#define meshtastic_Config_LoRaConfig_config_ok_to_mqtt_tag 105 #define meshtastic_Config_BluetoothConfig_enabled_tag 1 #define meshtastic_Config_BluetoothConfig_mode_tag 2 #define meshtastic_Config_BluetoothConfig_fixed_pin_tag 3 @@ -887,7 +890,8 @@ X(a, STATIC, SINGULAR, BOOL, sx126x_rx_boosted_gain, 13) \ X(a, STATIC, SINGULAR, FLOAT, override_frequency, 14) \ X(a, STATIC, SINGULAR, BOOL, pa_fan_disabled, 15) \ X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \ -X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) +X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) \ +X(a, STATIC, SINGULAR, BOOL, config_ok_to_mqtt, 105) #define meshtastic_Config_LoRaConfig_CALLBACK NULL #define meshtastic_Config_LoRaConfig_DEFAULT NULL @@ -944,7 +948,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; #define meshtastic_Config_BluetoothConfig_size 10 #define meshtastic_Config_DeviceConfig_size 98 #define meshtastic_Config_DisplayConfig_size 30 -#define meshtastic_Config_LoRaConfig_size 82 +#define meshtastic_Config_LoRaConfig_size 85 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 #define meshtastic_Config_NetworkConfig_size 196 #define meshtastic_Config_PositionConfig_size 62 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 692402210..209084220 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -358,7 +358,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size #define meshtastic_ChannelFile_size 718 #define meshtastic_NodeInfoLite_size 183 -#define meshtastic_OEMStore_size 3497 +#define meshtastic_OEMStore_size 3500 #define meshtastic_PositionLite_size 28 #define meshtastic_UserLite_size 96 diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 91a23dc4f..72f29500c 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size -#define meshtastic_LocalConfig_size 664 +#define meshtastic_LocalConfig_size 667 #define meshtastic_LocalModuleConfig_size 687 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 9d7ff74a1..053b69a77 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -580,6 +580,9 @@ typedef struct _meshtastic_Data { /* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving a message a heart or poop emoji. */ uint32_t emoji; + /* Defaults to false. Indicates the user approves the packet being uploaded to MQTT. */ + bool has_ok_to_mqtt; + bool ok_to_mqtt; } meshtastic_Data; /* Waypoint message, used to share arbitrary locations across the mesh */ @@ -1082,7 +1085,7 @@ extern "C" { #define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}} #define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}} -#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0} +#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} @@ -1107,7 +1110,7 @@ extern "C" { #define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}} #define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}} -#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0} +#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} @@ -1176,6 +1179,7 @@ extern "C" { #define meshtastic_Data_request_id_tag 6 #define meshtastic_Data_reply_id_tag 7 #define meshtastic_Data_emoji_tag 8 +#define meshtastic_Data_ok_to_mqtt_tag 9 #define meshtastic_Waypoint_id_tag 1 #define meshtastic_Waypoint_latitude_i_tag 2 #define meshtastic_Waypoint_longitude_i_tag 3 @@ -1351,7 +1355,8 @@ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \ X(a, STATIC, SINGULAR, FIXED32, source, 5) \ X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \ X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \ -X(a, STATIC, SINGULAR, FIXED32, emoji, 8) +X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \ +X(a, STATIC, OPTIONAL, BOOL, ok_to_mqtt, 9) #define meshtastic_Data_CALLBACK NULL #define meshtastic_Data_DEFAULT NULL @@ -1629,13 +1634,13 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; #define meshtastic_ChunkedPayload_size 245 #define meshtastic_ClientNotification_size 415 #define meshtastic_Compressed_size 243 -#define meshtastic_Data_size 270 +#define meshtastic_Data_size 272 #define meshtastic_DeviceMetadata_size 46 #define meshtastic_FileInfo_size 236 #define meshtastic_FromRadio_size 510 #define meshtastic_Heartbeat_size 0 #define meshtastic_LogRecord_size 426 -#define meshtastic_MeshPacket_size 364 +#define meshtastic_MeshPacket_size 366 #define meshtastic_MqttClientProxyMessage_size 501 #define meshtastic_MyNodeInfo_size 18 #define meshtastic_NeighborInfo_size 258 From c77b89d85c836a9ec2b2d0302c98eb88abcefe3b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:51:22 -0500 Subject: [PATCH 022/252] [create-pull-request] automated change (#4645) --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/protobufs b/protobufs index 96b10c036..0acaec6ef 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 96b10c0364c3f13940df30ddabc74488ff1ba76e +Subproject commit 0acaec6eff00e748beeae89148093221f131cd9c diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 053b69a77..948e89f22 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -580,9 +580,9 @@ typedef struct _meshtastic_Data { /* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving a message a heart or poop emoji. */ uint32_t emoji; - /* Defaults to false. Indicates the user approves the packet being uploaded to MQTT. */ - bool has_ok_to_mqtt; - bool ok_to_mqtt; + /* Bitfield for extra flags. First use is to indicate that user approves the packet being uploaded to MQTT. */ + bool has_bitfield; + uint8_t bitfield; } meshtastic_Data; /* Waypoint message, used to share arbitrary locations across the mesh */ @@ -1179,7 +1179,7 @@ extern "C" { #define meshtastic_Data_request_id_tag 6 #define meshtastic_Data_reply_id_tag 7 #define meshtastic_Data_emoji_tag 8 -#define meshtastic_Data_ok_to_mqtt_tag 9 +#define meshtastic_Data_bitfield_tag 9 #define meshtastic_Waypoint_id_tag 1 #define meshtastic_Waypoint_latitude_i_tag 2 #define meshtastic_Waypoint_longitude_i_tag 3 @@ -1356,7 +1356,7 @@ X(a, STATIC, SINGULAR, FIXED32, source, 5) \ X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \ X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \ X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \ -X(a, STATIC, OPTIONAL, BOOL, ok_to_mqtt, 9) +X(a, STATIC, OPTIONAL, UINT32, bitfield, 9) #define meshtastic_Data_CALLBACK NULL #define meshtastic_Data_DEFAULT NULL @@ -1634,13 +1634,13 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; #define meshtastic_ChunkedPayload_size 245 #define meshtastic_ClientNotification_size 415 #define meshtastic_Compressed_size 243 -#define meshtastic_Data_size 272 +#define meshtastic_Data_size 273 #define meshtastic_DeviceMetadata_size 46 #define meshtastic_FileInfo_size 236 #define meshtastic_FromRadio_size 510 #define meshtastic_Heartbeat_size 0 #define meshtastic_LogRecord_size 426 -#define meshtastic_MeshPacket_size 366 +#define meshtastic_MeshPacket_size 367 #define meshtastic_MqttClientProxyMessage_size 501 #define meshtastic_MyNodeInfo_size 18 #define meshtastic_NeighborInfo_size 258 From 2f2ddae12a7a41ce13d97c1486833f25cf0cb267 Mon Sep 17 00:00:00 2001 From: git bisector Date: Fri, 6 Sep 2024 17:19:53 -0700 Subject: [PATCH 023/252] Report PWD when no battery present. --- src/modules/Telemetry/DeviceTelemetry.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index f22685d43..305be9904 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -100,8 +100,9 @@ meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry() #if ARCH_PORTDUINO t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL; #else - t.variant.device_metrics.battery_level = - powerStatus->getIsCharging() ? MAGIC_USB_BATTERY_LEVEL : powerStatus->getBatteryChargePercent(); + t.variant.device_metrics.battery_level = (!powerStatus->getHasBattery() || powerStatus->getIsCharging()) + ? MAGIC_USB_BATTERY_LEVEL + : powerStatus->getBatteryChargePercent(); #endif t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent(); t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0; From ba28ffb65ab5bc40fe7c89a4a8d3da48e2ae40db Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sat, 7 Sep 2024 11:59:45 +0800 Subject: [PATCH 024/252] Simplify GNSS Probe code This patch takes inspiration from our I2CDetect code where we have many sensors that can be detected rather simply. It creates a new macro, PROBE_SIMPLE(Chip name, Command to run, response, Driver, timeout) and converts existing simple cases to use this macro. --- src/gps/GPS.cpp | 76 +++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 6e6228d03..b5e1991ae 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1184,6 +1184,15 @@ int GPS::prepareDeepSleep(void *unused) return 0; } +#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \ + LOG_DEBUG("Trying " TOWRITE " (" CHIP ") ...\n"); \ + clearBuffer(); \ + _serial_gps->write(TOWRITE "\r\n"); \ + if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \ + LOG_INFO(CHIP " detected, using " #DRIVER " Module\n"); \ + return DRIVER; \ + } + GnssModel_t GPS::probe(int serialSpeed) { #if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) || defined(ARCH_STM32WL) @@ -1198,11 +1207,7 @@ GnssModel_t GPS::probe(int serialSpeed) #ifdef GNSS_AIROHA return GNSS_MODEL_AG3335; #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}; delay(100); @@ -1211,67 +1216,24 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n"); delay(20); - // get version information from Unicore UFirebirdII Series - // Works for: UC6580, UM620, UM621, UM670A, UM680A, or UM681A - _serial_gps->write("$PDTINFO\r\n"); - delay(750); - if (getACK("UC6580", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("UC6580 detected, using UC6580 Module\n"); - return GNSS_MODEL_UC6580; - } - - clearBuffer(); - _serial_gps->write("$PDTINFO\r\n"); - delay(750); - if (getACK("UM600", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("UM600 detected, using UC6580 Module\n"); - return GNSS_MODEL_UC6580; - } - - // Get version information for ATGM336H - clearBuffer(); - _serial_gps->write("$PCAS06,1*1A\r\n"); - if (getACK("$GPTXT,01,01,02,HW=ATGM336H", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("ATGM336H GNSS init succeeded, using ATGM336H Module\n"); - return GNSS_MODEL_ATGM336H; - } - + // Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A + PROBE_SIMPLE("UC6580", "$PDTINFO", "UC6580", GNSS_MODEL_UC6580, 500); + PROBE_SIMPLE("UM600", "$PDTINFO", "UM600", GNSS_MODEL_UC6580, 500); + PROBE_SIMPLE("ATGM336H", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H, 500); /* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS)) based on AT6558 */ - clearBuffer(); - _serial_gps->write("$PCAS06,1*1A\r\n"); - if (getACK("$GPTXT,01,01,02,HW=ATGM332D", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("ATGM332D detected, using ATGM336H Module\n"); - return GNSS_MODEL_ATGM336H; - } + PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500); /* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */ - clearBuffer(); - _serial_gps->write("PAIR020*38\r\n"); - if (getACK("$PAIR020,AG3335", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("Aioha AG3335 detected, using AG3335 Module\n"); - return GNSS_MODEL_AG3335; - } + PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500); - // Get version information - clearBuffer(); - _serial_gps->write("$PCAS06,0*1B\r\n"); - 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; - } + PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500); // Close all NMEA sentences, valid for L76B MTK platform (Waveshare Pico GPS) _serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n"); delay(20); - // Get version information - clearBuffer(); - _serial_gps->write("$PMTK605*31\r\n"); - if (getACK("Quectel-L76B", 500) == GNSS_RESPONSE_OK) { - LOG_INFO("L76B GNSS init succeeded, using L76B GNSS Module\n"); - return GNSS_MODEL_MTK_L76B; - } + PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500); uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; UBXChecksum(cfg_rate, sizeof(cfg_rate)); @@ -1840,4 +1802,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS +#endif // Exclude GPS \ No newline at end of file From bf343290331cf7b007d5a1111d78ac24d2105779 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 7 Sep 2024 18:21:59 -0500 Subject: [PATCH 025/252] Adds the data bitfield and ok_to_mqtt bit (#4643) * Don't filter PKI packets just for being encrypted. * Add ok_to_mqtt config and bit * Bitfield * Adjust dontmqttmebro logic. * Manipulate bitfield only in router.cpp * Want_ack is not want_response * Bitfield macros * Use new Bitfield macro in MQTT.cpp --------- Co-authored-by: Ben Meadors --- src/mesh/Channels.cpp | 4 ---- src/mesh/Channels.h | 10 +++++++++- src/mesh/NodeDB.cpp | 1 + src/mesh/Router.cpp | 8 ++++++++ src/mesh/Router.h | 5 +++++ src/mqtt/MQTT.cpp | 35 +++++++++++++++++++++++------------ 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index bba7571d2..47c013443 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -13,10 +13,6 @@ #include "mqtt/MQTT.h" #endif -/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128) -static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, - 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}; - Channels channels; const char *Channels::adminChannel = "admin"; diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h index 4f87cb309..e5a750f71 100644 --- a/src/mesh/Channels.h +++ b/src/mesh/Channels.h @@ -129,4 +129,12 @@ class Channels }; /// Singleton channel table -extern Channels channels; \ No newline at end of file +extern Channels channels; + +/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128) +static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, + 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}; + +static const uint8_t eventpsk[] = {0x38, 0x4b, 0xbc, 0xc0, 0x1d, 0xc0, 0x22, 0xd1, 0x81, 0xbf, 0x36, + 0xb8, 0x61, 0x21, 0xe1, 0xfb, 0x96, 0xb7, 0x2e, 0x55, 0xbf, 0x74, + 0x22, 0x7e, 0x9d, 0x6a, 0xfb, 0x48, 0xd6, 0x4c, 0xb1, 0xa1}; \ No newline at end of file diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 6613ad3c3..06180310a 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -285,6 +285,7 @@ void NodeDB::installDefaultConfig() config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off) config.lora.override_duty_cycle = false; + config.lora.config_ok_to_mqtt = false; #ifdef CONFIG_LORA_REGION_USERPREFS config.lora.region = CONFIG_LORA_REGION_USERPREFS; #else diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index d8e578db1..b222872fa 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -378,6 +378,8 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // parsing was successful p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded p->channel = chIndex; // change to store the index instead of the hash + if (p->decoded.has_bitfield) + p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK; /* Not actually ever used. // Decompress if needed. jm @@ -424,6 +426,12 @@ 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) { + if (p->from == nodeDB->getNodeNum()) { + p->decoded.has_bitfield = true; + p->decoded.bitfield |= (config.lora.config_ok_to_mqtt << BITFIELD_OK_TO_MQTT_SHIFT); + p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT); + } + size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); /* Not actually used, so save the cycles diff --git a/src/mesh/Router.h b/src/mesh/Router.h index 98486745b..fd4b0ccf9 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -148,3 +148,8 @@ extern Router *router; /// Generate a unique packet id // FIXME, move this someplace better PacketId generatePacketId(); + +#define BITFIELD_WANT_RESPONSE_SHIFT 1 +#define BITFIELD_OK_TO_MQTT_SHIFT 0 +#define BITFIELD_WANT_RESPONSE_MASK (1 << BITFIELD_WANT_RESPONSE_SHIFT) +#define BITFIELD_OK_TO_MQTT_MASK (1 << BITFIELD_OK_TO_MQTT_SHIFT) \ No newline at end of file diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 797fc7dc3..d14c7a923 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -514,19 +514,29 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & return; // no channels have an uplink enabled auto &ch = channels.getByIndex(chIndex); - if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { - LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n"); - return; - } + if (!mp.pki_encrypted) { + if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { + LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n"); + return; + } - if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 && - (mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || - mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) { - LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n"); - return; - } + // check for the lowest bit of the data bitfield set false, and the use of one of the default keys. + if (mp_decoded.from != nodeDB->getNodeNum() && mp_decoded.decoded.has_bitfield && + !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) && + (ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) || + (ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) { + LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag\n"); + return; + } - if (ch.settings.uplink_enabled || mp.pki_encrypted) { + if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 && + (mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || + mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) { + LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n"); + return; + } + } + if (mp.pki_encrypted || ch.settings.uplink_enabled) { const char *channelId = mp.pki_encrypted ? "PKI" : channels.getGlobalId(chIndex); meshtastic_ServiceEnvelope *env = mqttPool.allocZeroed(); @@ -537,7 +547,8 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & if (moduleConfig.mqtt.encryption_enabled) { env->packet = (meshtastic_MeshPacket *)∓ LOG_DEBUG("encrypted message\n"); - } else { + } else if (mp_decoded.which_payload_variant == + meshtastic_MeshPacket_decoded_tag) { // Don't upload a still-encrypted PKI packet env->packet = (meshtastic_MeshPacket *)&mp_decoded; LOG_DEBUG("portnum %i message\n", env->packet->decoded.portnum); } From e470619e3d86f6c1d8caacda43dd9d8951b5b7d4 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 9 Sep 2024 01:33:56 +0800 Subject: [PATCH 026/252] Remove undefined declaration (#4652) The getNMEA method was introduced to the header but never defined in code. As it's unused, remove it. --- src/gps/GPS.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gps/GPS.h b/src/gps/GPS.h index c0e9fb8b6..87607851c 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -297,7 +297,6 @@ class GPS : private concurrency::OSThread virtual int32_t runOnce() override; // Get GNSS model - String getNMEA(); GnssModel_t probe(int serialSpeed); // delay counter to allow more sats before fixed position stops GPS thread @@ -310,4 +309,4 @@ class GPS : private concurrency::OSThread }; extern GPS *gps; -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS From 6217e97c4168cf1e1b7304ba24a430b723ca9098 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 8 Sep 2024 09:09:01 +0800 Subject: [PATCH 027/252] Add support for AG3352 and fix AG3335 support AG33352 is a Mediatek/Airoha GPS/GLONASS/Galileo/BeiDou receiver. Patch adds relevant detection and setup code. Thanks to Bluebrolly and kongduino for providing the relevant information and testing. This patch also fixes support for the A3335, which is a related chip. The setup and detection code now works as tested on a real life T-1000E! Thanks to @gpsfan for the guidance. --- src/gps/GPS.cpp | 22 ++++++++++++---------- src/gps/GPS.h | 5 +++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index b5e1991ae..7e5207f5e 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -505,18 +505,18 @@ bool GPS::setup() delay(250); _serial_gps->write("$CFGMSG,6,1,0\r\n"); delay(250); - } else if (gnssModel == GNSS_MODEL_AG3335) { + } else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) { _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC // Configure NMEA (sentences will output once per fix) - _serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON + _serial_gps->write("$PAIR062,0,1*3F\r\n"); // GGA ON _serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF - _serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON + _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF - _serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON + _serial_gps->write("$PAIR062,4,1*3B\r\n"); // RMC ON _serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF - _serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON + _serial_gps->write("$PAIR062,6,0*38\r\n"); // ZDA ON delay(250); _serial_gps->write("$PAIR513*3D\r\n"); // save configuration @@ -1204,9 +1204,6 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->updateBaudRate(serialSpeed); } #endif -#ifdef GNSS_AIROHA - return GNSS_MODEL_AG3335; -#endif memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); uint8_t buffer[768] = {0}; @@ -1225,7 +1222,12 @@ GnssModel_t GPS::probe(int serialSpeed) PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500); /* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */ - PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500); + _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume + _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume + _serial_gps->write("$PAIR513*3D\r\n"); // save configuration + PROBE_SIMPLE("AG3335", "$PAIR021*39", "$PAIR021,AG3335", GNSS_MODEL_AG3335, 500); + PROBE_SIMPLE("AG3352", "$PAIR021*39", "$PAIR021,AG3352", GNSS_MODEL_AG3352, 500); + PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500); PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500); @@ -1802,4 +1804,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS diff --git a/src/gps/GPS.h b/src/gps/GPS.h index c0e9fb8b6..c2e660a49 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -30,7 +30,8 @@ typedef enum { GNSS_MODEL_UC6580, GNSS_MODEL_UNKNOWN, GNSS_MODEL_MTK_L76B, - GNSS_MODEL_AG3335 + GNSS_MODEL_AG3335, + GNSS_MODEL_AG3352 } GnssModel_t; typedef enum { @@ -310,4 +311,4 @@ class GPS : private concurrency::OSThread }; extern GPS *gps; -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS From ebe1b40bee4e7d4bcb332e91a5cb7f072ed2f662 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 9 Sep 2024 09:28:04 +0800 Subject: [PATCH 028/252] If GPS sleepTime is Zero, don't sleep. At the moment if the result of sleepTime calculations comes out to zero, we put the GPS into HARDSLEEP (losing all its status) and then immediately make it ACTIVE again. This patch avoids that toga. fixes https://github.com/meshtastic/firmware/issues/4657 --- 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 b5e1991ae..46c76c4ae 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1019,7 +1019,7 @@ void GPS::down() LOG_DEBUG("%us until next search\n", sleepTime / 1000); // If update interval less than 10 seconds, no attempt to sleep - if (updateInterval <= 10 * 1000UL) + if (updateInterval <= 10 * 1000UL || sleepTime == 0) setPowerState(GPS_IDLE); else { From fabd6b0d6fbd6781d80207167a99683fe38d943b Mon Sep 17 00:00:00 2001 From: thebentern <9000580+thebentern@users.noreply.github.com> Date: Mon, 9 Sep 2024 02:54:25 +0000 Subject: [PATCH 029/252] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 95d3d2538..69c478482 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 0 +build = 1 From dacb452d47859db93ca8d3e90732ac8cf2437b01 Mon Sep 17 00:00:00 2001 From: David <2941290+dhskinner@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:16:58 +1000 Subject: [PATCH 030/252] Bugfix (#4660) --- src/input/cardKbI2cImpl.cpp | 4 ++-- .../heltec_wireless_tracker/variant.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 1bff49475..8aaebcb45 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -9,7 +9,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {} void CardKbI2cImpl::init() { -#ifndef ARCH_PORTDUINO +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) if (cardkb_found.address == 0x00) { LOG_DEBUG("Rescanning for I2C keyboard\n"); uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR}; @@ -57,4 +57,4 @@ void CardKbI2cImpl::init() } #endif inputBroker->registerSource(this); -} +} \ No newline at end of file diff --git a/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp index 84264ef58..0a19a9c3b 100644 --- a/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp +++ b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp @@ -10,10 +10,14 @@ void lateInitVariant() { // LOG_DEBUG("Heltec tracker initVariant\n"); -#ifdef VEXT_ENABLE - GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE); - GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin(); +#ifndef MESHTASTIC_EXCLUDE_GPS + GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin(); +#else + GpioVirtPin *virtGpsEnable = new GpioVirtPin(); +#endif + +#ifndef MESHTASTIC_EXCLUDE_SCREEN // On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the // display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed. GpioVirtPin *virtScreenEnable = new GpioVirtPin(); @@ -25,8 +29,11 @@ void lateInitVariant() // Assume screen is initially powered splitter->set(true); } +#endif +#if defined(VEXT_ENABLE) && (!defined(MESHTASTIC_EXCLUDE_GPS) || !defined(MESHTASTIC_EXCLUDE_SCREEN)) // If either the GPS or the screen is on, turn on the external power regulator + GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE); new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or); #endif } From e9d55de3cb7e5b028a33b82146394d948a1d73ce Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 9 Sep 2024 20:54:11 +0800 Subject: [PATCH 031/252] Fix out-of-bound array access in T1000X Sensor (#4663) if u8i == 135, then u8i++ runs, the loop exits since u8i == 136, then value for u8i is 136 after the for loop. then in the next line, ntc_res2[u8i] will read past the end of the array --- src/modules/Telemetry/Sensor/T1000xSensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Telemetry/Sensor/T1000xSensor.cpp b/src/modules/Telemetry/Sensor/T1000xSensor.cpp index 4079d8ae3..4772aeb9e 100644 --- a/src/modules/Telemetry/Sensor/T1000xSensor.cpp +++ b/src/modules/Telemetry/Sensor/T1000xSensor.cpp @@ -95,7 +95,7 @@ float T1000xSensor::getTemp() Vout = ntc_vot; Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP; - for (u8i = 0; u8i < 136; u8i++) { + for (u8i = 0; u8i < 135; u8i++) { if (Rt >= ntc_res2[u8i]) { break; } From dc8cc122a62242536021a2fbbe86d84928a693b6 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 9 Sep 2024 22:20:21 +0800 Subject: [PATCH 032/252] Add explicit to JSONValue constructors (#4665) --- src/serialization/JSONValue.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/serialization/JSONValue.h b/src/serialization/JSONValue.h index 0380d324b..16d53e89f 100644 --- a/src/serialization/JSONValue.h +++ b/src/serialization/JSONValue.h @@ -40,15 +40,15 @@ class JSONValue public: JSONValue(/*NULL*/); - JSONValue(const char *m_char_value); - JSONValue(const std::string &m_string_value); - JSONValue(bool m_bool_value); - JSONValue(double m_number_value); - JSONValue(int m_integer_value); - JSONValue(unsigned int m_integer_value); - JSONValue(const JSONArray &m_array_value); - JSONValue(const JSONObject &m_object_value); - JSONValue(const JSONValue &m_source); + explicit JSONValue(const char *m_char_value); + explicit JSONValue(const std::string &m_string_value); + explicit JSONValue(bool m_bool_value); + explicit JSONValue(double m_number_value); + explicit JSONValue(int m_integer_value); + explicit JSONValue(unsigned int m_integer_value); + explicit JSONValue(const JSONArray &m_array_value); + explicit JSONValue(const JSONObject &m_object_value); + explicit JSONValue(const JSONValue &m_source); ~JSONValue(); bool IsNull() const; From 2f9dcee954ed9568aa7bc7fee163670598aba901 Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Mon, 9 Sep 2024 19:13:00 +0200 Subject: [PATCH 033/252] Fix size calculation of route/SNR array --- src/modules/TraceRouteModule.cpp | 8 ++++---- src/modules/TraceRouteModule.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp index dd3d0b4f9..23b4f1ccf 100644 --- a/src/modules/TraceRouteModule.cpp +++ b/src/modules/TraceRouteModule.cpp @@ -53,7 +53,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro uint8_t hopsTaken = p.hop_start - p.hop_limit; int8_t diff = hopsTaken - *route_count; for (uint8_t i = 0; i < diff; i++) { - if (*route_count < sizeof(*route) / sizeof(route[0])) { + if (*route_count < ROUTE_SIZE) { route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop *route_count += 1; } @@ -61,7 +61,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro // Add unknown SNR values if necessary diff = *route_count - *snr_count; for (uint8_t i = 0; i < diff; i++) { - if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { + if (*snr_count < ROUTE_SIZE) { snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR *snr_count += 1; } @@ -89,7 +89,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa snr_list = updated->snr_back; } - if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { + if (*snr_count < ROUTE_SIZE) { snr_list[*snr_count] = (int8_t)(snr * 4); // Convert SNR to 1 byte *snr_count += 1; } @@ -97,7 +97,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa return; // Length of route array can normally not be exceeded due to the max. hop_limit of 7 - if (*route_count < sizeof(*route) / sizeof(route[0])) { + if (*route_count < ROUTE_SIZE) { route[*route_count] = myNodeInfo.my_node_num; *route_count += 1; } else { diff --git a/src/modules/TraceRouteModule.h b/src/modules/TraceRouteModule.h index fe69300de..afe2b3871 100644 --- a/src/modules/TraceRouteModule.h +++ b/src/modules/TraceRouteModule.h @@ -1,6 +1,8 @@ #pragma once #include "ProtobufModule.h" +#define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0]) + /** * A module that traces the route to a certain destination node */ From 106dab23db826b52873bead8a88f7a1bab60c8fb Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 9 Sep 2024 14:20:14 -0500 Subject: [PATCH 034/252] Revert "Changes by create-pull-request action" (#4671) --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 69c478482..95d3d2538 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 1 +build = 0 From 4ed12bf21d43dcb40368025e96dea414f8ab1f9b Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:22:32 +0200 Subject: [PATCH 035/252] Try fix repeatedly getting a new NodeNum (#4670) --- 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 06180310a..5244fd10f 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -121,6 +121,8 @@ NodeDB::NodeDB() owner.hw_model = HW_VENDOR; // Ensure user (nodeinfo) role is set to whatever we're configured to owner.role = config.device.role; + // Ensure macaddr is set to our macaddr as it will be copied in our info below + memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr)); // Include our owner in the node db under our nodenum meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum()); @@ -1194,4 +1196,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co LOG_ERROR("A critical failure occurred, portduino is exiting..."); exit(2); #endif -} +} \ No newline at end of file From 4e850296b6af3c3091680f301926f6a674277573 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 10 Sep 2024 13:24:57 -0500 Subject: [PATCH 036/252] Fix repeatedly getting new NodeNum and add more debug (#4674) * All the debug * Change `memccpy()` to `memcpy()` * Brint all the bytes of the MAC Address from the NodeDB * Check for blank MAC Address in ourown NodeDB entry * One more `memccpy()` * Clean-up debug log --------- Co-authored-by: GUVWAF --- src/mesh/NodeDB.cpp | 4 +++- src/mesh/TypeConversions.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5244fd10f..5183166cd 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -646,7 +646,9 @@ void NodeDB::pickNewNodeNum() while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) || ((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 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); + LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so " + "trying for 0x%x\n", + nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate); nodeNum = candidate; } LOG_DEBUG("Using nodenum 0x%x \n", nodeNum); diff --git a/src/mesh/TypeConversions.cpp b/src/mesh/TypeConversions.cpp index 513728ca5..6a90ac703 100644 --- a/src/mesh/TypeConversions.cpp +++ b/src/mesh/TypeConversions.cpp @@ -78,7 +78,7 @@ meshtastic_UserLite TypeConversions::ConvertToUserLite(meshtastic_User user) lite.hw_model = user.hw_model; lite.role = user.role; lite.is_licensed = user.is_licensed; - memccpy(lite.macaddr, user.macaddr, sizeof(user.macaddr), sizeof(lite.macaddr)); + memcpy(lite.macaddr, user.macaddr, sizeof(lite.macaddr)); memcpy(lite.public_key.bytes, user.public_key.bytes, sizeof(lite.public_key.bytes)); lite.public_key.size = user.public_key.size; return lite; @@ -94,7 +94,7 @@ meshtastic_User TypeConversions::ConvertToUser(uint32_t nodeNum, meshtastic_User user.hw_model = lite.hw_model; user.role = lite.role; user.is_licensed = lite.is_licensed; - memccpy(user.macaddr, lite.macaddr, sizeof(lite.macaddr), sizeof(user.macaddr)); + memcpy(user.macaddr, lite.macaddr, sizeof(user.macaddr)); memcpy(user.public_key.bytes, lite.public_key.bytes, sizeof(user.public_key.bytes)); user.public_key.size = lite.public_key.size; From 013021941e6209ae52e4c7571fabc46e58f1c493 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 10 Sep 2024 15:30:40 -0500 Subject: [PATCH 037/252] Remove scaling of smart position broadcast minimum interval specifically (#4677) * Remove scaling of smart position broacast minimum interval specifically * Trunk --- src/modules/PositionModule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h index c4ef66501..41b86b795 100644 --- a/src/modules/PositionModule.h +++ b/src/modules/PositionModule.h @@ -63,7 +63,7 @@ class PositionModule : public ProtobufModule, private concu bool hasQualityTimesource(); const uint32_t minimumTimeThreshold = - Default::getConfiguredOrDefaultMsScaled(config.position.broadcast_smart_minimum_interval_secs, 30, numOnlineNodes); + Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30); }; struct SmartPosition { From 6724f1f7ea3e9e9d87d4592c033ff8950cbfb6fe Mon Sep 17 00:00:00 2001 From: zerolint <179066619+zerolint@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:51:28 -0400 Subject: [PATCH 038/252] Print Unix epoch on time_t 64bit platforms (#4673) Fixes (#4600) by using unsigned 32bit for epoch. Co-authored-by: Ben Meadors --- src/gps/RTC.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 070038672..c056bb9e4 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -43,7 +43,10 @@ void readFromRTC() t.tm_sec = rtc.getSecond(); tv.tv_sec = gm_mktime(&t); tv.tv_usec = 0; - LOG_DEBUG("Read RTC time from RV3028 as %ld\n", tv.tv_sec); + + uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms + LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, t.tm_mon + 1, + t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch); timeStartMsec = now; zeroOffsetSecs = tv.tv_sec; if (currentQuality == RTCQualityNone) { @@ -71,7 +74,10 @@ void readFromRTC() t.tm_sec = tc.second; tv.tv_sec = gm_mktime(&t); tv.tv_usec = 0; - LOG_DEBUG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec); + + uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms + LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch); timeStartMsec = now; zeroOffsetSecs = tv.tv_sec; if (currentQuality == RTCQualityNone) { @@ -81,7 +87,8 @@ void readFromRTC() #else if (!gettimeofday(&tv, NULL)) { uint32_t now = millis(); - LOG_DEBUG("Read RTC time as %ld\n", tv.tv_sec); + uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms + LOG_DEBUG("Read RTC time as %ld\n", printableEpoch); timeStartMsec = now; zeroOffsetSecs = tv.tv_sec; } @@ -101,6 +108,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) { static uint32_t lastSetMsec = 0; uint32_t now = millis(); + uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms bool shouldSet; if (forceUpdate) { @@ -113,7 +121,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) } else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { // Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift shouldSet = true; - LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec); + LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch); } else { shouldSet = false; LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q)); @@ -140,8 +148,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #endif tm *t = gmtime(&tv->tv_sec); rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); - LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); + LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec, printableEpoch); } #elif defined(PCF8563_RTC) if (rtc_found.address == PCF8563_RTC) { @@ -154,8 +162,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #endif tm *t = gmtime(&tv->tv_sec); rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); - LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); + LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, + t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch); } #elif defined(ARCH_ESP32) settimeofday(tv, NULL); @@ -272,4 +280,4 @@ time_t gm_mktime(struct tm *tm) #else return mktime(tm); #endif -} \ No newline at end of file +} From e8e9826adc3905d1e3b50b2a851de88ba21f9276 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 10 Sep 2024 19:27:59 -0500 Subject: [PATCH 039/252] Temp: Grab pre-release tag --- .github/workflows/build_esp32.yml | 1 + .github/workflows/build_esp32_c3.yml | 1 + .github/workflows/build_esp32_s3.yml | 1 + .github/workflows/package_amd64.yml | 1 + .github/workflows/package_raspbian.yml | 1 + 5 files changed, 5 insertions(+) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 4cbb4c7a4..db9f049a7 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -20,6 +20,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web + version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index 07727d711..fc836e170 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -22,6 +22,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web + version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 10773833e..dc89f3ae3 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -20,6 +20,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web + version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index ae7bf3242..5ae3349ba 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -27,6 +27,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web + version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index 5471332c5..0720e3433 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -27,6 +27,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web + version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} From 1ba4f6e2223d6e6f1595445add774f2e71d8b19e Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 10 Sep 2024 20:07:06 -0500 Subject: [PATCH 040/252] Revert "Temp: Grab pre-release tag" This reverts commit e8e9826adc3905d1e3b50b2a851de88ba21f9276. --- .github/workflows/build_esp32.yml | 1 - .github/workflows/build_esp32_c3.yml | 1 - .github/workflows/build_esp32_s3.yml | 1 - .github/workflows/package_amd64.yml | 1 - .github/workflows/package_raspbian.yml | 1 - 5 files changed, 5 deletions(-) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index db9f049a7..4cbb4c7a4 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -20,7 +20,6 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web - version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index fc836e170..07727d711 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -22,7 +22,6 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web - version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index dc89f3ae3..10773833e 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -20,7 +20,6 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web - version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index 5ae3349ba..ae7bf3242 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -27,7 +27,6 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web - version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index 0720e3433..5471332c5 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -27,7 +27,6 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web - version: "tags/pre-release" file: build.tar target: build.tar token: ${{ secrets.GITHUB_TOKEN }} From 9ac0e26d426132162614be9ef74fedf46e305410 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 11 Sep 2024 08:42:26 -0500 Subject: [PATCH 041/252] Add option to preserve private key for factory reset (config) (#4679) * Add option to preserve private key for factory reset (config) * Typo fix * Copy the key in the right direction, and set the size. * Don't set the key size back to 0 right after setting it to 32. * Set the key size before using it to do a memcpy. * Use the right key_size for backing up private_key * Don't factoryReset() for a missing nodeDB * Disable Bluetooth in AdminModule when resetting device settings or nodeDB to avoid race * Add checks for valid objects before deinit bluetooth * Add disableBluetooth to handleSetConfig, handleSetModuleConfig, and commit settings --------- Co-authored-by: Jonathan Bennett --- src/mesh/NodeDB.cpp | 23 +++++++++++++++++------ src/mesh/NodeDB.h | 3 ++- src/modules/AdminModule.cpp | 23 ++++++++++++++++++++++- src/modules/AdminModule.h | 4 +++- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5183166cd..5d1db88ae 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -245,7 +245,7 @@ bool NodeDB::factoryReset(bool eraseBleBonds) #endif // second, install default state (this will deal with the duplicate mac address issue) installDefaultDeviceState(); - installDefaultConfig(); + installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds installDefaultModuleConfig(); installDefaultChannels(); // third, write everything to disk @@ -268,8 +268,13 @@ bool NodeDB::factoryReset(bool eraseBleBonds) return true; } -void NodeDB::installDefaultConfig() +void NodeDB::installDefaultConfig(bool preserveKey = false) { + uint8_t private_key_temp[32]; + bool shouldPreserveKey = preserveKey && config.has_security && config.security.private_key.size > 0; + if (shouldPreserveKey) { + memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size); + } LOG_INFO("Installing default LocalConfig\n"); memset(&config, 0, sizeof(meshtastic_LocalConfig)); config.version = DEVICESTATE_CUR_VER; @@ -310,8 +315,14 @@ void NodeDB::installDefaultConfig() #else config.security.admin_key[0].size = 0; #endif + if (shouldPreserveKey) { + config.security.private_key.size = 32; + memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size); + printBytes("Restored key", config.security.private_key.bytes, config.security.private_key.size); + } else { + config.security.private_key.size = 0; + } config.security.public_key.size = 0; - config.security.private_key.size = 0; #ifdef PIN_GPS_EN config.position.gps_en_gpio = PIN_GPS_EN; #endif @@ -714,7 +725,7 @@ void NodeDB::loadFromDisk() //} else { if (devicestate.version < DEVICESTATE_MIN_VER) { LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version); - factoryReset(); + installDefaultDeviceState(); } else { LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version, devicestate.node_db_lite.size()); @@ -730,7 +741,7 @@ void NodeDB::loadFromDisk() } else { if (config.version < DEVICESTATE_MIN_VER) { LOG_WARN("config %d is old, discarding\n", config.version); - installDefaultConfig(); + installDefaultConfig(true); } else { LOG_INFO("Loaded saved config version %d\n", config.version); } @@ -1043,7 +1054,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde if (p.public_key.size > 0) { printBytes("Incoming Pubkey: ", p.public_key.bytes, 32); if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one - LOG_INFO("Public Key set for node, not updateing!\n"); + LOG_INFO("Public Key set for node, not updating!\n"); // we copy the key into the incoming packet, to prevent overwrite memcpy(p.public_key.bytes, info->user.public_key.bytes, 32); } else { diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index a71f3e134..c94a7653c 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -182,7 +182,8 @@ class NodeDB void cleanupMeshDB(); /// Reinit device state from scratch (not loading from disk) - void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig(); + void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(bool preserveKey), + installDefaultModuleConfig(); /// write to flash /// @return true if the save was successful diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index d88f17a86..4deb99eb7 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -186,18 +186,22 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta break; } case meshtastic_AdminMessage_factory_reset_config_tag: { + disableBluetooth(); LOG_INFO("Initiating factory config reset\n"); nodeDB->factoryReset(); + LOG_INFO("Factory config reset finished, rebooting soon.\n"); reboot(DEFAULT_REBOOT_SECONDS); break; } case meshtastic_AdminMessage_factory_reset_device_tag: { + disableBluetooth(); LOG_INFO("Initiating full factory reset\n"); nodeDB->factoryReset(true); reboot(DEFAULT_REBOOT_SECONDS); break; } case meshtastic_AdminMessage_nodedb_reset_tag: { + disableBluetooth(); LOG_INFO("Initiating node-db reset\n"); nodeDB->resetNodes(); reboot(DEFAULT_REBOOT_SECONDS); @@ -209,6 +213,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta break; } case meshtastic_AdminMessage_commit_edit_settings_tag: { + disableBluetooth(); LOG_INFO("Committing transaction for edited settings\n"); hasOpenEditTransaction = false; saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS); @@ -559,12 +564,16 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) break; } + if (requiresReboot) { + disableBluetooth(); + } saveChanges(changes, requiresReboot); } void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) { + disableBluetooth(); switch (c.which_payload_variant) { case meshtastic_ModuleConfig_mqtt_tag: LOG_INFO("Setting module config: MQTT\n"); @@ -636,7 +645,6 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) moduleConfig.paxcounter = c.payload_variant.paxcounter; break; } - saveChanges(SEGMENT_MODULECONFIG); } @@ -1031,3 +1039,16 @@ bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r) else return false; } + +void disableBluetooth() +{ +#if HAS_BLUETOOTH +#ifdef ARCH_ESP32 + if (nimbleBluetooth) + nimbleBluetooth->deinit(); +#elif defined(ARCH_NRF52) + if (nrf52Bluetooth) + nrf52Bluetooth->shutdown(); +#endif +#endif +} \ No newline at end of file diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index 61c54d1b1..328e1c824 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -59,4 +59,6 @@ class AdminModule : public ProtobufModule, public Obser bool messageIsRequest(meshtastic_AdminMessage *r); }; -extern AdminModule *adminModule; \ No newline at end of file +extern AdminModule *adminModule; + +void disableBluetooth(); \ No newline at end of file From ba9a3cd7195ab93e899314f6a0e4de8f854f3c88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:51:52 -0500 Subject: [PATCH 042/252] [create-pull-request] automated change (#4685) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 95d3d2538..69c478482 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 0 +build = 1 From f37df4d6bf0f82df7e19840422f7fdaeeafe0a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gjels=C3=B8?= <36234524+gjelsoe@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:53:17 +0200 Subject: [PATCH 043/252] Radiomaster Bandit Accelerometer support (#4667) * Added STK8xxxx Accelerometer chip Added detection of STK8BA53 to I2C scanner. Change the way and order MCP9808, lLISH3DH and STK8BA53 is detected since they all shares the same I2C address. * Accelerometer support Radiomaster Bandit. Enables tap to wake screen if enabled in config, * Trunk Trunk --- platformio.ini | 3 +- src/AccelerometerThread.h | 22 ++++++++++++++ src/configuration.h | 1 + src/detect/ScanI2C.cpp | 4 +-- src/detect/ScanI2C.h | 3 +- src/detect/ScanI2CTwoWire.cpp | 37 +++++++++++++++++------ variants/radiomaster_900_bandit/variant.h | 7 ++++- 7 files changed, 62 insertions(+), 15 deletions(-) diff --git a/platformio.ini b/platformio.ini index 87eb0afb7..7613a2f43 100644 --- a/platformio.ini +++ b/platformio.ini @@ -160,4 +160,5 @@ lib_deps = mprograms/QMC5883LCompass@^1.2.0 - https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee \ No newline at end of file + https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee + https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 \ No newline at end of file diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h index c2910007e..629d63c6a 100644 --- a/src/AccelerometerThread.h +++ b/src/AccelerometerThread.h @@ -11,6 +11,9 @@ #include #include #include +#ifdef STK8XXX_INT +#include +#endif #include #include #include @@ -24,6 +27,8 @@ #define ACCELEROMETER_CHECK_INTERVAL_MS 100 #define ACCELEROMETER_CLICK_THRESHOLD 40 +volatile static bool STK_IRQ; + static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) { Wire.beginTransmission(address); @@ -79,6 +84,11 @@ class AccelerometerThread : public concurrency::OSThread if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) { wakeScreen(); + } else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && STK_IRQ) { + STK_IRQ = false; + if (config.display.wake_on_tap_or_motion) { + wakeScreen(); + } } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) { uint8_t click = lis.getClick(); if (!config.device.double_tap_as_button_press) { @@ -188,6 +198,15 @@ class AccelerometerThread : public concurrency::OSThread mpu.setMotionDetectionDuration(20); mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized. mpu.setInterruptPinPolarity(true); +#ifdef STK8XXX_INT + } else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && stk8baxx.STK8xxx_Initialization(STK8xxx_VAL_RANGE_2G)) { + STK_IRQ = false; + LOG_DEBUG("STX8BAxx initialized\n"); + stk8baxx.STK8xxx_Anymotion_init(); + pinMode(STK8XXX_INT, INPUT_PULLUP); + attachInterrupt( + digitalPinToInterrupt(STK8XXX_INT), [] { STK_IRQ = true; }, RISING); +#endif } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) { LOG_DEBUG("LIS3DH initializing\n"); lis.setRange(LIS3DH_RANGE_2_G); @@ -262,6 +281,9 @@ class AccelerometerThread : public concurrency::OSThread ScanI2C::DeviceType acceleremoter_type; Adafruit_MPU6050 mpu; Adafruit_LIS3DH lis; +#ifdef STK8XXX_INT + STK8xxx stk8baxx; +#endif Adafruit_LSM6DS3TRC lsm; SensorBMA423 bmaSensor; bool BMA_IRQ = false; diff --git a/src/configuration.h b/src/configuration.h index 047dbd727..4ab33ef2b 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -144,6 +144,7 @@ along with this program. If not, see . // ACCELEROMETER // ----------------------------------------------------------------------------- #define MPU6050_ADDR 0x68 +#define STK8BXX_ADR 0x18 #define LIS3DH_ADR 0x18 #define BMA423_ADDR 0x19 #define LSM6DS3_ADDR 0x6A diff --git a/src/detect/ScanI2C.cpp b/src/detect/ScanI2C.cpp index 73bdf973b..eaba62a78 100644 --- a/src/detect/ScanI2C.cpp +++ b/src/detect/ScanI2C.cpp @@ -37,8 +37,8 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const { - ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160}; - return firstOfOrNONE(5, types); + ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX}; + return firstOfOrNONE(6, types); } ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 0a5b360de..638e8cd23 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -52,7 +52,8 @@ class ScanI2C AHT10, BMX160, DFROBOT_LARK, - NAU7802 + NAU7802, + STK8BAXX } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 21e7ca8ac..ad5d9fe4c 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -313,17 +313,34 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) } break; case MCP9808_ADDR: - registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2); - if (registerValue == 0x0400) { - type = MCP9808; - LOG_INFO("MCP9808 sensor found\n"); - } else { - type = LIS3DH; - LOG_INFO("LIS3DH accelerometer found\n"); + // We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some + // weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips. + { + // Check register 0x00 for 0x8700 response to ID STK8BA53 chip. + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2); + if (registerValue == 0x8700) { + type = STK8BAXX; + LOG_INFO("STK8BAXX accelerometer found\n"); + break; + } + + // Check register 0x07 for 0x0400 response to ID MCP9808 chip. + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2); + if (registerValue == 0x0400) { + type = MCP9808; + LOG_INFO("MCP9808 sensor found\n"); + break; + } + + // Check register 0x0F for 0x3300 response to ID LIS3DH chip. + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2); + if (registerValue == 0x3300) { + type = LIS3DH; + LOG_INFO("LIS3DH accelerometer found\n"); + } + + break; } - - break; - case SHT31_4x_ADDR: registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2); if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) { diff --git a/variants/radiomaster_900_bandit/variant.h b/variants/radiomaster_900_bandit/variant.h index 0499970f5..0c7417cac 100644 --- a/variants/radiomaster_900_bandit/variant.h +++ b/variants/radiomaster_900_bandit/variant.h @@ -11,12 +11,17 @@ /* I2C SDA and SCL. - 0x18 - STK8XXX Accelerometer, Not supported yet. + 0x18 - STK8XXX Accelerometer 0x3C - SH1115 Display Driver */ #define I2C_SDA 14 #define I2C_SCL 12 +/* + I2C STK8XXX Accelerometer Interrupt PIN to ESP32 Pin 6 - SENSOR_CAPP (GPIO37) +*/ +#define STK8XXX_INT 37 + /* No GPS - but free pins are available. */ From 371c3e05bf9bff7f0b4fd07c4eb39a5eb6401a53 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Thu, 12 Sep 2024 08:30:29 +0800 Subject: [PATCH 044/252] Beautify GPS_DEBUG getACK logging code (#4672) This getACK is used to look for ASCII responses, so print ASCII when GPS_DEBUG is enabled. This markedly assisted with recent AG3335 debugging. It works great with other chips too (tested eg ATGM336H). Even UBLOX prints understandable "GPTXT,01,01,01,PDTI inv format*35." responses. Credit to bluebrolly. on discord. --- src/gps/GPS.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 3ce0abe75..046f277ff 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -166,18 +166,21 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis) b = _serial_gps->read(); #ifdef GPS_DEBUG - LOG_DEBUG("%02X", (char *)buffer); + LOG_DEBUG("%c", (b >= 32 && b <= 126) ? b : '.'); #endif buffer[bytesRead] = b; bytesRead++; if ((bytesRead == 767) || (b == '\r')) { if (strnstr((char *)buffer, message, bytesRead) != nullptr) { #ifdef GPS_DEBUG - LOG_DEBUG("\r"); + LOG_DEBUG("\r\nFound: %s\r\n", message); // Log the found message #endif return GNSS_RESPONSE_OK; } else { bytesRead = 0; +#ifdef GPS_DEBUG + LOG_DEBUG("\r\n"); +#endif } } } @@ -1804,4 +1807,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS +#endif // Exclude GPS \ No newline at end of file From 910b6b7512c432e2ab7a59bb9acf4627dd824028 Mon Sep 17 00:00:00 2001 From: panaceya Date: Thu, 12 Sep 2024 03:31:30 +0300 Subject: [PATCH 045/252] OLED_ can be configured via userPrefs.h (#4624) --- src/graphics/Screen.cpp | 2 +- variants/diy/platformio.ini | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 68fdba207..da573bade 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "Screen.h" #include "../userPrefs.h" +#include "Screen.h" #include "PowerMon.h" #include "configuration.h" #if HAS_SCREEN diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini index adc10de44..2a55f7a79 100644 --- a/variants/diy/platformio.ini +++ b/variants/diy/platformio.ini @@ -7,7 +7,6 @@ build_flags = ${esp32_base.build_flags} -D DIY_V1 -D EBYTE_E22 - -D OLED_RU -I variants/diy/v1 ; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules @@ -19,7 +18,6 @@ build_flags = ${esp32_base.build_flags} -D DIY_V1 -D EBYTE_E22 - -D OLED_RU -I variants/diy/v1_1 ; Port to Disaster Radio's ESP32-v3 Dev Board @@ -52,7 +50,6 @@ board_level = extra build_flags = ${nrf52840_base.build_flags} -I variants/diy/nrf52_promicro_diy_xtal -D NRF52_PROMICRO_DIY - -D OLED_RU -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/nrf52_promicro_diy_xtal> lib_deps = @@ -68,7 +65,6 @@ board_level = extra build_flags = ${nrf52840_base.build_flags} -I variants/diy/nrf52_promicro_diy_tcxo -D NRF52_PROMICRO_DIY - -D OLED_RU -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/nrf52_promicro_diy_tcxo> lib_deps = From 625254cf909a7e0137cefbff19c733541739a6fb Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:44:30 +0200 Subject: [PATCH 046/252] Support Seeed SenseCAP Indicator (#4279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * preliminary target environment * add debug tool * add screen definitions * screen definitions * remove rtc, debug build * correct rotation * Add real hwmodel * fix width * use IO expander ports * link to modified arduino-esp32 * added config_detail * rotate screen * remove touch INT * add delay to display log * color log and radiolib log * LoRa init * make trunk happy * add lovyanGFX patch lib for io expander * fix lib * fix display&touch function * touch driver I2C scan * remove delay * build for release * minor code cleanup * allow trunk to be happy --------- Co-authored-by: Ben Meadors Co-authored-by: Thomas Göttgens --- boards/seeed-sensecap-indicator.json | 42 ++++++ src/configuration.h | 6 + src/detect/ScanI2C.h | 2 + src/detect/ScanI2CTwoWire.cpp | 2 + src/graphics/Screen.cpp | 24 ++-- src/graphics/ScreenFonts.h | 4 +- src/graphics/TFTDisplay.cpp | 123 +++++++++++++++++- src/graphics/images.h | 4 +- src/main.cpp | 4 +- src/platform/esp32/architecture.h | 2 + .../seeed-sensecap-indicator/pins_arduino.h | 56 ++++++++ .../seeed-sensecap-indicator/platformio.ini | 28 ++++ variants/seeed-sensecap-indicator/variant.h | 64 +++++++++ 13 files changed, 340 insertions(+), 21 deletions(-) create mode 100644 boards/seeed-sensecap-indicator.json create mode 100644 variants/seeed-sensecap-indicator/pins_arduino.h create mode 100644 variants/seeed-sensecap-indicator/platformio.ini create mode 100644 variants/seeed-sensecap-indicator/variant.h diff --git a/boards/seeed-sensecap-indicator.json b/boards/seeed-sensecap-indicator.json new file mode 100644 index 000000000..3fc57126f --- /dev/null +++ b/boards/seeed-sensecap-indicator.json @@ -0,0 +1,42 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "partitions": "default_8MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=0", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [["0x1A86", "0x7523"]], + "mcu": "esp32s3", + "variant": "esp32s3r8" + }, + "connectivity": ["wifi", "bluetooth", "lora"], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": ["esp-builtin"], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino"], + "name": "Seeed Studio SenseCAP Indicator", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "speed": 921600 + }, + "url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html", + "vendor": "Seeed Studio" +} diff --git a/src/configuration.h b/src/configuration.h index 4ab33ef2b..72420cc59 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -163,6 +163,7 @@ along with this program. If not, see . // ----------------------------------------------------------------------------- // IO Expander // ----------------------------------------------------------------------------- +#define TCA9535_ADDR 0x20 #define TCA9555_ADDR 0x26 // ----------------------------------------------------------------------------- @@ -172,6 +173,11 @@ along with this program. If not, see . #define GPS_THREAD_INTERVAL 200 #endif +// ----------------------------------------------------------------------------- +// Touchscreen +// ----------------------------------------------------------------------------- +#define FT6336U_ADDR 0x48 + // convert 24-bit color to 16-bit (56K) #define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)) diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 638e8cd23..743de7a9a 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -42,6 +42,7 @@ class ScanI2C BMA423, BQ24295, LSM6DS3, + TCA9535, TCA9555, VEML7700, RCWL9620, @@ -53,6 +54,7 @@ class ScanI2C BMX160, DFROBOT_LARK, NAU7802, + FT6336U, STK8BAXX } DeviceType; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index ad5d9fe4c..48341034b 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -388,12 +388,14 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(BMX160_ADDR, BMX160, "BMX160 accelerometer found\n"); SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n"); SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address); + SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found\n"); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n"); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n"); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n"); SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n"); SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n"); SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n"); + SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found\n"); default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index da573bade..ff1254812 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "../userPrefs.h" #include "Screen.h" +#include "../userPrefs.h" #include "PowerMon.h" #include "configuration.h" #if HAS_SCREEN @@ -1093,8 +1093,8 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat { char usersString[20]; snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal()); -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS)) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS)) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) display->drawFastImage(x, y + 3, 8, 8, imgUser); #else @@ -1515,7 +1515,8 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O #elif defined(USE_SSD1306) dispdev = new SSD1306Wire(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); -#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS) +#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || defined(RAK14014) || \ + defined(HX8357_CS) dispdev = new TFTDisplay(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); #elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY) @@ -1707,7 +1708,8 @@ void Screen::setup() // Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically // flip it. If you have a headache now, you're welcome. if (!config.display.flip_screen) { -#if defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS) +#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \ + defined(RAK14014) || defined(HX8357_CS) static_cast(dispdev)->flipScreenVertically(); #else dispdev->flipScreenVertically(); @@ -2420,8 +2422,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 #ifdef ARCH_ESP32 if (millis() - storeForwardModule->lastHeartbeat > (storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS)) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS)) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgQuestionL1); @@ -2432,8 +2434,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 imgQuestion); #endif } else { -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS)) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS)) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8, imgSFL1); @@ -2447,8 +2449,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 #endif } else { // TODO: Raspberry Pi supports more than just the one screen size -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS) || ARCH_PORTDUINO) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgInfoL1); diff --git a/src/graphics/ScreenFonts.h b/src/graphics/ScreenFonts.h index 267f6e0a8..34c832635 100644 --- a/src/graphics/ScreenFonts.h +++ b/src/graphics/ScreenFonts.h @@ -12,8 +12,8 @@ #include "graphics/fonts/OLEDDisplayFontsUA.h" #endif -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS)) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS)) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) // The screen is bigger so use bigger fonts #define FONT_SMALL ArialMT_Plain_16 // Height: 19 diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 2849dd9a9..c0326abec 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -500,10 +500,126 @@ class LGFX : public lgfx::LGFX_Device static LGFX *tft = nullptr; +#elif defined(ST7701_CS) +#include // Graphics and font library for ST7701 driver chip +#include +#include + +class LGFX : public lgfx::LGFX_Device +{ + lgfx::Panel_ST7701 _panel_instance; + lgfx::Bus_RGB _bus_instance; + lgfx::Light_PWM _light_instance; + lgfx::Touch_FT5x06 _touch_instance; + + public: + LGFX(void) + { + { + auto cfg = _panel_instance.config(); + cfg.memory_width = 800; + cfg.memory_height = 480; + cfg.panel_width = TFT_WIDTH; + cfg.panel_height = TFT_HEIGHT; + cfg.offset_x = TFT_OFFSET_X; + cfg.offset_y = TFT_OFFSET_Y; + _panel_instance.config(cfg); + } + + { + auto cfg = _panel_instance.config_detail(); + cfg.pin_cs = ST7701_CS; + cfg.pin_sclk = ST7701_SCK; + cfg.pin_mosi = ST7701_SDA; + // cfg.use_psram = 1; + _panel_instance.config_detail(cfg); + } + + { + auto cfg = _bus_instance.config(); + cfg.panel = &_panel_instance; +#ifdef SENSECAP_INDICATOR + cfg.pin_d0 = GPIO_NUM_15; // B0 + cfg.pin_d1 = GPIO_NUM_14; // B1 + cfg.pin_d2 = GPIO_NUM_13; // B2 + cfg.pin_d3 = GPIO_NUM_12; // B3 + cfg.pin_d4 = GPIO_NUM_11; // B4 + + cfg.pin_d5 = GPIO_NUM_10; // G0 + cfg.pin_d6 = GPIO_NUM_9; // G1 + cfg.pin_d7 = GPIO_NUM_8; // G2 + cfg.pin_d8 = GPIO_NUM_7; // G3 + cfg.pin_d9 = GPIO_NUM_6; // G4 + cfg.pin_d10 = GPIO_NUM_5; // G5 + + cfg.pin_d11 = GPIO_NUM_4; // R0 + cfg.pin_d12 = GPIO_NUM_3; // R1 + cfg.pin_d13 = GPIO_NUM_2; // R2 + cfg.pin_d14 = GPIO_NUM_1; // R3 + cfg.pin_d15 = GPIO_NUM_0; // R4 + + cfg.pin_henable = GPIO_NUM_18; + cfg.pin_vsync = GPIO_NUM_17; + cfg.pin_hsync = GPIO_NUM_16; + cfg.pin_pclk = GPIO_NUM_21; + cfg.freq_write = 12000000; + + cfg.hsync_polarity = 0; + cfg.hsync_front_porch = 10; + cfg.hsync_pulse_width = 8; + cfg.hsync_back_porch = 50; + + cfg.vsync_polarity = 0; + cfg.vsync_front_porch = 10; + cfg.vsync_pulse_width = 8; + cfg.vsync_back_porch = 20; + + cfg.pclk_active_neg = 0; + cfg.de_idle_high = 1; + cfg.pclk_idle_high = 0; +#endif + _bus_instance.config(cfg); + } + _panel_instance.setBus(&_bus_instance); + + { + auto cfg = _light_instance.config(); + cfg.pin_bl = ST7701_BL; + _light_instance.config(cfg); + } + _panel_instance.light(&_light_instance); + + { + auto cfg = _touch_instance.config(); + cfg.pin_cs = -1; + cfg.x_min = 0; + cfg.x_max = 479; + cfg.y_min = 0; + cfg.y_max = 479; + cfg.pin_int = -1; // don't use SCREEN_TOUCH_INT; + cfg.pin_rst = SCREEN_TOUCH_RST; + cfg.bus_shared = true; + cfg.offset_rotation = TFT_OFFSET_ROTATION; + + cfg.i2c_port = TOUCH_I2C_PORT; + cfg.i2c_addr = TOUCH_SLAVE_ADDRESS; + cfg.pin_sda = I2C_SDA; + cfg.pin_scl = I2C_SCL; + cfg.freq = 400000; + _touch_instance.config(cfg); + _panel_instance.setTouch(&_touch_instance); + } + + setPanel(&_panel_instance); + } +}; + +static LGFX *tft = nullptr; + #endif -#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || defined(HX8357_CS) || \ - (ARCH_PORTDUINO && HAS_SCREEN != 0) +#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || \ + defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0) #include "SPILock.h" #include "TFTDisplay.h" #include @@ -709,7 +825,6 @@ bool TFTDisplay::connect() #ifdef UNPHONE unphone.backlight(true); // using unPhone library - LOG_INFO("Power to TFT Backlight\n"); #endif tft->init(); @@ -725,7 +840,7 @@ bool TFTDisplay::connect() attachInterrupt(digitalPinToInterrupt(SCREEN_TOUCH_INT), rak14014_tpIntHandle, FALLING); #elif defined(T_DECK) || defined(PICOMPUTER_S3) || defined(CHATTER_2) tft->setRotation(1); // T-Deck has the TFT in landscape -#elif defined(T_WATCH_S3) +#elif defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR) tft->setRotation(2); // T-Watch S3 left-handed orientation #else tft->setRotation(3); // Orient horizontal and wide underneath the silkscreen name label diff --git a/src/graphics/images.h b/src/graphics/images.h index ab3767a89..7028f18e3 100644 --- a/src/graphics/images.h +++ b/src/graphics/images.h @@ -20,8 +20,8 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03 0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f}; #endif -#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(USE_ST7789) || \ - defined(HX8357_CS) || ARCH_PORTDUINO) && \ +#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ + defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff}; const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f}; diff --git a/src/main.cpp b/src/main.cpp index 83758d5ee..1401f4f0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -745,8 +745,8 @@ void setup() #if !MESHTASTIC_EXCLUDE_I2C // Don't call screen setup until after nodedb is setup (because we need // the current region name) -#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS) || \ - defined(USE_ST7789) +#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || \ + defined(HX8357_CS) || defined(USE_ST7789) screen->setup(); #elif defined(ARCH_PORTDUINO) if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) { diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index f86b342ce..93630aa8a 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -166,6 +166,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E290 #elif defined(HELTEC_MESH_NODE_T114) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 +#elif defined(SENSECAP_INDICATOR) +#define HW_VENDOR meshtastic_HardwareModel_SENSECAP_INDICATOR #endif // ----------------------------------------------------------------------------- diff --git a/variants/seeed-sensecap-indicator/pins_arduino.h b/variants/seeed-sensecap-indicator/pins_arduino.h new file mode 100644 index 000000000..300f0e0f5 --- /dev/null +++ b/variants/seeed-sensecap-indicator/pins_arduino.h @@ -0,0 +1,56 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +// static const uint8_t LED_BUILTIN = -1; + +// static const uint8_t TX = 43; +// static const uint8_t RX = 44; + +static const uint8_t SDA = 39; +static const uint8_t SCL = 40; + +// Default SPI will be mapped to Radio +static const uint8_t SS = -1; +static const uint8_t MOSI = 48; +static const uint8_t MISO = 47; +static const uint8_t SCK = 41; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A6 = 7; +static const uint8_t A7 = 8; +static const uint8_t A8 = 9; +static const uint8_t A9 = 10; +static const uint8_t A10 = 11; +static const uint8_t A11 = 12; +static const uint8_t A12 = 13; +static const uint8_t A13 = 14; +static const uint8_t A14 = 15; +static const uint8_t A15 = 16; +static const uint8_t A16 = 17; +static const uint8_t A17 = 18; +static const uint8_t A18 = 19; +static const uint8_t A19 = 20; + +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T13 = 13; +static const uint8_t T14 = 14; + +#endif /* Pins_Arduino_h */ \ No newline at end of file diff --git a/variants/seeed-sensecap-indicator/platformio.ini b/variants/seeed-sensecap-indicator/platformio.ini new file mode 100644 index 000000000..e6bb2145e --- /dev/null +++ b/variants/seeed-sensecap-indicator/platformio.ini @@ -0,0 +1,28 @@ +; Seeed Studio SenseCAP Indicator +[env:seeed-sensecap-indicator] +extends = esp32s3_base +platform_packages = + platformio/framework-arduinoespressif32 @ https://github.com/mverch67/arduino-esp32.git#add_tca9535 ; based on 2.0.16 + +board = seeed-sensecap-indicator +board_check = true +upload_protocol = esptool + +build_flags = ${esp32_base.build_flags} + -Ivariants/seeed-sensecap-indicator + -DSENSECAP_INDICATOR + -DCONFIG_ARDUHAL_LOG_COLORS + -DRADIOLIB_DEBUG_SPI=0 + -DRADIOLIB_DEBUG_PROTOCOL=0 + -DRADIOLIB_DEBUG_BASIC=0 + -DRADIOLIB_VERBOSE_ASSERT=0 + -DRADIOLIB_SPI_PARANOID=0 + -DIO_EXPANDER=0x40 + -DIO_EXPANDER_IRQ=42 + ;-DIO_EXPANDER_DEBUG + -DUSE_ARDUINO_HAL_GPIO + +lib_deps = ${esp32s3_base.lib_deps} + https://github.com/mverch67/LovyanGFX#develop + earlephilhower/ESP8266Audio@^1.9.7 + earlephilhower/ESP8266SAM@^1.0.1 \ No newline at end of file diff --git a/variants/seeed-sensecap-indicator/variant.h b/variants/seeed-sensecap-indicator/variant.h new file mode 100644 index 000000000..d7ed329eb --- /dev/null +++ b/variants/seeed-sensecap-indicator/variant.h @@ -0,0 +1,64 @@ +#define I2C_SDA 39 +#define I2C_SCL 40 + +#define BUTTON_PIN 38 +// #define BUTTON_NEED_PULLUP + +// #define BATTERY_PIN 27 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +// #define ADC_CHANNEL ADC1_GPIO27_CHANNEL +// #define ADC_MULTIPLIER 2 + +// ST7701 TFT LCD +#define ST7701_CS (4 | IO_EXPANDER) +#define ST7701_RS -1 // DC +#define ST7701_SDA 48 // MOSI +#define ST7701_SCK 41 +#define ST7701_RESET (5 | IO_EXPANDER) +#define ST7701_MISO 47 +#define ST7701_BUSY -1 +#define ST7701_BL 45 +#define ST7701_SPI_HOST SPI2_HOST +#define ST7701_BACKLIGHT_EN 45 +#define SPI_FREQUENCY 20000000 +#define SPI_READ_FREQUENCY 16000000 +#define TFT_HEIGHT 480 +#define TFT_WIDTH 480 +#define TFT_OFFSET_X 0 +#define TFT_OFFSET_Y 0 +#define TFT_OFFSET_ROTATION 0 +#define TFT_BL 45 +#define SCREEN_ROTATE +#define SCREEN_TRANSITION_FRAMERATE 5 // fps + +#define HAS_TOUCHSCREEN 1 +#define SCREEN_TOUCH_INT (6 | IO_EXPANDER) +#define SCREEN_TOUCH_RST (7 | IO_EXPANDER) +#define TOUCH_I2C_PORT 0 +#define TOUCH_SLAVE_ADDRESS 0x48 + +// Buzzer +#define PIN_BUZZER 19 + +#define HAS_GPS 0 +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +#define USE_SX1262 +#define USE_SX1268 + +#define LORA_SCK 41 +#define LORA_MISO 47 +#define LORA_MOSI 48 +#define LORA_CS (0 | IO_EXPANDER) + +#define LORA_DIO0 -1 // a no connect on the SX1262 module +#define LORA_RESET (1 | IO_EXPANDER) +#define LORA_DIO1 (3 | IO_EXPANDER) // SX1262 IRQ +#define LORA_DIO2 (2 | IO_EXPANDER) // SX1262 BUSY +#define LORA_DIO3 + +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_DIO2 +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH From 3d72fbb19e524bf87d4851b7b4134130ab09aa5c Mon Sep 17 00:00:00 2001 From: Vertex <5567402+RealityAnomaly@users.noreply.github.com> Date: Thu, 12 Sep 2024 18:20:38 +0100 Subject: [PATCH 047/252] Define SX126X_ANT_SW for the RAK11200 to allow it to function correctly on the RAK19007 base (#4690) --- variants/rak11200/variant.h | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/rak11200/variant.h b/variants/rak11200/variant.h index 3cd601254..259fa6e87 100644 --- a/variants/rak11200/variant.h +++ b/variants/rak11200/variant.h @@ -70,6 +70,7 @@ static const uint8_t SCK = 33; #define LORA_CS SS #define USE_SX1262 +#define SX126X_ANT_SW WB_IO2 #define SX126X_CS SS // NSS for SX126X #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 From 9527874815ca98427d6a1d114b65095e64ff60f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Sep 2024 22:42:10 +0200 Subject: [PATCH 048/252] First stab at ESP32-C6 support for TLora-C6 --- arch/esp32/esp32c6.ini | 47 ++++++++++++++++++++++++ src/gps/GPS.cpp | 5 ++- src/graphics/Screen.cpp | 28 +++++++------- src/main.cpp | 14 ++++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/TypedQueue.h | 2 +- src/mesh/api/ServerAPI.cpp | 2 +- src/mesh/wifi/WiFiAPClient.cpp | 3 +- src/modules/ExternalNotificationModule.h | 2 +- src/modules/PositionModule.cpp | 16 ++++---- src/modules/SerialModule.cpp | 21 ++++++++++- src/mqtt/MQTT.cpp | 4 ++ src/mqtt/MQTT.h | 4 ++ src/platform/esp32/main-esp32.cpp | 12 +++++- src/power.h | 1 + src/serialization/JSON.cpp | 2 +- src/sleep.cpp | 4 +- variants/tlora_c6/platformio.ini | 5 +++ variants/tlora_c6/variant.h | 16 ++++++++ 19 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 arch/esp32/esp32c6.ini create mode 100644 variants/tlora_c6/platformio.ini create mode 100644 variants/tlora_c6/variant.h diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini new file mode 100644 index 000000000..a7bcdc0e8 --- /dev/null +++ b/arch/esp32/esp32c6.ini @@ -0,0 +1,47 @@ +[esp32c6_base] +extends = esp32_base +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +build_flags = + ${arduino_base.build_flags} + -Wall + -Wextra + -Isrc/platform/esp32 + -std=c++11 + -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL + -DAXP_DEBUG_PORT=Serial + -DCONFIG_BT_NIMBLE_ENABLED + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 + -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DSERIAL_BUFFER_SIZE=4096 + -DLIBPAX_ARDUINO + -DLIBPAX_WIFI + -DLIBPAX_BLE + -DMESHTASTIC_EXCLUDE_WEBSERVER + ;-DDEBUG_HEAP + ; TEMP + -DHAS_BLUETOOTH=0 + -DMESHTASTIC_EXCLUDE_PAXCOUNTER + -DMESHTASTIC_EXCLUDE_BLUETOOTH + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +lib_deps = + ${arduino_base.lib_deps} + ${networking_base.lib_deps} + ${environmental_base.lib_deps} + https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 + https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f + rweather/Crypto@^0.4.0 + +build_src_filter = + ${esp32_base.build_src_filter} - + +monitor_speed = 115200 +monitor_filters = esp32_c3_exception_decoder + +lib_ignore = + NonBlockingRTTTL + NimBLE-Arduino + libpax + \ No newline at end of file diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 046f277ff..145d8b941 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -58,7 +58,8 @@ const char *getGPSPowerStateString(GPSPowerState state) case GPS_OFF: return "OFF"; default: - assert(false); // Unhandled enum value.. + assert(false); // Unhandled enum value.. + return "FALSE"; // to make new ESP-IDF happy } } @@ -328,7 +329,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); - uint16_t needRead; + uint16_t needRead = 0; while (millis() - startTime < waitMillis) { if (_serial_gps->available()) { diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index ff1254812..2de5e3f0a 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1004,55 +1004,55 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->setColor(WHITE); #ifndef EXCLUDE_EMOJI - if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { + if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbup); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44E") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44E") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbdown); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"❓") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "❓") == 0) { display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height, question); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"‼️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "‼️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5, bang_width, bang_height, bang); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F4A9") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F4A9") == 0) { display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5, poo_width, poo_height, poo); } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) { display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5, haha_width, haha_height, haha); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44B") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44B") == 0) { display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width, wave_icon_height, wave_icon); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F920") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F920") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height, cowboy); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F42D") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F42D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height, deadmau5); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xE2\x98\x80\xEF\xB8\x8F") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) { display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5, sun_width, sun_height, sun); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\u2614") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\u2614") == 0) { display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10, rain_width, rain_height, rain); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"☁️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "☁️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"🌫️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "🌫️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5, fog_width, fog_height, fog); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xf0\x9f\x98\x88") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) { display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"♥️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "♥️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart); } else { diff --git a/src/main.cpp b/src/main.cpp index 1401f4f0b..cbbe824e4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,15 +322,19 @@ void setup() #ifdef BUTTON_PIN #ifdef ARCH_ESP32 - // If the button is connected to GPIO 12, don't enable the ability to use - // meshtasticAdmin on the device. - pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); - +#if ESP_ARDUINO_VERSION_MAJOR >= 3 +#ifdef BUTTON_NEED_PULLUP + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP); +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN +#endif +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN #ifdef BUTTON_NEED_PULLUP gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); delay(10); #endif - +#endif #endif #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5d1db88ae..33fe5a090 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -49,7 +49,7 @@ NodeDB *nodeDB = nullptr; // we have plenty of ram so statically alloc this tempbuf (for now) -EXT_RAM_ATTR meshtastic_DeviceState devicestate; +EXT_RAM_BSS_ATTR meshtastic_DeviceState devicestate; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_LocalConfig config; meshtastic_LocalModuleConfig moduleConfig; diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index c96edae8e..f7d016f10 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -14,7 +14,7 @@ */ template class TypedQueue { - static_assert(std::is_pod::value, "T must be pod"); + static_assert(std::is_standard_layout::value, "T must be standard layout"); QueueHandle_t h; concurrency::OSThread *reader = NULL; diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 3a483aac1..097f4fa21 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,7 +45,7 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { - auto client = U::available(); + auto client = U::accept(); if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 07b03222e..e3203e6f7 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -309,7 +309,8 @@ static void WiFiEvent(WiFiEvent_t event) onNetworkConnected(); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str()); + LOG_INFO("Obtained Local IP6 address: %s\n", WiFi.linkLocalIPv6().toString().c_str()); + LOG_INFO("Obtained GlobalIP6 address: %s\n", WiFi.globalIPv6().toString().c_str()); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index 08e72c35a..a5dff3651 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -3,7 +3,7 @@ #include "SinglePortModule.h" #include "concurrency/OSThread.h" #include "configuration.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6) #include #else // Noop class for portduino. diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb6a58b2e..2a962c268 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -273,7 +273,7 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() meshtastic_TAKPacket takPacket = {.is_compressed = true, .has_contact = true, - .contact = {0}, + .contact = meshtastic_Contact_init_default, .has_group = true, .group = {meshtastic_MemberRole_TeamMember, meshtastic_Team_Cyan}, .has_status = true, @@ -282,13 +282,13 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() .battery = powerStatus->getBatteryChargePercent(), }, .which_payload_variant = meshtastic_TAKPacket_pli_tag, - {.pli = { - .latitude_i = localPosition.latitude_i, - .longitude_i = localPosition.longitude_i, - .altitude = localPosition.altitude_hae, - .speed = localPosition.ground_speed, - .course = static_cast(localPosition.ground_track), - }}}; + .payload_variant = {.pli = { + .latitude_i = localPosition.latitude_i, + .longitude_i = localPosition.longitude_i, + .altitude = localPosition.altitude_hae, + .speed = localPosition.ground_speed, + .course = static_cast(localPosition.ground_track), + }}}; auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign, sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index f0ba64f65..549fcf1d7 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -62,6 +62,9 @@ SerialModuleRadio *serialModuleRadio; #if defined(TTGO_T_ECHO) || defined(CANARYONE) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("SerialModule") {} +static Print *serialPrint = &Serial1; #else SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial2; @@ -137,7 +140,16 @@ int32_t SerialModule::runOnce() // Give it a chance to flush out 💩 delay(10); } -#ifdef ARCH_ESP32 +#if defined(CONFIG_IDF_TARGET_ESP32C6) + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial1.setRxBufferSize(RX_BUFFER); + Serial1.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); + } else { + Serial.begin(baud); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); + } + +#elif defined(ARCH_ESP32) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { Serial2.setRxBufferSize(RX_BUFFER); @@ -205,8 +217,13 @@ int32_t SerialModule::runOnce() processWXSerial(); } else { +#if defined(CONFIG_IDF_TARGET_ESP32C6) + while (Serial1.available()) { + serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#else while (Serial2.available()) { serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#endif serialModuleRadio->sendPayload(); } } @@ -392,7 +409,7 @@ uint32_t SerialModule::getBaudRate() */ void SerialModule::processWXSerial() { -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) +#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index d14c7a923..c59661a62 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -310,6 +310,7 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } #if HAS_WIFI && !defined(ARCH_PORTDUINO) +#ifndef CONFIG_IDF_TARGET_ESP32C6 if (moduleConfig.mqtt.tls_enabled) { // change default for encrypted to 8883 try { @@ -325,6 +326,9 @@ void MQTT::reconnect() LOG_INFO("Using non-TLS-encrypted session\n"); pubSub.setClient(mqttClient); } +#else + pubSub.setClient(mqttClient); +#endif #elif HAS_NETWORKING pubSub.setClient(mqttClient); #endif diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index ba0987783..c827e12ca 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -9,9 +9,11 @@ #if HAS_WIFI #include #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 #include #endif #endif +#endif #if HAS_ETHERNET #include #endif @@ -33,9 +35,11 @@ class MQTT : private concurrency::OSThread #if HAS_WIFI WiFiClient mqttClient; #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 WiFiClientSecure wifiSecureClient; #endif #endif +#endif #if HAS_ETHERNET EthernetClient mqttClient; #endif diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 1b997500a..12a6b5f74 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -13,6 +13,7 @@ #include "mesh/wifi/WiFiAPClient.h" #endif +#include "esp_mac.h" #include "meshUtils.h" #include "sleep.h" #include "soc/rtc.h" @@ -140,9 +141,16 @@ void esp32Setup() // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 +#ifdef CONFIG_IDF_TARGET_ESP32C6 + esp_task_wdt_config_t *wdt_config = (esp_task_wdt_config_t *)malloc(sizeof(esp_task_wdt_config_t)); + wdt_config->timeout_ms = APP_WATCHDOG_SECS * 1000; + wdt_config->trigger_panic = true; + res = esp_task_wdt_init(wdt_config); + assert(res == ESP_OK); +#else res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); assert(res == ESP_OK); - +#endif res = esp_task_wdt_add(NULL); assert(res == ESP_OK); @@ -216,7 +224,7 @@ void cpuDeepSleep(uint32_t msecToWake) // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. -#if SOC_RTCIO_HOLD_SUPPORTED +#if SOC_RTCIO_HOLD_SUPPORTED && SOC_PM_SUPPORT_EXT_WAKEUP uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif diff --git a/src/power.h b/src/power.h index a4307ee07..5a41b55f2 100644 --- a/src/power.h +++ b/src/power.h @@ -5,6 +5,7 @@ #include "configuration.h" #ifdef ARCH_ESP32 +// "legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h #include #include #endif diff --git a/src/serialization/JSON.cpp b/src/serialization/JSON.cpp index e98bf47b9..42e615108 100644 --- a/src/serialization/JSON.cpp +++ b/src/serialization/JSON.cpp @@ -184,7 +184,7 @@ bool JSON::ExtractString(const char **data, std::string &str) // End of the string? else if (next_char == '"') { (*data)++; - str.reserve(); // Remove unused capacity + str.shrink_to_fit(); // Remove unused capacity return true; } diff --git a/src/sleep.cpp b/src/sleep.cpp index 27e81ce54..b0802c624 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -446,12 +446,14 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { - static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss + static esp_pm_config_t esp32_config; // filled with zeros because bss #if CONFIG_IDF_TARGET_ESP32S3 esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32S2 esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ; +#elif CONFIG_IDF_TARGET_ESP32C6 + esp32_config.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32C3 esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ; #else diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini new file mode 100644 index 000000000..977e8ba86 --- /dev/null +++ b/variants/tlora_c6/platformio.ini @@ -0,0 +1,5 @@ +[env:tlora-c6] +extends = esp32c6_base +board = esp32-c6-devkitm-1 +build_flags = + ${esp32c6_base.build_flags} -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 \ No newline at end of file diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h new file mode 100644 index 000000000..08fefa809 --- /dev/null +++ b/variants/tlora_c6/variant.h @@ -0,0 +1,16 @@ +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 15 + +#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller + +#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost +#define LED_PIN 2 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP +#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. + +#define USE_RF95 +#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 \ No newline at end of file From d36c69396b79caa734dc3009798389fd9b6299a5 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 13 Sep 2024 10:42:40 -0500 Subject: [PATCH 049/252] Exclude meshtasticd binaries from firmware.zip (#4698) * Exclude meshtasticd binaries from firmware.zip * Incorrect --- .github/workflows/main_matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 36125f72f..9b97dcb2e 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -266,7 +266,7 @@ jobs: chmod +x ./output/device-update.sh - name: Zip firmware - run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x *.deb + run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x meshtasticd_* - uses: actions/download-artifact@v4 with: From 8b911f14cff15c4de6d7bdedb1bac854e7382d85 Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Fri, 13 Sep 2024 14:11:39 -0700 Subject: [PATCH 050/252] Update Bug Report.yml (#4702) --- .github/ISSUE_TEMPLATE/Bug Report.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml index b5ca0db40..f2d2f6507 100644 --- a/.github/ISSUE_TEMPLATE/Bug Report.yml +++ b/.github/ISSUE_TEMPLATE/Bug Report.yml @@ -49,10 +49,24 @@ body: - Heltec V3 - Heltec Wireless Paper - Heltec Wireless Tracker + - Heltec Mesh Node T114 + - Heltec Vision Master E213 + - Heltec Vision Master E290 + - Heltec Vision Master T190 + - Nano G1 + - Nano G1 Explorer + - Nano G2 Ultra - Raspberry Pi Pico (W) - Relay v1 - Relay v2 - Seeed Wio Tracker 1110 + - Seeed Card Tracker T1000-E + - Station G1 + - Station G2 + - unPhone + - CanaryOne + - Chatter + - Linux Native - DIY - Other validations: From b59bd6fee9feb5370d042a4408019627138373cb Mon Sep 17 00:00:00 2001 From: rcarteraz Date: Fri, 13 Sep 2024 14:11:54 -0700 Subject: [PATCH 051/252] Update feature.yml (#4700) --- .github/ISSUE_TEMPLATE/feature.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index b027a36cc..b50ccac26 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -18,6 +18,7 @@ body: - ESP32 - RP2040 - Linux Native + - Cross-Platform - other validations: required: true From 35cfe4318ac422f5820415fe96ceb91ddcf79cf5 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 13 Sep 2024 19:42:31 -0500 Subject: [PATCH 052/252] Stop past timestamps from setting our system time RTC (#4704) * Ignore attempts to set times in the past (before our build epoch) * TRONK --- platformio.ini | 1 + src/gps/RTC.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/platformio.ini b/platformio.ini index 7613a2f43..d561aaf74 100644 --- a/platformio.ini +++ b/platformio.ini @@ -81,6 +81,7 @@ build_flags = -Wno-missing-field-initializers -DRADIOLIB_EXCLUDE_APRS -DRADIOLIB_EXCLUDE_LORAWAN -DMESHTASTIC_EXCLUDE_DROPZONE=1 + -DBUILD_EPOCH=$UNIX_TIME ;-D OLED_PL monitor_speed = 115200 diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index c056bb9e4..42a98f568 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -109,6 +109,12 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) static uint32_t lastSetMsec = 0; uint32_t now = millis(); uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms +#ifdef BUILD_EPOCH + if (tv->tv_sec < BUILD_EPOCH) { + LOG_WARN("Ignoring time (%ld) before build epoch (%ld)!\n", printableEpoch, BUILD_EPOCH); + return false; + } +#endif bool shouldSet; if (forceUpdate) { From ae791ca7e19583f2ccc9d7190256e8d23d7dfc89 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 13 Sep 2024 19:43:50 -0500 Subject: [PATCH 053/252] Add buildstamp epoch to initial debug output --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 1401f4f0b..df90c4722 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -586,6 +586,9 @@ void setup() // Hello printInfo(); +#ifdef BUILD_EPOCH + LOG_INFO("Build timestamp: %ld\n", BUILD_EPOCH); +#endif #ifdef ARCH_ESP32 esp32Setup(); From 1ab5bf43559413519d9b4e95273951eaa00da4b8 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 14 Sep 2024 07:44:40 -0500 Subject: [PATCH 054/252] Use the time.age() value to correct stale GPS times (#4705) * Use the time.age() value to correct stale GPS times * Trunk --------- Co-authored-by: Ben Meadors --- src/gps/GPS.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 046f277ff..8abb4edb1 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1539,7 +1539,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s (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_sec = ti.second() + round(ti.age() / 1000); t.tm_min = ti.minute(); t.tm_hour = ti.hour(); t.tm_mday = d.day(); @@ -1547,8 +1547,8 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s 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); + LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d age %d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, ti.age()); perhapsSetRTC(RTCQualityGPS, t); return true; } else @@ -1807,4 +1807,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS From 8893529653cb23060f88f3ff56b092e5291facac Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:53:27 +0200 Subject: [PATCH 055/252] Make local stats number of Rx packets sum of good and bad (#4709) --- src/modules/Telemetry/DeviceTelemetry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 305be9904..04789af5e 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -124,7 +124,7 @@ void DeviceTelemetryModule::sendLocalStatsToPhone() telemetry.variant.local_stats.num_total_nodes = nodeDB->getNumMeshNodes(); if (RadioLibInterface::instance) { telemetry.variant.local_stats.num_packets_tx = RadioLibInterface::instance->txGood; - telemetry.variant.local_stats.num_packets_rx = RadioLibInterface::instance->rxGood; + telemetry.variant.local_stats.num_packets_rx = RadioLibInterface::instance->rxGood + RadioLibInterface::instance->rxBad; telemetry.variant.local_stats.num_packets_rx_bad = RadioLibInterface::instance->rxBad; } From 3a10a2785153e6282102f9376aee0102c6e29400 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 15 Sep 2024 06:27:59 -0500 Subject: [PATCH 056/252] Actually restrict remote hardware to gpio channel (#4717) --- src/modules/RemoteHardwareModule.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index 6910005a8..0242b59bc 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -47,6 +47,8 @@ RemoteHardwareModule::RemoteHardwareModule() : ProtobufModule("remotehardware", meshtastic_PortNum_REMOTE_HARDWARE_APP, &meshtastic_HardwareMessage_msg), concurrency::OSThread("RemoteHardwareModule") { + // restrict to the gpio channel for rx + boundChannel = Channels::gpioChannel; } bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &req, meshtastic_HardwareMessage *pptr) From ff8baa1c85d624b1354346ba3b2e19b733e0947c Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 15 Sep 2024 09:26:43 -0500 Subject: [PATCH 057/252] Don't use PKC on a non-primary channel unless specifically requested (#4715) * Don't use PKC on a non-primary channel unless specifically requested * Don't change from channel 0 if we can send a PKC packet. --- src/mesh/Router.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index b222872fa..deb4ef2bf 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -185,9 +185,12 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src) handleReceived(p, src); } - if (!p->channel) { // don't override if a channel was requested - p->channel = nodeDB->getMeshNodeChannel(p->to); - LOG_DEBUG("localSend to channel %d\n", p->channel); + if (!p->channel && !p->pki_encrypted) { // don't override if a channel was requested + meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to); + if (node && node->user.public_key.size == 0) { + p->channel = node->channel; + LOG_DEBUG("localSend to channel %d\n", p->channel); + } } return send(p); @@ -478,10 +481,20 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) #if !(MESHTASTIC_EXCLUDE_PKI) meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to); - if (!owner.is_licensed && config.security.private_key.size == 32 && p->to != NODENUM_BROADCAST && node != nullptr && - node->user.public_key.size > 0 && p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && - p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && - p->decoded.portnum != meshtastic_PortNum_POSITION_APP) { + // We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the node + // is not in the local nodedb + if ( + // Don't use PKC with Ham mode + !owner.is_licensed && + // Don't use PKC if it's not explicitly requested and a non-primary channel is requested + !(p->pki_encrypted != true && p->channel > 0) && + // Check for valid keys and single node destination + config.security.private_key.size == 32 && p->to != NODENUM_BROADCAST && node != nullptr && + // Check for a known public key for the destination + (node->user.public_key.size == 32) && + // Some portnums either make no sense to send with PKC + p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && + p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) { LOG_DEBUG("Using PKI!\n"); if (numbytes + 12 > MAX_RHPACKETLEN) return meshtastic_Routing_Error_TOO_LARGE; From dc3eba91002ff5510d6e28a286a75f5229aa4579 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 15 Sep 2024 18:57:02 -0500 Subject: [PATCH 058/252] Expand to MqttClientProxyMessage_size (#4726) --- src/mqtt/MQTT.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index d14c7a923..0f4c5a8c5 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -468,7 +468,7 @@ void MQTT::publishQueuedMessages() LOG_DEBUG("Publishing enqueued MQTT message\n"); // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets meshtastic_ServiceEnvelope *env = mqttQueue.dequeuePtr(0); - static uint8_t bytes[meshtastic_MeshPacket_size + 64]; + static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env); std::string topic; if (env->packet->pki_encrypted) { @@ -555,7 +555,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & if (moduleConfig.mqtt.proxy_to_client_enabled || this->isConnectedDirectly()) { // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets - static uint8_t bytes[meshtastic_MeshPacket_size + 64]; + static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env); std::string topic = cryptTopic + channelId + "/" + owner.id; LOG_DEBUG("MQTT Publish %s, %u bytes\n", topic.c_str(), numBytes); @@ -651,7 +651,7 @@ void MQTT::perhapsReportToMap() se->packet = mp; // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets - static uint8_t bytes[meshtastic_MeshPacket_size + 64]; + static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, se); LOG_INFO("MQTT Publish map report to %s\n", mapTopic.c_str()); From 8d57b6164abcd0f0d214b1981e61d21d1cab7256 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 15 Sep 2024 20:37:19 -0500 Subject: [PATCH 059/252] Add Heltec T1114 hardware model to build (#4719) --- src/platform/nrf52/architecture.h | 2 ++ variants/heltec_mesh_node_t114/platformio.ini | 1 + 2 files changed, 3 insertions(+) diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index 5a04dd6a7..d08f83965 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -71,6 +71,8 @@ #define HW_VENDOR meshtastic_HardwareModel_MS24SF1 #elif defined(PRIVATE_HW) || defined(FEATHER_DIY) #define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW +#elif defined(HELTEC_T1114) +#define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 #else #define HW_VENDOR meshtastic_HardwareModel_NRF52_UNKNOWN #endif diff --git a/variants/heltec_mesh_node_t114/platformio.ini b/variants/heltec_mesh_node_t114/platformio.ini index 1009ecce5..e0d8ca0cc 100644 --- a/variants/heltec_mesh_node_t114/platformio.ini +++ b/variants/heltec_mesh_node_t114/platformio.ini @@ -8,6 +8,7 @@ debug_tool = jlink build_flags = ${nrf52840_base.build_flags} -Ivariants/heltec_mesh_node_t114 -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" -DGPS_POWER_TOGGLE + -DHELTEC_T114 build_src_filter = ${nrf52_base.build_src_filter} +<../variants/heltec_mesh_node_t114> lib_deps = From 41a769aa06732279ae0dcec66eeb4c8ed0c74c73 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 16 Sep 2024 13:55:27 +0800 Subject: [PATCH 060/252] Fix Heltec T114 vendor definition @dahanc pointed out there was an extra one in there. --- src/platform/nrf52/architecture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index d08f83965..b2b7b5a20 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -71,7 +71,7 @@ #define HW_VENDOR meshtastic_HardwareModel_MS24SF1 #elif defined(PRIVATE_HW) || defined(FEATHER_DIY) #define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW -#elif defined(HELTEC_T1114) +#elif defined(HELTEC_T114) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 #else #define HW_VENDOR meshtastic_HardwareModel_NRF52_UNKNOWN From 4e8672cce45fb49f77878f21dd93128edaa6a73a Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Mon, 16 Sep 2024 10:40:52 +0200 Subject: [PATCH 061/252] Update variant.h --- variants/ME25LS01-4Y10TD_e-ink/variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/ME25LS01-4Y10TD_e-ink/variant.h b/variants/ME25LS01-4Y10TD_e-ink/variant.h index 60996d468..0b2b13068 100644 --- a/variants/ME25LS01-4Y10TD_e-ink/variant.h +++ b/variants/ME25LS01-4Y10TD_e-ink/variant.h @@ -97,7 +97,7 @@ static const uint8_t MISO = PIN_SPI_MISO; static const uint8_t SCK = PIN_SPI_SCK; // EPD SPI -#define PIN_SPI1_MISO (-1) // Not Used for EPD +#define PIN_SPI1_MISO (32 + 2) // Not Used for EPD but needs to be defined #define PIN_SPI1_MOSI (0 + 10) // EPD_MOSI P0.10 #define PIN_SPI1_SCK (0 + 9) // EPD_SCLK P0.09 From ea6f6c3668317d6ca5dc51e8dd4b2a99d84d7a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Sep 2024 22:42:10 +0200 Subject: [PATCH 062/252] First stab at ESP32-C6 support for TLora-C6 --- arch/esp32/esp32c6.ini | 47 ++++++++++++++++++++++++ src/gps/GPS.cpp | 5 ++- src/graphics/Screen.cpp | 28 +++++++------- src/main.cpp | 14 ++++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/TypedQueue.h | 2 +- src/mesh/api/ServerAPI.cpp | 2 +- src/mesh/wifi/WiFiAPClient.cpp | 3 +- src/modules/ExternalNotificationModule.h | 2 +- src/modules/PositionModule.cpp | 16 ++++---- src/modules/SerialModule.cpp | 21 ++++++++++- src/mqtt/MQTT.cpp | 4 ++ src/mqtt/MQTT.h | 4 ++ src/platform/esp32/main-esp32.cpp | 12 +++++- src/power.h | 1 + src/serialization/JSON.cpp | 2 +- src/sleep.cpp | 4 +- variants/tlora_c6/platformio.ini | 5 +++ variants/tlora_c6/variant.h | 16 ++++++++ 19 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 arch/esp32/esp32c6.ini create mode 100644 variants/tlora_c6/platformio.ini create mode 100644 variants/tlora_c6/variant.h diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini new file mode 100644 index 000000000..a7bcdc0e8 --- /dev/null +++ b/arch/esp32/esp32c6.ini @@ -0,0 +1,47 @@ +[esp32c6_base] +extends = esp32_base +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +build_flags = + ${arduino_base.build_flags} + -Wall + -Wextra + -Isrc/platform/esp32 + -std=c++11 + -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL + -DAXP_DEBUG_PORT=Serial + -DCONFIG_BT_NIMBLE_ENABLED + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 + -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DSERIAL_BUFFER_SIZE=4096 + -DLIBPAX_ARDUINO + -DLIBPAX_WIFI + -DLIBPAX_BLE + -DMESHTASTIC_EXCLUDE_WEBSERVER + ;-DDEBUG_HEAP + ; TEMP + -DHAS_BLUETOOTH=0 + -DMESHTASTIC_EXCLUDE_PAXCOUNTER + -DMESHTASTIC_EXCLUDE_BLUETOOTH + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +lib_deps = + ${arduino_base.lib_deps} + ${networking_base.lib_deps} + ${environmental_base.lib_deps} + https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 + https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f + rweather/Crypto@^0.4.0 + +build_src_filter = + ${esp32_base.build_src_filter} - + +monitor_speed = 115200 +monitor_filters = esp32_c3_exception_decoder + +lib_ignore = + NonBlockingRTTTL + NimBLE-Arduino + libpax + \ No newline at end of file diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 8abb4edb1..8938cc371 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -58,7 +58,8 @@ const char *getGPSPowerStateString(GPSPowerState state) case GPS_OFF: return "OFF"; default: - assert(false); // Unhandled enum value.. + assert(false); // Unhandled enum value.. + return "FALSE"; // to make new ESP-IDF happy } } @@ -328,7 +329,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); - uint16_t needRead; + uint16_t needRead = 0; while (millis() - startTime < waitMillis) { if (_serial_gps->available()) { diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index ff1254812..2de5e3f0a 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1004,55 +1004,55 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->setColor(WHITE); #ifndef EXCLUDE_EMOJI - if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { + if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbup); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44E") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44E") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbdown); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"❓") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "❓") == 0) { display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height, question); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"‼️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "‼️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5, bang_width, bang_height, bang); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F4A9") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F4A9") == 0) { display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5, poo_width, poo_height, poo); } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) { display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5, haha_width, haha_height, haha); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44B") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44B") == 0) { display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width, wave_icon_height, wave_icon); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F920") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F920") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height, cowboy); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F42D") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F42D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height, deadmau5); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xE2\x98\x80\xEF\xB8\x8F") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) { display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5, sun_width, sun_height, sun); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\u2614") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\u2614") == 0) { display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10, rain_width, rain_height, rain); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"☁️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "☁️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"🌫️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "🌫️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5, fog_width, fog_height, fog); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xf0\x9f\x98\x88") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) { display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"♥️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "♥️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart); } else { diff --git a/src/main.cpp b/src/main.cpp index df90c4722..2b7410ac1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,15 +322,19 @@ void setup() #ifdef BUTTON_PIN #ifdef ARCH_ESP32 - // If the button is connected to GPIO 12, don't enable the ability to use - // meshtasticAdmin on the device. - pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); - +#if ESP_ARDUINO_VERSION_MAJOR >= 3 +#ifdef BUTTON_NEED_PULLUP + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP); +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN +#endif +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN #ifdef BUTTON_NEED_PULLUP gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); delay(10); #endif - +#endif #endif #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5d1db88ae..33fe5a090 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -49,7 +49,7 @@ NodeDB *nodeDB = nullptr; // we have plenty of ram so statically alloc this tempbuf (for now) -EXT_RAM_ATTR meshtastic_DeviceState devicestate; +EXT_RAM_BSS_ATTR meshtastic_DeviceState devicestate; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_LocalConfig config; meshtastic_LocalModuleConfig moduleConfig; diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index c96edae8e..f7d016f10 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -14,7 +14,7 @@ */ template class TypedQueue { - static_assert(std::is_pod::value, "T must be pod"); + static_assert(std::is_standard_layout::value, "T must be standard layout"); QueueHandle_t h; concurrency::OSThread *reader = NULL; diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 3a483aac1..097f4fa21 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,7 +45,7 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { - auto client = U::available(); + auto client = U::accept(); if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 07b03222e..e3203e6f7 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -309,7 +309,8 @@ static void WiFiEvent(WiFiEvent_t event) onNetworkConnected(); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str()); + LOG_INFO("Obtained Local IP6 address: %s\n", WiFi.linkLocalIPv6().toString().c_str()); + LOG_INFO("Obtained GlobalIP6 address: %s\n", WiFi.globalIPv6().toString().c_str()); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index 08e72c35a..a5dff3651 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -3,7 +3,7 @@ #include "SinglePortModule.h" #include "concurrency/OSThread.h" #include "configuration.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6) #include #else // Noop class for portduino. diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb6a58b2e..2a962c268 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -273,7 +273,7 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() meshtastic_TAKPacket takPacket = {.is_compressed = true, .has_contact = true, - .contact = {0}, + .contact = meshtastic_Contact_init_default, .has_group = true, .group = {meshtastic_MemberRole_TeamMember, meshtastic_Team_Cyan}, .has_status = true, @@ -282,13 +282,13 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() .battery = powerStatus->getBatteryChargePercent(), }, .which_payload_variant = meshtastic_TAKPacket_pli_tag, - {.pli = { - .latitude_i = localPosition.latitude_i, - .longitude_i = localPosition.longitude_i, - .altitude = localPosition.altitude_hae, - .speed = localPosition.ground_speed, - .course = static_cast(localPosition.ground_track), - }}}; + .payload_variant = {.pli = { + .latitude_i = localPosition.latitude_i, + .longitude_i = localPosition.longitude_i, + .altitude = localPosition.altitude_hae, + .speed = localPosition.ground_speed, + .course = static_cast(localPosition.ground_track), + }}}; auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign, sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index f0ba64f65..549fcf1d7 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -62,6 +62,9 @@ SerialModuleRadio *serialModuleRadio; #if defined(TTGO_T_ECHO) || defined(CANARYONE) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("SerialModule") {} +static Print *serialPrint = &Serial1; #else SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial2; @@ -137,7 +140,16 @@ int32_t SerialModule::runOnce() // Give it a chance to flush out 💩 delay(10); } -#ifdef ARCH_ESP32 +#if defined(CONFIG_IDF_TARGET_ESP32C6) + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial1.setRxBufferSize(RX_BUFFER); + Serial1.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); + } else { + Serial.begin(baud); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); + } + +#elif defined(ARCH_ESP32) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { Serial2.setRxBufferSize(RX_BUFFER); @@ -205,8 +217,13 @@ int32_t SerialModule::runOnce() processWXSerial(); } else { +#if defined(CONFIG_IDF_TARGET_ESP32C6) + while (Serial1.available()) { + serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#else while (Serial2.available()) { serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#endif serialModuleRadio->sendPayload(); } } @@ -392,7 +409,7 @@ uint32_t SerialModule::getBaudRate() */ void SerialModule::processWXSerial() { -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) +#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 0f4c5a8c5..9068846e2 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -310,6 +310,7 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } #if HAS_WIFI && !defined(ARCH_PORTDUINO) +#ifndef CONFIG_IDF_TARGET_ESP32C6 if (moduleConfig.mqtt.tls_enabled) { // change default for encrypted to 8883 try { @@ -325,6 +326,9 @@ void MQTT::reconnect() LOG_INFO("Using non-TLS-encrypted session\n"); pubSub.setClient(mqttClient); } +#else + pubSub.setClient(mqttClient); +#endif #elif HAS_NETWORKING pubSub.setClient(mqttClient); #endif diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index ba0987783..c827e12ca 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -9,9 +9,11 @@ #if HAS_WIFI #include #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 #include #endif #endif +#endif #if HAS_ETHERNET #include #endif @@ -33,9 +35,11 @@ class MQTT : private concurrency::OSThread #if HAS_WIFI WiFiClient mqttClient; #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 WiFiClientSecure wifiSecureClient; #endif #endif +#endif #if HAS_ETHERNET EthernetClient mqttClient; #endif diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 1b997500a..12a6b5f74 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -13,6 +13,7 @@ #include "mesh/wifi/WiFiAPClient.h" #endif +#include "esp_mac.h" #include "meshUtils.h" #include "sleep.h" #include "soc/rtc.h" @@ -140,9 +141,16 @@ void esp32Setup() // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 +#ifdef CONFIG_IDF_TARGET_ESP32C6 + esp_task_wdt_config_t *wdt_config = (esp_task_wdt_config_t *)malloc(sizeof(esp_task_wdt_config_t)); + wdt_config->timeout_ms = APP_WATCHDOG_SECS * 1000; + wdt_config->trigger_panic = true; + res = esp_task_wdt_init(wdt_config); + assert(res == ESP_OK); +#else res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); assert(res == ESP_OK); - +#endif res = esp_task_wdt_add(NULL); assert(res == ESP_OK); @@ -216,7 +224,7 @@ void cpuDeepSleep(uint32_t msecToWake) // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. -#if SOC_RTCIO_HOLD_SUPPORTED +#if SOC_RTCIO_HOLD_SUPPORTED && SOC_PM_SUPPORT_EXT_WAKEUP uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif diff --git a/src/power.h b/src/power.h index a4307ee07..5a41b55f2 100644 --- a/src/power.h +++ b/src/power.h @@ -5,6 +5,7 @@ #include "configuration.h" #ifdef ARCH_ESP32 +// "legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h #include #include #endif diff --git a/src/serialization/JSON.cpp b/src/serialization/JSON.cpp index e98bf47b9..42e615108 100644 --- a/src/serialization/JSON.cpp +++ b/src/serialization/JSON.cpp @@ -184,7 +184,7 @@ bool JSON::ExtractString(const char **data, std::string &str) // End of the string? else if (next_char == '"') { (*data)++; - str.reserve(); // Remove unused capacity + str.shrink_to_fit(); // Remove unused capacity return true; } diff --git a/src/sleep.cpp b/src/sleep.cpp index 27e81ce54..b0802c624 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -446,12 +446,14 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { - static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss + static esp_pm_config_t esp32_config; // filled with zeros because bss #if CONFIG_IDF_TARGET_ESP32S3 esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32S2 esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ; +#elif CONFIG_IDF_TARGET_ESP32C6 + esp32_config.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32C3 esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ; #else diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini new file mode 100644 index 000000000..977e8ba86 --- /dev/null +++ b/variants/tlora_c6/platformio.ini @@ -0,0 +1,5 @@ +[env:tlora-c6] +extends = esp32c6_base +board = esp32-c6-devkitm-1 +build_flags = + ${esp32c6_base.build_flags} -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 \ No newline at end of file diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h new file mode 100644 index 000000000..08fefa809 --- /dev/null +++ b/variants/tlora_c6/variant.h @@ -0,0 +1,16 @@ +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 15 + +#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller + +#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost +#define LED_PIN 2 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP +#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. + +#define USE_RF95 +#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 \ No newline at end of file From 905194c6040bce4c1f036f1d040d23ba9029b187 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 16 Sep 2024 22:06:13 +0800 Subject: [PATCH 063/252] Remove lora_isp4520 (#4735) Per Ben: "We haven't supported any NRF5832 based board in quite some time. It's relatively resource constrained compared to the NRF52840" --- boards/lora_isp4520.json | 40 ------------ variants/lora_isp4520/platformio.ini | 18 ------ variants/lora_isp4520/variant.cpp | 52 --------------- variants/lora_isp4520/variant.h | 94 ---------------------------- 4 files changed, 204 deletions(-) delete mode 100644 boards/lora_isp4520.json delete mode 100644 variants/lora_isp4520/platformio.ini delete mode 100644 variants/lora_isp4520/variant.cpp delete mode 100644 variants/lora_isp4520/variant.h diff --git a/boards/lora_isp4520.json b/boards/lora_isp4520.json deleted file mode 100644 index 8125aa666..000000000 --- a/boards/lora_isp4520.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "build": { - "arduino": { - "ldscript": "nrf52832_s132_v6.ld" - }, - "core": "nRF5", - "cpu": "cortex-m4", - "extra_flags": "-DNRF52832_XXAA -DNRF52", - "f_cpu": "64000000L", - "mcu": "nrf52832", - "variant": "lora_isp4520", - "bsp": { - "name": "adafruit" - }, - "softdevice": { - "sd_flags": "-DS132", - "sd_name": "s132", - "sd_version": "6.1.1", - "sd_fwid": "0x00B7" - } - }, - "connectivity": ["bluetooth"], - "debug": { - "jlink_device": "nRF52832_xxAA", - "svd_path": "nrf52.svd", - "openocd_target": "nrf52840-mdk-rs" - }, - "frameworks": ["arduino"], - "name": "lora ISP4520", - "upload": { - "maximum_ram_size": 65536, - "maximum_size": 524288, - "require_upload_port": true, - "speed": 115200, - "protocol": "nrfutil", - "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"] - }, - "url": "", - "vendor": "PsiSoft" -} diff --git a/variants/lora_isp4520/platformio.ini b/variants/lora_isp4520/platformio.ini deleted file mode 100644 index 9d6563515..000000000 --- a/variants/lora_isp4520/platformio.ini +++ /dev/null @@ -1,18 +0,0 @@ -[env:lora_isp4520] -extends = nrf52_base -board = lora_isp4520 -board_level = extra - -# add our variants files to the include and src paths -build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520 - -# No screen and GPS on the board. We still need RTC.cpp for the RTC clock. -build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_isp4520> - - + + -lib_ignore = ${nrf52_base.lib_ignore} - ESP8266_SSD1306 - SparkFun Ublox Arduino Library - AXP202X_Library - TinyGPSPlus - -upload_protocol = jlink -monitor_port = /dev/ttyUSB0 \ No newline at end of file diff --git a/variants/lora_isp4520/variant.cpp b/variants/lora_isp4520/variant.cpp deleted file mode 100644 index 41b31384a..000000000 --- a/variants/lora_isp4520/variant.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. - Copyright (c) 2018, Adafruit Industries (adafruit.com) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "variant.h" -#include "nrf.h" -#include "wiring_constants.h" -#include "wiring_digital.h" - -const uint32_t g_ADigitalPinMap[] = { - 25, // D0 SPI_MISO - 24, // D1 SPI_NSS - 23, // D2 SPI_SCK - 4, // D3 VBAT - 11, // D4 DIO1 - 27, // D5 BUSY - 19, // D6 NRESET - 12, // D7 BUTTON2 - 22, // D8 BUTTON3 - 26, // D9 SPI_MOSI - 31, // D10 UART_RX - 2, // D11 UART_TX - 10, // D12 LED1 GREEN - 17, // D13 LED2 RED - 9, // D14 BUZZER - 7, // D15 BUTTON1 -}; - -#include -void initVariant() -{ - for (int i : {PIN_LED1, PIN_LED2}) { - pinMode(i, OUTPUT); - ledOff(i); - } -} diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h deleted file mode 100644 index 30b8fc169..000000000 --- a/variants/lora_isp4520/variant.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. - Copyright (c) 2018, Adafruit Industries (adafruit.com) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _VARIANT_LORA_ISP4520_ -#define _VARIANT_LORA_ISP4520_ - -#define USE_SEGGER -/*---------------------------------------------------------------------------- - * Headers - *----------------------------------------------------------------------------*/ - -#include "WVariant.h" - -#define USE_LFXO - -// #define USE_SEGGER - -// Number of pins defined in PinDescription array -#define PINS_COUNT (16) -#define NUM_DIGITAL_PINS (16) -#define NUM_ANALOG_INPUTS (1) -#define NUM_ANALOG_OUTPUTS (1) - -/* - * SPI Interfaces - */ -#define SPI_INTERFACES_COUNT 1 - -// These are in arduino pin numbers, -// translation in g_ADigitalPinMap in variants.cpp -#define PIN_SPI_MISO (0) -#define PIN_SPI_MOSI (9) -#define PIN_SPI_SCK (2) - -/* - * Wire Interfaces (I2C) - */ -#define WIRE_INTERFACES_COUNT 0 - -// GPIOs the SX1262 is connected -#define USE_SX1262 -#define SX126X_CS 1 // aka SPI_NSS -#define SX126X_DIO1 (4) -#define SX126X_BUSY (5) -#define SX126X_RESET (6) - -/* - * Serial interfaces - */ -#define PIN_SERIAL_RX (10) -#define PIN_SERIAL_TX (11) -// LEDs -#define PIN_LED1 (12) -#define PIN_LED2 (13) -#define PIN_BUZZER (14) - -#define LED_BUILTIN PIN_LED1 -#define LED_CONN PIN_LED2 - -#define LED_RED PIN_LED1 -#define LED_BLUE PIN_LED2 - -#define LED_STATE_ON 1 // State when LED is litted - -/* - * Buttons - */ -#define PIN_BUTTON1 (15) -#define PIN_BUTTON2 (7) -#define PIN_BUTTON3 (8) - -// ADC pin and voltage divider -#define BATTERY_PIN 3 -#define ADC_MULTIPLIER 1.436 - -#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 From f37276d5fcde65478194be334c1a0a7c05bd6978 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 10:32:21 -0500 Subject: [PATCH 064/252] [create-pull-request] automated change (#4736) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/atak.pb.h | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/protobufs b/protobufs index 0acaec6ef..0c0d061ec 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 0acaec6eff00e748beeae89148093221f131cd9c +Subproject commit 0c0d061ec58dec08b80334fd007ecb6c82cd8ed9 diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index 5fd18f963..50b57cd04 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -120,6 +120,7 @@ typedef struct _meshtastic_PLI { uint16_t course; } meshtastic_PLI; +typedef PB_BYTES_ARRAY_T(220) meshtastic_TAKPacket_detail_t; /* Packets for the official ATAK Plugin */ typedef struct _meshtastic_TAKPacket { /* Are the payloads strings compressed for LoRA transport? */ @@ -139,6 +140,9 @@ typedef struct _meshtastic_TAKPacket { meshtastic_PLI pli; /* ATAK GeoChat message */ meshtastic_GeoChat chat; + /* Generic CoT detail XML + May be compressed / truncated by the sender */ + meshtastic_TAKPacket_detail_t detail; } payload_variant; } meshtastic_TAKPacket; @@ -199,6 +203,7 @@ extern "C" { #define meshtastic_TAKPacket_status_tag 4 #define meshtastic_TAKPacket_pli_tag 5 #define meshtastic_TAKPacket_chat_tag 6 +#define meshtastic_TAKPacket_detail_tag 7 /* Struct field encoding specification for nanopb */ #define meshtastic_TAKPacket_FIELDLIST(X, a) \ @@ -207,7 +212,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, contact, 2) \ X(a, STATIC, OPTIONAL, MESSAGE, group, 3) \ X(a, STATIC, OPTIONAL, MESSAGE, status, 4) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,pli,payload_variant.pli), 5) \ -X(a, STATIC, ONEOF, MESSAGE, (payload_variant,chat,payload_variant.chat), 6) +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,chat,payload_variant.chat), 6) \ +X(a, STATIC, ONEOF, BYTES, (payload_variant,detail,payload_variant.detail), 7) #define meshtastic_TAKPacket_CALLBACK NULL #define meshtastic_TAKPacket_DEFAULT NULL #define meshtastic_TAKPacket_contact_MSGTYPE meshtastic_Contact From b3343303a9b77ce973bd253e138f21e7051e985e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 16 Sep 2024 21:36:54 +0200 Subject: [PATCH 065/252] write firmware version and hardware platform to Flash memory --- src/platform/esp32/main-esp32.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 1b997500a..0b6f7cf23 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -120,17 +120,24 @@ void esp32Setup() uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0); rebootCounter++; preferences.putUInt("rebootCounter", rebootCounter); + // store firmware version and hwrevision for access from OTA firmware + String fwrev = preferences.getString("firmwareVersion", ""); + if (fwrev.compareTo(optstr(APP_VERSION)) != 0) + preferences.putString("firmwareVersion", optstr(APP_VERSION)); + uint8_t hwven = preferences.getUInt("hwVendor", 0); + if (hwven != HW_VENDOR) + preferences.putUInt("hwVendor", HW_VENDOR); preferences.end(); LOG_DEBUG("Number of Device Reboots: %d\n", rebootCounter); #if !MESHTASTIC_EXCLUDE_BLUETOOTH String BLEOTA = BleOta::getOtaAppVersion(); if (BLEOTA.isEmpty()) { - LOG_DEBUG("No OTA firmware available\n"); + LOG_INFO("No OTA firmware available\n"); } else { - LOG_DEBUG("OTA firmware version %s\n", BLEOTA.c_str()); + LOG_INFO("OTA firmware version %s\n", BLEOTA.c_str()); } #else - LOG_DEBUG("No OTA firmware available\n"); + LOG_INFO("No OTA firmware available\n"); #endif // enableModemSleep(); From 1e665d5181e68be033790ec400327e0a27c855b5 Mon Sep 17 00:00:00 2001 From: jhps Date: Mon, 16 Sep 2024 17:11:55 -0700 Subject: [PATCH 066/252] Update T114 LED definitions to include only one simple controllable LED and two NEOPIXELS. (#4710) --- variants/heltec_mesh_node_t114/variant.cpp | 8 +------- variants/heltec_mesh_node_t114/variant.h | 23 ++++++++++------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/variants/heltec_mesh_node_t114/variant.cpp b/variants/heltec_mesh_node_t114/variant.cpp index cae079b74..85c9f4a72 100644 --- a/variants/heltec_mesh_node_t114/variant.cpp +++ b/variants/heltec_mesh_node_t114/variant.cpp @@ -32,13 +32,7 @@ const uint32_t g_ADigitalPinMap[] = { void initVariant() { - // LED1 & LED2 + // LED1 pinMode(PIN_LED1, OUTPUT); ledOff(PIN_LED1); - - pinMode(PIN_LED2, OUTPUT); - ledOff(PIN_LED2); - - pinMode(PIN_LED3, OUTPUT); - ledOff(PIN_LED3); } diff --git a/variants/heltec_mesh_node_t114/variant.h b/variants/heltec_mesh_node_t114/variant.h index e8c305990..454e66931 100644 --- a/variants/heltec_mesh_node_t114/variant.h +++ b/variants/heltec_mesh_node_t114/variant.h @@ -67,20 +67,17 @@ extern "C" { #define NUM_ANALOG_OUTPUTS (0) // LEDs -#define PIN_LED1 (32 + 3) // 13 red (confirmed on 1.0 board) -// Unused(by firmware) LEDs: -#define PIN_LED2 (1 + 1) // 14 blue -#define PIN_LED3 (1 + 11) // 15 green - -#define LED_RED PIN_LED3 -#define LED_BLUE PIN_LED1 -#define LED_GREEN PIN_LED2 - -#define LED_BUILTIN LED_BLUE -#define LED_CONN PIN_GREEN - +#define PIN_LED1 (32 + 3) // green (confirmed on 1.0 board) +#define LED_BLUE PIN_LED1 // fake for bluefruit library +#define LED_GREEN PIN_LED1 +#define LED_BUILTIN LED_GREEN #define LED_STATE_ON 0 // State when LED is lit +#define HAS_NEOPIXEL // Enable the use of neopixels +#define NEOPIXEL_COUNT 2 // How many neopixels are connected +#define NEOPIXEL_DATA 14 // gpio pin used to send data to the neopixels +#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use + /* * Buttons */ @@ -206,4 +203,4 @@ No longer populated on PCB * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif From 97fd189f43bbdc9b9467dcb161990960084c9960 Mon Sep 17 00:00:00 2001 From: Szetya Date: Thu, 12 Sep 2024 18:15:31 +0200 Subject: [PATCH 067/252] Compass update https://github.com/meshtastic/firmware/issues/4494 New compass arrow and replacement of the north marker with a small circle. --- src/graphics/Screen.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index ff1254812..6cf9e8f03 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1285,8 +1285,8 @@ static int8_t prevFrame = -1; // Draw the arrow pointing to a node's location void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian) { - Point tip(0.0f, 0.5f), tail(0.0f, -0.5f); // pointing up initially - float arrowOffsetX = 0.2f, arrowOffsetY = 0.2f; + Point tip(0.0f, 0.5f), tail(0.0f, -0.35f); // pointing up initially + float arrowOffsetX = 0.14f, arrowOffsetY = 1.0f; Point leftArrow(tip.x - arrowOffsetX, tip.y - arrowOffsetY), rightArrow(tip.x + arrowOffsetX, tip.y - arrowOffsetY); Point *arrowPoints[] = {&tip, &tail, &leftArrow, &rightArrow}; @@ -1296,9 +1296,15 @@ void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t com arrowPoints[i]->scale(compassDiam * 0.6); arrowPoints[i]->translate(compassX, compassY); } + /* Old arrow display->drawLine(tip.x, tip.y, tail.x, tail.y); display->drawLine(leftArrow.x, leftArrow.y, tip.x, tip.y); display->drawLine(rightArrow.x, rightArrow.y, tip.x, tip.y); + display->drawLine(leftArrow.x, leftArrow.y, tail.x, tail.y); + display->drawLine(rightArrow.x, rightArrow.y, tail.x, tail.y); + */ + display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y); + display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y); } // Get a string representation of the time passed since something happened @@ -1336,22 +1342,27 @@ void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t co // If north is supposed to be at the top of the compass we want rotation to be +0 if (config.display.compass_north_top) myHeading = -0; - - Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); + /* N sign points currently not deleted*/ + Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); //N sign points (N1-N4) Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); - Point *rosePoints[] = {&N1, &N2, &N3, &N4}; + Point NC1(0.00f, 0.50f); //north circle center point + Point *rosePoints[] = {&N1, &N2, &N3, &N4, &NC1}; uint16_t compassDiam = Screen::getCompassDiam(SCREEN_WIDTH, SCREEN_HEIGHT); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 5; i++) { // North on compass will be negative of heading rosePoints[i]->rotate(-myHeading); rosePoints[i]->scale(compassDiam); rosePoints[i]->translate(compassX, compassY); } + + /* changed the N sign to a small circle on the compass circle. display->drawLine(N1.x, N1.y, N3.x, N3.y); display->drawLine(N2.x, N2.y, N4.x, N4.y); display->drawLine(N1.x, N1.y, N4.x, N4.y); + */ + display->drawCircle(NC1.x, NC1.y, 4); // North sign circle, 4px radius is sufficient for all displays. } uint16_t Screen::getCompassDiam(uint32_t displayWidth, uint32_t displayHeight) @@ -2756,4 +2767,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg) } // namespace graphics #else graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {} -#endif // HAS_SCREEN \ No newline at end of file +#endif // HAS_SCREEN From 33e6f7f6e03950ed3ae0219cf27a6f231cff5f2d Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Sat, 14 Sep 2024 21:29:46 +1200 Subject: [PATCH 068/252] Hollow triangle for E-Ink; trunk formatting --- src/graphics/Screen.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6cf9e8f03..ae09ee408 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1303,7 +1303,11 @@ void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t com display->drawLine(leftArrow.x, leftArrow.y, tail.x, tail.y); display->drawLine(rightArrow.x, rightArrow.y, tail.x, tail.y); */ +#ifdef USE_EINK + display->drawTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y); +#else display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y); +#endif display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y); } @@ -1343,9 +1347,9 @@ void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t co if (config.display.compass_north_top) myHeading = -0; /* N sign points currently not deleted*/ - Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); //N sign points (N1-N4) + Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); // N sign points (N1-N4) Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); - Point NC1(0.00f, 0.50f); //north circle center point + Point NC1(0.00f, 0.50f); // north circle center point Point *rosePoints[] = {&N1, &N2, &N3, &N4, &NC1}; uint16_t compassDiam = Screen::getCompassDiam(SCREEN_WIDTH, SCREEN_HEIGHT); @@ -1356,13 +1360,13 @@ void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t co rosePoints[i]->scale(compassDiam); rosePoints[i]->translate(compassX, compassY); } - + /* changed the N sign to a small circle on the compass circle. display->drawLine(N1.x, N1.y, N3.x, N3.y); display->drawLine(N2.x, N2.y, N4.x, N4.y); display->drawLine(N1.x, N1.y, N4.x, N4.y); */ - display->drawCircle(NC1.x, NC1.y, 4); // North sign circle, 4px radius is sufficient for all displays. + display->drawCircle(NC1.x, NC1.y, 4); // North sign circle, 4px radius is sufficient for all displays. } uint16_t Screen::getCompassDiam(uint32_t displayWidth, uint32_t displayHeight) From 39c90dd581cbc742e2d55dc69936ab688471257d Mon Sep 17 00:00:00 2001 From: jp-bennett <5630967+jp-bennett@users.noreply.github.com> Date: Tue, 17 Sep 2024 02:53:44 +0000 Subject: [PATCH 069/252] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 8 ++++---- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 4 ++-- src/mesh/generated/meshtastic/mesh.pb.h | 10 +++++++--- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/protobufs b/protobufs index 0c0d061ec..c5108cfd6 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 0c0d061ec58dec08b80334fd007ecb6c82cd8ed9 +Subproject commit c5108cfd6bbc59adef44575dcec3067cbfbfeac1 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 66ffa0a4b..da2e43972 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -535,7 +535,7 @@ typedef struct _meshtastic_Config_SecurityConfig { meshtastic_Config_SecurityConfig_private_key_t private_key; /* The public key authorized to send admin messages to this node. */ pb_size_t admin_key_count; - meshtastic_Config_SecurityConfig_admin_key_t admin_key[1]; + meshtastic_Config_SecurityConfig_admin_key_t admin_key[3]; /* If true, device is considered to be "managed" by a mesh administrator via admin messages Device is managed by a mesh administrator. */ bool is_managed; @@ -660,7 +660,7 @@ extern "C" { #define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #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, 0}, 0, 0} #define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} -#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0} +#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_default {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, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0} @@ -671,7 +671,7 @@ extern "C" { #define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #define meshtastic_Config_LoRaConfig_init_zero {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, 0}, 0, 0} #define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} -#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0} +#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_zero {0} /* Field tags (for use in manual encoding/decoding) */ @@ -953,7 +953,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; #define meshtastic_Config_NetworkConfig_size 196 #define meshtastic_Config_PositionConfig_size 62 #define meshtastic_Config_PowerConfig_size 52 -#define meshtastic_Config_SecurityConfig_size 111 +#define meshtastic_Config_SecurityConfig_size 178 #define meshtastic_Config_SessionkeyConfig_size 0 #define meshtastic_Config_size 199 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 209084220..f87c84abe 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -358,7 +358,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size #define meshtastic_ChannelFile_size 718 #define meshtastic_NodeInfoLite_size 183 -#define meshtastic_OEMStore_size 3500 +#define meshtastic_OEMStore_size 3568 #define meshtastic_PositionLite_size 28 #define meshtastic_UserLite_size 96 diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 72f29500c..19600856f 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -186,8 +186,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; #define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg /* Maximum encoded size of messages (where known) */ -#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size -#define meshtastic_LocalConfig_size 667 +#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size +#define meshtastic_LocalConfig_size 735 #define meshtastic_LocalModuleConfig_size 687 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 948e89f22..f4e0a896b 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -316,7 +316,11 @@ typedef enum _meshtastic_Routing_Error { /* The client specified a PKI transport, but the node was unable to send the packet using PKI (and did not send the message at all) */ meshtastic_Routing_Error_PKI_FAILED = 34, /* The receiving node does not have a Public Key to decode with */ - meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY = 35 + meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY = 35, + /* Admin packet otherwise checks out, but uses a bogus or expired session key */ + meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY = 36, + /* Admin packet sent using PKC, but not from a public key on the admin key list */ + meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37 } meshtastic_Routing_Error; /* The priority of this message for sending. @@ -1026,8 +1030,8 @@ extern "C" { #define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1)) #define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE -#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY -#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY+1)) +#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED +#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED+1)) #define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET #define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX From 6f1db6fc630a69ee506abc5b0c462488e450850d Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 17 Sep 2024 08:37:12 +0800 Subject: [PATCH 070/252] Fix I2C address for QMC5883L. QMC5883L and HMC5883L are 3-axis compasses which are often confused. As reported by @Africmod, we had the wrong I2C address for the QMC5883L. This patch fixes the address and adds its HMC5883L so we keep info about both. Fixes https://github.com/meshtastic/firmware/issues/4144 --- src/configuration.h | 5 +++-- src/detect/ScanI2C.h | 3 ++- src/detect/ScanI2CTwoWire.cpp | 1 + src/main.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 72420cc59..349bd2870 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -124,7 +124,8 @@ along with this program. If not, see . #define INA3221_ADDR 0x42 #define QMC6310_ADDR 0x1C #define QMI8658_ADDR 0x6B -#define QMC5883L_ADDR 0x1E +#define QMC5883L_ADDR 0x0D +#define HMC5883L_ADDR 0x1E #define SHTC3_ADDR 0x70 #define LPS22HB_ADDR 0x5C #define LPS22HB_ADDR_ALT 0x5D @@ -331,4 +332,4 @@ along with this program. If not, see . #endif #include "DebugConfiguration.h" -#include "RF95Configuration.h" \ No newline at end of file +#include "RF95Configuration.h" diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 743de7a9a..090b1a968 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -36,6 +36,7 @@ class ScanI2C QMC6310, QMI8658, QMC5883L, + HMC5883L, PMSA0031, MPU6050, LIS3DH, @@ -118,4 +119,4 @@ class ScanI2C private: bool shouldSuppressScreen = false; -}; \ No newline at end of file +}; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 48341034b..f09eb3b95 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -382,6 +382,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) break; SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n") + SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found\n") SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n") SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n"); diff --git a/src/main.cpp b/src/main.cpp index df90c4722..2c8c0dcb8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -560,6 +560,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC6310, meshtastic_TelemetrySensorType_QMC6310) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::HMC5883L, meshtastic_TelemetrySensorType_QMC5883L) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700) @@ -1144,4 +1145,4 @@ void loop() } // if (didWake) LOG_DEBUG("wake!\n"); } -#endif \ No newline at end of file +#endif From b025eeb13cb299cfc9caa109cec29673929ddd6d Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:11:57 +0100 Subject: [PATCH 071/252] Update variant.h --- variants/rak11200/variant.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/rak11200/variant.h b/variants/rak11200/variant.h index 259fa6e87..01edb8b73 100644 --- a/variants/rak11200/variant.h +++ b/variants/rak11200/variant.h @@ -70,12 +70,12 @@ static const uint8_t SCK = 33; #define LORA_CS SS #define USE_SX1262 -#define SX126X_ANT_SW WB_IO2 +#define SX126X_ANT_SW WB_IO3 #define SX126X_CS SS // NSS for SX126X #define SX126X_DIO1 LORA_DIO1 #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET -#define SX126X_POWER_EN WB_IO3 +#define SX126X_POWER_EN WB_IO2 // 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 From cd6bd1e9a33c831c6220f997819ae78b2c9f1e21 Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:24:31 +0100 Subject: [PATCH 072/252] Update main.cpp --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2c8c0dcb8..b6cfd91aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -764,10 +764,11 @@ void setup() screen->print("Started...\n"); -#ifdef SX126X_ANT_SW - // make analog PA vs not PA switch on SX126x eval board work properly +// FIXME: move to SX126XInterface.cpp +// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually dealt in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to the RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself. One solution would be to set that pin as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=0 has the opposite and stable RF path effect as CTRL=1 and ¬CTRL=1, this depends on the RF switch, but for the cases where this works, this pin can be used. Better hardware design, which is done most the time, prevents this issue. +#ifdef SX126X_ANT_SW // Add RADIOLIB_NC check, and beforehand define as such if it is undefined. + digitalWrite(SX126X_ANT_SW, HIGH); pinMode(SX126X_ANT_SW, OUTPUT); - digitalWrite(SX126X_ANT_SW, 1); #endif #ifdef PIN_PWR_DELAY_MS From af3048561185a3450e044ff00467fe4e9917703e Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:27:45 +0100 Subject: [PATCH 073/252] Update main.cpp --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index b6cfd91aa..f88fa890e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -765,7 +765,7 @@ void setup() screen->print("Started...\n"); // FIXME: move to SX126XInterface.cpp -// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually dealt in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to the RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself. One solution would be to set that pin as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=0 has the opposite and stable RF path effect as CTRL=1 and ¬CTRL=1, this depends on the RF switch, but for the cases where this works, this pin can be used. Better hardware design, which is done most the time, prevents this issue. +// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually performed in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to this style of RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself, so the MCU can't control ¬CTRL at exactly the same time. One solution would be to set ¬CTRL as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=1 has the opposite and stable RF path effect as CTRL=0 and ¬CTRL=1, this depends on the RF switch, but it seems this usually works. Better hardware design, which is done most the time, means this workaround is not necessary. #ifdef SX126X_ANT_SW // Add RADIOLIB_NC check, and beforehand define as such if it is undefined. digitalWrite(SX126X_ANT_SW, HIGH); pinMode(SX126X_ANT_SW, OUTPUT); From 06cd9abd810781b991d17823ea7bb75a895d8570 Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:36:10 +0100 Subject: [PATCH 074/252] Update SX126xInterface.cpp --- src/mesh/SX126xInterface.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index fcb3e4edb..6f9a455b7 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -25,9 +25,16 @@ SX126xInterface::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs /// \return true if initialisation succeeded. template bool SX126xInterface::init() { -#ifdef SX126X_POWER_EN - pinMode(SX126X_POWER_EN, OUTPUT); + +// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually performed in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to this style of RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself, so the MCU can't control ¬CTRL at exactly the same time. One solution would be to set ¬CTRL as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=1 has the opposite and stable RF path effect as CTRL=0 and ¬CTRL=1, this depends on the RF switch, but it seems this usually works. Better hardware design, which is done most the time, means this workaround is not necessary. +#ifdef SX126X_ANT_SW // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly used and not part of the 'default' set of pin definitions. + digitalWrite(SX126X_ANT_SW, HIGH); + pinMode(SX126X_ANT_SW, OUTPUT); +#endif + +#ifdef SX126X_POWER_EN // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly used and not part of the 'default' set of pin definitions. digitalWrite(SX126X_POWER_EN, HIGH); + pinMode(SX126X_POWER_EN, OUTPUT); #endif #if ARCH_PORTDUINO From 34a543ec74967d6848ee7fb1fa73b4213845826e Mon Sep 17 00:00:00 2001 From: S5NC <145265251+S5NC@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:36:52 +0100 Subject: [PATCH 075/252] Update main.cpp --- src/main.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f88fa890e..86268ecac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -764,13 +764,6 @@ void setup() screen->print("Started...\n"); -// FIXME: move to SX126XInterface.cpp -// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually performed in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to this style of RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself, so the MCU can't control ¬CTRL at exactly the same time. One solution would be to set ¬CTRL as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=1 has the opposite and stable RF path effect as CTRL=0 and ¬CTRL=1, this depends on the RF switch, but it seems this usually works. Better hardware design, which is done most the time, means this workaround is not necessary. -#ifdef SX126X_ANT_SW // Add RADIOLIB_NC check, and beforehand define as such if it is undefined. - digitalWrite(SX126X_ANT_SW, HIGH); - pinMode(SX126X_ANT_SW, OUTPUT); -#endif - #ifdef PIN_PWR_DELAY_MS // This may be required to give the peripherals time to power up. delay(PIN_PWR_DELAY_MS); From bc753e69032c022288d57019f3bf7151bb69afe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Sep 2024 20:50:07 +0200 Subject: [PATCH 076/252] trunk fmt --- src/mesh/SX126xInterface.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 6f9a455b7..6d23206bd 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -26,13 +26,22 @@ SX126xInterface::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs template bool SX126xInterface::init() { -// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO paths). The negation is usually performed in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to this style of RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and DIO2's switching is done by the SX126X itself, so the MCU can't control ¬CTRL at exactly the same time. One solution would be to set ¬CTRL as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=1 has the opposite and stable RF path effect as CTRL=0 and ¬CTRL=1, this depends on the RF switch, but it seems this usually works. Better hardware design, which is done most the time, means this workaround is not necessary. -#ifdef SX126X_ANT_SW // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly used and not part of the 'default' set of pin definitions. +// Typically, the RF switch on SX126x boards is controlled by two signals, which are negations of each other (switched RFIO +// paths). The negation is usually performed in hardware, or (suboptimal design) TXEN and RXEN are the two inputs to this style of +// RF switch. On some boards, there is no hardware negation between CTRL and ¬CTRL, but CTRL is internally connected to DIO2, and +// DIO2's switching is done by the SX126X itself, so the MCU can't control ¬CTRL at exactly the same time. One solution would be +// to set ¬CTRL as SX126X_TXEN or SX126X_RXEN, but they may already be used for another purpose, such as controlling another +// PA/LNA. Keeping ¬CTRL high seems to work, as long CTRL=1, ¬CTRL=1 has the opposite and stable RF path effect as CTRL=0 and +// ¬CTRL=1, this depends on the RF switch, but it seems this usually works. Better hardware design, which is done most the time, +// means this workaround is not necessary. +#ifdef SX126X_ANT_SW // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly + // used and not part of the 'default' set of pin definitions. digitalWrite(SX126X_ANT_SW, HIGH); pinMode(SX126X_ANT_SW, OUTPUT); #endif - -#ifdef SX126X_POWER_EN // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly used and not part of the 'default' set of pin definitions. + +#ifdef SX126X_POWER_EN // Perhaps add RADIOLIB_NC check, and beforehand define as such if it is undefined, but it is not commonly + // used and not part of the 'default' set of pin definitions. digitalWrite(SX126X_POWER_EN, HIGH); pinMode(SX126X_POWER_EN, OUTPUT); #endif From 11378325e0d2c911d3bd35dbbfafbc6f818268e4 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 17 Sep 2024 06:29:18 -0500 Subject: [PATCH 077/252] Separate GPS and NTP RTCQuality logic and allow GPS time to always set us (#4721) --- src/gps/RTC.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 42a98f568..728284242 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -124,8 +124,11 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) } else if (q > currentQuality) { shouldSet = true; LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q)); - } else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { - // Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift + } else if (q == RTCQualityGPS) { + shouldSet = true; + LOG_DEBUG("Reapplying GPS time: %ld secs\n", printableEpoch); + } else if (q == RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { + // Every 12 hrs we will slam in a new NTP or Phone GPS / NTP time, to correct for local RTC clock drift shouldSet = true; LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch); } else { From a967dd52f31a4ea00e79219dde18499fea803c76 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 17 Sep 2024 06:31:39 -0500 Subject: [PATCH 078/252] More useful PKC logging (#4742) --- src/mesh/CryptoEngine.cpp | 9 +++++---- src/mesh/Router.cpp | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mesh/CryptoEngine.cpp b/src/mesh/CryptoEngine.cpp index a5322a65a..79666b321 100644 --- a/src/mesh/CryptoEngine.cpp +++ b/src/mesh/CryptoEngine.cpp @@ -84,7 +84,7 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ // Calculate the shared secret with the destination node and encrypt printBytes("Attempting encrypt using nonce: ", nonce, 13); - printBytes("Attempting encrypt using shared_key: ", shared_key, 32); + printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8); aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut, auth); // this can write up to 15 bytes longer than numbytes past bytesOut *extraNonce = extraNonceTmp; @@ -117,7 +117,7 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size } initNonce(fromNode, packetNum, *extraNonce); printBytes("Attempting decrypt using nonce: ", nonce, 13); - printBytes("Attempting decrypt using shared_key: ", shared_key, 32); + printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8); return aes_ccm_ad(shared_key, 32, nonce, 8, bytes, numBytes - 12, nullptr, 0, auth, bytesOut); } @@ -137,11 +137,12 @@ bool CryptoEngine::setDHKey(uint32_t nodeNum) LOG_DEBUG("Node %d or their public_key not found\n", nodeNum); return false; } - + printBytes("Generating DH with remote pubkey: ", node->user.public_key.bytes, 32); + printBytes("And local pubkey: ", config.security.public_key.bytes, 32); if (!setDHPublicKey(node->user.public_key.bytes)) return false; - printBytes("DH Output: ", shared_key, 32); + // printBytes("DH Output: ", shared_key, 32); /** * D.J. Bernstein reccomends hashing the shared key. We want to do this because there are diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index deb4ef2bf..3cf30519b 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -347,8 +347,11 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // memcpy(bytes, ScratchEncrypted, rawSize); // TODO: Rename the bytes buffers // chIndex = 8; } else { + LOG_ERROR("PKC Decrypted, but pb_decode failed!\n"); return false; } + } else { + LOG_WARN("PKC decrypt attempted but failed!\n"); } } #endif From be306cc3849d080bc2fb6549ee16c6b39e5ca94e Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 17 Sep 2024 19:48:56 +0800 Subject: [PATCH 079/252] Increase GPS FIFO Buffer Size for RP2040 (#4741) As discovered and tested by @Mictronics, default Serial FIFO size on the Pico is 32bytes, which is not enough for GPS messages. This patch increases the Serial GPS FIFO buffer size to 256 for the RP2040 Architecture fixes https://github.com/meshtastic/firmware/issues/3989 --- src/gps/GPS.cpp | 17 +++++++++++++++-- src/gps/GPS.h | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 8abb4edb1..01fa65816 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -26,6 +26,8 @@ #if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) HardwareSerial *GPS::_serial_gps = &Serial1; +#elif defined(ARCH_RP2040) +SerialUART *GPS::_serial_gps = &Serial1; #else HardwareSerial *GPS::_serial_gps = NULL; #endif @@ -1198,9 +1200,13 @@ int GPS::prepareDeepSleep(void *unused) GnssModel_t GPS::probe(int serialSpeed) { -#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) || defined(ARCH_STM32WL) +#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL) _serial_gps->end(); _serial_gps->begin(serialSpeed); +#elif defined(ARCH_RP2040) + _serial_gps->end(); + _serial_gps->setFIFOSize(256); + _serial_gps->begin(serialSpeed); #else if (_serial_gps->baudRate() != serialSpeed) { LOG_DEBUG("Setting Baud to %i\n", serialSpeed); @@ -1265,9 +1271,13 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->write(_message_prt, sizeof(_message_prt)); delay(500); serialSpeed = 9600; -#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_RP2040) || defined(ARCH_STM32WL) +#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL) _serial_gps->end(); _serial_gps->begin(serialSpeed); +#elif defined(ARCH_RP2040) + _serial_gps->end(); + _serial_gps->setFIFOSize(256); + _serial_gps->begin(serialSpeed); #else _serial_gps->updateBaudRate(serialSpeed); #endif @@ -1428,6 +1438,9 @@ GPS *GPS::createGps() 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); +#elif defined(ARCH_RP2040) + _serial_gps->setFIFOSize(256); + _serial_gps->begin(GPS_BAUDRATE); #else _serial_gps->begin(GPS_BAUDRATE); #endif diff --git a/src/gps/GPS.h b/src/gps/GPS.h index caff48f32..3423edb68 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -102,7 +102,7 @@ class GPS : private concurrency::OSThread public: /** If !NULL we will use this serial port to construct our GPS */ -#if defined(RPI_PICO_WAVESHARE) +#if defined(ARCH_RP2040) static SerialUART *_serial_gps; #else static HardwareSerial *_serial_gps; From db4dc88d6f1e624a03cf10e35233463a5620d60e Mon Sep 17 00:00:00 2001 From: Andre K Date: Tue, 17 Sep 2024 08:50:49 -0300 Subject: [PATCH 080/252] feat: enable remote admin to set/clear fixed positions (#4713) Co-authored-by: Ben Meadors --- src/modules/AdminModule.cpp | 38 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 4deb99eb7..7b96d9c43 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -257,34 +257,26 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta break; } case meshtastic_AdminMessage_set_fixed_position_tag: { - if (fromOthers) { - LOG_INFO("Ignoring set_fixed_position command from another node.\n"); - } else { - LOG_INFO("Client is receiving a set_fixed_position command.\n"); - meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); - node->has_position = true; - node->position = TypeConversions::ConvertToPositionLite(r->set_fixed_position); - nodeDB->setLocalPosition(r->set_fixed_position); - config.position.fixed_position = true; - saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false); + LOG_INFO("Client is receiving a set_fixed_position command.\n"); + meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); + node->has_position = true; + node->position = TypeConversions::ConvertToPositionLite(r->set_fixed_position); + nodeDB->setLocalPosition(r->set_fixed_position); + config.position.fixed_position = true; + saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false); #if !MESHTASTIC_EXCLUDE_GPS - if (gps != nullptr) - gps->enable(); - // Send our new fixed position to the mesh for good measure - positionModule->sendOurPosition(); + if (gps != nullptr) + gps->enable(); + // Send our new fixed position to the mesh for good measure + positionModule->sendOurPosition(); #endif - } break; } case meshtastic_AdminMessage_remove_fixed_position_tag: { - if (fromOthers) { - LOG_INFO("Ignoring remove_fixed_position command from another node.\n"); - } else { - LOG_INFO("Client is receiving a remove_fixed_position command.\n"); - nodeDB->clearLocalPosition(); - config.position.fixed_position = false; - saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false); - } + LOG_INFO("Client is receiving a remove_fixed_position command.\n"); + nodeDB->clearLocalPosition(); + config.position.fixed_position = false; + saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false); break; } case meshtastic_AdminMessage_set_time_only_tag: { From a47570d65a09275caac90be91956fd99be7af297 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 06:52:42 -0500 Subject: [PATCH 081/252] [create-pull-request] automated change (#4746) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/deviceonly.pb.h | 7 ++++--- src/mesh/generated/meshtastic/mesh.pb.h | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/protobufs b/protobufs index c5108cfd6..1e212f113 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit c5108cfd6bbc59adef44575dcec3067cbfbfeac1 +Subproject commit 1e212f113583dfd8d21a0daa47a32b080d3f842f diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index f87c84abe..a905c4526 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -94,6 +94,7 @@ typedef struct _meshtastic_NodeInfoLite { /* True if we witnessed the node over MQTT instead of LoRA transport */ bool via_mqtt; /* Number of hops away from us this node is (0 if adjacent) */ + bool has_hops_away; uint8_t hops_away; /* True if node is in our favorites list Persists between NodeDB internal clean ups */ @@ -202,13 +203,13 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} -#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, 0, 0} +#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}} #define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0} #define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default} #define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} -#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, 0, 0} +#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}} #define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0} #define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero} @@ -287,7 +288,7 @@ X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ -X(a, STATIC, SINGULAR, UINT32, hops_away, 9) \ +X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) #define meshtastic_NodeInfoLite_CALLBACK NULL #define meshtastic_NodeInfoLite_DEFAULT NULL diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index f4e0a896b..44159858b 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -745,6 +745,7 @@ typedef struct _meshtastic_NodeInfo { /* True if we witnessed the node over MQTT instead of LoRA transport */ bool via_mqtt; /* Number of hops away from us this node is (0 if adjacent) */ + bool has_hops_away; uint8_t hops_away; /* True if node is in our favorites list Persists between NodeDB internal clean ups */ @@ -1093,7 +1094,7 @@ extern "C" { #define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} -#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, 0, 0} +#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_MyNodeInfo_init_default {0, 0, 0} #define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_QueueStatus_init_default {0, 0, 0, 0} @@ -1118,7 +1119,7 @@ extern "C" { #define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} -#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, 0, 0} +#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_MyNodeInfo_init_zero {0, 0, 0} #define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_QueueStatus_init_zero {0, 0, 0, 0} @@ -1415,7 +1416,7 @@ X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ -X(a, STATIC, SINGULAR, UINT32, hops_away, 9) \ +X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) #define meshtastic_NodeInfo_CALLBACK NULL #define meshtastic_NodeInfo_DEFAULT NULL From 2a6921292e77194bb199a4697eace5c47a2c277c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 17 Sep 2024 10:05:55 -0500 Subject: [PATCH 082/252] Implement CoT detail support in TAKPacket (#4748) * Implement CoT detail support in TAKPacket * dest, src * More coffee is needed * SAVE --- src/modules/AtakPluginModule.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/AtakPluginModule.cpp b/src/modules/AtakPluginModule.cpp index 437a341db..72d069619 100644 --- a/src/modules/AtakPluginModule.cpp +++ b/src/modules/AtakPluginModule.cpp @@ -52,6 +52,10 @@ meshtastic_TAKPacket AtakPluginModule::cloneTAKPacketData(meshtastic_TAKPacket * } else if (t->which_payload_variant == meshtastic_TAKPacket_chat_tag) { clone.which_payload_variant = meshtastic_TAKPacket_chat_tag; clone.payload_variant.chat = {0}; + } else if (t->which_payload_variant == meshtastic_TAKPacket_detail_tag) { + clone.which_payload_variant = meshtastic_TAKPacket_detail_tag; + clone.payload_variant.detail.size = t->payload_variant.detail.size; + memcpy(clone.payload_variant.detail.bytes, t->payload_variant.detail.bytes, t->payload_variant.detail.size); } return clone; From f5016763fdda5b428dd62caaf1ab9e2550bdd08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 17 Sep 2024 17:33:21 +0200 Subject: [PATCH 083/252] change evaluation order to silence warning about "found" (#4749) --- src/mesh/NodeDB.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5d1db88ae..7e8abb747 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -654,8 +654,8 @@ void NodeDB::pickNewNodeNum() } meshtastic_NodeInfoLite *found; - while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) || - ((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0)) { + while (((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0) || + (nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED)) { 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, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so " "trying for 0x%x\n", From 50fb4ab22ac412f7aec766e7cad2313109f9510a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 17 Sep 2024 12:08:04 -0500 Subject: [PATCH 084/252] Implement optional hops_away on NodeInfo/Lite (#4747) * Implement optional hops_away on NodeInfo/Lite * Trunk --- src/mesh/NodeDB.cpp | 4 +++- src/mesh/PhoneAPI.cpp | 2 +- src/mesh/TypeConversions.cpp | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 7e8abb747..dca639070 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1112,8 +1112,10 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp) info->via_mqtt = mp.via_mqtt; // Store if we received this packet via MQTT // If hopStart was set and there wasn't someone messing with the limit in the middle, add hopsAway - if (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start) + if (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start) { + info->has_hops_away = true; info->hops_away = mp.hop_start - mp.hop_limit; + } } } diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 30af9d7b0..742bdbf34 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -194,7 +194,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) auto us = nodeDB->readNextMeshNode(readIndex); if (us) { nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us); - nodeInfoForPhone.hops_away = 0; + nodeInfoForPhone.has_hops_away = false; nodeInfoForPhone.is_favorite = true; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; fromRadioScratch.node_info = nodeInfoForPhone; diff --git a/src/mesh/TypeConversions.cpp b/src/mesh/TypeConversions.cpp index 6a90ac703..550f87021 100644 --- a/src/mesh/TypeConversions.cpp +++ b/src/mesh/TypeConversions.cpp @@ -11,9 +11,13 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo info.last_heard = lite->last_heard; info.channel = lite->channel; info.via_mqtt = lite->via_mqtt; - info.hops_away = lite->hops_away; info.is_favorite = lite->is_favorite; + if (lite->has_hops_away) { + info.has_hops_away = true; + info.hops_away = lite->hops_away; + } + if (lite->has_position) { info.has_position = true; if (lite->position.latitude_i != 0) From 923458bc18fc74462f8d09b3a9990fd543fb5611 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:55:16 -0500 Subject: [PATCH 085/252] [create-pull-request] automated change (#4754) Co-authored-by: jp-bennett <5630967+jp-bennett@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/protobufs b/protobufs index 1e212f113..164e59873 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 1e212f113583dfd8d21a0daa47a32b080d3f842f +Subproject commit 164e598734a813ae00a2a74266e9e06438f030ce diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 44159858b..921dfa55b 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -876,6 +876,8 @@ typedef struct _meshtastic_DeviceMetadata { meshtastic_HardwareModel hw_model; /* Has Remote Hardware enabled */ bool hasRemoteHardware; + /* Has PKC capabilities */ + bool hasPKC; } meshtastic_DeviceMetadata; /* Packets from the radio to the phone will appear on the fromRadio characteristic. @@ -1105,7 +1107,7 @@ extern "C" { #define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}} #define meshtastic_Neighbor_init_default {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} +#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0} #define meshtastic_Heartbeat_init_default {0} #define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default} #define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}} @@ -1130,7 +1132,7 @@ extern "C" { #define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}} #define meshtastic_Neighbor_init_zero {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} +#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0} #define meshtastic_Heartbeat_init_zero {0} #define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero} #define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}} @@ -1261,6 +1263,7 @@ extern "C" { #define meshtastic_DeviceMetadata_position_flags_tag 8 #define meshtastic_DeviceMetadata_hw_model_tag 9 #define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10 +#define meshtastic_DeviceMetadata_hasPKC_tag 11 #define meshtastic_FromRadio_id_tag 1 #define meshtastic_FromRadio_packet_tag 2 #define meshtastic_FromRadio_my_info_tag 3 @@ -1541,7 +1544,8 @@ X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6) \ X(a, STATIC, SINGULAR, UENUM, role, 7) \ X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \ X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \ -X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) +X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) \ +X(a, STATIC, SINGULAR, BOOL, hasPKC, 11) #define meshtastic_DeviceMetadata_CALLBACK NULL #define meshtastic_DeviceMetadata_DEFAULT NULL @@ -1640,7 +1644,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; #define meshtastic_ClientNotification_size 415 #define meshtastic_Compressed_size 243 #define meshtastic_Data_size 273 -#define meshtastic_DeviceMetadata_size 46 +#define meshtastic_DeviceMetadata_size 48 #define meshtastic_FileInfo_size 236 #define meshtastic_FromRadio_size 510 #define meshtastic_Heartbeat_size 0 From c78302a2ee979925e7aa9d008350c0495110a424 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 17 Sep 2024 19:34:05 -0500 Subject: [PATCH 086/252] Add hasPKC to deviceMetadata (#4755) --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 86268ecac..a6e6ad631 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1091,6 +1091,9 @@ extern meshtastic_DeviceMetadata getDeviceMetadata() deviceMetadata.position_flags = config.position.position_flags; deviceMetadata.hw_model = HW_VENDOR; deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled; +#if !(MESHTASTIC_EXCLUDE_PKI) + deviceMetadata.hasPKC = true; +#endif return deviceMetadata; } #ifndef PIO_UNIT_TESTING From 2d52803dbde083d3e2ddce29cc3314e75d9f2fb5 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 17 Sep 2024 21:09:24 -0500 Subject: [PATCH 087/252] Add new admin error types (#4750) Co-authored-by: Ben Meadors --- src/modules/AdminModule.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 7b96d9c43..48048b054 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -73,12 +73,38 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta meshtastic_Channel *ch = &channels.getByIndex(mp.channel); // Could tighten this up further by tracking the last public_key we went an AdminMessage request to // and only allowing responses from that remote. - if (!((mp.from == 0 && !config.security.is_managed) || messageIsResponse(r) || - (strcasecmp(ch->settings.name, Channels::adminChannel) == 0 && config.security.admin_channel_enabled) || - (mp.pki_encrypted && memcmp(mp.public_key.bytes, config.security.admin_key[0].bytes, 32) == 0))) { - LOG_INFO("Ignoring admin payload %i\n", r->which_payload_variant); + if (messageIsResponse(r)) { + LOG_DEBUG("Allowing admin response message\n"); + } else if (mp.from == 0) { + if (config.security.is_managed) { + LOG_INFO("Ignoring local admin payload because is_managed.\n"); + return handled; + } + } else if (strcasecmp(ch->settings.name, Channels::adminChannel) == 0) { + if (!config.security.admin_channel_enabled) { + LOG_INFO("Ignoring admin channel, as legacy admin is disabled.\n"); + myReply = allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp); + return handled; + } + } else if (mp.pki_encrypted) { + if ((config.security.admin_key[0].size == 32 && + memcmp(mp.public_key.bytes, config.security.admin_key[0].bytes, 32) == 0) || + (config.security.admin_key[1].size == 32 && + memcmp(mp.public_key.bytes, config.security.admin_key[1].bytes, 32) == 0) || + (config.security.admin_key[2].size == 32 && + memcmp(mp.public_key.bytes, config.security.admin_key[2].bytes, 32) == 0)) { + LOG_INFO("PKC admin payload with authorized sender key.\n"); + } else { + myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED, &mp); + LOG_INFO("Received PKC admin payload, but the sender public key does not match the admin authorized key!\n"); + return handled; + } + } else { + LOG_INFO("Ignoring unauthorized admin payload %i\n", r->which_payload_variant); + myReply = allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp); return handled; } + LOG_INFO("Handling admin payload %i\n", r->which_payload_variant); // all of the get and set messages, including those for other modules, flow through here first. @@ -86,6 +112,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta if (mp.from != 0 && !messageIsRequest(r) && !messageIsResponse(r)) { if (!checkPassKey(r)) { LOG_WARN("Admin message without session_key!\n"); + myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY, &mp); return handled; } } From 4289cb089b92024a0945a1c8fbbe55cb66b88bcd Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 18 Sep 2024 00:17:48 -0500 Subject: [PATCH 088/252] Update package_raspbian.yml to build on self-hosted (#4761) * Update package_raspbian.yml to build on self-hosted * Update package_raspbian_armv7l.yml to use self hosted --- .github/workflows/package_raspbian.yml | 2 +- .github/workflows/package_raspbian_armv7l.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index 5471332c5..ab541899f 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian.yml package-raspbian: - runs-on: ubuntu-latest + runs-on: [linux] needs: build-raspbian steps: - name: Checkout code diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index 5b9c9aa71..cadce17c3 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian_armv7l.yml package-raspbian_armv7l: - runs-on: ubuntu-latest + runs-on: [linux] needs: build-raspbian_armv7l steps: - name: Checkout code From 3eebdcefa417619549163469aa70624c6178f777 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 18 Sep 2024 00:28:54 -0500 Subject: [PATCH 089/252] More CI fun --- .github/workflows/build_esp32.yml | 2 +- .github/workflows/package_raspbian.yml | 2 +- .github/workflows/package_raspbian_armv7l.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 4cbb4c7a4..68525fc7d 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -9,7 +9,7 @@ on: jobs: build-esp32: - runs-on: ubuntu-latest + runs-on: [linux, x64] steps: - uses: actions/checkout@v4 - name: Build base diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index ab541899f..5471332c5 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian.yml package-raspbian: - runs-on: [linux] + runs-on: ubuntu-latest needs: build-raspbian steps: - name: Checkout code diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index cadce17c3..5b9c9aa71 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian_armv7l.yml package-raspbian_armv7l: - runs-on: [linux] + runs-on: ubuntu-latest needs: build-raspbian_armv7l steps: - name: Checkout code From c6196b226062fa650c943d1778d590f9415bb43c Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 18 Sep 2024 01:11:08 -0500 Subject: [PATCH 090/252] Update build_esp32.yml -- less CI fun --- .github/workflows/build_esp32.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 68525fc7d..4cbb4c7a4 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -9,7 +9,7 @@ on: jobs: build-esp32: - runs-on: [linux, x64] + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build base From 19c57e8ec6746d1769533ca1d2615eda0313222a Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Wed, 18 Sep 2024 22:05:32 +0800 Subject: [PATCH 091/252] Fix Chatter 2 blank screen on boot (#4759) As reported by @eureekasigns and @GPSFan, Chatter 2 had begun to show a blank screen on boot after recent TFT display changes. Setting TFT_BACKLIGHT_ON LOW resolves the issue. Fixes https://github.com/meshtastic/firmware/issues/4751 --- variants/chatter2/variant.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/variants/chatter2/variant.h b/variants/chatter2/variant.h index b7f946970..5c27e2fb5 100644 --- a/variants/chatter2/variant.h +++ b/variants/chatter2/variant.h @@ -66,6 +66,7 @@ #define SCREEN_ROTATE #define SCREEN_TRANSITION_FRAMERATE 5 // fps #define DISPLAY_FORCE_SMALL_FONTS +#define TFT_BACKLIGHT_ON LOW // Battery @@ -121,4 +122,4 @@ // cannot serve any extra function even if requested to LORA_DIO3 value is never used in src (as we are not using RF95), so no // need to define, and DIO3_AS_TCXO_AT_1V8 is set so it cannot serve any extra function even if requested to (from 13.3.2.1 // DioxMask in SX1262 datasheet: Note that if DIO2 or DIO3 are used to control the RF Switch or the TCXO, the IRQ will not be -// generated even if it is mapped to the pins.) \ No newline at end of file +// generated even if it is mapped to the pins.) From 35e1c401e2f6b041a87546c44f3f79fd624c33d4 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Wed, 18 Sep 2024 23:12:49 +0800 Subject: [PATCH 092/252] PMSA0031 sensors require ~3secs before coming up on I2C (#4743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * PMSA0031 sensors require ~3secs before coming up on I2C As reported by @MALAONE1 and debugged by @shodan8192 , PMSA0031s on a RAK4631 take 3 seconds before they can become detectable on I2c. Add a delay(4000) before I2C scan if the air quality sensor pin is defined. Fixes https://github.com/meshtastic/firmware/issues/3690 * Remove 4 second wait and rescan during air quality init for the sensor * works without but this triggers my OCD --------- Co-authored-by: Thomas Göttgens Co-authored-by: Ben Meadors --- src/main.cpp | 4 +-- src/modules/Telemetry/AirQualityTelemetry.cpp | 25 +++++++++++++++---- src/modules/Telemetry/AirQualityTelemetry.h | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a6e6ad631..e24ba68b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -390,7 +390,7 @@ void setup() #endif #ifdef AQ_SET_PIN - // RAK-12039 set pin for Air quality sensor + // RAK-12039 set pin for Air quality sensor. Detectable on I2C after ~3 seconds, so we need to rescan later pinMode(AQ_SET_PIN, OUTPUT); digitalWrite(AQ_SET_PIN, HIGH); #endif @@ -1142,4 +1142,4 @@ void loop() } // if (didWake) LOG_DEBUG("wake!\n"); } -#endif +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index d07296710..56d308cfa 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -10,11 +10,11 @@ #include "PowerFSM.h" #include "RTC.h" #include "Router.h" +#include "detect/ScanI2CTwoWire.h" #include "main.h" int32_t AirQualityTelemetryModule::runOnce() { - int32_t result = INT32_MAX; /* Uncomment the preferences below if you want to use the module without having to configure it from the PythonAPI or WebUI. @@ -29,21 +29,36 @@ int32_t AirQualityTelemetryModule::runOnce() if (firstTime) { // This is the first time the OSThread library has called this function, so do some setup - firstTime = 0; + firstTime = false; if (moduleConfig.telemetry.air_quality_enabled) { LOG_INFO("Air quality Telemetry: Initializing\n"); if (!aqi.begin_I2C()) { - LOG_WARN("Could not establish i2c connection to AQI sensor\n"); + LOG_WARN("Could not establish i2c connection to AQI sensor. Rescanning...\n"); + // rescan for late arriving sensors. AQI Module starts about 10 seconds into the boot so this is plenty. + uint8_t i2caddr_scan[] = {PMSA0031_ADDR}; + uint8_t i2caddr_asize = 1; + auto i2cScanner = std::unique_ptr(new ScanI2CTwoWire()); +#if defined(I2C_SDA1) + i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize); +#endif + i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize); + auto found = i2cScanner->find(ScanI2C::DeviceType::PMSA0031); + if (found.type != ScanI2C::DeviceType::NONE) { + nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first = found.address.address; + nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].second = + i2cScanner->fetchI2CBus(found.address); + return 1000; + } return disable(); } return 1000; } - return result; + return disable(); } else { // if we somehow got to a second run of this module with measurement disabled, then just wait forever if (!moduleConfig.telemetry.air_quality_enabled) - return result; + return disable(); uint32_t now = millis(); if (((lastSentToMesh == 0) || diff --git a/src/modules/Telemetry/AirQualityTelemetry.h b/src/modules/Telemetry/AirQualityTelemetry.h index 23df6ac58..fb8edd07e 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.h +++ b/src/modules/Telemetry/AirQualityTelemetry.h @@ -44,7 +44,7 @@ class AirQualityTelemetryModule : private concurrency::OSThread, public Protobuf private: Adafruit_PM25AQI aqi; PM25_AQI_Data data = {0}; - bool firstTime = 1; + bool firstTime = true; meshtastic_MeshPacket *lastMeasurementPacket; uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute uint32_t lastSentToMesh = 0; From 777bcf691a1a033cc31f96820aa1681499493e85 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 18 Sep 2024 10:13:07 -0500 Subject: [PATCH 093/252] Initial PhoneAPI rate-limiting of messages on certain ports (#4756) --- src/mesh/Default.h | 2 ++ src/mesh/PhoneAPI.cpp | 26 +++++++++++++++++++++++++- src/mesh/PhoneAPI.h | 10 ++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/mesh/Default.h b/src/mesh/Default.h index bafa60898..5641b5d25 100644 --- a/src/mesh/Default.h +++ b/src/mesh/Default.h @@ -3,6 +3,8 @@ #include #define ONE_DAY 24 * 60 * 60 #define ONE_MINUTE_MS 60 * 1000 +#define THIRTY_SECONDS_MS 30 * 1000 +#define FIVE_SECONDS_MS 5 * 1000 #define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60) #define default_telemetry_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 30 * 60) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 742bdbf34..121687c49 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -25,6 +25,7 @@ #if !MESHTASTIC_EXCLUDE_MQTT #include "mqtt/MQTT.h" #endif +#include PhoneAPI::PhoneAPI() { @@ -541,14 +542,37 @@ bool PhoneAPI::available() return false; } +void PhoneAPI::sendNotification(meshtastic_LogRecord_Level level, uint32_t replyId, const char *message) +{ + meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed(); + cn->has_reply_id = true; + cn->reply_id = replyId; + cn->level = meshtastic_LogRecord_Level_WARNING; + cn->time = getValidTime(RTCQualityFromNet); + strncpy(cn->message, message, sizeof(cn->message)); + service->sendClientNotification(cn); + delete cn; +} + /** * Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool */ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) { printPacket("PACKET FROM PHONE", &p); + if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] && + (millis() - lastPortNumToRadio[p.decoded.portnum]) < (THIRTY_SECONDS_MS)) { + LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); + sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds"); + return false; + } else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] && + (millis() - lastPortNumToRadio[p.decoded.portnum]) < (FIVE_SECONDS_MS)) { + LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); + sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds"); + return false; + } + lastPortNumToRadio[p.decoded.portnum] = millis(); service->handleToRadio(p); - return true; } diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 5feb1c4bf..1e09b9535 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -2,8 +2,10 @@ #include "Observer.h" #include "mesh-pb-constants.h" +#include "meshtastic/portnums.pb.h" #include #include +#include #include // Make sure that we never let our packets grow too large for one BLE packet @@ -48,6 +50,9 @@ class PhoneAPI uint8_t config_state = 0; + // Hashmap of timestamps for last time we received a packet on the API per portnum + std::unordered_map lastPortNumToRadio; + /** * Each packet sent to the phone has an incrementing count */ @@ -99,6 +104,11 @@ class PhoneAPI */ virtual bool handleToRadio(const uint8_t *buf, size_t len); + /** + * Send a (client)notification to the phone + */ + virtual void sendNotification(meshtastic_LogRecord_Level level, uint32_t replyId, const char *message); + /** * Get the next packet we want to send to the phone * From deada41ceec0a783cb2c2770c935cd4fcd8abb36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:49:12 -0500 Subject: [PATCH 094/252] [create-pull-request] automated change (#4765) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/clientonly.pb.h | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/protobufs b/protobufs index 164e59873..5709c0a05 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 164e598734a813ae00a2a74266e9e06438f030ce +Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197 diff --git a/src/mesh/generated/meshtastic/clientonly.pb.h b/src/mesh/generated/meshtastic/clientonly.pb.h index dc323292a..5720c1c02 100644 --- a/src/mesh/generated/meshtastic/clientonly.pb.h +++ b/src/mesh/generated/meshtastic/clientonly.pb.h @@ -5,6 +5,7 @@ #define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED #include #include "meshtastic/localonly.pb.h" +#include "meshtastic/mesh.pb.h" #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -28,6 +29,15 @@ typedef struct _meshtastic_DeviceProfile { /* The ModuleConfig of the node */ bool has_module_config; meshtastic_LocalModuleConfig module_config; + /* Fixed position data */ + bool has_fixed_position; + meshtastic_Position fixed_position; + /* Ringtone for ExternalNotification */ + bool has_ringtone; + char ringtone[231]; + /* Predefined messages for CannedMessage */ + bool has_canned_messages; + char canned_messages[201]; } meshtastic_DeviceProfile; @@ -36,8 +46,8 @@ extern "C" { #endif /* Initializer values for message structs */ -#define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default} -#define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero} +#define meshtastic_DeviceProfile_init_default {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_Position_init_default, false, "", false, ""} +#define meshtastic_DeviceProfile_init_zero {false, "", false, "", {{NULL}, NULL}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero, false, meshtastic_Position_init_zero, false, "", false, ""} /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_DeviceProfile_long_name_tag 1 @@ -45,6 +55,9 @@ extern "C" { #define meshtastic_DeviceProfile_channel_url_tag 3 #define meshtastic_DeviceProfile_config_tag 4 #define meshtastic_DeviceProfile_module_config_tag 5 +#define meshtastic_DeviceProfile_fixed_position_tag 6 +#define meshtastic_DeviceProfile_ringtone_tag 7 +#define meshtastic_DeviceProfile_canned_messages_tag 8 /* Struct field encoding specification for nanopb */ #define meshtastic_DeviceProfile_FIELDLIST(X, a) \ @@ -52,11 +65,15 @@ X(a, STATIC, OPTIONAL, STRING, long_name, 1) \ X(a, STATIC, OPTIONAL, STRING, short_name, 2) \ X(a, CALLBACK, OPTIONAL, STRING, channel_url, 3) \ X(a, STATIC, OPTIONAL, MESSAGE, config, 4) \ -X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) +X(a, STATIC, OPTIONAL, MESSAGE, module_config, 5) \ +X(a, STATIC, OPTIONAL, MESSAGE, fixed_position, 6) \ +X(a, STATIC, OPTIONAL, STRING, ringtone, 7) \ +X(a, STATIC, OPTIONAL, STRING, canned_messages, 8) #define meshtastic_DeviceProfile_CALLBACK pb_default_field_callback #define meshtastic_DeviceProfile_DEFAULT NULL #define meshtastic_DeviceProfile_config_MSGTYPE meshtastic_LocalConfig #define meshtastic_DeviceProfile_module_config_MSGTYPE meshtastic_LocalModuleConfig +#define meshtastic_DeviceProfile_fixed_position_MSGTYPE meshtastic_Position extern const pb_msgdesc_t meshtastic_DeviceProfile_msg; From 2ebfcea94eaf8e4826ce52795c43c316aada0a39 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Wed, 18 Sep 2024 19:43:13 +0200 Subject: [PATCH 095/252] DetectionSensor: broadcast all state changes Closes #4753 --- src/modules/DetectionSensorModule.cpp | 14 ++++++++++---- src/modules/DetectionSensorModule.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 20d91a381..d637fa7c6 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -49,10 +49,16 @@ int32_t DetectionSensorModule::runOnce() // LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin)); - if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) && - hasDetectionEvent()) { - sendDetectionMessage(); - return DELAYED_INTERVAL; + if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) { + if (hasDetectionEvent()) { + wasDetected = true; + sendDetectionMessage(); + return DELAYED_INTERVAL; + } else if (wasDetected) { + wasDetected = false; + sendCurrentStateMessage(); + 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 diff --git a/src/modules/DetectionSensorModule.h b/src/modules/DetectionSensorModule.h index ed6cddda5..eb17bf3a2 100644 --- a/src/modules/DetectionSensorModule.h +++ b/src/modules/DetectionSensorModule.h @@ -15,6 +15,7 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh private: bool firstTime = true; uint32_t lastSentToMesh = 0; + bool wasDetected = false; void sendDetectionMessage(); void sendCurrentStateMessage(); bool hasDetectionEvent(); From cc89e85e712fec5fbf16d62a9207ca9636da6b6a Mon Sep 17 00:00:00 2001 From: David Huang Date: Thu, 19 Sep 2024 00:53:33 -0500 Subject: [PATCH 096/252] Another missed define for the T114 --- boards/heltec_mesh_node_t114.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/heltec_mesh_node_t114.json b/boards/heltec_mesh_node_t114.json index 5c97d8c75..2bd306eb9 100644 --- a/boards/heltec_mesh_node_t114.json +++ b/boards/heltec_mesh_node_t114.json @@ -5,7 +5,7 @@ }, "core": "nRF5", "cpu": "cortex-m4", - "extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA", + "extra_flags": "-DHELTEC_T114 -DNRF52840_XXAA", "f_cpu": "64000000L", "hwids": [ ["0x239A", "0x4405"], From 7c32ab3023c3e1a19c97bf9d4b724743124e2d48 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Thu, 19 Sep 2024 08:20:53 +0200 Subject: [PATCH 097/252] Update ms24sf1.json --- boards/ms24sf1.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/ms24sf1.json b/boards/ms24sf1.json index 4e28507da..8356e3012 100644 --- a/boards/ms24sf1.json +++ b/boards/ms24sf1.json @@ -5,7 +5,7 @@ }, "core": "nRF5", "cpu": "cortex-m4", - "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", + "extra_flags": "-DMS24SF1 -DNRF52840_XXAA", "f_cpu": "64000000L", "hwids": [ ["0x239A", "0x8029"], From 7289b295e85caf13c28930c795c525a0aab4a396 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Thu, 19 Sep 2024 08:20:57 +0200 Subject: [PATCH 098/252] Update me25ls01-4y10td.json --- boards/me25ls01-4y10td.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/me25ls01-4y10td.json b/boards/me25ls01-4y10td.json index 46c526a7c..9e1d63265 100644 --- a/boards/me25ls01-4y10td.json +++ b/boards/me25ls01-4y10td.json @@ -5,7 +5,7 @@ }, "core": "nRF5", "cpu": "cortex-m4", - "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", + "extra_flags": "-DME25LS01_4Y10TD -DNRF52840_XXAA", "f_cpu": "64000000L", "hwids": [ ["0x239A", "0x8029"], From 5c4c0965af040878e9270f8030673c0b3d099b0e Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Thu, 19 Sep 2024 08:21:00 +0200 Subject: [PATCH 099/252] Update nordic_pca10059.json --- boards/nordic_pca10059.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nordic_pca10059.json b/boards/nordic_pca10059.json index b99e3c763..6540817a2 100644 --- a/boards/nordic_pca10059.json +++ b/boards/nordic_pca10059.json @@ -5,7 +5,7 @@ }, "core": "nRF5", "cpu": "cortex-m4", - "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA", + "extra_flags": "-DNORDIC_PCA10059 -DNRF52840_XXAA", "f_cpu": "64000000L", "hwids": [ ["0x239A", "0x8029"], From 6473cf0b698176fe0dc2fb8e88155b1087cfc7fb Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Thu, 19 Sep 2024 19:48:22 +0800 Subject: [PATCH 100/252] Update RadioLib to 7.0.0 (#4771) We were not too many commits behind, and the changes since then were either for LoraWAN or useful minor bug fixes for SX1280. --- platformio.ini | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index d561aaf74..f38ec41e4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -88,8 +88,7 @@ monitor_speed = 115200 monitor_filters = direct lib_deps = -; jgromes/RadioLib@~6.6.0 - https://github.com/jgromes/RadioLib.git#3115fc2d6700a9aee05888791ac930a910f2628f + jgromes/RadioLib@~7.0.0 https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 @@ -162,4 +161,4 @@ lib_deps = https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee - https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 \ No newline at end of file + https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 From 91b4199f9d63526f254f1ced374c20194a98b749 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 19 Sep 2024 10:46:18 -0500 Subject: [PATCH 101/252] Revert "DetectionSensor: broadcast all state changes" (#4776) --- src/modules/DetectionSensorModule.cpp | 14 ++++---------- src/modules/DetectionSensorModule.h | 1 - 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index d637fa7c6..20d91a381 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -49,16 +49,10 @@ int32_t DetectionSensorModule::runOnce() // LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin)); - if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) { - if (hasDetectionEvent()) { - wasDetected = true; - sendDetectionMessage(); - return DELAYED_INTERVAL; - } else if (wasDetected) { - wasDetected = false; - sendCurrentStateMessage(); - return DELAYED_INTERVAL; - } + if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) && + hasDetectionEvent()) { + sendDetectionMessage(); + 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 diff --git a/src/modules/DetectionSensorModule.h b/src/modules/DetectionSensorModule.h index eb17bf3a2..ed6cddda5 100644 --- a/src/modules/DetectionSensorModule.h +++ b/src/modules/DetectionSensorModule.h @@ -15,7 +15,6 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh private: bool firstTime = true; uint32_t lastSentToMesh = 0; - bool wasDetected = false; void sendDetectionMessage(); void sendCurrentStateMessage(); bool hasDetectionEvent(); From d3a293a0d82d044bee9c9894011862f0a38dafa6 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 19 Sep 2024 12:10:39 -0500 Subject: [PATCH 102/252] Flag semgrep to not run on self-hosted The semgrep action runs inside a docker container, and docker in podman just doesn't work. --- .github/workflows/sec_sast_semgrep_pull.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sec_sast_semgrep_pull.yml b/.github/workflows/sec_sast_semgrep_pull.yml index b6c288494..2575cbf01 100644 --- a/.github/workflows/sec_sast_semgrep_pull.yml +++ b/.github/workflows/sec_sast_semgrep_pull.yml @@ -4,7 +4,7 @@ on: pull_request jobs: semgrep-diff: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 container: image: returntocorp/semgrep From 114df8cb1bfa1c7d124935b48e7faec0fba99fb3 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 19 Sep 2024 13:29:17 -0500 Subject: [PATCH 103/252] Pin sensorlib version --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index f38ec41e4..9b869a036 100644 --- a/platformio.ini +++ b/platformio.ini @@ -156,7 +156,7 @@ lib_deps = https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 boschsensortec/BME68x Sensor Library@^1.1.40407 https://github.com/KodinLanewave/INA3221@^1.0.0 - lewisxhe/SensorLib@^0.2.0 + lewisxhe/SensorLib@0.2.0 mprograms/QMC5883LCompass@^1.2.0 From 0f3450ad441f766bd451e9f2d2cfea09b5730431 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 19 Sep 2024 18:21:30 -0500 Subject: [PATCH 104/252] Mark package workflows for gh hosted runners --- .github/workflows/package_amd64.yml | 2 +- .github/workflows/package_raspbian.yml | 2 +- .github/workflows/package_raspbian_armv7l.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index ae7bf3242..0b5093f24 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_native.yml package-native: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: build-native steps: - name: Checkout code diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index 5471332c5..bcbda53e2 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian.yml package-raspbian: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: build-raspbian steps: - name: Checkout code diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index 5b9c9aa71..1308fe925 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -13,7 +13,7 @@ jobs: uses: ./.github/workflows/build_raspbian_armv7l.yml package-raspbian_armv7l: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: build-raspbian_armv7l steps: - name: Checkout code From 921d92c649be1f7088e74e7d32cd0bed1fcfd373 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 20 Sep 2024 06:55:16 -0500 Subject: [PATCH 105/252] Drop received packets from self --- src/mqtt/MQTT.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 0f4c5a8c5..c15ac3325 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -158,6 +158,11 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet); p->via_mqtt = true; // Mark that the packet was received via MQTT + if (p->from == 0 || p->from == nodeDB->getNodeNum()) { + LOG_INFO("Ignoring downlink message we originally sent.\n"); + packetPool.release(p); + return; + } if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { p->channel = ch.index; } From 85d722232e470ed22720b97e634098616350354a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 20 Sep 2024 07:22:11 -0500 Subject: [PATCH 106/252] Additional decoded packet ignores --- src/mqtt/MQTT.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index c15ac3325..6840700e5 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -164,6 +164,16 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) return; } if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { + if (moduleConfig.mqtt.encryption_enabled) { + LOG_INFO("Ignoring decoded message on MQTT, encryption is enabled.\n"); + packetPool.release(p); + return; + } + if (p->decoded.portnum == meshtastic_PortNum_ADMIN_APP) { + LOG_INFO("Ignoring decoded admin packet.\n"); + packetPool.release(p); + return; + } p->channel = ch.index; } From 6ffdc9875bfadb2da05fffbcb9f6a3371bd9c448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Sep 2024 22:42:10 +0200 Subject: [PATCH 107/252] First stab at ESP32-C6 support for TLora-C6 --- arch/esp32/esp32c6.ini | 47 ++++++++++++++++++++++++ src/gps/GPS.cpp | 5 ++- src/graphics/Screen.cpp | 28 +++++++------- src/main.cpp | 14 ++++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/TypedQueue.h | 2 +- src/mesh/api/ServerAPI.cpp | 2 +- src/mesh/wifi/WiFiAPClient.cpp | 3 +- src/modules/ExternalNotificationModule.h | 2 +- src/modules/PositionModule.cpp | 16 ++++---- src/modules/SerialModule.cpp | 21 ++++++++++- src/mqtt/MQTT.cpp | 4 ++ src/mqtt/MQTT.h | 4 ++ src/platform/esp32/main-esp32.cpp | 12 +++++- src/power.h | 1 + src/serialization/JSON.cpp | 2 +- src/sleep.cpp | 4 +- variants/tlora_c6/platformio.ini | 5 +++ variants/tlora_c6/variant.h | 16 ++++++++ 19 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 arch/esp32/esp32c6.ini create mode 100644 variants/tlora_c6/platformio.ini create mode 100644 variants/tlora_c6/variant.h diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini new file mode 100644 index 000000000..a7bcdc0e8 --- /dev/null +++ b/arch/esp32/esp32c6.ini @@ -0,0 +1,47 @@ +[esp32c6_base] +extends = esp32_base +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +build_flags = + ${arduino_base.build_flags} + -Wall + -Wextra + -Isrc/platform/esp32 + -std=c++11 + -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL + -DAXP_DEBUG_PORT=Serial + -DCONFIG_BT_NIMBLE_ENABLED + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 + -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DSERIAL_BUFFER_SIZE=4096 + -DLIBPAX_ARDUINO + -DLIBPAX_WIFI + -DLIBPAX_BLE + -DMESHTASTIC_EXCLUDE_WEBSERVER + ;-DDEBUG_HEAP + ; TEMP + -DHAS_BLUETOOTH=0 + -DMESHTASTIC_EXCLUDE_PAXCOUNTER + -DMESHTASTIC_EXCLUDE_BLUETOOTH + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +lib_deps = + ${arduino_base.lib_deps} + ${networking_base.lib_deps} + ${environmental_base.lib_deps} + https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 + https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f + rweather/Crypto@^0.4.0 + +build_src_filter = + ${esp32_base.build_src_filter} - + +monitor_speed = 115200 +monitor_filters = esp32_c3_exception_decoder + +lib_ignore = + NonBlockingRTTTL + NimBLE-Arduino + libpax + \ No newline at end of file diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 01fa65816..19cfa0044 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -60,7 +60,8 @@ const char *getGPSPowerStateString(GPSPowerState state) case GPS_OFF: return "OFF"; default: - assert(false); // Unhandled enum value.. + assert(false); // Unhandled enum value.. + return "FALSE"; // to make new ESP-IDF happy } } @@ -330,7 +331,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); - uint16_t needRead; + uint16_t needRead = 0; while (millis() - startTime < waitMillis) { if (_serial_gps->available()) { diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index ae09ee408..07fb5d28e 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1004,55 +1004,55 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->setColor(WHITE); #ifndef EXCLUDE_EMOJI - if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { + if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbup); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44E") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44E") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbdown); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"❓") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "❓") == 0) { display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height, question); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"‼️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "‼️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5, bang_width, bang_height, bang); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F4A9") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F4A9") == 0) { display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5, poo_width, poo_height, poo); } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) { display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5, haha_width, haha_height, haha); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44B") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44B") == 0) { display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width, wave_icon_height, wave_icon); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F920") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F920") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height, cowboy); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F42D") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F42D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height, deadmau5); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xE2\x98\x80\xEF\xB8\x8F") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) { display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5, sun_width, sun_height, sun); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\u2614") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\u2614") == 0) { display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10, rain_width, rain_height, rain); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"☁️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "☁️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"🌫️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "🌫️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5, fog_width, fog_height, fog); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xf0\x9f\x98\x88") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) { display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"♥️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "♥️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart); } else { diff --git a/src/main.cpp b/src/main.cpp index e24ba68b3..5057d7f57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,15 +322,19 @@ void setup() #ifdef BUTTON_PIN #ifdef ARCH_ESP32 - // If the button is connected to GPIO 12, don't enable the ability to use - // meshtasticAdmin on the device. - pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); - +#if ESP_ARDUINO_VERSION_MAJOR >= 3 +#ifdef BUTTON_NEED_PULLUP + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP); +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN +#endif +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN #ifdef BUTTON_NEED_PULLUP gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); delay(10); #endif - +#endif #endif #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dca639070..12b731ab1 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -49,7 +49,7 @@ NodeDB *nodeDB = nullptr; // we have plenty of ram so statically alloc this tempbuf (for now) -EXT_RAM_ATTR meshtastic_DeviceState devicestate; +EXT_RAM_BSS_ATTR meshtastic_DeviceState devicestate; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_LocalConfig config; meshtastic_LocalModuleConfig moduleConfig; diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index c96edae8e..f7d016f10 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -14,7 +14,7 @@ */ template class TypedQueue { - static_assert(std::is_pod::value, "T must be pod"); + static_assert(std::is_standard_layout::value, "T must be standard layout"); QueueHandle_t h; concurrency::OSThread *reader = NULL; diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 3a483aac1..097f4fa21 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,7 +45,7 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { - auto client = U::available(); + auto client = U::accept(); if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 07b03222e..e3203e6f7 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -309,7 +309,8 @@ static void WiFiEvent(WiFiEvent_t event) onNetworkConnected(); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str()); + LOG_INFO("Obtained Local IP6 address: %s\n", WiFi.linkLocalIPv6().toString().c_str()); + LOG_INFO("Obtained GlobalIP6 address: %s\n", WiFi.globalIPv6().toString().c_str()); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index 08e72c35a..a5dff3651 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -3,7 +3,7 @@ #include "SinglePortModule.h" #include "concurrency/OSThread.h" #include "configuration.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6) #include #else // Noop class for portduino. diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb6a58b2e..2a962c268 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -273,7 +273,7 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() meshtastic_TAKPacket takPacket = {.is_compressed = true, .has_contact = true, - .contact = {0}, + .contact = meshtastic_Contact_init_default, .has_group = true, .group = {meshtastic_MemberRole_TeamMember, meshtastic_Team_Cyan}, .has_status = true, @@ -282,13 +282,13 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() .battery = powerStatus->getBatteryChargePercent(), }, .which_payload_variant = meshtastic_TAKPacket_pli_tag, - {.pli = { - .latitude_i = localPosition.latitude_i, - .longitude_i = localPosition.longitude_i, - .altitude = localPosition.altitude_hae, - .speed = localPosition.ground_speed, - .course = static_cast(localPosition.ground_track), - }}}; + .payload_variant = {.pli = { + .latitude_i = localPosition.latitude_i, + .longitude_i = localPosition.longitude_i, + .altitude = localPosition.altitude_hae, + .speed = localPosition.ground_speed, + .course = static_cast(localPosition.ground_track), + }}}; auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign, sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index f0ba64f65..549fcf1d7 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -62,6 +62,9 @@ SerialModuleRadio *serialModuleRadio; #if defined(TTGO_T_ECHO) || defined(CANARYONE) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("SerialModule") {} +static Print *serialPrint = &Serial1; #else SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial2; @@ -137,7 +140,16 @@ int32_t SerialModule::runOnce() // Give it a chance to flush out 💩 delay(10); } -#ifdef ARCH_ESP32 +#if defined(CONFIG_IDF_TARGET_ESP32C6) + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial1.setRxBufferSize(RX_BUFFER); + Serial1.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); + } else { + Serial.begin(baud); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); + } + +#elif defined(ARCH_ESP32) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { Serial2.setRxBufferSize(RX_BUFFER); @@ -205,8 +217,13 @@ int32_t SerialModule::runOnce() processWXSerial(); } else { +#if defined(CONFIG_IDF_TARGET_ESP32C6) + while (Serial1.available()) { + serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#else while (Serial2.available()) { serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#endif serialModuleRadio->sendPayload(); } } @@ -392,7 +409,7 @@ uint32_t SerialModule::getBaudRate() */ void SerialModule::processWXSerial() { -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) +#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 6840700e5..240fae0f9 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -325,6 +325,7 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } #if HAS_WIFI && !defined(ARCH_PORTDUINO) +#ifndef CONFIG_IDF_TARGET_ESP32C6 if (moduleConfig.mqtt.tls_enabled) { // change default for encrypted to 8883 try { @@ -340,6 +341,9 @@ void MQTT::reconnect() LOG_INFO("Using non-TLS-encrypted session\n"); pubSub.setClient(mqttClient); } +#else + pubSub.setClient(mqttClient); +#endif #elif HAS_NETWORKING pubSub.setClient(mqttClient); #endif diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index ba0987783..c827e12ca 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -9,9 +9,11 @@ #if HAS_WIFI #include #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 #include #endif #endif +#endif #if HAS_ETHERNET #include #endif @@ -33,9 +35,11 @@ class MQTT : private concurrency::OSThread #if HAS_WIFI WiFiClient mqttClient; #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 WiFiClientSecure wifiSecureClient; #endif #endif +#endif #if HAS_ETHERNET EthernetClient mqttClient; #endif diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 0b6f7cf23..f16accab6 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -13,6 +13,7 @@ #include "mesh/wifi/WiFiAPClient.h" #endif +#include "esp_mac.h" #include "meshUtils.h" #include "sleep.h" #include "soc/rtc.h" @@ -147,9 +148,16 @@ void esp32Setup() // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 +#ifdef CONFIG_IDF_TARGET_ESP32C6 + esp_task_wdt_config_t *wdt_config = (esp_task_wdt_config_t *)malloc(sizeof(esp_task_wdt_config_t)); + wdt_config->timeout_ms = APP_WATCHDOG_SECS * 1000; + wdt_config->trigger_panic = true; + res = esp_task_wdt_init(wdt_config); + assert(res == ESP_OK); +#else res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); assert(res == ESP_OK); - +#endif res = esp_task_wdt_add(NULL); assert(res == ESP_OK); @@ -223,7 +231,7 @@ void cpuDeepSleep(uint32_t msecToWake) // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. -#if SOC_RTCIO_HOLD_SUPPORTED +#if SOC_RTCIO_HOLD_SUPPORTED && SOC_PM_SUPPORT_EXT_WAKEUP uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif diff --git a/src/power.h b/src/power.h index a4307ee07..5a41b55f2 100644 --- a/src/power.h +++ b/src/power.h @@ -5,6 +5,7 @@ #include "configuration.h" #ifdef ARCH_ESP32 +// "legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h #include #include #endif diff --git a/src/serialization/JSON.cpp b/src/serialization/JSON.cpp index e98bf47b9..42e615108 100644 --- a/src/serialization/JSON.cpp +++ b/src/serialization/JSON.cpp @@ -184,7 +184,7 @@ bool JSON::ExtractString(const char **data, std::string &str) // End of the string? else if (next_char == '"') { (*data)++; - str.reserve(); // Remove unused capacity + str.shrink_to_fit(); // Remove unused capacity return true; } diff --git a/src/sleep.cpp b/src/sleep.cpp index 27e81ce54..b0802c624 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -446,12 +446,14 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { - static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss + static esp_pm_config_t esp32_config; // filled with zeros because bss #if CONFIG_IDF_TARGET_ESP32S3 esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32S2 esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ; +#elif CONFIG_IDF_TARGET_ESP32C6 + esp32_config.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32C3 esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ; #else diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini new file mode 100644 index 000000000..977e8ba86 --- /dev/null +++ b/variants/tlora_c6/platformio.ini @@ -0,0 +1,5 @@ +[env:tlora-c6] +extends = esp32c6_base +board = esp32-c6-devkitm-1 +build_flags = + ${esp32c6_base.build_flags} -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 \ No newline at end of file diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h new file mode 100644 index 000000000..08fefa809 --- /dev/null +++ b/variants/tlora_c6/variant.h @@ -0,0 +1,16 @@ +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 15 + +#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller + +#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost +#define LED_PIN 2 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP +#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. + +#define USE_RF95 +#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 \ No newline at end of file From ba31a7c753e829c6dba1253f02f85681989f47fb Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Sat, 21 Sep 2024 06:27:41 +1200 Subject: [PATCH 108/252] Honor flip & color for Heltec T114 and T190 (#4786) * Honor TFT_MESH color if defined for Heltec T114 or T190 * Temporary: point lib_deps at fork of Heltec's ST7789 library For demo only, until ST7789 is merged * Update lib_deps; tidy preprocessor logic --- src/graphics/Screen.cpp | 7 +++++++ variants/heltec_mesh_node_t114/platformio.ini | 2 +- variants/heltec_vision_master_t190/platformio.ini | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index ae09ee408..31f522a43 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1670,6 +1670,11 @@ void Screen::setup() static_cast(dispdev)->setSubtype(7); #endif +#if defined(USE_ST7789) && defined(TFT_MESH) + // Heltec T114 and T190: honor a custom text color, if defined in variant.h + static_cast(dispdev)->setRGB(TFT_MESH); +#endif + // Initialising the UI will init the display too. ui->init(); @@ -1726,6 +1731,8 @@ void Screen::setup() #if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \ defined(RAK14014) || defined(HX8357_CS) static_cast(dispdev)->flipScreenVertically(); +#elif defined(USE_ST7789) + static_cast(dispdev)->flipScreenVertically(); #else dispdev->flipScreenVertically(); #endif diff --git a/variants/heltec_mesh_node_t114/platformio.ini b/variants/heltec_mesh_node_t114/platformio.ini index e0d8ca0cc..1b06c7f5e 100644 --- a/variants/heltec_mesh_node_t114/platformio.ini +++ b/variants/heltec_mesh_node_t114/platformio.ini @@ -14,4 +14,4 @@ build_src_filter = ${nrf52_base.build_src_filter} +<../variants/heltec_mesh_node lib_deps = ${nrf52840_base.lib_deps} lewisxhe/PCF8563_Library@^1.0.1 - https://github.com/meshtastic/st7789#7181320e7ed05c7fb5fd2d32f14723bce6088b7b \ No newline at end of file + https://github.com/meshtastic/st7789#bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f \ No newline at end of file diff --git a/variants/heltec_vision_master_t190/platformio.ini b/variants/heltec_vision_master_t190/platformio.ini index fd0001439..0c504d62b 100644 --- a/variants/heltec_vision_master_t190/platformio.ini +++ b/variants/heltec_vision_master_t190/platformio.ini @@ -9,5 +9,5 @@ build_flags = lib_deps = ${esp32s3_base.lib_deps} lewisxhe/PCF8563_Library@^1.0.1 - https://github.com/meshtastic/st7789#7181320e7ed05c7fb5fd2d32f14723bce6088b7b + https://github.com/meshtastic/st7789#bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f upload_speed = 921600 \ No newline at end of file From 0664c09f9dff0184be16752b5cae7095f1a23465 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 20 Sep 2024 14:55:53 -0500 Subject: [PATCH 109/252] Download debian files after firmware zip --- .github/workflows/main_matrix.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 9b97dcb2e..549a5d60f 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -251,12 +251,6 @@ jobs: merge-multiple: true path: ./output - - uses: actions/download-artifact@v4 - with: - pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb - merge-multiple: true - path: ./output - - name: Display structure of downloaded files run: ls -R @@ -314,6 +308,12 @@ jobs: asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip asset_content_type: application/zip + - uses: actions/download-artifact@v4 + with: + pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb + merge-multiple: true + path: ./output + - name: Add raspbian aarch64 .deb uses: actions/upload-release-asset@v1 env: From c2272ce5a102ded4606bf989c30bff377303b2bd Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:30:32 -0700 Subject: [PATCH 110/252] set title for protobufs bump PR (#4792) --- .github/workflows/update_protobufs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 4402a280e..b46c070f1 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -28,6 +28,7 @@ jobs: - name: Create pull request uses: peter-evans/create-pull-request@v6 with: + title: Update protobufs and classes add-paths: | protobufs src/mesh From ed13105aec493a771f3750b3bc50d45fba0f4601 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:30:49 -0700 Subject: [PATCH 111/252] set title for version bump PR (#4791) --- .github/workflows/main_matrix.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 549a5d60f..588f0981a 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -351,5 +351,6 @@ jobs: - name: Create version.properties pull request uses: peter-evans/create-pull-request@v6 with: + title: Bump version.properties add-paths: | version.properties From ec848bab5298559f149da4a58965b1fa7f58ad86 Mon Sep 17 00:00:00 2001 From: Jason Murray Date: Fri, 20 Sep 2024 14:40:10 -0700 Subject: [PATCH 112/252] Enable Dependabot --- .github/dependabot.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..c81c7fc07 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: +- package-ecosystem: docker + directory: devcontainer + schedule: + interval: daily + time: "05:00" + timezone: US/Pacific +- package-ecosystem: docker + directory: / + schedule: + interval: daily + time: "05:00" + timezone: US/Pacific +- package-ecosystem: gitsubmodule + directory: / + schedule: + interval: daily + time: "05:00" + timezone: US/Pacific +- package-ecosystem: github-actions + directory: /.github/workflows + schedule: + interval: daily + time: "05:00" + timezone: US/Pacific From 7368cb99dc146beb0c469c351571be04ed5a6d72 Mon Sep 17 00:00:00 2001 From: Jason Murray Date: Fri, 20 Sep 2024 19:22:45 -0700 Subject: [PATCH 113/252] chore: trunk fmt --- .github/dependabot.yml | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c81c7fc07..b15e8c1ce 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,26 +1,26 @@ version: 2 updates: -- package-ecosystem: docker - directory: devcontainer - schedule: - interval: daily - time: "05:00" - timezone: US/Pacific -- package-ecosystem: docker - directory: / - schedule: - interval: daily - time: "05:00" - timezone: US/Pacific -- package-ecosystem: gitsubmodule - directory: / - schedule: - interval: daily - time: "05:00" - timezone: US/Pacific -- package-ecosystem: github-actions - directory: /.github/workflows - schedule: - interval: daily - time: "05:00" - timezone: US/Pacific + - package-ecosystem: docker + directory: devcontainer + schedule: + interval: daily + time: 05:00 + timezone: US/Pacific + - package-ecosystem: docker + directory: / + schedule: + interval: daily + time: 05:00 + timezone: US/Pacific + - package-ecosystem: gitsubmodule + directory: / + schedule: + interval: daily + time: 05:00 + timezone: US/Pacific + - package-ecosystem: github-actions + directory: /.github/workflows + schedule: + interval: daily + time: 05:00 + timezone: US/Pacific From 74e647043924bc60e5a573170d60b01b69daacb5 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sat, 21 Sep 2024 14:20:30 +0800 Subject: [PATCH 114/252] fix dependabot syntax (#4795) * fix dependabot syntax * Update dependabot.yml * Update dependabot.yml --- .github/dependabot.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b15e8c1ce..616c16ce2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,23 +4,23 @@ updates: directory: devcontainer schedule: interval: daily - time: 05:00 + time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check timezone: US/Pacific - package-ecosystem: docker directory: / schedule: interval: daily - time: 05:00 + time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check timezone: US/Pacific - package-ecosystem: gitsubmodule directory: / schedule: interval: daily - time: 05:00 + time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check timezone: US/Pacific - package-ecosystem: github-actions directory: /.github/workflows schedule: interval: daily - time: 05:00 + time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check timezone: US/Pacific From 38828412830e0d6f6a6b23219c646648bceb013a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 08:17:31 +0000 Subject: [PATCH 115/252] Bump peter-evans/create-pull-request from 6 to 7 in /.github/workflows (#4797) --- .github/workflows/main_matrix.yml | 2 +- .github/workflows/update_protobufs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 588f0981a..be09c24b2 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -349,7 +349,7 @@ jobs: bin/bump_version.py - name: Create version.properties pull request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: title: Bump version.properties add-paths: | diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index b46c070f1..f93930a83 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -26,7 +26,7 @@ jobs: ./bin/regen-protos.sh - name: Create pull request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: title: Update protobufs and classes add-paths: | From f1cf2bf413d80935f7abbae2fe68cbd7c9a66b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 12 Sep 2024 22:42:10 +0200 Subject: [PATCH 116/252] First stab at ESP32-C6 support for TLora-C6 --- arch/esp32/esp32c6.ini | 47 ++++++++++++++++++++++++ src/gps/GPS.cpp | 5 ++- src/graphics/Screen.cpp | 28 +++++++------- src/main.cpp | 14 ++++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/TypedQueue.h | 2 +- src/mesh/api/ServerAPI.cpp | 2 +- src/mesh/wifi/WiFiAPClient.cpp | 3 +- src/modules/ExternalNotificationModule.h | 2 +- src/modules/PositionModule.cpp | 16 ++++---- src/modules/SerialModule.cpp | 21 ++++++++++- src/mqtt/MQTT.cpp | 4 ++ src/mqtt/MQTT.h | 4 ++ src/platform/esp32/main-esp32.cpp | 12 +++++- src/power.h | 1 + src/serialization/JSON.cpp | 2 +- src/sleep.cpp | 4 +- variants/tlora_c6/platformio.ini | 5 +++ variants/tlora_c6/variant.h | 16 ++++++++ 19 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 arch/esp32/esp32c6.ini create mode 100644 variants/tlora_c6/platformio.ini create mode 100644 variants/tlora_c6/variant.h diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini new file mode 100644 index 000000000..a7bcdc0e8 --- /dev/null +++ b/arch/esp32/esp32c6.ini @@ -0,0 +1,47 @@ +[esp32c6_base] +extends = esp32_base +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +build_flags = + ${arduino_base.build_flags} + -Wall + -Wextra + -Isrc/platform/esp32 + -std=c++11 + -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL + -DAXP_DEBUG_PORT=Serial + -DCONFIG_BT_NIMBLE_ENABLED + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 + -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + -DSERIAL_BUFFER_SIZE=4096 + -DLIBPAX_ARDUINO + -DLIBPAX_WIFI + -DLIBPAX_BLE + -DMESHTASTIC_EXCLUDE_WEBSERVER + ;-DDEBUG_HEAP + ; TEMP + -DHAS_BLUETOOTH=0 + -DMESHTASTIC_EXCLUDE_PAXCOUNTER + -DMESHTASTIC_EXCLUDE_BLUETOOTH + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +lib_deps = + ${arduino_base.lib_deps} + ${networking_base.lib_deps} + ${environmental_base.lib_deps} + https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 + https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f + rweather/Crypto@^0.4.0 + +build_src_filter = + ${esp32_base.build_src_filter} - + +monitor_speed = 115200 +monitor_filters = esp32_c3_exception_decoder + +lib_ignore = + NonBlockingRTTTL + NimBLE-Arduino + libpax + \ No newline at end of file diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 01fa65816..19cfa0044 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -60,7 +60,8 @@ const char *getGPSPowerStateString(GPSPowerState state) case GPS_OFF: return "OFF"; default: - assert(false); // Unhandled enum value.. + assert(false); // Unhandled enum value.. + return "FALSE"; // to make new ESP-IDF happy } } @@ -330,7 +331,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t { uint16_t ubxFrameCounter = 0; uint32_t startTime = millis(); - uint16_t needRead; + uint16_t needRead = 0; while (millis() - startTime < waitMillis) { if (_serial_gps->available()) { diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 31f522a43..a34a6f1ed 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1004,55 +1004,55 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->setColor(WHITE); #ifndef EXCLUDE_EMOJI - if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44D") == 0) { + if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbup); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44E") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44E") == 0) { display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, thumbdown); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"❓") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "❓") == 0) { display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height, question); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"‼️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "‼️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5, bang_width, bang_height, bang); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F4A9") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F4A9") == 0) { display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5, poo_width, poo_height, poo); } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) { display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5, haha_width, haha_height, haha); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F44B") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F44B") == 0) { display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width, wave_icon_height, wave_icon); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F920") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F920") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height, cowboy); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\U0001F42D") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\U0001F42D") == 0) { display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height, deadmau5); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xE2\x98\x80\xEF\xB8\x8F") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) { display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5, sun_width, sun_height, sun); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\u2614") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\u2614") == 0) { display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10, rain_width, rain_height, rain); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"☁️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "☁️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"🌫️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "🌫️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5, fog_width, fog_height, fog); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"\xf0\x9f\x98\x88") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) { display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil); - } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), u8"♥️") == 0) { + } else if (strcmp(reinterpret_cast(mp.decoded.payload.bytes), "♥️") == 0) { display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart); } else { diff --git a/src/main.cpp b/src/main.cpp index e24ba68b3..5057d7f57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -322,15 +322,19 @@ void setup() #ifdef BUTTON_PIN #ifdef ARCH_ESP32 - // If the button is connected to GPIO 12, don't enable the ability to use - // meshtasticAdmin on the device. - pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); - +#if ESP_ARDUINO_VERSION_MAJOR >= 3 +#ifdef BUTTON_NEED_PULLUP + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP); +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN +#endif +#else + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN #ifdef BUTTON_NEED_PULLUP gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); delay(10); #endif - +#endif #endif #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dca639070..12b731ab1 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -49,7 +49,7 @@ NodeDB *nodeDB = nullptr; // we have plenty of ram so statically alloc this tempbuf (for now) -EXT_RAM_ATTR meshtastic_DeviceState devicestate; +EXT_RAM_BSS_ATTR meshtastic_DeviceState devicestate; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_LocalConfig config; meshtastic_LocalModuleConfig moduleConfig; diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index c96edae8e..f7d016f10 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -14,7 +14,7 @@ */ template class TypedQueue { - static_assert(std::is_pod::value, "T must be pod"); + static_assert(std::is_standard_layout::value, "T must be standard layout"); QueueHandle_t h; concurrency::OSThread *reader = NULL; diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 3a483aac1..097f4fa21 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,7 +45,7 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { - auto client = U::available(); + auto client = U::accept(); if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 07b03222e..e3203e6f7 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -309,7 +309,8 @@ static void WiFiEvent(WiFiEvent_t event) onNetworkConnected(); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str()); + LOG_INFO("Obtained Local IP6 address: %s\n", WiFi.linkLocalIPv6().toString().c_str()); + LOG_INFO("Obtained GlobalIP6 address: %s\n", WiFi.globalIPv6().toString().c_str()); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h index 08e72c35a..a5dff3651 100644 --- a/src/modules/ExternalNotificationModule.h +++ b/src/modules/ExternalNotificationModule.h @@ -3,7 +3,7 @@ #include "SinglePortModule.h" #include "concurrency/OSThread.h" #include "configuration.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6) #include #else // Noop class for portduino. diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb6a58b2e..2a962c268 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -273,7 +273,7 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() meshtastic_TAKPacket takPacket = {.is_compressed = true, .has_contact = true, - .contact = {0}, + .contact = meshtastic_Contact_init_default, .has_group = true, .group = {meshtastic_MemberRole_TeamMember, meshtastic_Team_Cyan}, .has_status = true, @@ -282,13 +282,13 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() .battery = powerStatus->getBatteryChargePercent(), }, .which_payload_variant = meshtastic_TAKPacket_pli_tag, - {.pli = { - .latitude_i = localPosition.latitude_i, - .longitude_i = localPosition.longitude_i, - .altitude = localPosition.altitude_hae, - .speed = localPosition.ground_speed, - .course = static_cast(localPosition.ground_track), - }}}; + .payload_variant = {.pli = { + .latitude_i = localPosition.latitude_i, + .longitude_i = localPosition.longitude_i, + .altitude = localPosition.altitude_hae, + .speed = localPosition.ground_speed, + .course = static_cast(localPosition.ground_track), + }}}; auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign, sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL); diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index f0ba64f65..549fcf1d7 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -62,6 +62,9 @@ SerialModuleRadio *serialModuleRadio; #if defined(TTGO_T_ECHO) || defined(CANARYONE) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("SerialModule") {} +static Print *serialPrint = &Serial1; #else SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} static Print *serialPrint = &Serial2; @@ -137,7 +140,16 @@ int32_t SerialModule::runOnce() // Give it a chance to flush out 💩 delay(10); } -#ifdef ARCH_ESP32 +#if defined(CONFIG_IDF_TARGET_ESP32C6) + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial1.setRxBufferSize(RX_BUFFER); + Serial1.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); + } else { + Serial.begin(baud); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); + } + +#elif defined(ARCH_ESP32) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { Serial2.setRxBufferSize(RX_BUFFER); @@ -205,8 +217,13 @@ int32_t SerialModule::runOnce() processWXSerial(); } else { +#if defined(CONFIG_IDF_TARGET_ESP32C6) + while (Serial1.available()) { + serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#else while (Serial2.available()) { serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); +#endif serialModuleRadio->sendPayload(); } } @@ -392,7 +409,7 @@ uint32_t SerialModule::getBaudRate() */ void SerialModule::processWXSerial() { -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) +#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 6840700e5..240fae0f9 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -325,6 +325,7 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } #if HAS_WIFI && !defined(ARCH_PORTDUINO) +#ifndef CONFIG_IDF_TARGET_ESP32C6 if (moduleConfig.mqtt.tls_enabled) { // change default for encrypted to 8883 try { @@ -340,6 +341,9 @@ void MQTT::reconnect() LOG_INFO("Using non-TLS-encrypted session\n"); pubSub.setClient(mqttClient); } +#else + pubSub.setClient(mqttClient); +#endif #elif HAS_NETWORKING pubSub.setClient(mqttClient); #endif diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index ba0987783..c827e12ca 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -9,9 +9,11 @@ #if HAS_WIFI #include #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 #include #endif #endif +#endif #if HAS_ETHERNET #include #endif @@ -33,9 +35,11 @@ class MQTT : private concurrency::OSThread #if HAS_WIFI WiFiClient mqttClient; #if !defined(ARCH_PORTDUINO) +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3 WiFiClientSecure wifiSecureClient; #endif #endif +#endif #if HAS_ETHERNET EthernetClient mqttClient; #endif diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 0b6f7cf23..f16accab6 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -13,6 +13,7 @@ #include "mesh/wifi/WiFiAPClient.h" #endif +#include "esp_mac.h" #include "meshUtils.h" #include "sleep.h" #include "soc/rtc.h" @@ -147,9 +148,16 @@ void esp32Setup() // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 +#ifdef CONFIG_IDF_TARGET_ESP32C6 + esp_task_wdt_config_t *wdt_config = (esp_task_wdt_config_t *)malloc(sizeof(esp_task_wdt_config_t)); + wdt_config->timeout_ms = APP_WATCHDOG_SECS * 1000; + wdt_config->trigger_panic = true; + res = esp_task_wdt_init(wdt_config); + assert(res == ESP_OK); +#else res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); assert(res == ESP_OK); - +#endif res = esp_task_wdt_add(NULL); assert(res == ESP_OK); @@ -223,7 +231,7 @@ void cpuDeepSleep(uint32_t msecToWake) // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. -#if SOC_RTCIO_HOLD_SUPPORTED +#if SOC_RTCIO_HOLD_SUPPORTED && SOC_PM_SUPPORT_EXT_WAKEUP uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif diff --git a/src/power.h b/src/power.h index a4307ee07..5a41b55f2 100644 --- a/src/power.h +++ b/src/power.h @@ -5,6 +5,7 @@ #include "configuration.h" #ifdef ARCH_ESP32 +// "legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h #include #include #endif diff --git a/src/serialization/JSON.cpp b/src/serialization/JSON.cpp index e98bf47b9..42e615108 100644 --- a/src/serialization/JSON.cpp +++ b/src/serialization/JSON.cpp @@ -184,7 +184,7 @@ bool JSON::ExtractString(const char **data, std::string &str) // End of the string? else if (next_char == '"') { (*data)++; - str.reserve(); // Remove unused capacity + str.shrink_to_fit(); // Remove unused capacity return true; } diff --git a/src/sleep.cpp b/src/sleep.cpp index 27e81ce54..b0802c624 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -446,12 +446,14 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { - static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss + static esp_pm_config_t esp32_config; // filled with zeros because bss #if CONFIG_IDF_TARGET_ESP32S3 esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32S2 esp32_config.max_freq_mhz = CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ; +#elif CONFIG_IDF_TARGET_ESP32C6 + esp32_config.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32C3 esp32_config.max_freq_mhz = CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ; #else diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini new file mode 100644 index 000000000..977e8ba86 --- /dev/null +++ b/variants/tlora_c6/platformio.ini @@ -0,0 +1,5 @@ +[env:tlora-c6] +extends = esp32c6_base +board = esp32-c6-devkitm-1 +build_flags = + ${esp32c6_base.build_flags} -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 \ No newline at end of file diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h new file mode 100644 index 000000000..08fefa809 --- /dev/null +++ b/variants/tlora_c6/variant.h @@ -0,0 +1,16 @@ +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 15 + +#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller + +#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost +#define LED_PIN 2 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP +#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. + +#define USE_RF95 +#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 \ No newline at end of file From 8e5928276b734f56fe2936ab8be7f6ee92de1713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 21 Sep 2024 11:27:14 +0200 Subject: [PATCH 117/252] update pin definitions update toolchain enable telemetry fix compilation --- arch/esp32/esp32c6.ini | 11 ++--------- platformio.ini | 2 -- src/Power.cpp | 2 ++ src/sleep.cpp | 1 + variants/tlora_c6/platformio.ini | 8 +++++++- variants/tlora_c6/variant.h | 32 +++++++++++++++++++------------- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini index a7bcdc0e8..65c63b299 100644 --- a/arch/esp32/esp32c6.ini +++ b/arch/esp32/esp32c6.ini @@ -1,18 +1,12 @@ [esp32c6_base] extends = esp32_base -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +platform = https://github.com/Jason2866/platform-espressif32.git#d8d8f1bcf4bfcae82db2bef70a2b0014f1d2bc13 build_flags = ${arduino_base.build_flags} -Wall -Wextra -Isrc/platform/esp32 -std=c++11 - -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DAXP_DEBUG_PORT=Serial - -DCONFIG_BT_NIMBLE_ENABLED - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DSERIAL_BUFFER_SIZE=4096 -DLIBPAX_ARDUINO @@ -24,7 +18,6 @@ build_flags = -DHAS_BLUETOOTH=0 -DMESHTASTIC_EXCLUDE_PAXCOUNTER -DMESHTASTIC_EXCLUDE_BLUETOOTH - -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR lib_deps = ${arduino_base.lib_deps} @@ -37,7 +30,7 @@ lib_deps = build_src_filter = ${esp32_base.build_src_filter} - -monitor_speed = 115200 +monitor_speed = 460800 monitor_filters = esp32_c3_exception_decoder lib_ignore = diff --git a/platformio.ini b/platformio.ini index 9b869a036..7e4116991 100644 --- a/platformio.ini +++ b/platformio.ini @@ -152,13 +152,11 @@ lib_deps = emotibit/EmotiBit MLX90632@^1.0.8 dfrobot/DFRobot_RTU@^1.0.3 - https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 boschsensortec/BME68x Sensor Library@^1.1.40407 https://github.com/KodinLanewave/INA3221@^1.0.0 lewisxhe/SensorLib@0.2.0 mprograms/QMC5883LCompass@^1.2.0 - https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 diff --git a/src/Power.cpp b/src/Power.cpp index 61a6c987d..047f3d768 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -136,6 +136,7 @@ using namespace meshtastic; */ static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor +// warning: 'void adcEnable()' defined but not used [-Wunused-function] static void adcEnable() { #ifdef ADC_CTRL // enable adc voltage divider when we need to read @@ -149,6 +150,7 @@ static void adcEnable() #endif } +// warning: 'void adcDisable()' defined but not used [-Wunused-function] static void adcDisable() { #ifdef ADC_CTRL // disable adc voltage divider when we need to read diff --git a/src/sleep.cpp b/src/sleep.cpp index b0802c624..9efbabb35 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -17,6 +17,7 @@ #include "target_specific.h" #ifdef ARCH_ESP32 +// "esp_pm_config_esp32_t is deprecated, please include esp_pm.h and use esp_pm_config_t instead" #include "esp32/pm.h" #include "esp_pm.h" #if HAS_WIFI diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini index 977e8ba86..3a8fd2c19 100644 --- a/variants/tlora_c6/platformio.ini +++ b/variants/tlora_c6/platformio.ini @@ -2,4 +2,10 @@ extends = esp32c6_base board = esp32-c6-devkitm-1 build_flags = - ${esp32c6_base.build_flags} -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 \ No newline at end of file + ${esp32c6_base.build_flags} + -D PRIVATE_HW + -D TLORA_C6 + -I variants/tlora_c6 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/esp32c3" \ No newline at end of file diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h index 08fefa809..e16bfb767 100644 --- a/variants/tlora_c6/variant.h +++ b/variants/tlora_c6/variant.h @@ -1,16 +1,22 @@ -#define I2C_SDA 4 // I2C pins for this board -#define I2C_SCL 15 +#define I2C_SDA 8 // I2C pins for this board +#define I2C_SCL 9 -#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller - -#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost -#define LED_PIN 2 // If defined we will blink this LED -#define BUTTON_PIN 0 // If defined, this will be used for user button presses -#define BUTTON_NEED_PULLUP +#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost +#define LED_PIN 7 // If defined we will blink this LED #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. -#define USE_RF95 -#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 \ No newline at end of file +#define USE_SX1262 +#define LORA_SCK 6 +#define LORA_MISO 1 +#define LORA_MOSI 0 +#define LORA_CS 18 +#define LORA_RESET 21 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 23 +#define SX126X_DIO2 20 +#define SX126X_BUSY 22 +#define SX126X_RESET LORA_RESET +#define SX126X_RXEN 15 +#define SX126X_TXEN 14 +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 \ No newline at end of file From 6490cadd35b1703361a2cd820aa0a84acf5696d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 09:30:36 +0000 Subject: [PATCH 118/252] Bump docker/build-push-action from 5 to 6 in /.github/workflows (#4800) --- .github/workflows/build_native.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index 51bef0c13..1fb44a717 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -67,7 +67,7 @@ jobs: - name: Docker build and push tagged versions if: ${{ github.event_name == 'workflow_dispatch' }} continue-on-error: true # FIXME: Failing docker login auth - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile @@ -77,7 +77,7 @@ jobs: - name: Docker build and push if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} continue-on-error: true # FIXME: Failing docker login auth - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile From 52cef05c70bdebbad972327b748bc7bd964c86c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 21 Sep 2024 12:42:51 +0200 Subject: [PATCH 119/252] heltec-wireless-bridge requires Proto PR first --- src/platform/esp32/architecture.h | 2 ++ .../heltec_wireless_bridge/platformio.ini | 6 ++++ variants/heltec_wireless_bridge/variant.h | 29 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 variants/heltec_wireless_bridge/platformio.ini create mode 100644 variants/heltec_wireless_bridge/variant.h diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 93630aa8a..90c4c392d 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -76,6 +76,8 @@ #ifdef HELTEC_V2_1 #define HW_VENDOR meshtastic_HardwareModel_HELTEC_V2_1 #endif +#elif defined(HELTEC_WIRELESS_BRIDGE) +#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_BRIDGE #elif defined(ARDUINO_HELTEC_WIFI_LORA_32) #define HW_VENDOR meshtastic_HardwareModel_HELTEC_V1 #elif defined(TLORA_V1) diff --git a/variants/heltec_wireless_bridge/platformio.ini b/variants/heltec_wireless_bridge/platformio.ini new file mode 100644 index 000000000..45c3aba74 --- /dev/null +++ b/variants/heltec_wireless_bridge/platformio.ini @@ -0,0 +1,6 @@ +[env:heltec-wireless-bridge] +;build_type = debug ; to make it possible to step through our jtag debugger +extends = esp32_base +board = heltec_wifi_lora_32 +build_flags = + ${esp32_base.build_flags} -D HELTEC_WIRELESS_BRIDGE -I variants/heltec_wireless_bridge \ No newline at end of file diff --git a/variants/heltec_wireless_bridge/variant.h b/variants/heltec_wireless_bridge/variant.h new file mode 100644 index 000000000..7c4f41660 --- /dev/null +++ b/variants/heltec_wireless_bridge/variant.h @@ -0,0 +1,29 @@ +// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine. +// Tested on Neo6m module. +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 36 +#define GPS_TX_PIN 33 + +#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 15 +#endif + +#define LED_PIN 25 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses + +#define USE_RF95 +#define LORA_DIO0 26 // a No connect on the SX1262 module +#ifndef USE_JTAG +#define LORA_RESET 14 +#endif +#define LORA_DIO1 35 +#define LORA_DIO2 34 // Not really used + +// ratio of voltage divider = 3.20 (R1=100k, R2=220k) +#define ADC_MULTIPLIER 3.2 + +#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define ADC_CHANNEL ADC2_GPIO13_CHANNEL +#define BAT_MEASURE_ADC_UNIT 2 \ No newline at end of file From de706523f56070cf3a4b7393b00485432774facf Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sat, 21 Sep 2024 19:10:59 +0800 Subject: [PATCH 120/252] Actions: Semgrep Images have moved from returntocorp to semgrep (#4774) https://hub.docker.com/r/returntocorp/semgrep notes: "We've moved! Official Docker images for Semgrep now available at semgrep/semgrep." Patch updates our CI workflow for these images. Co-authored-by: Ben Meadors --- .github/workflows/sec_sast_semgrep_cron.yml | 2 +- .github/workflows/sec_sast_semgrep_pull.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sec_sast_semgrep_cron.yml b/.github/workflows/sec_sast_semgrep_cron.yml index 2a0361f5e..54bbbe6d2 100644 --- a/.github/workflows/sec_sast_semgrep_cron.yml +++ b/.github/workflows/sec_sast_semgrep_cron.yml @@ -12,7 +12,7 @@ jobs: semgrep-full: runs-on: ubuntu-latest container: - image: returntocorp/semgrep + image: semgrep/semgrep steps: # step 1 diff --git a/.github/workflows/sec_sast_semgrep_pull.yml b/.github/workflows/sec_sast_semgrep_pull.yml index 2575cbf01..9013f1c74 100644 --- a/.github/workflows/sec_sast_semgrep_pull.yml +++ b/.github/workflows/sec_sast_semgrep_pull.yml @@ -6,7 +6,7 @@ jobs: semgrep-diff: runs-on: ubuntu-22.04 container: - image: returntocorp/semgrep + image: semgrep/semgrep steps: # step 1 From acd044fdeac80a5ba9d1431c929b541833336f8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 06:11:32 -0500 Subject: [PATCH 121/252] Bump meshtestic from `31ee3d9` to `37245b3` (#4799) Bumps [meshtestic](https://github.com/meshtastic/meshTestic) from `31ee3d9` to `37245b3`. - [Commits](https://github.com/meshtastic/meshTestic/compare/31ee3d90c8bef61e835c3271be2c7cda8c4a5cc2...37245b3d612a9272f546bbb092837bafdad46bc2) --- updated-dependencies: - dependency-name: meshtestic dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- meshtestic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtestic b/meshtestic index 31ee3d90c..37245b3d6 160000 --- a/meshtestic +++ b/meshtestic @@ -1 +1 @@ -Subproject commit 31ee3d90c8bef61e835c3271be2c7cda8c4a5cc2 +Subproject commit 37245b3d612a9272f546bbb092837bafdad46bc2 From 953beb56b1104b1016a334789e3e53b075eb5ede Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 06:12:05 -0500 Subject: [PATCH 122/252] [create-pull-request] automated change (#4789) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 69c478482..b30827191 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 1 +build = 2 From c053c7d9aef30873cb0a039bbed051a6a0db4036 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 06:13:09 -0500 Subject: [PATCH 123/252] Bump pnpm/action-setup from 2 to 4 in /.github/workflows (#4798) Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 4. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v2...v4) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f58b38ac9..bf3d15dba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -77,7 +77,7 @@ jobs: pio upgrade - name: Setup pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 with: version: latest From e6c7c80b3f6d4bc3fdbc6c369146b5d00de8df9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 21 Sep 2024 14:50:19 +0200 Subject: [PATCH 124/252] Raspberry Pico2 - needs protos --- arch/esp32/esp32.ini | 2 +- arch/nrf52/nrf52.ini | 2 +- arch/portduino/portduino.ini | 2 +- arch/{rp2040 => rp2xx0}/rp2040.ini | 2 +- arch/rp2xx0/rp2350.ini | 23 +++++++++ arch/stm32/stm32.ini | 2 +- .../{rp2040 => rp2xx0}/architecture.h | 2 + .../main-rp2xx0.cpp} | 0 variants/rpipico2/platformio.ini | 16 ++++++ variants/rpipico2/variant.h | 50 +++++++++++++++++++ 10 files changed, 96 insertions(+), 5 deletions(-) rename arch/{rp2040 => rp2xx0}/rp2040.ini (97%) create mode 100644 arch/rp2xx0/rp2350.ini rename src/platform/{rp2040 => rp2xx0}/architecture.h (90%) rename src/platform/{rp2040/main-rp2040.cpp => rp2xx0/main-rp2xx0.cpp} (100%) create mode 100644 variants/rpipico2/platformio.ini create mode 100644 variants/rpipico2/variant.h diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 0dd6cbc1d..13360be78 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -5,7 +5,7 @@ custom_esp32_kind = esp32 platform = platformio/espressif32@6.7.0 build_src_filter = - ${arduino_base.build_src_filter} - - - - - + ${arduino_base.build_src_filter} - - - - - upload_speed = 921600 debug_init_break = tbreak setup diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini index 503da2aab..04880d540 100644 --- a/arch/nrf52/nrf52.ini +++ b/arch/nrf52/nrf52.ini @@ -16,7 +16,7 @@ build_flags = -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - - lib_deps= ${arduino_base.lib_deps} diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 482b1f9c5..aae3525b6 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -9,7 +9,7 @@ build_src_filter = - - - - - + - - - + diff --git a/arch/rp2040/rp2040.ini b/arch/rp2xx0/rp2040.ini similarity index 97% rename from arch/rp2040/rp2040.ini rename to arch/rp2xx0/rp2040.ini index dd3a4d7ff..d3f27a676 100644 --- a/arch/rp2040/rp2040.ini +++ b/arch/rp2xx0/rp2040.ini @@ -8,7 +8,7 @@ board_build.core = earlephilhower board_build.filesystem_size = 0.5m build_flags = ${arduino_base.build_flags} -Wno-unused-variable - -Isrc/platform/rp2040 + -Isrc/platform/rp2xx0 -D__PLAT_RP2040__ # -D _POSIX_THREADS build_src_filter = diff --git a/arch/rp2xx0/rp2350.ini b/arch/rp2xx0/rp2350.ini new file mode 100644 index 000000000..96ed0cb21 --- /dev/null +++ b/arch/rp2xx0/rp2350.ini @@ -0,0 +1,23 @@ +; Common settings for rp2040 Processor based targets +[rp2350_base] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9e55f6db5c56b9867c69fe473f388beea4546672 +extends = arduino_base +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#a6ab6e1f95bc1428d667d55ea7173c0744acc03c ; 4.0.2+ + +board_build.core = earlephilhower +board_build.filesystem_size = 0.5m +build_flags = + ${arduino_base.build_flags} -Wno-unused-variable + -Isrc/platform/rp2xx0 + -D__PLAT_RP2040__ +# -D _POSIX_THREADS +build_src_filter = + ${arduino_base.build_src_filter} - - - - - - - - - + +lib_ignore = + BluetoothOTA + +lib_deps = + ${arduino_base.lib_deps} + ${environmental_base.lib_deps} + rweather/Crypto \ No newline at end of file diff --git a/arch/stm32/stm32.ini b/arch/stm32/stm32.ini index 050dbf7f0..4be290015 100644 --- a/arch/stm32/stm32.ini +++ b/arch/stm32/stm32.ini @@ -22,7 +22,7 @@ build_flags = -fdata-sections build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - - - - - - board_upload.offset_address = 0x08000000 upload_protocol = stlink diff --git a/src/platform/rp2040/architecture.h b/src/platform/rp2xx0/architecture.h similarity index 90% rename from src/platform/rp2040/architecture.h rename to src/platform/rp2xx0/architecture.h index 3f75735d3..8c7dfc0cd 100644 --- a/src/platform/rp2040/architecture.h +++ b/src/platform/rp2xx0/architecture.h @@ -23,6 +23,8 @@ #if defined(RPI_PICO) #define HW_VENDOR meshtastic_HardwareModel_RPI_PICO +#elif defined(RPI_PICO2) +#define HW_VENDOR meshtastic_HardwareModel_RPI_PICO2 #elif defined(RAK11310) #define HW_VENDOR meshtastic_HardwareModel_RAK11310 #elif defined(SENSELORA_RP2040) diff --git a/src/platform/rp2040/main-rp2040.cpp b/src/platform/rp2xx0/main-rp2xx0.cpp similarity index 100% rename from src/platform/rp2040/main-rp2040.cpp rename to src/platform/rp2xx0/main-rp2xx0.cpp diff --git a/variants/rpipico2/platformio.ini b/variants/rpipico2/platformio.ini new file mode 100644 index 000000000..a63414418 --- /dev/null +++ b/variants/rpipico2/platformio.ini @@ -0,0 +1,16 @@ +[env:pico2] +extends = rp2350_base +board = rpipico2 +upload_protocol = picotool + +# add our variants files to the include and src paths +build_flags = ${rp2350_base.build_flags} + -DRPI_PICO2 + -Ivariants/rpipico2 + -DDEBUG_RP2040_PORT=Serial + -DHW_SPI1_DEVICE + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus" +lib_deps = + ${rp2350_base.lib_deps} +debug_build_flags = ${rp2350_base.build_flags} +debug_tool = cmsis-dap ; for e.g. Picotool \ No newline at end of file diff --git a/variants/rpipico2/variant.h b/variants/rpipico2/variant.h new file mode 100644 index 000000000..7efaeaf7a --- /dev/null +++ b/variants/rpipico2/variant.h @@ -0,0 +1,50 @@ +// #define RADIOLIB_CUSTOM_ARDUINO 1 +// #define RADIOLIB_TONE_UNSUPPORTED 1 +// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1 + +#define ARDUINO_ARCH_AVR + +// default I2C pins: +// SDA = 4 +// SCL = 5 + +// Recommended pins for SerialModule: +// txd = 8 +// rxd = 9 + +#define EXT_NOTIFY_OUT 22 +#define BUTTON_PIN 17 + +#define LED_PIN PIN_LED + +#define BATTERY_PIN 26 +// ratio of voltage divider = 3.0 (R17=200k, R18=100k) +#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic +#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION + +#define USE_SX1262 + +#undef LORA_SCK +#undef LORA_MISO +#undef LORA_MOSI +#undef LORA_CS + +#define LORA_SCK 10 +#define LORA_MISO 12 +#define LORA_MOSI 11 +#define LORA_CS 3 + +#define LORA_DIO0 RADIOLIB_NC +#define LORA_RESET 15 +#define LORA_DIO1 20 +#define LORA_DIO2 2 +#define LORA_DIO3 RADIOLIB_NC + +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_DIO2 +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif From 54f56438da20d27e5fb3d5262af95138557a2883 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Sun, 22 Sep 2024 00:59:17 +1200 Subject: [PATCH 125/252] Re-order doDeepSleep (#4802) Make sure PMU sleep takes place before I2C ends --- src/sleep.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sleep.cpp b/src/sleep.cpp index 27e81ce54..e6814f027 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -271,13 +271,6 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false) digitalWrite(LORA_CS, HIGH); gpio_hold_en((gpio_num_t)LORA_CS); } - -#if defined(I2C_SDA) - Wire.end(); - pinMode(I2C_SDA, ANALOG); - pinMode(I2C_SCL, ANALOG); -#endif - #endif #ifdef HAS_PMU @@ -315,6 +308,14 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false) } #endif +#if defined(ARCH_ESP32) && defined(I2C_SDA) + // Added by https://github.com/meshtastic/firmware/pull/4418 + // Possibly to support Heltec Capsule Sensor? + Wire.end(); + pinMode(I2C_SDA, ANALOG); + pinMode(I2C_SCL, ANALOG); +#endif + console->flush(); cpuDeepSleep(msecToWake); } From f324ab7de762351f19941847377875444fe56842 Mon Sep 17 00:00:00 2001 From: thebentern <9000580+thebentern@users.noreply.github.com> Date: Sat, 21 Sep 2024 13:12:45 +0000 Subject: [PATCH 126/252] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index 5709c0a05..9b8490784 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197 +Subproject commit 9b84907847b67047b72f9792f4b47532b308bbe4 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 921dfa55b..aa83ff27a 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -71,6 +71,8 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_RAK2560 = 22, /* Heltec HRU-3601: https://heltec.org/project/hru-3601/ */ meshtastic_HardwareModel_HELTEC_HRU_3601 = 23, + /* Heltec Wireless Bridge */ + meshtastic_HardwareModel_HELTEC_WIRELESS_BRIDGE = 24, /* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */ meshtastic_HardwareModel_STATION_G1 = 25, /* RAK11310 (RP2040 + SX1262) */ @@ -199,6 +201,8 @@ typedef enum _meshtastic_HardwareModel { /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK_COREBASIC = 77, meshtastic_HardwareModel_M5STACK_CORE2 = 78, + /* Pico2 with Waveshare Hat, same as Pico */ + meshtastic_HardwareModel_RPI_PICO2 = 79, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 202699239fca94e8a3804e46bd42afc3a22bd5c6 Mon Sep 17 00:00:00 2001 From: Jason Murray Date: Sat, 21 Sep 2024 07:37:37 -0700 Subject: [PATCH 127/252] feat: trigger class update when protobufs are changed --- .github/workflows/update_protobufs.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index f93930a83..466767273 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -1,5 +1,10 @@ -name: "Update protobufs and regenerate classes" -on: workflow_dispatch +name: Update protobufs and regenerate classes +on: + pull_request: + branches: + - master + paths: + - meshtastic/** jobs: update-protobufs: @@ -11,10 +16,6 @@ jobs: with: submodules: true - - name: Update submodule - run: | - git submodule update --remote protobufs - - name: Download nanopb run: | wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz @@ -25,10 +26,11 @@ jobs: run: | ./bin/regen-protos.sh - - name: Create pull request - uses: peter-evans/create-pull-request@v7 + - name: Commit changes + uses: EndBug/add-and-commit@v9 with: - title: Update protobufs and classes - add-paths: | - protobufs - src/mesh + add: src/mesh + author_name: CI Bot + author_email: meshtastic-ci-bot@users.noreply.github.com + default_author: github_actor + message: Update classes from protobugs From 2072ebd196d7dbf70e82d3f1af1d335596b95f62 Mon Sep 17 00:00:00 2001 From: Jason Murray Date: Sat, 21 Sep 2024 08:49:36 -0700 Subject: [PATCH 128/252] meshtastic/ is a test suite; protobufs/ contains protobufs; --- .github/workflows/update_protobufs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index 466767273..eb1ca3648 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -4,7 +4,7 @@ on: branches: - master paths: - - meshtastic/** + - protobufs/** jobs: update-protobufs: @@ -33,4 +33,4 @@ jobs: author_name: CI Bot author_email: meshtastic-ci-bot@users.noreply.github.com default_author: github_actor - message: Update classes from protobugs + message: Update classes from protobufs From d21087f6396a46bb63748a015109d9b68a77b164 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 21 Sep 2024 16:17:30 -0500 Subject: [PATCH 129/252] Update platform-native to pick up portduino crash fix (#4807) --- arch/portduino/portduino.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index aae3525b6..30cc190d2 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -1,6 +1,6 @@ ; The Portduino based sim environment on top of any host OS, all hardware will be simulated [portduino_base] -platform = https://github.com/meshtastic/platform-native.git#ad8112adf82ce1f5b917092cf32be07a077801a0 +platform = https://github.com/meshtastic/platform-native.git#6b3796d697481c8f6e3f4aa5c111bd9979f29e64 framework = arduino build_src_filter = From 893bbe09d18e3d479f724f9eb30b0182421b4b8a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 21 Sep 2024 16:34:26 -0500 Subject: [PATCH 130/252] Hopefully extract and commit to meshtastic.github.io --- .github/workflows/main_matrix.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index be09c24b2..3564b8f93 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -354,3 +354,29 @@ jobs: title: Bump version.properties add-paths: | version.properties + + - name: Checkout meshtastic/meshtastic.github.io + uses: actions/checkout@v4 + with: + repository: meshtastic/meshtastic.github.io + token: ${{ secrets.GITHUB_TOKEN }} + path: meshtastic.github.io + + - name: Display structure of downloaded files + run: ls -R + + - name: Extract firmware.zip + run: | + unzip ./firmware-${{ steps.version.outputs.version }}.zip -d meshtastic.github.io/firmware-${{ steps.version.outputs.version }} + + - name: Display structure of downloaded files + run: ls -R + + - name: Commit and push changes + run: | + cd meshtastic.github.io + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "Add firmware version ${{ steps.version.outputs.version }}" + git push From 51af7475080c6d83d2b5c0c82de2b651dcd7268f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 21 Sep 2024 20:53:23 -0500 Subject: [PATCH 131/252] CI fixes --- .github/workflows/main_matrix.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 3564b8f93..19a92d8b8 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -359,7 +359,7 @@ jobs: uses: actions/checkout@v4 with: repository: meshtastic/meshtastic.github.io - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.ARTIFACTS_TOKEN }} path: meshtastic.github.io - name: Display structure of downloaded files @@ -375,6 +375,7 @@ jobs: - name: Commit and push changes run: | cd meshtastic.github.io + find . -type f -name 'meshtasticd_*' -exec rm -f {} + git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" git add . From 2ff0af55b1bc79ea5889f120e9a981edf06a5b18 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 22 Sep 2024 02:47:49 -0400 Subject: [PATCH 132/252] [Board] DIY "t-energy-s3_e22" (#4782) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New variant "t-energy-s3_e22" - Lilygo T-Energy-S3 - NanoVHF "Mesh-v1.06-TTGO-T18" board - Ebyte E22 Series * add board_level = extra * Update variant.h --------- Co-authored-by: Thomas Göttgens Co-authored-by: Tom Fifield --- variants/diy/platformio.ini | 20 ++++++++++- variants/diy/t-energy-s3_e22/variant.h | 46 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 variants/diy/t-energy-s3_e22/variant.h diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini index 2a55f7a79..f3c22b7a8 100644 --- a/variants/diy/platformio.ini +++ b/variants/diy/platformio.ini @@ -69,4 +69,22 @@ build_flags = ${nrf52840_base.build_flags} build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/nrf52_promicro_diy_tcxo> lib_deps = ${nrf52840_base.lib_deps} -debug_tool = jlink \ No newline at end of file +debug_tool = jlink + +; NanoVHF T-Energy-S3 + E22(0)-xxxM - DIY +[env:t-energy-s3_e22] +extends = esp32s3_base +board = esp32-s3-devkitc-1 +board_level = extra +board_upload.flash_size = 16MB ;Specify the FLASH capacity as 16MB +board_build.arduino.memory_type = qio_opi ;Enable internal PSRAM +build_unflags = + ${esp32s3_base.build_unflags} + -D ARDUINO_USB_MODE=1 +build_flags = + ${esp32s3_base.build_flags} + -D EBYTE_ESP32_S3 + -D BOARD_HAS_PSRAM + -D ARDUINO_USB_MODE=0 + -D ARDUINO_USB_CDC_ON_BOOT=1 + -I variants/diy/t-energy-s3_e22 diff --git a/variants/diy/t-energy-s3_e22/variant.h b/variants/diy/t-energy-s3_e22/variant.h new file mode 100644 index 000000000..6933d7715 --- /dev/null +++ b/variants/diy/t-energy-s3_e22/variant.h @@ -0,0 +1,46 @@ +// NanoVHF T-Energy-S3 + E22(0)-xxxM - DIY +// https://github.com/NanoVHF/Meshtastic-DIY/tree/main/PCB/ESP-32-devkit_EBYTE-E22/Mesh-v1.06-TTGO-T18 + +// Battery +#define BATTERY_PIN 3 +#define ADC_MULTIPLIER 2.0 +#define ADC_CHANNEL ADC1_GPIO3_CHANNEL + +// Button on NanoVHF PCB +#define BUTTON_PIN 39 + +// I2C via connectors on NanoVHF PCB +#define I2C_SCL 2 +#define I2C_SDA 42 + +// Screen (disabled) +#define HAS_SCREEN 0 // Assume no screen present by default to prevent crash... + +// GPS via T-Energy-S3 onboard connector +#define HAS_GPS 1 +#define GPS_TX_PIN 43 +#define GPS_RX_PIN 44 + +// LoRa +#define USE_SX1262 // E22-900M30S, E22-900M22S, and E22-900MM22S (not E220!) use SX1262 +#define USE_SX1268 // E22-400M30S, E22-400M33S, E22-400M22S, and E22-400MM22S use SX1268 + +#define SX126X_MAX_POWER 22 // SX126xInterface.cpp defaults to 22 if not defined, but here we define it for good practice +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V + +#define SX126X_CS 5 // EBYTE module's NSS pin // FIXME: rename to SX126X_SS +#define SX126X_SCK 6 // EBYTE module's SCK pin +#define SX126X_MOSI 13 // EBYTE module's MOSI pin +#define SX126X_MISO 4 // EBYTE module's MISO pin +#define SX126X_RESET 1 // EBYTE module's NRST pin +#define SX126X_BUSY 48 // EBYTE module's BUSY pin +#define SX126X_DIO1 47 // EBYTE module's DIO1 pin + +#define SX126X_TXEN 10 // Schematic connects EBYTE module's TXEN pin to MCU +#define SX126X_RXEN 12 // Schematic connects EBYTE module's RXEN pin to MCU + +#define LORA_CS SX126X_CS // Compatibility with variant file configuration structure +#define LORA_SCK SX126X_SCK // Compatibility with variant file configuration structure +#define LORA_MOSI SX126X_MOSI // Compatibility with variant file configuration structure +#define LORA_MISO SX126X_MISO // Compatibility with variant file configuration structure +#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure From 9f8d86cb25febfb86c57f395549b7deb82458065 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Sun, 22 Sep 2024 04:22:00 -0700 Subject: [PATCH 133/252] Consolidate variant build steps (#4806) * poc: consolidate variant build steps * use build-variant action * only checkout once and clean up after run --- .github/actions/build-variant/action.yml | 97 ++++++++++++++++++++++++ .github/workflows/build_esp32.yml | 60 ++++----------- .github/workflows/build_esp32_c3.yml | 59 ++++---------- .github/workflows/build_esp32_s3.yml | 60 ++++----------- .github/workflows/build_nrf52.yml | 22 ++---- .github/workflows/build_rpi2040.yml | 22 ++---- .github/workflows/build_stm32.yml | 24 ++---- 7 files changed, 159 insertions(+), 185 deletions(-) create mode 100644 .github/actions/build-variant/action.yml diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml new file mode 100644 index 000000000..0a96a0155 --- /dev/null +++ b/.github/actions/build-variant/action.yml @@ -0,0 +1,97 @@ +name: Setup Build Variant Composite Action +description: Variant build actions for Meshtastic Platform IO steps + +inputs: + board: + description: The board to build for + required: true + github_token: + description: GitHub token + required: true + build-script-path: + description: Path to the build script + required: true + remove-debug-flags: + description: A newline separated list of files to remove debug flags from + required: false + default: "" + ota-firmware-source: + description: The OTA firmware file to pull + required: false + default: "" + ota-firmware-target: + description: The target path to store the OTA firmware file + required: false + default: "" + artifact-paths: + description: A newline separated list of paths to store as artifacts + required: false + default: "" + include-web-ui: + description: Include the web UI in the build + required: false + default: "false" + +runs: + using: composite + steps: + - uses: actions/checkout@v4 + + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Pull web ui + if: ${{ inputs.include-web-ui == "true" }} + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ inputs.github_token }} + + - name: Unpack web ui + if: ${{ inputs.include-web-ui == "true" }} + shell: bash + run: | + tar -xf build.tar -C data/static + rm build.tar + + - name: Remove debug flags for release + shell: bash + if: ${{ inputs.remove-debug-flags != "" }} + run: | + for PATH in ${{ inputs.remove-debug-flags }}; do + sed -i '/DDEBUG_HEAP/d' ${PATH} + done + + - name: Build ${{ inputs.board }} + shell: bash + run: ${{ inputs.build-script-path }} ${{ inputs.board }} + + - name: Pull OTA Firmware + if: ${{ inputs.ota-firmware-source != "" && inputs.ota-firmware-target != "" }} + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/firmware-ota + file: ${{ inputs.ota-firmware-source }} + target: ${{ inputs.ota-firmware-target }} + token: ${{ inputs.github_token }} + + - name: Get release version string + shell: bash + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | + ${{ inputs.artifact-paths }} + + - name: Clean up resources + shell: bash + run: | + rm -rf . diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 4cbb4c7a4..8b7017fc9 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -11,53 +11,21 @@ jobs: build-esp32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/firmware-ota - file: firmware.bin - target: release/bleota.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware.bin + ota-firmware-target: release/bleota.bin + artifact-paths: | release/*.bin release/*.elf + include-web-ui: true diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index 07727d711..249f6f126 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -13,51 +13,20 @@ jobs: build-esp32-c3: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master + - name: Build ESP32-C3 + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/firmware-ota - file: firmware-c3.bin - target: release/bleota-c3.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware-c3.bin + ota-firmware-target: release/bleota-c3.bin + artifact-paths: | release/*.bin release/*.elf diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 10773833e..7df3e5737 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -11,51 +11,21 @@ jobs: build-esp32-s3: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master + - name: Build ESP32-S3 + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/firmware-ota - file: firmware-s3.bin - target: release/bleota-s3.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware-s3.bin + ota-firmware-target: release/bleota-s3.bin + artifact-paths: | release/*.bin release/*.elf + include-web-ui: true diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml index ac509a096..85d3635cd 100644 --- a/.github/workflows/build_nrf52.yml +++ b/.github/workflows/build_nrf52.yml @@ -11,24 +11,14 @@ jobs: build-nrf52: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - name: Build NRF52 - run: bin/build-nrf52.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-nrf52.sh + artifact-paths: | release/*.hex release/*.uf2 release/*.elf diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml index 6e258fe2a..d3e19f8fd 100644 --- a/.github/workflows/build_rpi2040.yml +++ b/.github/workflows/build_rpi2040.yml @@ -11,23 +11,13 @@ jobs: build-rpi2040: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - name: Build Raspberry Pi 2040 - run: ./bin/build-rpi2040.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-rpi2040.sh + artifact-paths: | release/*.uf2 release/*.elf diff --git a/.github/workflows/build_stm32.yml b/.github/workflows/build_stm32.yml index d13c52c8a..9252087df 100644 --- a/.github/workflows/build_stm32.yml +++ b/.github/workflows/build_stm32.yml @@ -11,23 +11,13 @@ jobs: build-stm32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Build STM32 - run: bin/build-stm32.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + - name: Build Raspberry Pi 2040 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-stm32.sh + artifact-paths: | release/*.hex release/*.bin From 7db98ca1dade6459dd170f8fe1fda1adee05da67 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 22 Sep 2024 19:39:35 +0800 Subject: [PATCH 134/252] Revert "Consolidate variant build steps (#4806)" (#4816) This reverts commit 9f8d86cb25febfb86c57f395549b7deb82458065. --- .github/actions/build-variant/action.yml | 97 ------------------------ .github/workflows/build_esp32.yml | 62 +++++++++++---- .github/workflows/build_esp32_c3.yml | 59 ++++++++++---- .github/workflows/build_esp32_s3.yml | 60 +++++++++++---- .github/workflows/build_nrf52.yml | 22 ++++-- .github/workflows/build_rpi2040.yml | 22 ++++-- .github/workflows/build_stm32.yml | 24 ++++-- 7 files changed, 186 insertions(+), 160 deletions(-) delete mode 100644 .github/actions/build-variant/action.yml diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml deleted file mode 100644 index 0a96a0155..000000000 --- a/.github/actions/build-variant/action.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: Setup Build Variant Composite Action -description: Variant build actions for Meshtastic Platform IO steps - -inputs: - board: - description: The board to build for - required: true - github_token: - description: GitHub token - required: true - build-script-path: - description: Path to the build script - required: true - remove-debug-flags: - description: A newline separated list of files to remove debug flags from - required: false - default: "" - ota-firmware-source: - description: The OTA firmware file to pull - required: false - default: "" - ota-firmware-target: - description: The target path to store the OTA firmware file - required: false - default: "" - artifact-paths: - description: A newline separated list of paths to store as artifacts - required: false - default: "" - include-web-ui: - description: Include the web UI in the build - required: false - default: "false" - -runs: - using: composite - steps: - - uses: actions/checkout@v4 - - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Pull web ui - if: ${{ inputs.include-web-ui == "true" }} - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ inputs.github_token }} - - - name: Unpack web ui - if: ${{ inputs.include-web-ui == "true" }} - shell: bash - run: | - tar -xf build.tar -C data/static - rm build.tar - - - name: Remove debug flags for release - shell: bash - if: ${{ inputs.remove-debug-flags != "" }} - run: | - for PATH in ${{ inputs.remove-debug-flags }}; do - sed -i '/DDEBUG_HEAP/d' ${PATH} - done - - - name: Build ${{ inputs.board }} - shell: bash - run: ${{ inputs.build-script-path }} ${{ inputs.board }} - - - name: Pull OTA Firmware - if: ${{ inputs.ota-firmware-source != "" && inputs.ota-firmware-target != "" }} - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/firmware-ota - file: ${{ inputs.ota-firmware-source }} - target: ${{ inputs.ota-firmware-target }} - token: ${{ inputs.github_token }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | - ${{ inputs.artifact-paths }} - - - name: Clean up resources - shell: bash - run: | - rm -rf . diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 8b7017fc9..4cbb4c7a4 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -11,21 +11,53 @@ jobs: build-esp32: runs-on: ubuntu-latest steps: - - name: Build ESP32 - id: build - uses: ./.github/actions/build-variant + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - remove-debug-flags: | - ./arch/esp32/esp32.ini - ./arch/esp32/esp32s2.ini - ./arch/esp32/esp32s3.ini - ./arch/esp32/esp32c3.ini - build-script-path: bin/build-esp32.sh - ota-firmware-source: firmware.bin - ota-firmware-target: release/bleota.bin - artifact-paths: | + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Unpack web ui + run: | + tar -xf build.tar -C data/static + rm build.tar + + - name: Remove debug flags for release + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini + + - name: Build ESP32 + run: bin/build-esp32.sh ${{ inputs.board }} + + - name: Pull OTA Firmware + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/firmware-ota + file: firmware.bin + target: release/bleota.bin + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get release version string + shell: bash + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.bin release/*.elf - include-web-ui: true diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index 249f6f126..07727d711 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -13,20 +13,51 @@ jobs: build-esp32-c3: runs-on: ubuntu-latest steps: - - name: Build ESP32-C3 - id: build - uses: ./.github/actions/build-variant + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - remove-debug-flags: | - ./arch/esp32/esp32.ini - ./arch/esp32/esp32s2.ini - ./arch/esp32/esp32s3.ini - ./arch/esp32/esp32c3.ini - build-script-path: bin/build-esp32.sh - ota-firmware-source: firmware-c3.bin - ota-firmware-target: release/bleota-c3.bin - artifact-paths: | + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Unpack web ui + run: | + tar -xf build.tar -C data/static + rm build.tar + - name: Remove debug flags for release + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini + - name: Build ESP32 + run: bin/build-esp32.sh ${{ inputs.board }} + + - name: Pull OTA Firmware + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/firmware-ota + file: firmware-c3.bin + target: release/bleota-c3.bin + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get release version string + shell: bash + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.bin release/*.elf diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 7df3e5737..10773833e 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -11,21 +11,51 @@ jobs: build-esp32-s3: runs-on: ubuntu-latest steps: - - name: Build ESP32-S3 - id: build - uses: ./.github/actions/build-variant + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - remove-debug-flags: | - ./arch/esp32/esp32.ini - ./arch/esp32/esp32s2.ini - ./arch/esp32/esp32s3.ini - ./arch/esp32/esp32c3.ini - build-script-path: bin/build-esp32.sh - ota-firmware-source: firmware-s3.bin - ota-firmware-target: release/bleota-s3.bin - artifact-paths: | + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Unpack web ui + run: | + tar -xf build.tar -C data/static + rm build.tar + - name: Remove debug flags for release + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini + sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini + - name: Build ESP32 + run: bin/build-esp32.sh ${{ inputs.board }} + + - name: Pull OTA Firmware + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/firmware-ota + file: firmware-s3.bin + target: release/bleota-s3.bin + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get release version string + shell: bash + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.bin release/*.elf - include-web-ui: true diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml index 85d3635cd..ac509a096 100644 --- a/.github/workflows/build_nrf52.yml +++ b/.github/workflows/build_nrf52.yml @@ -11,14 +11,24 @@ jobs: build-nrf52: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + - name: Build NRF52 - id: build - uses: ./.github/actions/build-variant + run: bin/build-nrf52.sh ${{ inputs.board }} + + - name: Get release version string + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - build-script-path: bin/build-nrf52.sh - artifact-paths: | + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.hex release/*.uf2 release/*.elf diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml index d3e19f8fd..6e258fe2a 100644 --- a/.github/workflows/build_rpi2040.yml +++ b/.github/workflows/build_rpi2040.yml @@ -11,13 +11,23 @@ jobs: build-rpi2040: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + - name: Build Raspberry Pi 2040 - id: build - uses: ./.github/actions/build-variant + run: ./bin/build-rpi2040.sh ${{ inputs.board }} + + - name: Get release version string + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - build-script-path: bin/build-rpi2040.sh - artifact-paths: | + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.uf2 release/*.elf diff --git a/.github/workflows/build_stm32.yml b/.github/workflows/build_stm32.yml index 9252087df..d13c52c8a 100644 --- a/.github/workflows/build_stm32.yml +++ b/.github/workflows/build_stm32.yml @@ -11,13 +11,23 @@ jobs: build-stm32: runs-on: ubuntu-latest steps: - - name: Build Raspberry Pi 2040 - id: build - uses: ./.github/actions/build-variant + - uses: actions/checkout@v4 + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Build STM32 + run: bin/build-stm32.sh ${{ inputs.board }} + + - name: Get release version string + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - board: ${{ inputs.board }} - build-script-path: bin/build-stm32.sh - artifact-paths: | + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | release/*.hex release/*.bin From 2e24d244beb0f1ef89f88b44da91b65d6876be50 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 22 Sep 2024 23:00:32 +0800 Subject: [PATCH 135/252] Make Ublox code more readable (#4727) * Simplify Ublox code Ublox comes in a myriad of versions and settings. Presently our configuration code does a lot of branching based on versions being or not being present. This patch adds version detection earlier in the piece and branches on the set gnssModel instead to create separate setup methods for Ublox 6, Ublox 7/8/9, and Ublox10. Additionally, adds a macro to make the code much shorter and more readable. * Make trunk happy * Make trunk happy --------- Co-authored-by: Ben Meadors --- src/gps/GPS.cpp | 410 ++++++++++++++++++------------------------------ src/gps/GPS.h | 8 +- src/gps/ubx.h | 7 + 3 files changed, 164 insertions(+), 261 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 01fa65816..147858cdb 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -525,268 +525,144 @@ bool GPS::setup() delay(250); _serial_gps->write("$PAIR513*3D\r\n"); // save configuration + } else if (gnssModel == GNSS_MODEL_UBLOX6) { + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500); + SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500); + SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500); - } 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 + // Turn off unwanted NMEA messages, set update rate + SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500); - if (strncmp(info.hwVersion, "000A0000", 8) != 0) { - if (strncmp(info.hwVersion, "00040007", 8) != 0) { - // The original ublox Neo-6 is GPS only and doesn't support the UBX-CFG-GNSS message - // Max7 seems to only support GPS *or* GLONASS - // Neo-7 is supposed to support GPS *and* GLONASS but NAKs the CFG-GNSS command to do it - // So treat all the u-blox 7 series as GPS only - // M8 can support 3 constallations at once so turn on GPS, GLONASS and Galileo (or BeiDou) + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_ECO, "Unable to enable powersaving ECO mode for Neo-6.\n", 500); + SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_AID, "Unable to disable UBX-AID.\n", 500); - if (strncmp(info.hwVersion, "00070000", 8) == 0) { - 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_8), _message_GNSS_8); - _serial_gps->write(UBXscratch, msglen); - } + msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to save GNSS module configuration.\n"); + } else { + LOG_INFO("GNSS module configuration saved!\n"); + } + } else if (gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || gnssModel == GNSS_MODEL_UBLOX9) { + if (gnssModel == GNSS_MODEL_UBLOX7) { + LOG_DEBUG("Setting GPS+SBAS\n"); + msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7); + _serial_gps->write(UBXscratch, msglen); + } else { // 8,9 + msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_8), _message_GNSS_8); + _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+Galileo. 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 for the M8 it tends to be more... 1 sec should be enough ;>) - delay(1000); - } + 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 (gnssModel == GNSS_MODEL_UBLOX7) { + LOG_INFO("GNSS configured for GPS+SBAS.\n"); + } else { // 8,9 + LOG_INFO("GNSS configured for GPS+SBAS+GLONASS+Galileo.\n"); } - // Disable Text Info messages - msglen = makeUBXPacket(0x06, 0x02, sizeof(_message_DISABLE_TXT_INFO), _message_DISABLE_TXT_INFO); + // Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next + // commands for the M8 it tends to be more... 1 sec should be enough ;>) + delay(1000); + } + + // Disable Text Info messages //6,7,8,9 + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500); + + if (gnssModel == GNSS_MODEL_UBLOX8) { // 8 clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x02, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable text info messages.\n"); - } - // ToDo add M10 tests for below - if (strncmp(info.hwVersion, "00080000", 8) == 0) { - msglen = makeUBXPacket(0x06, 0x39, sizeof(_message_JAM_8), _message_JAM_8); + SEND_UBX_PACKET(0x06, 0x39, _message_JAM_8, "Unable to enable interference resistance.\n", 500); + + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5_8, "Unable to configure NAVX5_8 settings.\n", 500); + } else { // 6,7,9 + SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500); + SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500); + } + // Turn off unwanted NMEA messages, set update rate + SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500); + SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500); + + if (uBloxProtocolVersion >= 18) { + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "Unable to enable powersaving for GPS.\n", 500); + SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500); + + // For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats. + if (gnssModel == GNSS_MODEL_UBLOX8) { clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x39, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable interference resistance.\n"); - } - - msglen = makeUBXPacket(0x06, 0x23, sizeof(_message_NAVX5_8), _message_NAVX5_8); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x23, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to configure NAVX5_8 settings.\n"); - } - } else { - msglen = makeUBXPacket(0x06, 0x39, sizeof(_message_JAM_6_7), _message_JAM_6_7); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x39, 500) != 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, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to configure NAVX5 settings.\n"); - } - } - // Turn off unwanted NMEA messages, set update rate - - msglen = makeUBXPacket(0x06, 0x08, sizeof(_message_1HZ), _message_1HZ); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x08, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to set GPS update rate.\n"); - } - - msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GLL), _message_GLL); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA GLL.\n"); - } - - msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GSA), _message_GSA); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x01, 500) != 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, 500) != 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, 500) != 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, 500) != 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, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable NMEA GGA.\n"); - } - - if (uBloxProtocolVersion >= 18) { - msglen = makeUBXPacket(0x06, 0x86, sizeof(_message_PMS), _message_PMS); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x86, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving for GPS.\n"); - } - msglen = makeUBXPacket(0x06, 0x3B, sizeof(_message_CFG_PM2), _message_CFG_PM2); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x3B, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving details for GPS.\n"); - } - // For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats. - if (strncmp(info.hwVersion, "00080000", 8) == 0) { - msglen = makeUBXPacket(0x06, 0x17, sizeof(_message_NMEA), _message_NMEA); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x17, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable NMEA 4.10.\n"); - } - } - } else { - if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode is only for Neo-6 - msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x11, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving ECO mode for Neo-6.\n"); - } - msglen = makeUBXPacket(0x06, 0x3B, sizeof(_message_CFG_PM2), _message_CFG_PM2); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x3B, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving details for GPS.\n"); - } - msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_AID), _message_AID); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable UBX-AID.\n"); - } - } else { - msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x11, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving mode for GPS.\n"); - } - - msglen = makeUBXPacket(0x06, 0x3B, sizeof(_message_CFG_PM2), _message_CFG_PM2); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x3B, 500) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving details for GPS.\n"); - } - } + SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "Unable to enable NMEA 4.10.\n", 500); } } else { - // LOG_INFO("u-blox M10 hardware found.\n"); - delay(1000); - // First disable all NMEA messages in RAM layer - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_NMEA_RAM), _message_VALSET_DISABLE_NMEA_RAM); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA messages for M10 GPS RAM.\n"); - } - delay(250); - // Next disable unwanted NMEA messages in BBR layer - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_NMEA_BBR), _message_VALSET_DISABLE_NMEA_BBR); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable NMEA messages for M10 GPS BBR.\n"); - } - delay(250); - // Disable Info txt messages in RAM layer - msglen = - makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_TXT_INFO_RAM), _message_VALSET_DISABLE_TXT_INFO_RAM); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable Info messages for M10 GPS RAM.\n"); - } - delay(250); - // Next disable Info txt messages in BBR layer - msglen = - makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_TXT_INFO_BBR), _message_VALSET_DISABLE_TXT_INFO_BBR); - clearBuffer(); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable Info messages for M10 GPS BBR.\n"); - } - // Do M10 configuration for Power Management. - - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_PM_RAM), _message_VALSET_PM_RAM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving for M10 GPS RAM.\n"); - } - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_PM_BBR), _message_VALSET_PM_BBR); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable powersaving for M10 GPS BBR.\n"); - } - - delay(250); - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ITFM_RAM), _message_VALSET_ITFM_RAM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable Jamming detection M10 GPS RAM.\n"); - } - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ITFM_BBR), _message_VALSET_ITFM_BBR); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable Jamming detection M10 GPS BBR.\n"); - } - - // Here is where the init commands should go to do further M10 initialization. - delay(250); - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_SBAS_RAM), _message_VALSET_DISABLE_SBAS_RAM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable SBAS M10 GPS RAM.\n"); - } - delay(750); // will cause a receiver restart so wait a bit - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_SBAS_BBR), _message_VALSET_DISABLE_SBAS_BBR); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to disable SBAS M10 GPS BBR.\n"); - } - delay(750); // will cause a receiver restart so wait a bit - // Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep. - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ENABLE_NMEA_BBR), _message_VALSET_ENABLE_NMEA_BBR); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable messages for M10 GPS BBR.\n"); - } - delay(250); - // Next enable wanted NMEA messages in RAM layer - msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ENABLE_NMEA_RAM), _message_VALSET_ENABLE_NMEA_RAM); - _serial_gps->write(UBXscratch, msglen); - if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) { - LOG_WARN("Unable to enable messages for M10 GPS RAM.\n"); - } - // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. - // BBR will survive a restart, and power off for a while, but modules with small backup - // batteries or super caps will not retain the config for a long power off time. + SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_PSM, "Unable to enable powersaving mode for GPS.\n", 500); + SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500); } + + msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE); + _serial_gps->write(UBXscratch, msglen); + if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) { + LOG_WARN("Unable to save GNSS module configuration.\n"); + } else { + LOG_INFO("GNSS module configuration saved!\n"); + } + } else if (gnssModel == GNSS_MODEL_UBLOX10) { + delay(1000); + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "Unable to disable NMEA messages in M10 RAM.\n", 300); + delay(750); + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "Unable to disable NMEA messages in M10 BBR.\n", 300); + delay(750); + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM, + "Unable to disable Info messages for M10 GPS RAM.\n", 300); + delay(750); + // Next disable Info txt messages in BBR layer + clearBuffer(); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR, + "Unable to disable Info messages for M10 GPS BBR.\n", 300); + delay(750); + // Do M10 configuration for Power Management. + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_RAM, "Unable to enable powersaving for M10 GPS RAM.\n", 300); + delay(750); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_BBR, "Unable to enable powersaving for M10 GPS BBR.\n", 300); + delay(750); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_RAM, "Unable to enable Jamming detection M10 GPS RAM.\n", 300); + delay(750); + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_BBR, "Unable to enable Jamming detection M10 GPS BBR.\n", 300); + delay(750); + // Here is where the init commands should go to do further M10 initialization. + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_RAM, "Unable to disable SBAS M10 GPS RAM.\n", 300); + delay(750); // will cause a receiver restart so wait a bit + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "Unable to disable SBAS M10 GPS BBR.\n", 300); + delay(750); // will cause a receiver restart so wait a bit + + // Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep. + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "Unable to enable messages for M10 GPS BBR.\n", 300); + delay(750); + // Next enable wanted NMEA messages in RAM layer + SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_RAM, "Unable to enable messages for M10 GPS RAM.\n", 500); + delay(750); + + // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. + // BBR will survive a restart, and power off for a while, but modules with small backup + // batteries or super caps will not retain the config for a long power off time. msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE); _serial_gps->write(UBXscratch, msglen); if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) { @@ -949,7 +825,8 @@ void GPS::setPowerPMU(bool on) void GPS::setPowerUBLOX(bool on, uint32_t sleepMs) { // Abort: if not UBLOX hardware - if (gnssModel != GNSS_MODEL_UBLOX) + if (!(gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || + gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)) return; // If waking @@ -972,7 +849,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs) } // Determine hardware version - if (strncmp(info.hwVersion, "000A0000", 8) != 0) { + if (gnssModel == GNSS_MODEL_UBLOX10) { // Encode the sleep time in millis into the packet for (int i = 0; i < 4; i++) gps->_message_PMREQ[0 + i] = sleepMs >> (i * 8); @@ -1031,7 +908,9 @@ void GPS::down() // Check whether the GPS hardware is capable of GPS_SOFTSLEEP // If not, fallback to GPS_HARDSLEEP instead bool softsleepSupported = false; - if (gnssModel == GNSS_MODEL_UBLOX) // U-blox is supported via PMREQ + // U-blox is supported via PMREQ + if (gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || + gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10) softsleepSupported = true; #ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin softsleepSupported = true; @@ -1106,7 +985,9 @@ int32_t GPS::runOnce() // if we have received valid NMEA claim we are connected setConnected(); } else { - if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) && (gnssModel == GNSS_MODEL_UBLOX)) { + if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) && + (gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || + gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)) { // reset the GPS on next bootup if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) { LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n"); @@ -1335,9 +1216,9 @@ GnssModel_t GPS::probe(int serialSpeed) strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer)); // LOG_DEBUG("GetModel:%s\n", (char *)buffer); if (strlen((char *)buffer)) { - LOG_INFO("UBlox GNSS probe succeeded, using UBlox %s GNSS Module\n", (char *)buffer); + LOG_INFO("%s detected, using GNSS_MODEL_UBLOX\n", (char *)buffer); } else { - LOG_INFO("UBlox GNSS probe succeeded, using UBlox GNSS Module\n"); + LOG_INFO("Generic Ublox detected, using GNSS_MODEL_UBLOX\n"); } } else if (!strncmp(info.extension[i], "PROTVER", 7)) { char *ptr = nullptr; @@ -1352,9 +1233,20 @@ GnssModel_t GPS::probe(int serialSpeed) } } } + if (strncmp(info.hwVersion, "00040007", 8) == 0) { + return GNSS_MODEL_UBLOX6; + } else if (strncmp(info.hwVersion, "00070000", 8) == 0) { + return GNSS_MODEL_UBLOX7; + } else if (strncmp(info.hwVersion, "00080000", 8) == 0) { + return GNSS_MODEL_UBLOX8; + } else if (strncmp(info.hwVersion, "00190000", 8) == 0) { + return GNSS_MODEL_UBLOX9; + } else if (strncmp(info.hwVersion, "000A0000", 8) == 0) { + return GNSS_MODEL_UBLOX10; + } } - return GNSS_MODEL_UBLOX; + return GNSS_MODEL_UNKNOWN; } GPS *GPS::createGps() diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 3423edb68..48aecc8b9 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -26,7 +26,11 @@ struct uBloxGnssModelInfo { typedef enum { GNSS_MODEL_ATGM336H, GNSS_MODEL_MTK, - GNSS_MODEL_UBLOX, + GNSS_MODEL_UBLOX6, + GNSS_MODEL_UBLOX7, + GNSS_MODEL_UBLOX8, + GNSS_MODEL_UBLOX9, + GNSS_MODEL_UBLOX10, GNSS_MODEL_UC6580, GNSS_MODEL_UNKNOWN, GNSS_MODEL_MTK_L76B, @@ -310,4 +314,4 @@ class GPS : private concurrency::OSThread }; extern GPS *gps; -#endif // Exclude GPS +#endif // Exclude GPS \ No newline at end of file diff --git a/src/gps/ubx.h b/src/gps/ubx.h index 0852c331d..64e45f160 100644 --- a/src/gps/ubx.h +++ b/src/gps/ubx.h @@ -1,3 +1,10 @@ +#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \ + msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \ + _serial_gps->write(UBXscratch, msglen); \ + if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \ + LOG_WARN(#ERRMSG); \ + } + // Power Management uint8_t GPS::_message_PMREQ[] PROGMEM = { From 18aac0ba25e0a638fd7cbab4b73c95105892b88e Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 22 Sep 2024 16:09:46 -0500 Subject: [PATCH 136/252] Consider the LoRa header when checking packet length --- src/mesh/RadioInterface.h | 1 + src/mesh/Router.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index f1016e3d8..d0d20926c 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -10,6 +10,7 @@ #define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission #define MAX_RHPACKETLEN 256 +#define LORA_HEADER_LENGTH 16 #define PACKET_FLAGS_HOP_LIMIT_MASK 0x07 #define PACKET_FLAGS_WANT_ACK_MASK 0x08 diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 3cf30519b..a6b946761 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -475,7 +475,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) } } */ - if (numbytes > MAX_RHPACKETLEN) + if (numbytes + LORA_HEADER_LENGTH > MAX_RHPACKETLEN) return meshtastic_Routing_Error_TOO_LARGE; // printBytes("plaintext", bytes, numbytes); @@ -499,7 +499,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) { LOG_DEBUG("Using PKI!\n"); - if (numbytes + 12 > MAX_RHPACKETLEN) + if (numbytes + LORA_HEADER_LENGTH + 12 > MAX_RHPACKETLEN) return meshtastic_Routing_Error_TOO_LARGE; if (p->pki_encrypted && !memfll(p->public_key.bytes, 0, 32) && memcmp(p->public_key.bytes, node->user.public_key.bytes, 32) != 0) { From 1f8aa1efc75dd337a77fa6b56425de71a33b8704 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Mon, 23 Sep 2024 18:22:06 +0800 Subject: [PATCH 137/252] Minor fix (#4666) * Minor fixes It turns out setting a map value with the index notation causes an lookup that can be avoided with emplace. Apply this to one line in the StoreForward module. Fix also Cppcheck-determined highly minor performance increase by passing gpiochipname as a const reference :) The amount of cycles used on this laptop while learning about these callouts from cppcheck is unlikely to ever be more than the cycles saved by the fixes ;) * Update PortduinoGlue.cpp --- src/modules/esp32/StoreForwardModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index c696d342a..db09a0bfd 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -127,7 +127,7 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_ { uint32_t count = 0; if (lastRequest.find(dest) == lastRequest.end()) { - lastRequest[dest] = 0; + lastRequest.emplace(dest, 0); } for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) { if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) { From 11598beb160d590cf10948423a7341cda69df007 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Tue, 17 Sep 2024 22:12:12 +1200 Subject: [PATCH 138/252] Implement optional second I2C bus for NRF52840 Enabled at compile-time if WIRE_INFERFACES_COUNT defined as 2 --- src/detect/ScanI2CTwoWire.cpp | 6 +++--- src/gps/RTC.cpp | 8 ++++---- src/input/cardKbI2cImpl.cpp | 2 +- src/input/kbI2cBase.cpp | 2 +- src/main.cpp | 4 ++++ 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index f09eb3b95..472a9d70a 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -162,13 +162,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) Melopero_RV3028 rtc; #endif -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) if (port == I2CPort::WIRE1) { i2cBus = &Wire1; } else { #endif i2cBus = &Wire; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) } #endif @@ -423,7 +423,7 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const if (address.port == ScanI2C::I2CPort::WIRE) { return &Wire; } else { -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) return &Wire1; #else return &Wire; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 728284242..98dea4674 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -29,7 +29,7 @@ void readFromRTC() if (rtc_found.address == RV3028_RTC) { uint32_t now = millis(); Melopero_RV3028 rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -58,7 +58,7 @@ void readFromRTC() uint32_t now = millis(); PCF8563_Class rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); @@ -150,7 +150,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #ifdef RV3028_RTC if (rtc_found.address == RV3028_RTC) { Melopero_RV3028 rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -164,7 +164,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) if (rtc_found.address == PCF8563_RTC) { PCF8563_Class rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 8aaebcb45..1f7fd284d 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -16,7 +16,7 @@ void CardKbI2cImpl::init() uint8_t i2caddr_asize = 3; auto i2cScanner = std::unique_ptr(new ScanI2CTwoWire()); -#if defined(I2C_SDA1) +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize); #endif i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize); diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 2692fc80d..a25a85d82 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -33,7 +33,7 @@ int32_t KbI2cBase::runOnce() if (!i2cBus) { switch (cardkb_found.port) { case ScanI2C::WIRE1: -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) LOG_DEBUG("Using I2C Bus 1 (the second one)\n"); i2cBus = &Wire1; if (cardkb_found.address == BBQ10_KB_ADDR) { diff --git a/src/main.cpp b/src/main.cpp index e24ba68b3..0ab9c0e34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,6 +360,8 @@ void setup() Wire1.begin(); #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); +#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) + Wire1.begin(); #endif #if defined(I2C_SDA) && defined(ARCH_RP2040) @@ -427,6 +429,8 @@ void setup() #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1); +#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) + i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1); #endif #if defined(I2C_SDA) && defined(ARCH_RP2040) From f960164c0e68a02c6a66546e470295619efb10d4 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Tue, 17 Sep 2024 22:17:53 +1200 Subject: [PATCH 139/252] Add I2C bus to Heltec T114 header pins SDA: P0.13 SCL: P0.16 Uses bus 1, leaving bus 0 routed to the unpopulated footprint for the RTC (general future-proofing) --- variants/heltec_mesh_node_t114/variant.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/variants/heltec_mesh_node_t114/variant.h b/variants/heltec_mesh_node_t114/variant.h index 454e66931..6a7c85b92 100644 --- a/variants/heltec_mesh_node_t114/variant.h +++ b/variants/heltec_mesh_node_t114/variant.h @@ -92,13 +92,22 @@ No longer populated on PCB #define PIN_SERIAL2_TX (0 + 10) // #define PIN_SERIAL2_EN (0 + 17) -/** - Wire Interfaces - */ -#define WIRE_INTERFACES_COUNT 1 +/* + * I2C + */ -#define PIN_WIRE_SDA (26) -#define PIN_WIRE_SCL (27) +#define WIRE_INTERFACES_COUNT 2 + +// I2C bus 0 +// Routed to footprint for PCF8563TS RTC +// Not populated on T114 V1, maybe in future? +#define PIN_WIRE_SDA (0 + 26) // P0.26 +#define PIN_WIRE_SCL (0 + 27) // P0.27 + +// I2C bus 1 +// Available on header pins, for general use +#define PIN_WIRE1_SDA (0 + 13) // P0.13 +#define PIN_WIRE1_SCL (0 + 16) // P0.16 // QSPI Pins #define PIN_QSPI_SCK (32 + 14) From 1487ca2a3025267a5fb3150935863001fc82a5e4 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Wed, 18 Sep 2024 03:28:23 +1200 Subject: [PATCH 140/252] Tidier macros --- src/configuration.h | 10 ++++++++++ src/detect/ScanI2CTwoWire.cpp | 6 +++--- src/gps/RTC.cpp | 8 ++++---- src/input/cardKbI2cImpl.cpp | 2 +- src/input/kbI2cBase.cpp | 2 +- src/main.cpp | 2 +- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 349bd2870..7416e0a3e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -210,6 +210,16 @@ along with this program. If not, see . #define MINIMUM_SAFE_FREE_HEAP 1500 #endif +#ifndef WIRE_INTERFACES_COUNT +// Officially an NRF52 macro +// Repurposed cross-platform to identify devices using Wire1 +#if defined(I2C_SDA1) || defined(PIN_WIRE_SDA) +#define WIRE_INTERFACES_COUNT 2 +#elif HAS_WIRE +#define WIRE_INTERFACES_COUNT 1 +#endif +#endif + /* Step #3: mop up with disabled values for HAS_ options not handled by the above two */ #ifndef HAS_WIFI diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 472a9d70a..98f40be76 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -162,13 +162,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) Melopero_RV3028 rtc; #endif -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 if (port == I2CPort::WIRE1) { i2cBus = &Wire1; } else { #endif i2cBus = &Wire; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 } #endif @@ -423,7 +423,7 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const if (address.port == ScanI2C::I2CPort::WIRE) { return &Wire; } else { -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 return &Wire1; #else return &Wire; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 98dea4674..b6cab5a6e 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -29,7 +29,7 @@ void readFromRTC() if (rtc_found.address == RV3028_RTC) { uint32_t now = millis(); Melopero_RV3028 rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -58,7 +58,7 @@ void readFromRTC() uint32_t now = millis(); PCF8563_Class rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); @@ -150,7 +150,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #ifdef RV3028_RTC if (rtc_found.address == RV3028_RTC) { Melopero_RV3028 rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -164,7 +164,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) if (rtc_found.address == PCF8563_RTC) { PCF8563_Class rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 1f7fd284d..f1df6b137 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -16,7 +16,7 @@ void CardKbI2cImpl::init() uint8_t i2caddr_asize = 3; auto i2cScanner = std::unique_ptr(new ScanI2CTwoWire()); -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize); #endif i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize); diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index a25a85d82..1d8154bcf 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -33,7 +33,7 @@ int32_t KbI2cBase::runOnce() if (!i2cBus) { switch (cardkb_found.port) { case ScanI2C::WIRE1: -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 LOG_DEBUG("Using I2C Bus 1 (the second one)\n"); i2cBus = &Wire1; if (cardkb_found.address == BBQ10_KB_ADDR) { diff --git a/src/main.cpp b/src/main.cpp index 0ab9c0e34..447e12a62 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,7 +360,7 @@ void setup() Wire1.begin(); #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); -#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) +#elif WIRE_INTERFACES_COUNT == 2 Wire1.begin(); #endif From 76900555e8382baab00ed95ea40de5fc12e0c707 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Thu, 19 Sep 2024 02:49:24 +1200 Subject: [PATCH 141/252] Swap SDA and SCL SDA=P0.16, SCL=P0.13 --- variants/heltec_mesh_node_t114/variant.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/heltec_mesh_node_t114/variant.h b/variants/heltec_mesh_node_t114/variant.h index 6a7c85b92..2cea3ef2f 100644 --- a/variants/heltec_mesh_node_t114/variant.h +++ b/variants/heltec_mesh_node_t114/variant.h @@ -106,8 +106,8 @@ No longer populated on PCB // I2C bus 1 // Available on header pins, for general use -#define PIN_WIRE1_SDA (0 + 13) // P0.13 -#define PIN_WIRE1_SCL (0 + 16) // P0.16 +#define PIN_WIRE1_SDA (0 + 16) // P0.16 +#define PIN_WIRE1_SCL (0 + 13) // P0.13 // QSPI Pins #define PIN_QSPI_SCK (32 + 14) From 3ff9398b92e43bf15a5fe5858f651d9f88b1e237 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Mon, 23 Sep 2024 05:34:19 -0700 Subject: [PATCH 142/252] Revert "Update classes on protobufs update" (#4824) * Revert "Update classes on protobufs update" * remove quotes to fix trunk. --------- Co-authored-by: Tom Fifield --- .github/workflows/update_protobufs.yml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index eb1ca3648..7ce767370 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -1,10 +1,5 @@ name: Update protobufs and regenerate classes -on: - pull_request: - branches: - - master - paths: - - protobufs/** +on: workflow_dispatch jobs: update-protobufs: @@ -16,6 +11,10 @@ jobs: with: submodules: true + - name: Update submodule + run: | + git submodule update --remote protobufs + - name: Download nanopb run: | wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz @@ -26,11 +25,10 @@ jobs: run: | ./bin/regen-protos.sh - - name: Commit changes - uses: EndBug/add-and-commit@v9 + - name: Create pull request + uses: peter-evans/create-pull-request@v7 with: - add: src/mesh - author_name: CI Bot - author_email: meshtastic-ci-bot@users.noreply.github.com - default_author: github_actor - message: Update classes from protobufs + title: Update protobufs and classes + add-paths: | + protobufs + src/mesh From e8829b8f52045796a1b2410d241332f833274d10 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 23 Sep 2024 08:58:14 -0500 Subject: [PATCH 143/252] Refactor and consolidate time window logic (#4826) * Refactor and consolidate windowing logic * Trunk * Fixes * More * Fix braces and remove unused now variables. There was a brace in src/mesh/RadioLibInterface.cpp that was breaking compile on some architectures. Additionally, there were some brace errors in src/modules/Telemetry/AirQualityTelemetry.cpp src/modules/Telemetry/EnvironmentTelemetry.cpp src/mesh/wifi/WiFiAPClient.cpp Move throttle include in WifiAPClient.cpp to top. Add Default.h to sleep.cpp rest of files just remove unused now variables. * Remove a couple more meows --------- Co-authored-by: Tom Fifield --- src/Power.cpp | 4 +++- src/SerialConsole.cpp | 6 ++++-- src/gps/GPS.cpp | 19 +++++++++---------- src/gps/RTC.cpp | 3 ++- src/graphics/EInkDynamicDisplay.cpp | 9 ++++----- src/graphics/Screen.cpp | 8 +++++--- src/input/ExpressLRSFiveWay.cpp | 9 ++++----- src/input/ScanAndSelect.cpp | 5 +++-- src/input/SerialKeyboard.cpp | 3 ++- src/main.cpp | 3 ++- src/mesh/LR11x0Interface.cpp | 10 ++++++---- src/mesh/PacketHistory.cpp | 14 ++++++-------- src/mesh/PhoneAPI.cpp | 5 +++-- src/mesh/RadioLibInterface.cpp | 5 +++-- src/mesh/SX126xInterface.cpp | 12 +++++++----- src/mesh/SX128xInterface.cpp | 9 +++++---- src/mesh/StreamAPI.cpp | 6 +++--- src/mesh/Throttle.cpp | 8 ++++++++ src/mesh/Throttle.h | 1 + src/mesh/wifi/WiFiAPClient.cpp | 5 +++-- src/modules/CannedMessageModule.cpp | 3 ++- src/modules/DetectionSensorModule.cpp | 9 ++++++--- src/modules/NeighborInfoModule.cpp | 4 +++- src/modules/NodeInfoModule.cpp | 8 ++++---- src/modules/PositionModule.cpp | 2 +- src/modules/PowerStressModule.cpp | 3 ++- src/modules/RangeTestModule.cpp | 3 ++- src/modules/RemoteHardwareModule.cpp | 6 +++--- src/modules/SerialModule.cpp | 10 +++++----- src/modules/Telemetry/AirQualityTelemetry.cpp | 10 +++++----- .../Telemetry/EnvironmentTelemetry.cpp | 14 +++++++------- src/modules/Telemetry/PowerTelemetry.cpp | 14 +++++++------- .../Telemetry/Sensor/NAU7802Sensor.cpp | 3 ++- src/modules/esp32/StoreForwardModule.cpp | 6 +++++- src/mqtt/MQTT.cpp | 3 ++- src/sleep.cpp | 5 ++++- 36 files changed, 143 insertions(+), 104 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 61a6c987d..b3a67abd5 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -13,6 +13,7 @@ #include "power.h" #include "NodeDB.h" #include "PowerFSM.h" +#include "Throttle.h" #include "buzz/buzz.h" #include "configuration.h" #include "main.h" @@ -30,6 +31,7 @@ #if HAS_WIFI #include #endif + #endif #ifndef DELAY_FOREVER @@ -244,7 +246,7 @@ class AnalogBatteryLevel : public HasBatteryLevel config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER; // Do not call analogRead() often. const uint32_t min_read_interval = 5000; - if (millis() - last_read_time_ms > min_read_interval) { + if (!Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) { last_read_time_ms = millis(); uint32_t raw = 0; diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index b911e15da..2c1133771 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -1,6 +1,8 @@ #include "SerialConsole.h" +#include "Default.h" #include "NodeDB.h" #include "PowerFSM.h" +#include "Throttle.h" #include "configuration.h" #include "time.h" @@ -47,7 +49,7 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con #if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040) time_t timeout = millis(); while (!Port) { - if ((millis() - timeout) < 5000) { + if (Throttle::isWithinTimespanMs(timeout, FIVE_SECONDS_MS)) { delay(100); } else { break; @@ -73,7 +75,7 @@ void SerialConsole::flush() bool SerialConsole::checkIsConnected() { uint32_t now = millis(); - return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT; + return Throttle::isWithinTimespanMs(lastContactMsec, SERIAL_CONNECTION_TIMEOUT); } /** diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 147858cdb..4fa676913 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -6,6 +6,7 @@ #include "NodeDB.h" #include "PowerMon.h" #include "RTC.h" +#include "Throttle.h" #include "main.h" // pmu_found #include "sleep.h" @@ -206,7 +207,7 @@ GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMilli // ACK-NACK| 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x00 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX | // ACK-ACK | 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x01 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX | - while (millis() - startTime < waitMillis) { + while (Throttle::isWithinTimespanMs(startTime, waitMillis)) { if (_serial_gps->available()) { buffer[bufferPos++] = _serial_gps->read(); @@ -275,7 +276,7 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) buf[9] += buf[8]; } - while (millis() - startTime < waitMillis) { + while (Throttle::isWithinTimespanMs(startTime, waitMillis)) { if (ack > 9) { #ifdef GPS_DEBUG LOG_DEBUG("\n"); @@ -332,7 +333,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t uint32_t startTime = millis(); uint16_t needRead; - while (millis() - startTime < waitMillis) { + while (Throttle::isWithinTimespanMs(startTime, waitMillis)) { if (_serial_gps->available()) { int c = _serial_gps->read(); switch (ubxFrameCounter) { @@ -1420,16 +1421,15 @@ bool GPS::lookForTime() #ifdef GNSS_AIROHA uint8_t fix = reader.fixQuality(); - uint32_t now = millis(); if (fix > 0) { if (lastFixStartMsec > 0) { - if ((now - lastFixStartMsec) < GPS_FIX_HOLD_TIME) { + if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) { return false; } else { clearBuffer(); } } else { - lastFixStartMsec = now; + lastFixStartMsec = millis(); return false; } } else { @@ -1473,16 +1473,15 @@ bool GPS::lookForLocation() #ifdef GNSS_AIROHA if ((config.position.gps_update_interval * 1000) >= (GPS_FIX_HOLD_TIME * 2)) { uint8_t fix = reader.fixQuality(); - uint32_t now = millis(); if (fix > 0) { if (lastFixStartMsec > 0) { - if ((now - lastFixStartMsec) < GPS_FIX_HOLD_TIME) { + if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) { return false; } else { clearBuffer(); } } else { - lastFixStartMsec = now; + lastFixStartMsec = millis(); return false; } } else { @@ -1712,4 +1711,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS +#endif // Exclude GPS \ No newline at end of file diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index b6cab5a6e..d9ac56b74 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -2,6 +2,7 @@ #include "configuration.h" #include "detect/ScanI2C.h" #include "main.h" +#include #include #include @@ -127,7 +128,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) } else if (q == RTCQualityGPS) { shouldSet = true; LOG_DEBUG("Reapplying GPS time: %ld secs\n", printableEpoch); - } else if (q == RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { + } else if (q == RTCQualityNTP && !Throttle::isWithinTimespanMs(lastSetMsec, (12 * 60 * 60 * 1000UL))) { // Every 12 hrs we will slam in a new NTP or Phone GPS / NTP time, to correct for local RTC clock drift shouldSet = true; LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch); diff --git a/src/graphics/EInkDynamicDisplay.cpp b/src/graphics/EInkDynamicDisplay.cpp index c31941a60..ca994b2c9 100644 --- a/src/graphics/EInkDynamicDisplay.cpp +++ b/src/graphics/EInkDynamicDisplay.cpp @@ -1,3 +1,4 @@ +#include "Throttle.h" #include "configuration.h" #if defined(USE_EINK) && defined(USE_EINK_DYNAMICDISPLAY) @@ -231,15 +232,13 @@ void EInkDynamicDisplay::checkForPromotion() // Is it too soon for another frame of this type? void EInkDynamicDisplay::checkRateLimiting() { - uint32_t now = millis(); - // Sanity check: millis() overflow - just let the update run.. - if (previousRunMs > now) + if (previousRunMs > millis()) return; // Skip update: too soon for BACKGROUND if (frameFlags == BACKGROUND) { - if (now - previousRunMs < EINK_LIMIT_RATE_BACKGROUND_SEC * 1000) { + if (Throttle::isWithinTimespanMs(previousRunMs, EINK_LIMIT_RATE_BACKGROUND_SEC * 1000)) { refresh = SKIPPED; reason = EXCEEDED_RATELIMIT_FULL; return; @@ -252,7 +251,7 @@ void EInkDynamicDisplay::checkRateLimiting() // Skip update: too soon for RESPONSIVE if (frameFlags & RESPONSIVE) { - if (now - previousRunMs < EINK_LIMIT_RATE_RESPONSIVE_SEC * 1000) { + if (Throttle::isWithinTimespanMs(previousRunMs, EINK_LIMIT_RATE_RESPONSIVE_SEC * 1000)) { refresh = SKIPPED; reason = EXCEEDED_RATELIMIT_FAST; LOG_DEBUG("refresh=SKIPPED, reason=EXCEEDED_RATELIMIT_FAST, frameFlags=0x%x\n", frameFlags); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 31f522a43..19b20e8dc 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -22,6 +22,7 @@ along with this program. If not, see . #include "Screen.h" #include "../userPrefs.h" #include "PowerMon.h" +#include "Throttle.h" #include "configuration.h" #if HAS_SCREEN #include @@ -117,6 +118,7 @@ static bool heartbeat = false; #define SCREEN_HEIGHT display->getHeight() #include "graphics/ScreenFonts.h" +#include #define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2) @@ -1949,7 +1951,7 @@ int32_t Screen::runOnce() if (showingNormalScreen) { // standard screen loop handling here if (config.display.auto_screen_carousel_secs > 0 && - (millis() - lastScreenTransition) > (config.display.auto_screen_carousel_secs * 1000)) { + !Throttle::isWithinTimespanMs(lastScreenTransition, config.display.auto_screen_carousel_secs * 1000)) { // If an E-Ink display struggles with fast refresh, force carousel to use full refresh instead // Carousel is potentially a major source of E-Ink display wear @@ -2442,8 +2444,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 // Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo if (moduleConfig.store_forward.enabled) { #ifdef ARCH_ESP32 - if (millis() - storeForwardModule->lastHeartbeat > - (storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit + if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat, + (storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \ defined(USE_ST7789) || defined(HX8357_CS)) && \ !defined(DISPLAY_FORCE_SMALL_FONTS) diff --git a/src/input/ExpressLRSFiveWay.cpp b/src/input/ExpressLRSFiveWay.cpp index c444800ba..af4433dae 100644 --- a/src/input/ExpressLRSFiveWay.cpp +++ b/src/input/ExpressLRSFiveWay.cpp @@ -1,5 +1,5 @@ - #include "ExpressLRSFiveWay.h" +#include "Throttle.h" #ifdef INPUTBROKER_EXPRESSLRSFIVEWAY_TYPE @@ -76,11 +76,10 @@ void ExpressLRSFiveWay::update(int *keyValue, bool *keyLongPressed) *keyValue = NO_PRESS; int newKey = readKey(); - uint32_t now = millis(); if (keyInProcess == NO_PRESS) { // New key down if (newKey != NO_PRESS) { - keyDownStart = now; + keyDownStart = millis(); // DBGLN("down=%u", newKey); } } else { @@ -88,7 +87,7 @@ void ExpressLRSFiveWay::update(int *keyValue, bool *keyLongPressed) if (newKey == NO_PRESS) { // DBGLN("up=%u", keyInProcess); if (!isLongPressed) { - if ((now - keyDownStart) > KEY_DEBOUNCE_MS) { + if (!Throttle::isWithinTimespanMs(keyDownStart, KEY_DEBOUNCE_MS)) { *keyValue = keyInProcess; *keyLongPressed = false; } @@ -101,7 +100,7 @@ void ExpressLRSFiveWay::update(int *keyValue, bool *keyLongPressed) } // else still pressing, waiting for long if not already signaled else if (!isLongPressed) { - if ((now - keyDownStart) > KEY_LONG_PRESS_MS) { + if (!Throttle::isWithinTimespanMs(keyDownStart, KEY_LONG_PRESS_MS)) { *keyValue = keyInProcess; *keyLongPressed = true; isLongPressed = true; diff --git a/src/input/ScanAndSelect.cpp b/src/input/ScanAndSelect.cpp index d693d768c..65ca7e332 100644 --- a/src/input/ScanAndSelect.cpp +++ b/src/input/ScanAndSelect.cpp @@ -6,6 +6,7 @@ #include "ScanAndSelect.h" #include "modules/CannedMessageModule.h" +#include // Config static const char name[] = "scanAndSelect"; // should match "allow input source" string @@ -75,7 +76,7 @@ int32_t ScanAndSelectInput::runOnce() else { // Duration enough for long press // Long press not yet fired (prevent repeat firing while held) - if (!longPressFired && now - downSinceMs > durationLongMs) { + if (!longPressFired && Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) { longPressFired = true; longPress(); } @@ -91,7 +92,7 @@ int32_t ScanAndSelectInput::runOnce() // Long press event didn't already fire if (held && !longPressFired) { // Duration enough for short press - if (now - downSinceMs > durationShortMs) { + if (!Throttle::isWithinTimespanMs(downSinceMs, durationShortMs)) { shortPress(); } } diff --git a/src/input/SerialKeyboard.cpp b/src/input/SerialKeyboard.cpp index 7b7a2f3ec..4827e8995 100644 --- a/src/input/SerialKeyboard.cpp +++ b/src/input/SerialKeyboard.cpp @@ -1,5 +1,6 @@ #include "SerialKeyboard.h" #include "configuration.h" +#include #ifdef INPUTBROKER_SERIAL_TYPE #define CANNED_MESSAGE_MODULE_ENABLE 1 // in case it's not set in the variant file @@ -73,7 +74,7 @@ int32_t SerialKeyboard::runOnce() // Serial.print ("X"); // Serial.println (shiftRegister2, BIN); - if (millis() - lastPressTime > 500) { + if (!Throttle::isWithinTimespanMs(lastPressTime, 500)) { quickPress = 0; } diff --git a/src/main.cpp b/src/main.cpp index 447e12a62..01fccf2b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,7 @@ #include "Led.h" #include "RTC.h" #include "SPILock.h" +#include "Throttle.h" #include "concurrency/OSThread.h" #include "concurrency/Periodic.h" #include "detect/ScanI2C.h" @@ -1122,7 +1123,7 @@ void loop() #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10 * 1000L) { + if (!Throttle::isWithinTimespanMs(lastPrint, 10 * 1000L)) { lastPrint = millis(); meshtastic::printThreadInfo("main"); } diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index c0742f241..e237c354f 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -1,7 +1,9 @@ #include "LR11x0Interface.h" +#include "Throttle.h" #include "configuration.h" #include "error.h" #include "mesh/NodeDB.h" + #ifdef ARCH_PORTDUINO #include "PortduinoGlue.h" #endif @@ -275,15 +277,15 @@ template bool LR11x0Interface::isActivelyReceiving() bool detected = (irq & (RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED)); // Handle false detections if (detected) { - uint32_t now = millis(); if (!activeReceiveStart) { - activeReceiveStart = now; - } else if ((now - activeReceiveStart > 2 * preambleTimeMsec) && !(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID)) { + activeReceiveStart = millis(); + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && + !(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID)) { // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag activeReceiveStart = 0; LOG_DEBUG("Ignore false preamble detection.\n"); return false; - } else if (now - activeReceiveStart > maxPacketTimeMsec) { + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag activeReceiveStart = 0; LOG_DEBUG("Ignore false header detection.\n"); diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index 26a73a3fe..ed1c3c59c 100644 --- a/src/mesh/PacketHistory.cpp +++ b/src/mesh/PacketHistory.cpp @@ -5,6 +5,7 @@ #ifdef ARCH_PORTDUINO #include "platform/portduino/PortduinoGlue.h" #endif +#include "Throttle.h" PacketHistory::PacketHistory() { @@ -22,18 +23,17 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd return false; // Not a floodable message ID, so we don't care } - uint32_t now = millis(); - PacketRecord r; r.id = p->id; r.sender = getFrom(p); - r.rxTimeMsec = now; + r.rxTimeMsec = millis(); auto found = recentPackets.find(r); bool seenRecently = (found != recentPackets.end()); // found not equal to .end() means packet was seen recently - if (seenRecently && (now - found->rxTimeMsec) >= FLOOD_EXPIRE_TIME) { // Check whether found packet has already expired - recentPackets.erase(found); // Erase and pretend packet has not been seen recently + if (seenRecently && + !Throttle::isWithinTimespanMs(found->rxTimeMsec, FLOOD_EXPIRE_TIME)) { // Check whether found packet has already expired + recentPackets.erase(found); // Erase and pretend packet has not been seen recently found = recentPackets.end(); seenRecently = false; } @@ -64,12 +64,10 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd */ void PacketHistory::clearExpiredRecentPackets() { - uint32_t now = millis(); - LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size()); for (auto it = recentPackets.begin(); it != recentPackets.end();) { - if ((now - it->rxTimeMsec) >= FLOOD_EXPIRE_TIME) { + if (!Throttle::isWithinTimespanMs(it->rxTimeMsec, FLOOD_EXPIRE_TIME)) { it = recentPackets.erase(it); // erase returns iterator pointing to element immediately following the one erased } else { ++it; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 121687c49..2ed7a69db 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -25,6 +25,7 @@ #if !MESHTASTIC_EXCLUDE_MQTT #include "mqtt/MQTT.h" #endif +#include "Throttle.h" #include PhoneAPI::PhoneAPI() @@ -561,12 +562,12 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) { printPacket("PACKET FROM PHONE", &p); if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] && - (millis() - lastPortNumToRadio[p.decoded.portnum]) < (THIRTY_SECONDS_MS)) { + Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) { LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds"); return false; } else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] && - (millis() - lastPortNumToRadio[p.decoded.portnum]) < (FIVE_SECONDS_MS)) { + Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) { LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds"); return false; diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index f299ebff2..6cdb3b99e 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -3,6 +3,7 @@ #include "NodeDB.h" #include "PowerMon.h" #include "SPILock.h" +#include "Throttle.h" #include "configuration.h" #include "error.h" #include "main.h" @@ -41,7 +42,7 @@ void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in) uint32_t start = millis(); while (digitalRead(busy)) { - if (millis() - start >= 2000) { + if (!Throttle::isWithinTimespanMs(start, 2000)) { LOG_ERROR("GPIO mid-transfer timeout, is it connected?"); return; } @@ -114,7 +115,7 @@ bool RadioLibInterface::canSendImmediately() } // If we've been trying to send the same packet more than one minute and we haven't gotten a // TX IRQ from the radio, the radio is probably broken. - if (busyTx && (millis() - lastTxStart > 60000)) { + if (busyTx && !Throttle::isWithinTimespanMs(lastTxStart, 60000)) { LOG_ERROR("Hardware Failure! busyTx for more than 60s\n"); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_TRANSMIT_FAILED); // reboot in 5 seconds when this condition occurs. diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 6d23206bd..2c6096062 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -6,6 +6,8 @@ #include "PortduinoGlue.h" #endif +#include "Throttle.h" + // 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 @@ -319,15 +321,15 @@ template bool SX126xInterface::isActivelyReceiving() bool detected = (irq & (RADIOLIB_SX126X_IRQ_HEADER_VALID | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED)); // Handle false detections if (detected) { - uint32_t now = millis(); if (!activeReceiveStart) { - activeReceiveStart = now; - } else if ((now - activeReceiveStart > 2 * preambleTimeMsec) && !(irq & RADIOLIB_SX126X_IRQ_HEADER_VALID)) { + activeReceiveStart = millis(); + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && + !(irq & RADIOLIB_SX126X_IRQ_HEADER_VALID)) { // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag activeReceiveStart = 0; LOG_DEBUG("Ignore false preamble detection.\n"); return false; - } else if (now - activeReceiveStart > maxPacketTimeMsec) { + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag activeReceiveStart = 0; LOG_DEBUG("Ignore false header detection.\n"); @@ -359,4 +361,4 @@ template bool SX126xInterface::sleep() #endif return true; -} +} \ No newline at end of file diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index 9ff9ac2d7..270356e26 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -1,4 +1,5 @@ #include "SX128xInterface.h" +#include "Throttle.h" #include "configuration.h" #include "error.h" #include "mesh/NodeDB.h" @@ -294,15 +295,15 @@ template bool SX128xInterface::isActivelyReceiving() // Handle false detections if (detected) { - uint32_t now = millis(); if (!activeReceiveStart) { - activeReceiveStart = now; - } else if ((now - activeReceiveStart > 2 * preambleTimeMsec) && !(irq & RADIOLIB_SX128X_IRQ_HEADER_VALID)) { + activeReceiveStart = millis(); + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && + !(irq & RADIOLIB_SX128X_IRQ_HEADER_VALID)) { // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag activeReceiveStart = 0; LOG_DEBUG("Ignore false preamble detection.\n"); return false; - } else if (now - activeReceiveStart > maxPacketTimeMsec) { + } else if (Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag activeReceiveStart = 0; LOG_DEBUG("Ignore false header detection.\n"); diff --git a/src/mesh/StreamAPI.cpp b/src/mesh/StreamAPI.cpp index 9f59aa971..c3d85ed33 100644 --- a/src/mesh/StreamAPI.cpp +++ b/src/mesh/StreamAPI.cpp @@ -1,6 +1,7 @@ #include "StreamAPI.h" #include "PowerFSM.h" #include "RTC.h" +#include "Throttle.h" #include "configuration.h" #define START1 0x94 @@ -20,10 +21,9 @@ int32_t StreamAPI::runOncePart() */ int32_t StreamAPI::readStream() { - uint32_t now = millis(); if (!stream->available()) { // Nothing available this time, if the computer has talked to us recently, poll often, otherwise let CPU sleep a long time - bool recentRx = (now - lastRxMsec) < 2000; + bool recentRx = Throttle::isWithinTimespanMs(lastRxMsec, 2000); return recentRx ? 5 : 250; } else { while (stream->available()) { // Currently we never want to block @@ -71,7 +71,7 @@ int32_t StreamAPI::readStream() } // we had bytes available this time, so assume we might have them next time also - lastRxMsec = now; + lastRxMsec = millis(); return 0; } } diff --git a/src/mesh/Throttle.cpp b/src/mesh/Throttle.cpp index d8f23f9dc..f278cc843 100644 --- a/src/mesh/Throttle.cpp +++ b/src/mesh/Throttle.cpp @@ -24,4 +24,12 @@ bool Throttle::execute(uint32_t *lastExecutionMs, uint32_t minumumIntervalMs, vo onDefer(); } return false; +} + +/// @brief Check if the last execution time is within the interval +/// @param lastExecutionMs The last execution time in milliseconds +/// @param timeSpanMs The interval in milliseconds of the timespan +bool Throttle::isWithinTimespanMs(uint32_t lastExecutionMs, uint32_t timeSpanMs) +{ + return (millis() - lastExecutionMs) < timeSpanMs; } \ No newline at end of file diff --git a/src/mesh/Throttle.h b/src/mesh/Throttle.h index 8115595a4..8b4bb5d30 100644 --- a/src/mesh/Throttle.h +++ b/src/mesh/Throttle.h @@ -6,4 +6,5 @@ class Throttle { public: static bool execute(uint32_t *lastExecutionMs, uint32_t minumumIntervalMs, void (*func)(void), void (*onDefer)(void) = NULL); + static bool isWithinTimespanMs(uint32_t lastExecutionMs, uint32_t intervalMs); }; \ No newline at end of file diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 07b03222e..d1169dc3b 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -23,6 +23,7 @@ static void WiFiEvent(WiFiEvent_t event); #endif #ifndef DISABLE_NTP +#include "Throttle.h" #include #endif @@ -142,7 +143,7 @@ static int32_t reconnectWiFi() } #ifndef DISABLE_NTP - if (WiFi.isConnected() && (((millis() - lastrun_ntp) > 43200000) || (lastrun_ntp == 0))) { // every 12 hours + if (WiFi.isConnected() && (!Throttle::isWithinTimespanMs(lastrun_ntp, 43200000) || (lastrun_ntp == 0))) { // every 12 hours LOG_DEBUG("Updating NTP time from %s\n", config.network.ntp_server); if (timeClient.update()) { LOG_DEBUG("NTP Request Success - Setting RTCQualityNTP if needed\n"); @@ -420,4 +421,4 @@ uint8_t getWifiDisconnectReason() { return wifiDisconnectReason; } -#endif +#endif \ No newline at end of file diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 87a3e8927..a1b9c4dc0 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -27,6 +27,7 @@ #endif #include "graphics/ScreenFonts.h" +#include // Remove Canned message screen if no action is taken for some milliseconds #define INACTIVATE_AFTER_MS 20000 @@ -422,7 +423,7 @@ int32_t CannedMessageModule::runOnce() this->notifyObservers(&e); } else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && - ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) { + !Throttle::isWithinTimespanMs(this->lastTouchMillis, INACTIVATE_AFTER_MS)) { // Reset module e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen this->currentMessageIndex = -1; diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 20d91a381..670fd3208 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -5,6 +5,7 @@ #include "PowerFSM.h" #include "configuration.h" #include "main.h" +#include DetectionSensorModule *detectionSensorModule; #define GPIO_POLLING_INTERVAL 100 @@ -49,7 +50,8 @@ int32_t DetectionSensorModule::runOnce() // LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin)); - if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) && + if (!Throttle::isWithinTimespanMs(lastSentToMesh, + Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) && hasDetectionEvent()) { sendDetectionMessage(); return DELAYED_INTERVAL; @@ -58,8 +60,9 @@ int32_t DetectionSensorModule::runOnce() // of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state // change detections. else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 && - (millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, - default_telemetry_broadcast_interval_secs)) { + !Throttle::isWithinTimespanMs(lastSentToMesh, + Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, + default_telemetry_broadcast_interval_secs))) { sendCurrentStateMessage(); return DELAYED_INTERVAL; } diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index 218fb8801..a3a3b9bb4 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -3,6 +3,7 @@ #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" +#include NeighborInfoModule *neighborInfoModule; @@ -87,7 +88,8 @@ void NeighborInfoModule::cleanUpNeighbors() NodeNum my_node_id = nodeDB->getNodeNum(); for (auto it = neighbors.rbegin(); it != neighbors.rend();) { // We will remove a neighbor if we haven't heard from them in twice the broadcast interval - if ((now - it->last_rx_time > it->node_broadcast_interval_secs * 2) && (it->node_id != my_node_id)) { + if (!Throttle::isWithinTimespanMs(it->last_rx_time, it->node_broadcast_interval_secs * 2) && + (it->node_id != my_node_id)) { LOG_DEBUG("Removing neighbor with node ID 0x%x\n", it->node_id); it = std::vector::reverse_iterator( neighbors.erase(std::next(it).base())); // Erase the element and update the iterator diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index cb047a4dc..41f008fb0 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -6,6 +6,7 @@ #include "Router.h" #include "configuration.h" #include "main.h" +#include NodeInfoModule *nodeInfoModule; @@ -67,13 +68,12 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply() LOG_DEBUG("Skip sending NodeInfo due to > 40 percent channel util.\n"); return NULL; } - uint32_t now = millis(); // If we sent our NodeInfo less than 5 min. ago, don't send it again as it may be still underway. - if (!shorterTimeout && lastSentToMesh && (now - lastSentToMesh) < (5 * 60 * 1000)) { + if (!shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 5 * 60 * 1000)) { LOG_DEBUG("Skip sending NodeInfo since we just sent it less than 5 minutes ago.\n"); ignoreRequest = true; // Mark it as ignored for MeshModule return NULL; - } else if (shorterTimeout && lastSentToMesh && (now - lastSentToMesh) < (60 * 1000)) { + } else if (shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 60 * 1000)) { LOG_DEBUG("Skip sending actively requested NodeInfo since we just sent it less than 60 seconds ago.\n"); ignoreRequest = true; // Mark it as ignored for MeshModule return NULL; @@ -82,7 +82,7 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply() meshtastic_User &u = owner; LOG_INFO("sending owner %s/%s/%s\n", u.id, u.long_name, u.short_name); - lastSentToMesh = now; + lastSentToMesh = millis(); return allocDataProtobuf(u); } } diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index cb6a58b2e..4ba09385d 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -145,7 +145,7 @@ void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal, bool forceUp bool PositionModule::hasQualityTimesource() { bool setFromPhoneOrNtpToday = - lastSetFromPhoneNtpOrGps == 0 ? false : (millis() - lastSetFromPhoneNtpOrGps) <= (SEC_PER_DAY * 1000UL); + lastSetFromPhoneNtpOrGps == 0 ? false : Throttle::isWithinTimespanMs(lastSetFromPhoneNtpOrGps, SEC_PER_DAY * 1000UL); #if MESHTASTIC_EXCLUDE_GPS bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address); #else diff --git a/src/modules/PowerStressModule.cpp b/src/modules/PowerStressModule.cpp index 4c9f0df88..48159ba54 100644 --- a/src/modules/PowerStressModule.cpp +++ b/src/modules/PowerStressModule.cpp @@ -9,6 +9,7 @@ #include "main.h" #include "sleep.h" #include "target_specific.h" +#include extern void printInfo(); @@ -114,7 +115,7 @@ int32_t PowerStressModule::runOnce() break; case meshtastic_PowerStressMessage_Opcode_CPU_FULLON: { uint32_t start_msec = millis(); - while ((millis() - start_msec) < (uint32_t)sleep_msec) + while (Throttle::isWithinTimespanMs(start_msec, sleep_msec)) ; // Don't let CPU idle at all sleep_msec = 0; // we already slept break; diff --git a/src/modules/RangeTestModule.cpp b/src/modules/RangeTestModule.cpp index 8154a661e..b02494ef3 100644 --- a/src/modules/RangeTestModule.cpp +++ b/src/modules/RangeTestModule.cpp @@ -19,6 +19,7 @@ #include "configuration.h" #include "gps/GeoCoord.h" #include +#include RangeTestModule *rangeTestModule; RangeTestModuleRadio *rangeTestModuleRadio; @@ -79,7 +80,7 @@ int32_t RangeTestModule::runOnce() } // If we have been running for more than 8 hours, turn module back off - if (millis() - started > 28800000) { + if (!Throttle::isWithinTimespanMs(started, 28800000)) { LOG_INFO("Range Test Module - Disabling after 8 hours\n"); return disable(); } else { diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index 0242b59bc..f6b8b2e90 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -5,6 +5,7 @@ #include "Router.h" #include "configuration.h" #include "main.h" +#include #define NUM_GPIOS 64 @@ -118,11 +119,10 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r int32_t RemoteHardwareModule::runOnce() { if (moduleConfig.remote_hardware.enabled && watchGpios) { - uint32_t now = millis(); - if (now - lastWatchMsec >= WATCH_INTERVAL_MSEC) { + if (!Throttle::isWithinTimespanMs(lastWatchMsec, WATCH_INTERVAL_MSEC)) { uint64_t curVal = digitalReads(watchGpios); - lastWatchMsec = now; + lastWatchMsec = millis(); if (curVal != previousWatch) { previousWatch = curVal; diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index f0ba64f65..a4dbb072f 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -7,6 +7,7 @@ #include "Router.h" #include "configuration.h" #include +#include /* SerialModule @@ -97,8 +98,7 @@ SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") */ bool SerialModule::checkIsConnected() { - uint32_t now = millis(); - return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT; + return Throttle::isWithinTimespanMs(lastContactMsec, SERIAL_CONNECTION_TIMEOUT); } int32_t SerialModule::runOnce() @@ -182,13 +182,13 @@ int32_t SerialModule::runOnce() return runOncePart(); } else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) && HAS_GPS) { // in NMEA mode send out GGA every 2 seconds, Don't read from Port - if (millis() - lastNmeaTime > 2000) { + if (!Throttle::isWithinTimespanMs(lastNmeaTime, 2000)) { lastNmeaTime = millis(); printGGA(outbuf, sizeof(outbuf), localPosition); serialPrint->printf("%s", outbuf); } } else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) && HAS_GPS) { - if (millis() - lastNmeaTime > 10000) { + if (!Throttle::isWithinTimespanMs(lastNmeaTime, 10000)) { lastNmeaTime = millis(); uint32_t readIndex = 0; const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex); @@ -500,7 +500,7 @@ void SerialModule::processWXSerial() LOG_INFO("WS85 : %i %.1fg%.1f %.1fv %.1fv\n", atoi(windDir), strtof(windVel, nullptr), strtof(windGust, nullptr), batVoltageF, capVoltageF); } - if (gotwind && millis() - lastAveraged > averageIntervalMillis) { + if (gotwind && !Throttle::isWithinTimespanMs(lastAveraged, averageIntervalMillis)) { // calulate averages and send to the mesh float velAvg = 1.0 * velSum / velCount; diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 56d308cfa..0b6be1b7e 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -12,6 +12,7 @@ #include "Router.h" #include "detect/ScanI2CTwoWire.h" #include "main.h" +#include int32_t AirQualityTelemetryModule::runOnce() { @@ -60,15 +61,14 @@ int32_t AirQualityTelemetryModule::runOnce() if (!moduleConfig.telemetry.air_quality_enabled) return disable(); - uint32_t now = millis(); if (((lastSentToMesh == 0) || - ((now - lastSentToMesh) >= Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.air_quality_interval, - default_telemetry_broadcast_interval_secs, - numOnlineNodes))) && + !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( + moduleConfig.telemetry.air_quality_interval, + default_telemetry_broadcast_interval_secs, numOnlineNodes))) && airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) && airTime->isTxAllowedAirUtil()) { sendTelemetry(); - lastSentToMesh = now; + lastSentToMesh = millis(); } else if (service->isToPhoneQueueEmpty()) { // Just send to phone when it's not our time to send to mesh yet // Only send while queue is empty (phone assumed connected) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 31cb2f838..f94f7956b 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -64,6 +64,7 @@ T1000xSensor t1000xSensor; #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true #include "graphics/ScreenFonts.h" +#include int32_t EnvironmentTelemetryModule::runOnce() { @@ -155,21 +156,20 @@ int32_t EnvironmentTelemetryModule::runOnce() result = bme680Sensor.runTrigger(); } - uint32_t now = millis(); if (((lastSentToMesh == 0) || - ((now - lastSentToMesh) >= - Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.environment_update_interval, - default_telemetry_broadcast_interval_secs, numOnlineNodes))) && + !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( + moduleConfig.telemetry.environment_update_interval, + default_telemetry_broadcast_interval_secs, numOnlineNodes))) && airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) && airTime->isTxAllowedAirUtil()) { sendTelemetry(); - lastSentToMesh = now; - } else if (((lastSentToPhone == 0) || ((now - lastSentToPhone) >= sendToPhoneIntervalMs)) && + lastSentToMesh = millis(); + } else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) && (service->isToPhoneQueueEmpty())) { // Just send to phone when it's not our time to send to mesh yet // Only send while queue is empty (phone assumed connected) sendTelemetry(NODENUM_BROADCAST, true); - lastSentToPhone = now; + lastSentToPhone = millis(); } } return min(sendToPhoneIntervalMs, result); diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 318acf456..a493042a0 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -19,6 +19,7 @@ #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true #include "graphics/ScreenFonts.h" +#include int32_t PowerTelemetryModule::runOnce() { @@ -69,20 +70,19 @@ int32_t PowerTelemetryModule::runOnce() if (!moduleConfig.telemetry.power_measurement_enabled) return disable(); - uint32_t now = millis(); if (((lastSentToMesh == 0) || - ((now - lastSentToMesh) >= Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.power_update_interval, - default_telemetry_broadcast_interval_secs, - numOnlineNodes))) && + !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( + moduleConfig.telemetry.power_update_interval, + default_telemetry_broadcast_interval_secs, numOnlineNodes))) && airTime->isTxAllowedAirUtil()) { sendTelemetry(); - lastSentToMesh = now; - } else if (((lastSentToPhone == 0) || ((now - lastSentToPhone) >= sendToPhoneIntervalMs)) && + lastSentToMesh = millis(); + } else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) && (service->isToPhoneQueueEmpty())) { // Just send to phone when it's not our time to send to mesh yet // Only send while queue is empty (phone assumed connected) sendTelemetry(NODENUM_BROADCAST, true); - lastSentToPhone = now; + lastSentToPhone = millis(); } } return min(sendToPhoneIntervalMs, result); diff --git a/src/modules/Telemetry/Sensor/NAU7802Sensor.cpp b/src/modules/Telemetry/Sensor/NAU7802Sensor.cpp index d7dcbd09f..59f310a24 100644 --- a/src/modules/Telemetry/Sensor/NAU7802Sensor.cpp +++ b/src/modules/Telemetry/Sensor/NAU7802Sensor.cpp @@ -7,6 +7,7 @@ #include "NAU7802Sensor.h" #include "SafeFile.h" #include "TelemetrySensor.h" +#include #include #include @@ -40,7 +41,7 @@ bool NAU7802Sensor::getMetrics(meshtastic_Telemetry *measurement) uint32_t start = millis(); while (!nau7802.available()) { delay(100); - if (millis() - start > 1000) { + if (!Throttle::isWithinTimespanMs(start, 1000)) { nau7802.powerDown(); return false; } diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index db09a0bfd..51ec2a942 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -17,6 +17,7 @@ #include "NodeDB.h" #include "RTC.h" #include "Router.h" +#include "Throttle.h" #include "airtime.h" #include "configuration.h" #include "memGet.h" @@ -29,6 +30,9 @@ StoreForwardModule *storeForwardModule; +uint32_t lastHeartbeat = 0; +uint32_t heartbeatInterval = 60; // Default to 60 seconds, adjust as needed + int32_t StoreForwardModule::runOnce() { #ifdef ARCH_ESP32 @@ -42,7 +46,7 @@ int32_t StoreForwardModule::runOnce() this->busy = false; } } - } else if (this->heartbeat && (millis() - lastHeartbeat > (heartbeatInterval * 1000)) && + } else if (this->heartbeat && (!Throttle::isWithinTimespanMs(lastHeartbeat, heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) { lastHeartbeat = millis(); LOG_INFO("*** Sending heartbeat\n"); diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 6840700e5..56af9f663 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -21,6 +21,7 @@ #include "Default.h" #include "serialization/JSON.h" #include "serialization/MeshPacketSerializer.h" +#include #include const int reconnectMax = 5; @@ -610,7 +611,7 @@ void MQTT::perhapsReportToMap() if (!moduleConfig.mqtt.map_reporting_enabled || !(moduleConfig.mqtt.proxy_to_client_enabled || isConnectedDirectly())) return; - if (millis() - last_report_to_map < map_publish_interval_msecs) { + if (Throttle::isWithinTimespanMs(last_report_to_map, map_publish_interval_msecs)) { return; } else { if (map_position_precision == 0 || (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)) { diff --git a/src/sleep.cpp b/src/sleep.cpp index e6814f027..f32d24caa 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -5,6 +5,7 @@ #endif #include "ButtonThread.h" +#include "Default.h" #include "Led.h" #include "MeshRadio.h" #include "MeshService.h" @@ -28,6 +29,7 @@ esp_sleep_source_t wakeCause; // the reason we booted this time #endif +#include "Throttle.h" #ifndef INCLUDE_vTaskSuspend #define INCLUDE_vTaskSuspend 0 @@ -168,7 +170,8 @@ static void waitEnterSleep(bool skipPreflight = false) while (!doPreflightSleep()) { delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) - if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep + if (!Throttle::isWithinTimespanMs(now, + THIRTY_SECONDS_MS)) { // If we wait too long just report an error and go to sleep RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_SLEEP_ENTER_WAIT); assert(0); // FIXME - for now we just restart, need to fix bug #167 break; From be01c18c74d6a4bd8e3093ba4d81ded44bf94aca Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Thu, 19 Sep 2024 21:59:42 +0200 Subject: [PATCH 144/252] DetectionSensor: more flexible triggering --- src/mesh/NodeDB.cpp | 2 +- .../generated/meshtastic/module_config.pb.h | 45 +++++++++--- src/modules/DetectionSensorModule.cpp | 72 +++++++++++++++---- src/modules/DetectionSensorModule.h | 3 +- 4 files changed, 96 insertions(+), 26 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dca639070..c51ab9fb9 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -472,7 +472,7 @@ void NodeDB::installDefaultModuleConfig() moduleConfig.has_detection_sensor = true; moduleConfig.detection_sensor.enabled = false; - moduleConfig.detection_sensor.detection_triggered_high = true; + moduleConfig.detection_sensor.detection_trigger_type = meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; moduleConfig.detection_sensor.minimum_broadcast_secs = 45; moduleConfig.has_ambient_lighting = true; diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index 2e1985660..d4b82c93b 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -19,6 +19,23 @@ typedef enum _meshtastic_RemoteHardwarePinType { meshtastic_RemoteHardwarePinType_DIGITAL_WRITE = 2 } meshtastic_RemoteHardwarePinType; +typedef enum _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType { + /* Event is triggered if pin is low */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW = 0, + /* Event is triggered if pin is high */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH = 1, + /* Event is triggered when pin goes high to low */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_FALLING_EDGE = 2, + /* Event is triggered when pin goes low to high */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_RISING_EDGE = 3, + /* Event is triggered on every pin state change, low is considered to be + "active" */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_LOW = 4, + /* Event is triggered on every pin state change, high is considered to be + "active" */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH = 5 +} meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType; + /* Baudrate for codec2 voice */ typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud { meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0, @@ -144,11 +161,13 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig { typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { /* Whether the Module is enabled */ bool enabled; - /* Interval in seconds of how often we can send a message to the mesh when a state change is detected */ + /* Interval in seconds of how often we can send a message to the mesh when a + trigger event is detected */ uint32_t minimum_broadcast_secs; - /* Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes - When set to 0, only state changes will be broadcasted - Works as a sort of status heartbeat for peace of mind */ + /* Interval in seconds of how often we should send a message to the mesh + with the current state regardless of trigger events When set to 0, only + trigger events will be broadcasted Works as a sort of status heartbeat + for peace of mind */ uint32_t state_broadcast_secs; /* Send ASCII bell with alert message Useful for triggering ext. notification on bell */ @@ -159,9 +178,8 @@ typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { char name[20]; /* GPIO pin to monitor for state changes */ uint8_t monitor_pin; - /* Whether or not the GPIO pin state detection is triggered on HIGH (1) - Otherwise LOW (0) */ - bool detection_triggered_high; + /* The type of trigger event to be used */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType detection_trigger_type; /* Whether or not use INPUT_PULLUP mode for GPIO pin Only applicable if the board uses pull-up resistors on the pin */ bool use_pullup; @@ -427,6 +445,10 @@ extern "C" { #define _meshtastic_RemoteHardwarePinType_MAX meshtastic_RemoteHardwarePinType_DIGITAL_WRITE #define _meshtastic_RemoteHardwarePinType_ARRAYSIZE ((meshtastic_RemoteHardwarePinType)(meshtastic_RemoteHardwarePinType_DIGITAL_WRITE+1)) +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MAX meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_ARRAYSIZE ((meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType)(meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH+1)) + #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MAX meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_AudioConfig_Audio_Baud)(meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1)) @@ -448,6 +470,7 @@ extern "C" { +#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_trigger_type_ENUMTYPE meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType #define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud @@ -473,7 +496,7 @@ extern "C" { #define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0} +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_default {0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} @@ -489,7 +512,7 @@ extern "C" { #define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0} +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_zero {0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} @@ -523,7 +546,7 @@ extern "C" { #define meshtastic_ModuleConfig_DetectionSensorConfig_send_bell_tag 4 #define meshtastic_ModuleConfig_DetectionSensorConfig_name_tag 5 #define meshtastic_ModuleConfig_DetectionSensorConfig_monitor_pin_tag 6 -#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_triggered_high_tag 7 +#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_trigger_type_tag 7 #define meshtastic_ModuleConfig_DetectionSensorConfig_use_pullup_tag 8 #define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1 #define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2 @@ -688,7 +711,7 @@ X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \ X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \ X(a, STATIC, SINGULAR, STRING, name, 5) \ X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \ -X(a, STATIC, SINGULAR, BOOL, detection_triggered_high, 7) \ +X(a, STATIC, SINGULAR, UENUM, detection_trigger_type, 7) \ X(a, STATIC, SINGULAR, BOOL, use_pullup, 8) #define meshtastic_ModuleConfig_DetectionSensorConfig_CALLBACK NULL #define meshtastic_ModuleConfig_DetectionSensorConfig_DEFAULT NULL diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 20d91a381..20aa6d8e9 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -10,6 +10,41 @@ DetectionSensorModule *detectionSensorModule; #define GPIO_POLLING_INTERVAL 100 #define DELAYED_INTERVAL 1000 +typedef enum { + DetectionSensorVerdictDetected, + DetectionSensorVerdictSendState, + DetectionSensorVerdictNoop, +} DetectionSensorTriggerVerdict; + +typedef DetectionSensorTriggerVerdict (*DetectionSensorTriggerHandler)(bool prev, bool current); + +static DetectionSensorTriggerVerdict detection_trigger_logic_level(bool prev, bool current) +{ + return current ? DetectionSensorVerdictDetected : DetectionSensorVerdictNoop; +} + +static DetectionSensorTriggerVerdict detection_trigger_single_edge(bool prev, bool current) +{ + return (!prev && current) ? DetectionSensorVerdictDetected : DetectionSensorVerdictNoop; +} + +static DetectionSensorTriggerVerdict detection_trigger_either_edge(bool prev, bool current) +{ + if (prev == current) { + return DetectionSensorVerdictNoop; + } + return current ? DetectionSensorVerdictDetected : DetectionSensorVerdictSendState; +} + +const static DetectionSensorTriggerHandler handlers[_meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MAX + 1] = { + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW] = detection_trigger_logic_level, + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH] = detection_trigger_logic_level, + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_FALLING_EDGE] = detection_trigger_single_edge, + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_RISING_EDGE] = detection_trigger_single_edge, + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_LOW] = detection_trigger_either_edge, + [meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH] = detection_trigger_either_edge, +}; + int32_t DetectionSensorModule::runOnce() { /* @@ -21,8 +56,8 @@ int32_t DetectionSensorModule::runOnce() // moduleConfig.detection_sensor.monitor_pin = 21; // WisBlock RAK12013 Radar IO6 // moduleConfig.detection_sensor.minimum_broadcast_secs = 30; // moduleConfig.detection_sensor.state_broadcast_secs = 120; - // moduleConfig.detection_sensor.detection_triggered_high = true; - // strcpy(moduleConfig.detection_sensor.name, "Motion"); + // moduleConfig.detection_sensor.detection_trigger_type = + // meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; strcpy(moduleConfig.detection_sensor.name, "Motion"); if (moduleConfig.detection_sensor.enabled == false) return disable(); @@ -49,18 +84,29 @@ int32_t DetectionSensorModule::runOnce() // LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin)); - if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) && - hasDetectionEvent()) { - sendDetectionMessage(); - return DELAYED_INTERVAL; + if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) { + bool isDetected = hasDetectionEvent(); + DetectionSensorTriggerVerdict verdict = + handlers[moduleConfig.detection_sensor.detection_trigger_type](wasDetected, isDetected); + wasDetected = isDetected; + switch (verdict) { + case DetectionSensorVerdictDetected: + sendDetectionMessage(); + return DELAYED_INTERVAL; + case DetectionSensorVerdictSendState: + sendCurrentStateMessage(isDetected); + return DELAYED_INTERVAL; + case DetectionSensorVerdictNoop: + break; + } } // 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 // change detections. - else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 && - (millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, - default_telemetry_broadcast_interval_secs)) { - sendCurrentStateMessage(); + if (moduleConfig.detection_sensor.state_broadcast_secs > 0 && + (millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, + default_telemetry_broadcast_interval_secs)) { + sendCurrentStateMessage(hasDetectionEvent()); return DELAYED_INTERVAL; } return GPIO_POLLING_INTERVAL; @@ -86,10 +132,10 @@ void DetectionSensorModule::sendDetectionMessage() delete[] message; } -void DetectionSensorModule::sendCurrentStateMessage() +void DetectionSensorModule::sendCurrentStateMessage(bool state) { char *message = new char[40]; - sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, hasDetectionEvent()); + sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state); meshtastic_MeshPacket *p = allocDataPacket(); p->want_ack = false; @@ -105,5 +151,5 @@ bool DetectionSensorModule::hasDetectionEvent() { bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin); // LOG_DEBUG("Detection Sensor Module: Current state: %i\n", currentState); - return moduleConfig.detection_sensor.detection_triggered_high ? currentState : !currentState; + return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState; } \ No newline at end of file diff --git a/src/modules/DetectionSensorModule.h b/src/modules/DetectionSensorModule.h index ed6cddda5..b960c8744 100644 --- a/src/modules/DetectionSensorModule.h +++ b/src/modules/DetectionSensorModule.h @@ -15,8 +15,9 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh private: bool firstTime = true; uint32_t lastSentToMesh = 0; + bool wasDetected = false; void sendDetectionMessage(); - void sendCurrentStateMessage(); + void sendCurrentStateMessage(bool state); bool hasDetectionEvent(); }; From fa1cc5984170013d924f454454a1c1eeff3de918 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 23 Sep 2024 09:20:32 -0500 Subject: [PATCH 145/252] Rename message length headers and set payload max to 255 (#4827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rename message length headers and set payload max to 255 * Add MESHTASTIC_PKC_OVERHEAD * compare to MESHTASTIC_HEADER_LENGTH --------- Co-authored-by: Thomas Göttgens --- src/mesh/RadioInterface.cpp | 4 ++-- src/mesh/RadioInterface.h | 7 ++++--- src/mesh/Router.cpp | 14 +++++++------- src/modules/RangeTestModule.cpp | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 7b6b4f5fa..6fca67188 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -151,7 +151,7 @@ const RegionInfo regions[] = { const RegionInfo *myRegion; bool RadioInterface::uses_default_frequency_slot = true; -static uint8_t bytes[MAX_RHPACKETLEN]; +static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1]; void initRegion() { @@ -326,7 +326,7 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p) RadioInterface::RadioInterface() { - assert(sizeof(PacketHeader) == 16); // make sure the compiler did what we expected + assert(sizeof(PacketHeader) == MESHTASTIC_HEADER_LENGTH); // make sure the compiler did what we expected } bool RadioInterface::reconfigure() diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index d0d20926c..129861441 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -9,8 +9,9 @@ #define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission -#define MAX_RHPACKETLEN 256 -#define LORA_HEADER_LENGTH 16 +#define MAX_LORA_PAYLOAD_LEN 255 // max length of 255 per Semtech's datasheets on SX12xx +#define MESHTASTIC_HEADER_LENGTH 16 +#define MESHTASTIC_PKC_OVERHEAD 12 #define PACKET_FLAGS_HOP_LIMIT_MASK 0x07 #define PACKET_FLAGS_WANT_ACK_MASK 0x08 @@ -90,7 +91,7 @@ class RadioInterface /** * A temporary buffer used for sending/receiving packets, sized to hold the biggest buffer we might need * */ - uint8_t radiobuf[MAX_RHPACKETLEN]; + uint8_t radiobuf[MAX_LORA_PAYLOAD_LEN + 1]; /** * Enqueue a received packet for the registered receiver diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index a6b946761..a993ee7c0 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -36,8 +36,8 @@ static MemoryDynamic staticPool; Allocator &packetPool = staticPool; -static uint8_t bytes[MAX_RHPACKETLEN]; -static uint8_t ScratchEncrypted[MAX_RHPACKETLEN]; +static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1]; +static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1]; /** * Constructor @@ -330,13 +330,13 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // Attempt PKI decryption first if (p->channel == 0 && p->to == nodeDB->getNodeNum() && p->to > 0 && p->to != NODENUM_BROADCAST && nodeDB->getMeshNode(p->from) != nullptr && nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && - nodeDB->getMeshNode(p->to)->user.public_key.size > 0 && rawSize > 12) { + nodeDB->getMeshNode(p->to)->user.public_key.size > 0 && rawSize > MESHTASTIC_PKC_OVERHEAD) { LOG_DEBUG("Attempting PKI decryption\n"); if (crypto->decryptCurve25519(p->from, p->id, rawSize, ScratchEncrypted, bytes)) { LOG_INFO("PKI Decryption worked!\n"); memset(&p->decoded, 0, sizeof(p->decoded)); - rawSize -= 12; + rawSize -= MESHTASTIC_PKC_OVERHEAD; if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded) && p->decoded.portnum != meshtastic_PortNum_UNKNOWN_APP) { decrypted = true; @@ -475,7 +475,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) } } */ - if (numbytes + LORA_HEADER_LENGTH > MAX_RHPACKETLEN) + if (numbytes + MESHTASTIC_HEADER_LENGTH > MAX_LORA_PAYLOAD_LEN) return meshtastic_Routing_Error_TOO_LARGE; // printBytes("plaintext", bytes, numbytes); @@ -499,7 +499,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) { LOG_DEBUG("Using PKI!\n"); - if (numbytes + LORA_HEADER_LENGTH + 12 > MAX_RHPACKETLEN) + if (numbytes + MESHTASTIC_HEADER_LENGTH + MESHTASTIC_PKC_OVERHEAD > MAX_LORA_PAYLOAD_LEN) return meshtastic_Routing_Error_TOO_LARGE; if (p->pki_encrypted && !memfll(p->public_key.bytes, 0, 32) && memcmp(p->public_key.bytes, node->user.public_key.bytes, 32) != 0) { @@ -508,7 +508,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) return meshtastic_Routing_Error_PKI_FAILED; } crypto->encryptCurve25519(p->to, getFrom(p), p->id, numbytes, bytes, ScratchEncrypted); - numbytes += 12; + numbytes += MESHTASTIC_PKC_OVERHEAD; memcpy(p->encrypted.bytes, ScratchEncrypted, numbytes); p->channel = 0; p->pki_encrypted = true; diff --git a/src/modules/RangeTestModule.cpp b/src/modules/RangeTestModule.cpp index b02494ef3..c98f15d40 100644 --- a/src/modules/RangeTestModule.cpp +++ b/src/modules/RangeTestModule.cpp @@ -115,7 +115,7 @@ void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies) packetSequence++; - static char heartbeatString[MAX_RHPACKETLEN]; + static char heartbeatString[MAX_LORA_PAYLOAD_LEN + 1]; snprintf(heartbeatString, sizeof(heartbeatString), "seq %u", packetSequence); p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply From 9a7a4d38148433dc11bd07d8486005673ff620bc Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 23 Sep 2024 13:56:26 -0500 Subject: [PATCH 146/252] Check for null before printing debug (#4835) --- src/mesh/NodeDB.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dca639070..2820cafd4 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -657,9 +657,10 @@ void NodeDB::pickNewNodeNum() while (((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0) || (nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED)) { 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, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so " - "trying for 0x%x\n", - nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate); + if (found) + LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so " + "trying for 0x%x\n", + nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate); nodeNum = candidate; } LOG_DEBUG("Using nodenum 0x%x \n", nodeNum); From 9cbabb0468133474ad19a0c7be637bd8bd974289 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 23 Sep 2024 15:51:05 -0500 Subject: [PATCH 147/252] Teardown bluetooth phoneAPI better and fix client notification issue (#4834) * Teardown bluetooth phoneAPI better and fix client notification issue * Fix client notification draining --- src/mesh/MeshService.h | 3 +++ src/mesh/PhoneAPI.cpp | 39 +++++++++++++++++++-------- src/mesh/PhoneAPI.h | 7 ++--- src/nimble/NimbleBluetooth.cpp | 9 ++++++- src/platform/nrf52/NRF52Bluetooth.cpp | 5 ++-- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index ea1c4e345..e78c2be2c 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -92,6 +92,9 @@ class MeshService /// Return the next MqttClientProxyMessage packet destined to the phone. meshtastic_MqttClientProxyMessage *getMqttClientProxyMessageForPhone() { return toPhoneMqttProxyQueue.dequeuePtr(0); } + /// Return the next ClientNotification packet destined to the phone. + meshtastic_ClientNotification *getClientNotificationForPhone() { return toPhoneClientNotificationQueue.dequeuePtr(0); } + // search the queue for a request id and return the matching nodenum NodeNum getNodenumFromRequestId(uint32_t request_id); diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 2ed7a69db..103572990 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -62,9 +62,11 @@ void PhoneAPI::handleStartConfig() void PhoneAPI::close() { + LOG_INFO("PhoneAPI::close()\n"); + if (state != STATE_SEND_NOTHING) { state = STATE_SEND_NOTHING; - + resetReadIndex(); unobserve(&service->fromNumChanged); #ifdef FSCom unobserve(&xModem.packetReady); @@ -72,8 +74,17 @@ void PhoneAPI::close() releasePhonePacket(); // Don't leak phone packets on shutdown releaseQueueStatusPhonePacket(); releaseMqttClientProxyPhonePacket(); - + releaseClientNotification(); onConnectionChanged(false); + fromRadioScratch = {}; + toRadioScratch = {}; + nodeInfoForPhone = {}; + packetForPhone = NULL; + filesManifest.clear(); + fromRadioNum = 0; + config_nonce = 0; + config_state = 0; + pauseBluetoothLogging = false; } } @@ -405,6 +416,10 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) fromRadioScratch.which_payload_variant = meshtastic_FromRadio_xmodemPacket_tag; fromRadioScratch.xmodemPacket = xmodemPacketForPhone; xmodemPacketForPhone = meshtastic_XModem_init_zero; + } else if (clientNotification) { + fromRadioScratch.which_payload_variant = meshtastic_FromRadio_clientNotification_tag; + fromRadioScratch.clientNotification = *clientNotification; + releaseClientNotification(); } else if (packetForPhone) { printPacket("phone downloaded packet", packetForPhone); @@ -444,13 +459,6 @@ void PhoneAPI::sendConfigComplete() pauseBluetoothLogging = false; } -void PhoneAPI::handleDisconnect() -{ - filesManifest.clear(); - pauseBluetoothLogging = false; - LOG_INFO("PhoneAPI disconnect\n"); -} - void PhoneAPI::releasePhonePacket() { if (packetForPhone) { @@ -475,6 +483,14 @@ void PhoneAPI::releaseMqttClientProxyPhonePacket() } } +void PhoneAPI::releaseClientNotification() +{ + if (clientNotification) { + service->releaseClientNotificationToPool(clientNotification); + clientNotification = NULL; + } +} + /** * Return true if we have data available to send to the phone */ @@ -509,7 +525,9 @@ bool PhoneAPI::available() queueStatusPacketForPhone = service->getQueueStatusForPhone(); if (!mqttClientProxyMessageForPhone) mqttClientProxyMessageForPhone = service->getMqttClientProxyMessageForPhone(); - bool hasPacket = !!queueStatusPacketForPhone || !!mqttClientProxyMessageForPhone; + if (!clientNotification) + clientNotification = service->getClientNotificationForPhone(); + bool hasPacket = !!queueStatusPacketForPhone || !!mqttClientProxyMessageForPhone || !!clientNotification; if (hasPacket) return true; @@ -552,7 +570,6 @@ void PhoneAPI::sendNotification(meshtastic_LogRecord_Level level, uint32_t reply cn->time = getValidTime(RTCQualityFromNet); strncpy(cn->message, message, sizeof(cn->message)); service->sendClientNotification(cn); - delete cn; } /** diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 1e09b9535..cf6f55416 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -147,11 +147,6 @@ class PhoneAPI */ virtual void onNowHasData(uint32_t fromRadioNum) {} - /** - * Subclasses can use this to find out when a client drops the link - */ - virtual void handleDisconnect(); - private: void releasePhonePacket(); @@ -159,6 +154,8 @@ class PhoneAPI void releaseMqttClientProxyPhonePacket(); + void releaseClientNotification(); + /// begin a new connection void handleStartConfig(); diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index d959553a4..03fa80415 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -124,7 +124,14 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks } } - virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) { LOG_INFO("BLE disconnect\n"); } + virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) + { + LOG_INFO("BLE disconnect\n"); + + if (bluetoothPhoneAPI) { + bluetoothPhoneAPI->close(); + } + } }; static NimbleBluetoothToRadioCallback *toRadioCallbacks; diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 1405ea4f3..ec3ff3e8d 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -55,7 +55,6 @@ static BluetoothPhoneAPI *bluetoothPhoneAPI; void onConnect(uint16_t conn_handle) { - // Get the reference to current connection BLEConnection *connection = Bluefruit.Connection(conn_handle); connectionHandle = conn_handle; @@ -70,8 +69,10 @@ void onConnect(uint16_t conn_handle) */ void onDisconnect(uint16_t conn_handle, uint8_t reason) { - // FIXME - we currently assume only one active connection LOG_INFO("BLE Disconnected, reason = 0x%x\n", reason); + if (bluetoothPhoneAPI) { + bluetoothPhoneAPI->close(); + } } void onCccd(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value) { From c442cd7267820681a2259d5b5b4531370af2377c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 23 Sep 2024 15:53:42 -0500 Subject: [PATCH 148/252] Remove some straggler now --- src/SerialConsole.cpp | 3 +-- src/modules/NeighborInfoModule.cpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index 2c1133771..15366d222 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -74,7 +74,6 @@ void SerialConsole::flush() // For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages bool SerialConsole::checkIsConnected() { - uint32_t now = millis(); return Throttle::isWithinTimespanMs(lastContactMsec, SERIAL_CONNECTION_TIMEOUT); } @@ -122,4 +121,4 @@ void SerialConsole::log_to_serial(const char *logLevel, const char *format, va_l emitLogRecord(ll, thread ? thread->ThreadName.c_str() : "", format, arg); } else RedirectablePrint::log_to_serial(logLevel, format, arg); -} +} \ No newline at end of file diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index a3a3b9bb4..55ed46b5e 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -84,7 +84,6 @@ uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighb */ void NeighborInfoModule::cleanUpNeighbors() { - uint32_t now = getTime(); NodeNum my_node_id = nodeDB->getNodeNum(); for (auto it = neighbors.rbegin(); it != neighbors.rend();) { // We will remove a neighbor if we haven't heard from them in twice the broadcast interval From e78c7069996454157c53d1c8b3428a8d7a979a27 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 23 Sep 2024 18:40:54 -0500 Subject: [PATCH 149/252] Fix RAK4631 accelerometer (#4837) --- src/detect/ScanI2CTwoWire.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 98f40be76..c0e70503b 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -334,11 +334,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) // Check register 0x0F for 0x3300 response to ID LIS3DH chip. registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2); - if (registerValue == 0x3300) { + if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333 type = LIS3DH; LOG_INFO("LIS3DH accelerometer found\n"); } - break; } case SHT31_4x_ADDR: @@ -435,4 +434,4 @@ size_t ScanI2CTwoWire::countDevices() const { return foundDevices.size(); } -#endif +#endif \ No newline at end of file From 0ad1f776aec9a0c6bf9165fe15c054aa4dee5d32 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 23 Sep 2024 18:53:01 -0500 Subject: [PATCH 150/252] Manually regen protos for now --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/protobufs b/protobufs index 9b8490784..9651aa59e 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 9b84907847b67047b72f9792f4b47532b308bbe4 +Subproject commit 9651aa59eaa3b54d801b9c251efcfe842790db32 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index aa83ff27a..9ba69c612 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -109,7 +109,7 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_NRF52840_PCA10059 = 40, /* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */ meshtastic_HardwareModel_DR_DEV = 41, - /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK = 42, /* New Heltec LoRA32 with ESP32-S3 CPU */ meshtastic_HardwareModel_HELTEC_V3 = 43, @@ -198,11 +198,13 @@ typedef enum _meshtastic_HardwareModel { https://www.adafruit.com/product/938 ^^^ short A0 to switch to I2C address 0x3C */ meshtastic_HardwareModel_RP2040_FEATHER_RFM95 = 76, - /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK_COREBASIC = 77, meshtastic_HardwareModel_M5STACK_CORE2 = 78, /* Pico2 with Waveshare Hat, same as Pico */ meshtastic_HardwareModel_RPI_PICO2 = 79, + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ + meshtastic_HardwareModel_M5STACK_CORES3 = 80, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 428a567078bec2d45aac8fbffad1ccfb26ab841e Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 24 Sep 2024 08:16:44 +0800 Subject: [PATCH 151/252] Wire 1 is PIN_WIRE1_SDA (#4840) Based on #4745, PIN_WIRE1_SDA is the 'second' wire interface. This pach amends the check to determine whether a device has two wire interfaces should use PIN_WIRE1_SDA, rather than PIN_WIRE_SDA. --- src/configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configuration.h b/src/configuration.h index 7416e0a3e..0b470eef3 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -213,7 +213,7 @@ along with this program. If not, see . #ifndef WIRE_INTERFACES_COUNT // Officially an NRF52 macro // Repurposed cross-platform to identify devices using Wire1 -#if defined(I2C_SDA1) || defined(PIN_WIRE_SDA) +#if defined(I2C_SDA1) || defined(PIN_WIRE1_SDA) #define WIRE_INTERFACES_COUNT 2 #elif HAS_WIRE #define WIRE_INTERFACES_COUNT 1 From c39d270f4094316b51e41f8b50a3f11fc0cf8587 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 23 Sep 2024 23:41:28 -0500 Subject: [PATCH 152/252] Build message in printBytes, to not spam BLE log (#4843) --- src/meshUtils.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/meshUtils.cpp b/src/meshUtils.cpp index c6f2c69b4..4819f6ed7 100644 --- a/src/meshUtils.cpp +++ b/src/meshUtils.cpp @@ -60,10 +60,17 @@ char *strnstr(const char *s, const char *find, size_t slen) void printBytes(const char *label, const uint8_t *p, size_t numbytes) { - LOG_DEBUG("%s: ", label); - for (size_t i = 0; i < numbytes; i++) - LOG_DEBUG("%02x ", p[i]); - LOG_DEBUG("\n"); + char *messageBuffer; + int labelSize = strlen(label); + if (labelSize < 100 && numbytes < 64) { + messageBuffer = new char[labelSize + (numbytes * 3) + 2]; + strncpy(messageBuffer, label, labelSize); + for (size_t i = 0; i < numbytes; i++) + snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]); + strcpy(messageBuffer + labelSize + numbytes * 3, "\n"); + LOG_DEBUG(messageBuffer); + delete messageBuffer; + } } bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes) From b4c09ace23744e47afd0ea8e1f9be69c5c44446b Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Mon, 23 Sep 2024 22:47:31 -0700 Subject: [PATCH 153/252] Consolidate variant build steps (#4820) * poc: consolidate variant build steps * use build-variant action * only checkout once and clean up after run * checkout before local action --- .github/actions/build-variant/action.yml | 95 ++++++++++++++++++++++++ .github/workflows/build_esp32.yml | 58 ++++----------- .github/workflows/build_esp32_c3.yml | 57 ++++---------- .github/workflows/build_esp32_s3.yml | 58 ++++----------- .github/workflows/build_nrf52.yml | 20 ++--- .github/workflows/build_rpi2040.yml | 20 ++--- .github/workflows/build_stm32.yml | 22 ++---- 7 files changed, 157 insertions(+), 173 deletions(-) create mode 100644 .github/actions/build-variant/action.yml diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml new file mode 100644 index 000000000..f60620f24 --- /dev/null +++ b/.github/actions/build-variant/action.yml @@ -0,0 +1,95 @@ +name: Setup Build Variant Composite Action +description: Variant build actions for Meshtastic Platform IO steps + +inputs: + board: + description: The board to build for + required: true + github_token: + description: GitHub token + required: true + build-script-path: + description: Path to the build script + required: true + remove-debug-flags: + description: A newline separated list of files to remove debug flags from + required: false + default: "" + ota-firmware-source: + description: The OTA firmware file to pull + required: false + default: "" + ota-firmware-target: + description: The target path to store the OTA firmware file + required: false + default: "" + artifact-paths: + description: A newline separated list of paths to store as artifacts + required: false + default: "" + include-web-ui: + description: Include the web UI in the build + required: false + default: "false" + +runs: + using: composite + steps: + - name: Build base + id: base + uses: ./.github/actions/setup-base + + - name: Pull web ui + if: ${{ inputs.include-web-ui == "true" }} + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ inputs.github_token }} + + - name: Unpack web ui + if: ${{ inputs.include-web-ui == "true" }} + shell: bash + run: | + tar -xf build.tar -C data/static + rm build.tar + + - name: Remove debug flags for release + shell: bash + if: ${{ inputs.remove-debug-flags != "" }} + run: | + for PATH in ${{ inputs.remove-debug-flags }}; do + sed -i '/DDEBUG_HEAP/d' ${PATH} + done + + - name: Build ${{ inputs.board }} + shell: bash + run: ${{ inputs.build-script-path }} ${{ inputs.board }} + + - name: Pull OTA Firmware + if: ${{ inputs.ota-firmware-source != "" && inputs.ota-firmware-target != "" }} + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/firmware-ota + file: ${{ inputs.ota-firmware-source }} + target: ${{ inputs.ota-firmware-target }} + token: ${{ inputs.github_token }} + + - name: Get release version string + shell: bash + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | + ${{ inputs.artifact-paths }} + + - name: Clean up resources + shell: bash + run: | + rm -rf . diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 4cbb4c7a4..350454e18 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -12,52 +12,22 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/firmware-ota - file: firmware.bin - target: release/bleota.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware.bin + ota-firmware-target: release/bleota.bin + artifact-paths: | release/*.bin release/*.elf + include-web-ui: true diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index 07727d711..abfeb1f5a 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -14,50 +14,21 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master + - name: Build ESP32-C3 + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/firmware-ota - file: firmware-c3.bin - target: release/bleota-c3.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware-c3.bin + ota-firmware-target: release/bleota-c3.bin + artifact-paths: | release/*.bin release/*.elf diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 10773833e..174c0f941 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -12,50 +12,22 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - name: Pull web ui - uses: dsaltares/fetch-gh-release-asset@master + - name: Build ESP32-S3 + id: build + uses: ./.github/actions/build-variant with: - repo: meshtastic/web - file: build.tar - target: build.tar - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Unpack web ui - run: | - tar -xf build.tar -C data/static - rm build.tar - - name: Remove debug flags for release - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini - sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini - - name: Build ESP32 - run: bin/build-esp32.sh ${{ inputs.board }} - - - name: Pull OTA Firmware - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: meshtastic/firmware-ota - file: firmware-s3.bin - target: release/bleota-s3.bin - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get release version string - shell: bash - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: | + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware-s3.bin + ota-firmware-target: release/bleota-s3.bin + artifact-paths: | release/*.bin release/*.elf + include-web-ui: true diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml index ac509a096..606cb8a3e 100644 --- a/.github/workflows/build_nrf52.yml +++ b/.github/workflows/build_nrf52.yml @@ -12,23 +12,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - name: Build NRF52 - run: bin/build-nrf52.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-nrf52.sh + artifact-paths: | release/*.hex release/*.uf2 release/*.elf diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml index 6e258fe2a..b0508877d 100644 --- a/.github/workflows/build_rpi2040.yml +++ b/.github/workflows/build_rpi2040.yml @@ -12,22 +12,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - name: Build Raspberry Pi 2040 - run: ./bin/build-rpi2040.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-rpi2040.sh + artifact-paths: | release/*.uf2 release/*.elf diff --git a/.github/workflows/build_stm32.yml b/.github/workflows/build_stm32.yml index d13c52c8a..6858812e1 100644 --- a/.github/workflows/build_stm32.yml +++ b/.github/workflows/build_stm32.yml @@ -12,22 +12,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - name: Build STM32 - run: bin/build-stm32.sh ${{ inputs.board }} - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 + - name: Build Raspberry Pi 2040 + id: build + uses: ./.github/actions/build-variant with: - name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + build-script-path: bin/build-stm32.sh + artifact-paths: | release/*.hex release/*.bin From 682133501ab9b979906e603f3d9df60a331f4df5 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 24 Sep 2024 14:49:01 +0800 Subject: [PATCH 154/252] Syntax fix for github action (#4846) https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runs-for-composite-actions --- .github/actions/build-variant/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml index f60620f24..b698f9e57 100644 --- a/.github/actions/build-variant/action.yml +++ b/.github/actions/build-variant/action.yml @@ -40,7 +40,7 @@ runs: uses: ./.github/actions/setup-base - name: Pull web ui - if: ${{ inputs.include-web-ui == "true" }} + if: inputs.include-web-ui == 'true' uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/web @@ -49,7 +49,7 @@ runs: token: ${{ inputs.github_token }} - name: Unpack web ui - if: ${{ inputs.include-web-ui == "true" }} + if: inputs.include-web-ui == 'true' shell: bash run: | tar -xf build.tar -C data/static @@ -57,7 +57,7 @@ runs: - name: Remove debug flags for release shell: bash - if: ${{ inputs.remove-debug-flags != "" }} + if: inputs.remove-debug-flags != '' run: | for PATH in ${{ inputs.remove-debug-flags }}; do sed -i '/DDEBUG_HEAP/d' ${PATH} @@ -68,7 +68,7 @@ runs: run: ${{ inputs.build-script-path }} ${{ inputs.board }} - name: Pull OTA Firmware - if: ${{ inputs.ota-firmware-source != "" && inputs.ota-firmware-target != "" }} + if: inputs.ota-firmware-source != '' && inputs.ota-firmware-target != '' uses: dsaltares/fetch-gh-release-asset@master with: repo: meshtastic/firmware-ota From c72612d8266dbeebdd747c469ac9301b9068f82f Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Tue, 24 Sep 2024 00:41:40 -0700 Subject: [PATCH 155/252] sed doesn't like newlines (#4847) * sed doesn't like newlines * fold remove-debug-flags block * PATH is a system env var * Runners don't like rm -f ${workspace path} --- .github/actions/build-variant/action.yml | 11 +++-------- .github/workflows/build_esp32.yml | 2 +- .github/workflows/build_esp32_c3.yml | 2 +- .github/workflows/build_esp32_s3.yml | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml index b698f9e57..f9410eb03 100644 --- a/.github/actions/build-variant/action.yml +++ b/.github/actions/build-variant/action.yml @@ -12,7 +12,7 @@ inputs: description: Path to the build script required: true remove-debug-flags: - description: A newline separated list of files to remove debug flags from + description: A space separated list of files to remove debug flags from required: false default: "" ota-firmware-source: @@ -59,8 +59,8 @@ runs: shell: bash if: inputs.remove-debug-flags != '' run: | - for PATH in ${{ inputs.remove-debug-flags }}; do - sed -i '/DDEBUG_HEAP/d' ${PATH} + for INI_FILE in ${{ inputs.remove-debug-flags }}; do + sed -i '/DDEBUG_HEAP/d' ${INI_FILE} done - name: Build ${{ inputs.board }} @@ -88,8 +88,3 @@ runs: overwrite: true path: | ${{ inputs.artifact-paths }} - - - name: Clean up resources - shell: bash - run: | - rm -rf . diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 350454e18..5f97a349f 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -19,7 +19,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: | + remove-debug-flags: > ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index abfeb1f5a..8f3ded187 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -21,7 +21,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: | + remove-debug-flags: > ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 174c0f941..40d05573c 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -19,7 +19,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: | + remove-debug-flags: > ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini From 4fde1ca2a879bba65852cbd1d8c2c457d825ef43 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Tue, 24 Sep 2024 01:27:46 -0700 Subject: [PATCH 156/252] chomp trailing newline (#4848) --- .github/workflows/build_esp32.yml | 2 +- .github/workflows/build_esp32_c3.yml | 2 +- .github/workflows/build_esp32_s3.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 5f97a349f..041191d34 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -19,7 +19,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: > + remove-debug-flags: >- ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini diff --git a/.github/workflows/build_esp32_c3.yml b/.github/workflows/build_esp32_c3.yml index 8f3ded187..ddc2e2859 100644 --- a/.github/workflows/build_esp32_c3.yml +++ b/.github/workflows/build_esp32_c3.yml @@ -21,7 +21,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: > + remove-debug-flags: >- ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini diff --git a/.github/workflows/build_esp32_s3.yml b/.github/workflows/build_esp32_s3.yml index 40d05573c..29857ef17 100644 --- a/.github/workflows/build_esp32_s3.yml +++ b/.github/workflows/build_esp32_s3.yml @@ -19,7 +19,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} board: ${{ inputs.board }} - remove-debug-flags: > + remove-debug-flags: >- ./arch/esp32/esp32.ini ./arch/esp32/esp32s2.ini ./arch/esp32/esp32s3.ini From 139686d6399de7341d1c8d0f9015a7e44575d8b1 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Tue, 24 Sep 2024 11:11:16 +0200 Subject: [PATCH 157/252] bump protobufs --- src/mesh/generated/meshtastic/mesh.pb.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index aa83ff27a..9ba69c612 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -109,7 +109,7 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_NRF52840_PCA10059 = 40, /* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */ meshtastic_HardwareModel_DR_DEV = 41, - /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK = 42, /* New Heltec LoRA32 with ESP32-S3 CPU */ meshtastic_HardwareModel_HELTEC_V3 = 43, @@ -198,11 +198,13 @@ typedef enum _meshtastic_HardwareModel { https://www.adafruit.com/product/938 ^^^ short A0 to switch to I2C address 0x3C */ meshtastic_HardwareModel_RP2040_FEATHER_RFM95 = 76, - /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */ + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK_COREBASIC = 77, meshtastic_HardwareModel_M5STACK_CORE2 = 78, /* Pico2 with Waveshare Hat, same as Pico */ meshtastic_HardwareModel_RPI_PICO2 = 79, + /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ + meshtastic_HardwareModel_M5STACK_CORES3 = 80, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 ce480ae626563da2bf1904c34ab53b3d9e68c265 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Tue, 24 Sep 2024 11:16:04 +0200 Subject: [PATCH 158/252] fix comment style --- src/modules/DetectionSensorModule.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index de782b2ba..285aba582 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -58,7 +58,8 @@ int32_t DetectionSensorModule::runOnce() // moduleConfig.detection_sensor.minimum_broadcast_secs = 30; // moduleConfig.detection_sensor.state_broadcast_secs = 120; // moduleConfig.detection_sensor.detection_trigger_type = - // meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; strcpy(moduleConfig.detection_sensor.name, "Motion"); + // meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; + // strcpy(moduleConfig.detection_sensor.name, "Motion"); if (moduleConfig.detection_sensor.enabled == false) return disable(); From b709d478327e3fb71f9f8a6c9b5c698b70e5a64e Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 24 Sep 2024 18:50:03 +0800 Subject: [PATCH 159/252] Fix Ublox M10 Setup (#4842) There is no EXTINT pin available on the Tdeck, which uses the Ublox M10 GPS. Therefore our previous hack to use that pin makes the GPS not work. That workaround was implemented to fix sleep issues which have now since been fixed with the state machine. This patch restores the state prior to the hack, which is known-working. Additionaly, it was discovered that M10s hate it when you try and save to non-extistent eeprom/SPI flash. This patch creates a new SAVE command for the M10 that fixes this issue. Many thanks to @MisterC925 whose report and testing was essential for this fix. fixes https://github.com/meshtastic/firmware/issues/4625 Co-authored-by: Ken McGuire --- src/gps/GPS.cpp | 2 +- src/gps/GPS.h | 1 + src/gps/ubx.h | 57 +++++++++++++++++++++++++++---------------------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 4fa676913..285f3a2fd 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -664,7 +664,7 @@ bool GPS::setup() // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. // BBR will survive a restart, and power off for a while, but modules with small backup // batteries or super caps will not retain the config for a long power off time. - msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE); + msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE_10), _message_SAVE_10); _serial_gps->write(UBXscratch, msglen); if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) { LOG_WARN("Unable to save GNSS module configuration.\n"); diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 48aecc8b9..317d80544 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -134,6 +134,7 @@ class GPS : private concurrency::OSThread static const uint8_t _message_GGA[]; static const uint8_t _message_PMS[]; static const uint8_t _message_SAVE[]; + static const uint8_t _message_SAVE_10[]; // VALSET Commands for M10 static const uint8_t _message_VALSET_PM[]; diff --git a/src/gps/ubx.h b/src/gps/ubx.h index 64e45f160..c73a7efb3 100644 --- a/src/gps/ubx.h +++ b/src/gps/ubx.h @@ -323,6 +323,13 @@ const uint8_t GPS::_message_SAVE[] = { 0x17 // deviceMask: BBR, Flash, EEPROM, and SPI Flash }; +const uint8_t GPS::_message_SAVE_10[] = { + 0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared + 0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections + 0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded + 0x01 // deviceMask: only save to BBR +}; + // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. // BBR will survive a restart, and power off for a while, but modules with small backup // batteries or super caps will not retain the config for a long power off time. @@ -342,36 +349,36 @@ const uint8_t GPS::_message_SAVE[] = { // has details on low-power modes /* -CFG-PM2 has been replaced by many CFG-PM commands -CFG-PMS has been removed - -CFG-PM-OPERATEMODE E1 (0 | 1 | 2) -> 1 (PSMOO), because sporadic position updates are required instead of continous tracking <10s -(PSMCT) CFG-PM-POSUPDATEPERIOD U4 -> 0ms, no self-timed wakup because receiver power mode is controlled via "software standby -mode" by legacy UBX-RXM-PMREQ request CFG-PM-ACQPERIOD U4 -> 0ms, because receiver power mode is controlled via "software standby -mode" by legacy UBX-RXM-PMREQ request CFG-PM-ONTIME U4 -> 0ms, optional I guess CFG-PM-EXTINTBACKUP L -> 1, force receiver into -BACKUP mode when EXTINT (should be connected to GPS_EN_PIN) pin is "low" - -This is required because the receiver never enters low power mode if microcontroller is in deep-sleep. -Maybe the changing UART_RX levels trigger a wakeup but even with UBX-RXM-PMREQ[12] = 0x00 (all external wakeup sources disabled) -the receivcer remains in aquisition state -> potentially a bug - -Workaround: Control the EXTINT pin by the GPS_EN_PIN signal - -As mentioned in the M10 operational issues down below, power save won't allow the use of BDS B1C. -CFG-SIGNAL-BDS_B1C_ENA L -> 0 +OPERATEMODE E1 2 (0 | 1 | 2) +POSUPDATEPERIOD U4 5 +ACQPERIOD U4 10 +GRIDOFFSET U4 0 +ONTIME U2 1 +MINACQTIME U1 0 +MAXACQTIME U1 0 +DONOTENTEROFF L 1 +WAITTIMEFIX L 1 +UPDATEEPH L 1 +EXTINTWAKE L 0 no ext ints +EXTINTBACKUP L 0 no ext ints +EXTINTINACTIVE L 0 no ext ints +EXTINTACTIVITY U4 0 no ext ints +LIMITPEAKCURRENT L 1 // Ram layer config message: -// 01 01 00 00 01 00 D0 20 01 02 00 D0 40 00 00 00 00 03 00 D0 40 00 00 00 00 05 00 D0 30 00 00 0D 00 D0 10 01 +// b5 62 06 8a 26 00 00 01 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0 +// 10 01 8b de // BBR layer config message: -// 01 02 00 00 01 00 D0 20 01 02 00 D0 40 00 00 00 00 03 00 D0 40 00 00 00 00 05 00 D0 30 00 00 0D 00 D0 10 01 +// b5 62 06 8a 26 00 00 02 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0 +// 10 01 8c 03 */ -const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x01, 0x01, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, 0x01, - 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, 0x10, 0x01}; -const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x01, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, 0x01, - 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, 0x10, 0x01}; +const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0, + 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01}; +const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0, + 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01}; /* CFG-ITFM replaced by 5 valset messages which can be combined into one for RAM and one for BBR From adb094ebc961bf2354ab06cd1f5ef0aea6bbf327 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Tue, 24 Sep 2024 19:08:32 +0800 Subject: [PATCH 160/252] Remove old comments from main (#4849) These comments were circa 4 years old. Remove them. --- src/main.cpp | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 01fccf2b0..df4b622f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,9 +11,6 @@ #include "airtime.h" #include "buzz.h" -#include "error.h" -#include "power.h" -// #include "debug.h" #include "FSCommon.h" #include "Led.h" #include "RTC.h" @@ -22,6 +19,8 @@ #include "concurrency/OSThread.h" #include "concurrency/Periodic.h" #include "detect/ScanI2C.h" +#include "error.h" +#include "power.h" #if !MESHTASTIC_EXCLUDE_I2C #include "detect/ScanI2CTwoWire.h" @@ -39,7 +38,6 @@ #include "target_specific.h" #include #include -// #include #ifdef ARCH_ESP32 #if !MESHTASTIC_EXCLUDE_WEBSERVER @@ -1106,10 +1104,6 @@ void loop() { runASAP = false; - // axpDebugOutput.loop(); - - // heap_caps_check_integrity_all(true); // FIXME - disable this expensive check - #ifdef ARCH_ESP32 esp32Loop(); #endif @@ -1118,9 +1112,6 @@ void loop() #endif powerCommandsCheck(); - // For debugging - // if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving(); - #ifdef DEBUG_STACK static uint32_t lastPrint = 0; if (!Throttle::isWithinTimespanMs(lastPrint, 10 * 1000L)) { @@ -1129,22 +1120,13 @@ void loop() } #endif - // TODO: This should go into a thread handled by FreeRTOS. - // handleWebResponse(); - service->loop(); long delayMsec = mainController.runOrDelay(); - /* if (mainController.nextThread && delayMsec) - LOG_DEBUG("Next %s in %ld\n", mainController.nextThread->ThreadName.c_str(), - mainController.nextThread->tillRun(millis())); */ - // We want to sleep as long as possible here - because it saves power if (!runASAP && loopCanSleep()) { - // if(delayMsec > 100) LOG_DEBUG("sleeping %ld\n", delayMsec); mainDelay.delay(delayMsec); } - // if (didWake) LOG_DEBUG("wake!\n"); } #endif \ No newline at end of file From 4fbf666cd9887c50816efc148384a707efb1ba9c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 07:12:43 -0500 Subject: [PATCH 161/252] Try v3 --- .github/workflows/main_matrix.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 19a92d8b8..15e49d36c 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -156,10 +156,10 @@ jobs: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v3 with: path: ./ - merge-multiple: true + #merge-multiple: true - name: Display structure of downloaded files run: ls -R From d7badcc9cbb92e6957209e63e5e7ab75af6dc5e9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 07:17:38 -0500 Subject: [PATCH 162/252] Don't run checks on workflow_dispatch --- .github/workflows/main_matrix.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 15e49d36c..f8c7c65ab 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -51,6 +51,7 @@ jobs: matrix: ${{ fromJson(needs.setup.outputs.check) }} runs-on: ubuntu-latest + if: ${{ github.event_name != 'workflow_dispatch' }} steps: - uses: actions/checkout@v4 - name: Build base From e4d0e38f37845537560b6eeeb29694cb3f918198 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 08:25:25 -0500 Subject: [PATCH 163/252] Remove native and add v4 back --- .github/workflows/main_matrix.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index f8c7c65ab..e4c228cce 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -120,8 +120,8 @@ jobs: package-raspbian-armv7l: uses: ./.github/workflows/package_raspbian_armv7l.yml - package-native: - uses: ./.github/workflows/package_amd64.yml + # package-native: + # uses: ./.github/workflows/package_amd64.yml after-checks: runs-on: ubuntu-latest @@ -138,8 +138,7 @@ jobs: contents: write pull-requests: write runs-on: ubuntu-latest - needs: - [ + needs: [ build-esp32, build-esp32-s3, build-esp32-c3, @@ -148,7 +147,7 @@ jobs: build-stm32, package-raspbian, package-raspbian-armv7l, - package-native, + # package-native, ] steps: - name: Checkout code @@ -157,10 +156,10 @@ jobs: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: path: ./ - #merge-multiple: true + merge-multiple: true - name: Display structure of downloaded files run: ls -R From 10869ea10a8954d2471ae120aa0e4c76327c4fe7 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 09:10:29 -0500 Subject: [PATCH 164/252] Don't wait for after-checks --- .github/workflows/main_matrix.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index e4c228cce..acbe8a7d4 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -125,6 +125,7 @@ jobs: after-checks: runs-on: ubuntu-latest + if: ${{ github.event_name != 'workflow_dispatch' }} needs: [check] steps: - name: Checkout code @@ -231,7 +232,7 @@ jobs: release-artifacts: runs-on: ubuntu-latest if: ${{ github.event_name == 'workflow_dispatch' }} - needs: [gather-artifacts, after-checks] + needs: [gather-artifacts] steps: - name: Checkout uses: actions/checkout@v4 From 771cb52616ae719a872d08188b2ee3395022d7bb Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 10:52:46 -0500 Subject: [PATCH 165/252] Remove amd64 --- .github/workflows/main_matrix.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index acbe8a7d4..2ad346f09 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -335,15 +335,15 @@ jobs: asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb asset_content_type: application/vnd.debian.binary-package - - name: Add raspbian amd64 .deb - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - asset_content_type: application/vnd.debian.binary-package + # - name: Add raspbian amd64 .deb + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ github.token }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + # asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + # asset_content_type: application/vnd.debian.binary-package - name: Bump version.properties run: >- From 6c488fe81684e815a7555b5fc7663f05a12132b0 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 12:43:39 -0500 Subject: [PATCH 166/252] Ony run on test runner label --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bf3d15dba..40abcaf87 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ on: jobs: test-simulator: - runs-on: ubuntu-latest + runs-on: test-runner steps: - name: Install libbluetooth shell: bash From 5488c8f57995a05eefb46efde5680646e303459d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 12:54:04 -0500 Subject: [PATCH 167/252] Got the runner labels backwards --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 40abcaf87..58d0ca445 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ on: jobs: test-simulator: - runs-on: test-runner + runs-on: ubuntu-latest steps: - name: Install libbluetooth shell: bash @@ -57,7 +57,7 @@ jobs: reporter: java-junit hardware-tests: - runs-on: ubuntu-latest + runs-on: test-runner steps: - name: Checkout code uses: actions/checkout@v4 From c679932248ebf12e051c8ce9da0eff38ad1bb9fe Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 12:58:41 -0500 Subject: [PATCH 168/252] Setup python --- .github/workflows/tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 58d0ca445..357b4fe30 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,6 +62,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Upgrade python tools shell: bash run: | From c3e53d916df45f820936d96b40831fd4e8641a76 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:04:52 -0500 Subject: [PATCH 169/252] [create-pull-request] automated change (#4858) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index b30827191..8c8e94bec 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 2 +build = 3 From f8f9329529a7dd4411669d04da7a2022818bf7e7 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:16:24 -0500 Subject: [PATCH 170/252] pip3 --- .github/workflows/tests.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 357b4fe30..98b38254d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,18 +62,17 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.10' + # - uses: actions/setup-python@v5 + # with: + # python-version: '3.10' - name: Upgrade python tools shell: bash run: | - python -m pip install --upgrade pip - pip install -U --no-build-isolation --no-cache-dir "setuptools<72" - pip install -U platformio adafruit-nrfutil --no-build-isolation - pip install -U poetry --no-build-isolation - pip install -U meshtastic --pre --no-build-isolation + pip3 install -U --no-build-isolation --no-cache-dir "setuptools<72" + pip3 install -U platformio adafruit-nrfutil --no-build-isolation + pip3 install -U poetry --no-build-isolation + pip3 install -U meshtastic --pre --no-build-isolation - name: Upgrade platformio shell: bash From 752192b09a677e16ed45790f09ef17900ab4ff46 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:27:13 -0500 Subject: [PATCH 171/252] pipx --- .github/workflows/tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 98b38254d..b0e6e3c7c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -69,10 +69,10 @@ jobs: - name: Upgrade python tools shell: bash run: | - pip3 install -U --no-build-isolation --no-cache-dir "setuptools<72" - pip3 install -U platformio adafruit-nrfutil --no-build-isolation - pip3 install -U poetry --no-build-isolation - pip3 install -U meshtastic --pre --no-build-isolation + pipx install -U --no-cache-dir "setuptools<72" + pipx install -U platformio adafruit-nrfutil + pipx install -U poetry + pipx install -U meshtastic --pre - name: Upgrade platformio shell: bash From 4d269501dd3fbb0767f55bac007e307ecb6a4512 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:30:26 -0500 Subject: [PATCH 172/252] No args --- .github/workflows/tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b0e6e3c7c..f371b85b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -69,10 +69,10 @@ jobs: - name: Upgrade python tools shell: bash run: | - pipx install -U --no-cache-dir "setuptools<72" - pipx install -U platformio adafruit-nrfutil - pipx install -U poetry - pipx install -U meshtastic --pre + pipx install "setuptools<72" + pipx install platformio adafruit-nrfutil + pipx install poetry + pipx install meshtastic --pre - name: Upgrade platformio shell: bash From f2801a660bf34439ffdd61b6073d0b96e2761006 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:33:51 -0500 Subject: [PATCH 173/252] Update tests.yml --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f371b85b9..b727b4c49 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -66,10 +66,10 @@ jobs: # with: # python-version: '3.10' + # pipx install "setuptools<72" - name: Upgrade python tools shell: bash run: | - pipx install "setuptools<72" pipx install platformio adafruit-nrfutil pipx install poetry pipx install meshtastic --pre From 9710ac79d3330e0028bf51d40a01513b6f283693 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:37:40 -0500 Subject: [PATCH 174/252] Pipargs --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b727b4c49..fc8912da4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -72,7 +72,7 @@ jobs: run: | pipx install platformio adafruit-nrfutil pipx install poetry - pipx install meshtastic --pre + pipx install meshtastic --pip-args=--pre - name: Upgrade platformio shell: bash From 3c126212d5c4a04390c731418cf2825586a826ac Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:45:02 -0500 Subject: [PATCH 175/252] PIO script --- .github/workflows/tests.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fc8912da4..e173c619d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -70,10 +70,16 @@ jobs: - name: Upgrade python tools shell: bash run: | - pipx install platformio adafruit-nrfutil + pipx install adafruit-nrfutil pipx install poetry pipx install meshtastic --pip-args=--pre + - name: Install PlatformIO from script + shell: bash + run: | + curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py + python3 get-platformio.py + - name: Upgrade platformio shell: bash run: | From 292027f40f7591b37e5f029015eb0863177844b6 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 13:57:53 -0500 Subject: [PATCH 176/252] Setup node --- .github/workflows/tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e173c619d..e76273e9e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -85,6 +85,11 @@ jobs: run: | pio upgrade + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 18 + - name: Setup pnpm uses: pnpm/action-setup@v4 with: From a9d636c025c614da5877a22a11a91d93cdeaf320 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 14:02:12 -0500 Subject: [PATCH 177/252] Consolidate commands --- .github/workflows/tests.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e76273e9e..4b71816c9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -95,11 +95,10 @@ jobs: with: version: latest - - name: Install Dependencies - run: pnpm install - - - name: Setup devices - run: pnpm run setup - - - name: Execute end to end tests on connected hardware - run: pnpm run test + - name: Install dependencies, setup devices and run + shell: bash + run: | + cd meshtastic/ + pnpm install + pnpm run setup + pnpm run test From d6a008500a5828dc8cae33c110744d90b154df50 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 14:05:12 -0500 Subject: [PATCH 178/252] Who chose that ridiculous name anyway?! --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b71816c9..2f273529a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -98,7 +98,7 @@ jobs: - name: Install dependencies, setup devices and run shell: bash run: | - cd meshtastic/ + cd meshtestic/ pnpm install pnpm run setup pnpm run test From 64b2bf5f93169fc8fcc4386a029623c6bed3eaed Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 14:18:19 -0500 Subject: [PATCH 179/252] Checkout should handle this but oh well --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f273529a..431338721 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -98,6 +98,7 @@ jobs: - name: Install dependencies, setup devices and run shell: bash run: | + git submodule update --init --recursive cd meshtestic/ pnpm install pnpm run setup From e7569838c7fb38abe431e5060fa4e9d436bfc456 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 14:32:20 -0500 Subject: [PATCH 180/252] Bin path --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 431338721..925b91215 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -83,6 +83,7 @@ jobs: - name: Upgrade platformio shell: bash run: | + export PATH=$PATH:$HOME/.local/bin pio upgrade - name: Setup Node From cac640ea97ecde816ddada8d14484f0b4bd54dd8 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 14:57:20 -0500 Subject: [PATCH 181/252] Meshtestic submodule update --- meshtestic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtestic b/meshtestic index 37245b3d6..f56bbb54c 160000 --- a/meshtestic +++ b/meshtestic @@ -1 +1 @@ -Subproject commit 37245b3d612a9272f546bbb092837bafdad46bc2 +Subproject commit f56bbb54ce048d5670154fd77512a7d15eb5b7e6 From 1d0013918b80f9f8e48e414098add6405ddd30ae Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 15:15:55 -0500 Subject: [PATCH 182/252] master ref --- meshtestic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtestic b/meshtestic index f56bbb54c..37245b3d6 160000 --- a/meshtestic +++ b/meshtestic @@ -1 +1 @@ -Subproject commit f56bbb54ce048d5670154fd77512a7d15eb5b7e6 +Subproject commit 37245b3d612a9272f546bbb092837bafdad46bc2 From 67fd4b64af49cfb9189b1d78c81642989e9f4068 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 15:20:05 -0500 Subject: [PATCH 183/252] Actual ref --- meshtestic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtestic b/meshtestic index 37245b3d6..f568cbe9e 160000 --- a/meshtestic +++ b/meshtestic @@ -1 +1 @@ -Subproject commit 37245b3d612a9272f546bbb092837bafdad46bc2 +Subproject commit f568cbe9ec18bd4c1fd3a06d17209a7e5144d9be From 453b3a59b242645d3245e3052d71a6378196af3f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 15:24:08 -0500 Subject: [PATCH 184/252] python3 ref --- meshtestic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meshtestic b/meshtestic index f568cbe9e..dcac7e567 160000 --- a/meshtestic +++ b/meshtestic @@ -1 +1 @@ -Subproject commit f568cbe9ec18bd4c1fd3a06d17209a7e5144d9be +Subproject commit dcac7e5673005f4d8a2b1f0f6e06877b689d7519 From 10c51d8a05fd54e540ffebc027c8f8d88d685cd3 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 15:44:16 -0500 Subject: [PATCH 185/252] Put this back --- .github/workflows/main_matrix.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 2ad346f09..af8111a63 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -120,8 +120,8 @@ jobs: package-raspbian-armv7l: uses: ./.github/workflows/package_raspbian_armv7l.yml - # package-native: - # uses: ./.github/workflows/package_amd64.yml + package-native: + uses: ./.github/workflows/package_amd64.yml after-checks: runs-on: ubuntu-latest @@ -335,15 +335,15 @@ jobs: asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb asset_content_type: application/vnd.debian.binary-package - # - name: Add raspbian amd64 .deb - # uses: actions/upload-release-asset@v1 - # env: - # GITHUB_TOKEN: ${{ github.token }} - # with: - # upload_url: ${{ steps.create_release.outputs.upload_url }} - # asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - # asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - # asset_content_type: application/vnd.debian.binary-package + - name: Add raspbian amd64 .deb + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + asset_content_type: application/vnd.debian.binary-package - name: Bump version.properties run: >- From 65104d5d8c7eae04770cc0f486848b12173c2b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 24 Sep 2024 23:51:07 +0200 Subject: [PATCH 186/252] fix #4844 (#4859) --- src/main.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index df4b622f1..6f0099cb1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -624,7 +624,13 @@ void setup() buttonThread = new ButtonThread(); #endif - playStartMelody(); + // only play start melody when role is not tracker or sensor + if (config.power.is_power_saving == true && (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || + config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER || + config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)) + LOG_DEBUG("Tracker/Sensor: Skipping start melody\n"); + else + playStartMelody(); // fixed screen override? if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO) From c50df710bad0fbdd97093df19de20c75e7ea8c0d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 24 Sep 2024 20:12:42 -0500 Subject: [PATCH 187/252] Also put this back --- .github/workflows/main_matrix.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index af8111a63..ca9f1d37f 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -139,7 +139,8 @@ jobs: contents: write pull-requests: write runs-on: ubuntu-latest - needs: [ + needs: + [ build-esp32, build-esp32-s3, build-esp32-c3, @@ -148,7 +149,7 @@ jobs: build-stm32, package-raspbian, package-raspbian-armv7l, - # package-native, + package-native, ] steps: - name: Checkout code From f73aa8aa82575dbe1d83de54f349a49ca9e17af0 Mon Sep 17 00:00:00 2001 From: caveman99 <25002+caveman99@users.noreply.github.com> Date: Wed, 25 Sep 2024 08:28:33 +0000 Subject: [PATCH 188/252] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index 9651aa59e..eb915e71f 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 9651aa59eaa3b54d801b9c251efcfe842790db32 +Subproject commit eb915e71fc907bef97d98760aa4c6c18698b6c32 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 9ba69c612..b323ddf07 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -205,6 +205,10 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_RPI_PICO2 = 79, /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */ meshtastic_HardwareModel_M5STACK_CORES3 = 80, + /* Seeed XIAO S3 DK */ + meshtastic_HardwareModel_SEEED_XIAO_S3 = 81, + /* Nordic nRF52840+Semtech SX1262 LoRa BLE Combo Module. nRF52840+SX1262 MS24SF1 */ + meshtastic_HardwareModel_MS24SF1 = 82, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 1293c5cdd4aa54a18af162f670316aaa7e3ca829 Mon Sep 17 00:00:00 2001 From: dylanli Date: Wed, 25 Sep 2024 18:27:14 +0800 Subject: [PATCH 189/252] Support for Seeed XIAO S3 Board (#4850) * feat: add seeed-xiao-s3 board defination and pins defination * chore: add SEEED XIAO S3 into mesh pb * fix: fix trunk fmt check failed * Trunk fmt variant.h * Restore automatically generated file --------- Co-authored-by: Tom Fifield --- boards/seeed-xiao-s3.json | 41 +++++++++++++ src/platform/esp32/architecture.h | 2 + variants/seeed_xiao_s3/pins_arduino.h | 21 +++++++ variants/seeed_xiao_s3/platformio.ini | 17 ++++++ variants/seeed_xiao_s3/variant.h | 84 +++++++++++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 boards/seeed-xiao-s3.json create mode 100644 variants/seeed_xiao_s3/pins_arduino.h create mode 100644 variants/seeed_xiao_s3/platformio.ini create mode 100644 variants/seeed_xiao_s3/variant.h diff --git a/boards/seeed-xiao-s3.json b/boards/seeed-xiao-s3.json new file mode 100644 index 000000000..0b7b432a0 --- /dev/null +++ b/boards/seeed-xiao-s3.json @@ -0,0 +1,41 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=0" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [["0x2886", "0x0059"]], + "mcu": "esp32s3", + "variant": "seeed-xiao-s3" + }, + "connectivity": ["wifi", "bluetooth", "lora"], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": ["esp-builtin"], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "seeed-xiao-s3", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 8388608, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html", + "vendor": "Seeed Studio" +} diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 90c4c392d..a2e7dfc4e 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -170,6 +170,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114 #elif defined(SENSECAP_INDICATOR) #define HW_VENDOR meshtastic_HardwareModel_SENSECAP_INDICATOR +#elif defined(SEEED_XIAO_S3) +#define HW_VENDOR meshtastic_HardwareModel_SEEED_XIAO_S3 #endif // ----------------------------------------------------------------------------- diff --git a/variants/seeed_xiao_s3/pins_arduino.h b/variants/seeed_xiao_s3/pins_arduino.h new file mode 100644 index 000000000..52e96eaeb --- /dev/null +++ b/variants/seeed_xiao_s3/pins_arduino.h @@ -0,0 +1,21 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x2886 +#define USB_PID 0x0059 + +// GPIO48 Reference: https://github.com/espressif/arduino-esp32/pull/8600 + +// The default Wire will be mapped to Screen and Sensors +static const uint8_t SDA = 47; +static const uint8_t SCL = 48; + +// Default SPI will be mapped to Radio +static const uint8_t MISO = 8; +static const uint8_t SCK = 7; +static const uint8_t MOSI = 9; +static const uint8_t SS = 41; + +#endif /* Pins_Arduino_h */ diff --git a/variants/seeed_xiao_s3/platformio.ini b/variants/seeed_xiao_s3/platformio.ini new file mode 100644 index 000000000..3d10d7136 --- /dev/null +++ b/variants/seeed_xiao_s3/platformio.ini @@ -0,0 +1,17 @@ +[env:seeed-xiao-s3] +extends = esp32s3_base +board = seeed-xiao-s3 +board_check = true +board_build.mcu = esp32s3 +upload_protocol = esptool +upload_speed = 921600 +lib_deps = + ${esp32s3_base.lib_deps} +build_unflags = + ${esp32s3_base.build_unflags} + -DARDUINO_USB_MODE=1 +build_flags = + ${esp32s3_base.build_flags} -DSEEED_XIAO_S3 -I variants/seeed_xiao_s3 + -DBOARD_HAS_PSRAM + + -DARDUINO_USB_MODE=0 \ No newline at end of file diff --git a/variants/seeed_xiao_s3/variant.h b/variants/seeed_xiao_s3/variant.h new file mode 100644 index 000000000..ab886d354 --- /dev/null +++ b/variants/seeed_xiao_s3/variant.h @@ -0,0 +1,84 @@ +/* + ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄ +▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌ +▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌ +▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌ +▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌ +▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌ ▐░▌ + ▀▀▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░▌ ▐░▌ + ▐░▌▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌ + ▄▄▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄█░▌ +▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░▌ + ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ + + ▄ ▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ + ▐░▌ ▐░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ + ▐░▌ ▐░▌ ▀▀▀▀█░█▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌ ▐░█▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀█░▌ + ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌ ▐░▌ ▐░▌ + ▐░▐░▌ ▐░▌ ▐░█▄▄▄▄▄▄▄█░▌▐░▌ ▐░▌ ▐░█▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄█░▌ + ▐░▌ ▐░▌ ▐░░░░░░░░░░░▌▐░▌ ▐░▌ ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ + ▐░▌░▌ ▐░▌ ▐░█▀▀▀▀▀▀▀█░▌▐░▌ ▐░▌ ▀▀▀▀▀▀▀▀▀█░▌ ▀▀▀▀▀▀▀▀▀█░▌ + ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌ ▐░▌ ▐░▌ + ▐░▌ ▐░▌ ▄▄▄▄█░█▄▄▄▄ ▐░▌ ▐░▌▐░█▄▄▄▄▄▄▄█░▌ ▄▄▄▄▄▄▄▄▄█░▌ ▄▄▄▄▄▄▄▄▄█░▌ + ▐░▌ ▐░▌▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░░░░░░░░░░░▌ ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ + ▀ ▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ +*/ + +/* +Board Information: https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html +Expansion Board Infomation : https://www.seeedstudio.com/Seeeduino-XIAO-Expansion-board-p-4746.html +L76K GPS Module Information : https://www.seeedstudio.com/L76K-GNSS-Module-for-Seeed-Studio-XIAO-p-5864.html +*/ + +#define LED_PIN 48 +#define LED_STATE_ON 1 // State when LED is lit + +#define BUTTON_PIN 21 // This is the Program Button +#define BUTTON_NEED_PULLUP + +/*Warning: + https://www.seeedstudio.com/L76K-GNSS-Module-for-Seeed-Studio-XIAO-p-5864.html + L76K Expansion Board can not directly used, L76K Reset Pin needs to override or physically remove it, + otherwise it will conflict with the SPI pins +*/ +// #define GPS_L76K +#ifdef GPS_L76K +#define GPS_RX_PIN 44 +#define GPS_TX_PIN 43 +#define HAS_GPS 1 +#define GPS_BAUDRATE 9600 +#define GPS_THREAD_INTERVAL 50 +#define PIN_SERIAL1_RX PIN_GPS_TX +#define PIN_SERIAL1_TX PIN_GPS_RX +#define PIN_GPS_STANDBY 1 +#endif + +// XIAO S3 Expansion board has 1.3 inch OLED Screen +#define USCREEN_SSD1306 + +#define I2C_SDA 5 +#define I2C_SCL 6 + +// XIAO S3 LORA module +#define USE_SX1262 + +#define LORA_MISO 8 +#define LORA_SCK 7 +#define LORA_MOSI 9 +#define LORA_CS 41 + +#define LORA_RESET 42 +#define LORA_DIO1 39 + +#define LORA_DIO2 38 + +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY 40 +#define SX126X_RESET LORA_RESET + +// 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 \ No newline at end of file From 1129c929743c8eed8981ba3db3c735e24df5cf5f Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 25 Sep 2024 05:31:29 -0500 Subject: [PATCH 190/252] Add a second delay() to get the unit tests running on Rak4631 (#4862) --- test/test_crypto/test_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_crypto/test_main.cpp b/test/test_crypto/test_main.cpp index 129c88283..0c820178a 100644 --- a/test/test_crypto/test_main.cpp +++ b/test/test_crypto/test_main.cpp @@ -129,6 +129,7 @@ void setup() { // NOTE!!! Wait for >2 secs // if board doesn't support software reset via Serial.DTR/RTS + delay(10); delay(2000); UNITY_BEGIN(); // IMPORTANT LINE! From 40b3dbaa702f801eb803c806da2923f553695fc7 Mon Sep 17 00:00:00 2001 From: David <2941290+dhskinner@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:34:53 +1000 Subject: [PATCH 191/252] Add MAX17048 lipo fuel gauge (#4851) * Initial commit * Update MAX17048Sensor.cpp * Update EnvironmentTelemetry.cpp --------- Co-authored-by: Ben Meadors --- platformio.ini | 1 + src/Power.cpp | 121 +++++++++++- src/configuration.h | 1 + src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 1 + src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 14 +- src/modules/Telemetry/PowerTelemetry.cpp | 35 ++-- .../Telemetry/Sensor/MAX17048Sensor.cpp | 176 ++++++++++++++++++ src/modules/Telemetry/Sensor/MAX17048Sensor.h | 110 +++++++++++ src/power.h | 7 + 11 files changed, 449 insertions(+), 19 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/MAX17048Sensor.cpp create mode 100644 src/modules/Telemetry/Sensor/MAX17048Sensor.h diff --git a/platformio.ini b/platformio.ini index 9b869a036..81632ae0e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -136,6 +136,7 @@ lib_deps = adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA219@^1.2.0 + adafruit/Adafruit MAX1704X@^1.0.3 adafruit/Adafruit SHTC3 Library@^1.0.0 adafruit/Adafruit LPS2X@^2.0.4 adafruit/Adafruit SHT31 Library@^2.2.2 diff --git a/src/Power.cpp b/src/Power.cpp index b3a67abd5..bbb6cd2c3 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -77,6 +77,15 @@ INA219Sensor ina219Sensor; INA3221Sensor ina3221Sensor; #endif +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#include "modules/Telemetry/Sensor/MAX17048Sensor.h" +#include +extern std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; +#if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY) +MAX17048Sensor max17048Sensor; +#endif +#endif + #if HAS_RAKPROT && !defined(ARCH_PORTDUINO) RAK9154Sensor rak9154Sensor; #endif @@ -167,6 +176,7 @@ static void adcDisable() */ class AnalogBatteryLevel : public HasBatteryLevel { + public: /** * Battery state of charge, from 0 to 100 or -1 for unknown */ @@ -553,7 +563,12 @@ bool Power::analogInit() */ bool Power::setup() { - bool found = axpChipInit() || analogInit(); + // initialise one power sensor (only) + bool found = axpChipInit(); + if (!found) + found = lipoInit(); + if (!found) + found = analogInit(); #ifdef NRF_APM found = true; @@ -1044,4 +1059,106 @@ bool Power::axpChipInit() #else return false; #endif -} \ No newline at end of file +} + +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) + +/** + * Wrapper class for an I2C MAX17048 Lipo battery sensor. If there is no + * I2C sensor present, the class falls back to analog battery sensing + */ +class LipoBatteryLevel : public AnalogBatteryLevel +{ + private: + MAX17048Singleton *max17048 = nullptr; + + public: + /** + * Init the I2C MAX17048 Lipo battery level sensor + */ + bool runOnce() + { + if (max17048 == nullptr) { + max17048 = MAX17048Singleton::GetInstance(); + } + + // try to start if the sensor has been detected + if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX17048].first != 0) { + return max17048->runOnce(nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX17048].second); + } + return false; + } + + /** + * Battery state of charge, from 0 to 100 or -1 for unknown + */ + virtual int getBatteryPercent() override + { + if (!max17048->isInitialised()) + return AnalogBatteryLevel::getBatteryPercent(); + return max17048->getBusBatteryPercent(); + } + + /** + * The raw voltage of the battery in millivolts, or NAN if unknown + */ + virtual uint16_t getBattVoltage() override + { + if (!max17048->isInitialised()) + return AnalogBatteryLevel::getBattVoltage(); + return max17048->getBusVoltageMv(); + } + + /** + * return true if there is a battery installed in this unit + */ + virtual bool isBatteryConnect() override + { + if (!max17048->isInitialised()) + return AnalogBatteryLevel::isBatteryConnect(); + return max17048->isBatteryConnected(); + } + + /** + * return true if there is an external power source detected + */ + virtual bool isVbusIn() override + { + if (!max17048->isInitialised()) + return AnalogBatteryLevel::isVbusIn(); + return max17048->isExternallyPowered(); + } + + /** + * return true if the battery is currently charging + */ + virtual bool isCharging() override + { + if (!max17048->isInitialised()) + return AnalogBatteryLevel::isCharging(); + return max17048->isBatteryCharging(); + } +}; + +LipoBatteryLevel lipoLevel; + +/** + * Init the Lipo battery level sensor + */ +bool Power::lipoInit() +{ + bool result = lipoLevel.runOnce(); + LOG_DEBUG("Power::lipoInit lipo sensor is %s\n", result ? "ready" : "not ready yet"); + batteryLevel = &lipoLevel; + return true; +} + +#else +/** + * The Lipo battery level sensor is unavailable - default to AnalogBatteryLevel + */ +bool Power::lipoInit() +{ + return false; +} +#endif \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 0b470eef3..60d5a18ac 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -122,6 +122,7 @@ along with this program. If not, see . #define INA_ADDR_ALTERNATE 0x41 #define INA_ADDR_WAVESHARE_UPS 0x43 #define INA3221_ADDR 0x42 +#define MAX1704X_ADDR 0x36 #define QMC6310_ADDR 0x1C #define QMI8658_ADDR 0x6B #define QMC5883L_ADDR 0x0D diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 090b1a968..50959411b 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -28,6 +28,7 @@ class ScanI2C INA260, INA219, INA3221, + MAX17048, MCP9808, SHT31, SHT4X, diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index c0e70503b..285210c94 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -396,6 +396,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n"); SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n"); SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found\n"); + SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found\n"); default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); diff --git a/src/main.cpp b/src/main.cpp index 6f0099cb1..c93cff85f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -555,6 +555,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA3221, meshtastic_TelemetrySensorType_INA3221) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX17048, meshtastic_TelemetrySensorType_MAX17048) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index f94f7956b..969529881 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -83,7 +83,7 @@ int32_t EnvironmentTelemetryModule::runOnce() */ // moduleConfig.telemetry.environment_measurement_enabled = 1; - // moduleConfig.telemetry.environment_screen_enabled = 1; + // moduleConfig.telemetry.environment_screen_enabled = 1; // moduleConfig.telemetry.environment_update_interval = 15; if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) { @@ -144,6 +144,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = mlx90632Sensor.runOnce(); if (nau7802Sensor.hasSensor()) result = nau7802Sensor.runOnce(); + if (max17048Sensor.hasSensor()) + result = max17048Sensor.runOnce(); #endif } return result; @@ -156,6 +158,7 @@ int32_t EnvironmentTelemetryModule::runOnce() result = bme680Sensor.runTrigger(); } + uint32_t now = millis(); if (((lastSentToMesh == 0) || !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( moduleConfig.telemetry.environment_update_interval, @@ -397,6 +400,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity; } } + if (max17048Sensor.hasSensor()) { + valid = valid && max17048Sensor.getMetrics(m); + hasSensor = true; + } #endif return valid && hasSensor; @@ -587,6 +594,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule if (result != AdminMessageHandleResult::NOT_HANDLED) return result; } + if (max17048Sensor.hasSensor()) { + result = max17048Sensor.handleAdminMessage(mp, request, response); + if (result != AdminMessageHandleResult::NOT_HANDLED) + return result; + } return result; } diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index a493042a0..6130c2c83 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -60,6 +60,8 @@ int32_t PowerTelemetryModule::runOnce() result = ina260Sensor.runOnce(); if (ina3221Sensor.hasSensor() && !ina3221Sensor.isInitialized()) result = ina3221Sensor.runOnce(); + if (max17048Sensor.hasSensor() && !max17048Sensor.isInitialized()) + result = max17048Sensor.runOnce(); } return result; #else @@ -128,19 +130,23 @@ void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *s return; } + // Display current and voltage based on ...power_metrics.has_[channel/voltage/current]... flags display->setFont(FONT_SMALL); - String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C"; display->drawString(x, y += _fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); - if (lastMeasurement.variant.power_metrics.ch1_voltage != 0) { + if (lastMeasurement.variant.power_metrics.has_ch1_voltage || lastMeasurement.variant.power_metrics.has_ch1_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch 1 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 0) + "V / " + - String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA"); + "Ch1 Volt: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) + + "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA"); + } + if (lastMeasurement.variant.power_metrics.has_ch2_voltage || lastMeasurement.variant.power_metrics.has_ch2_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch 2 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 0) + "V / " + - String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA"); + "Ch2 Volt: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 2) + + "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA"); + } + if (lastMeasurement.variant.power_metrics.has_ch3_voltage || lastMeasurement.variant.power_metrics.has_ch3_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch 3 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 0) + "V / " + - String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA"); + "Ch3 Volt: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 2) + + "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA"); } } @@ -150,8 +156,8 @@ bool PowerTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &m #ifdef DEBUG_PORT const char *sender = getSenderShortName(mp); - LOG_INFO("(Received from %s): ch1_voltage=%f, ch1_current=%f, ch2_voltage=%f, ch2_current=%f, " - "ch3_voltage=%f, ch3_current=%f\n", + LOG_INFO("(Received from %s): ch1_voltage=%.1f, ch1_current=%.1f, ch2_voltage=%.1f, ch2_current=%.1f, " + "ch3_voltage=%.1f, ch3_current=%.1f\n", sender, t->variant.power_metrics.ch1_voltage, t->variant.power_metrics.ch1_current, t->variant.power_metrics.ch2_voltage, t->variant.power_metrics.ch2_current, t->variant.power_metrics.ch3_voltage, t->variant.power_metrics.ch3_current); @@ -172,12 +178,7 @@ bool PowerTelemetryModule::getPowerTelemetry(meshtastic_Telemetry *m) m->time = getTime(); m->which_variant = meshtastic_Telemetry_power_metrics_tag; - m->variant.power_metrics.ch1_voltage = 0; - m->variant.power_metrics.ch1_current = 0; - m->variant.power_metrics.ch2_voltage = 0; - m->variant.power_metrics.ch2_current = 0; - m->variant.power_metrics.ch3_voltage = 0; - m->variant.power_metrics.ch3_current = 0; + m->variant.power_metrics = meshtastic_PowerMetrics_init_zero; #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) if (ina219Sensor.hasSensor()) valid = ina219Sensor.getMetrics(m); @@ -185,6 +186,8 @@ bool PowerTelemetryModule::getPowerTelemetry(meshtastic_Telemetry *m) valid = ina260Sensor.getMetrics(m); if (ina3221Sensor.hasSensor()) valid = ina3221Sensor.getMetrics(m); + if (max17048Sensor.hasSensor()) + valid = max17048Sensor.getMetrics(m); #endif return valid; diff --git a/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp b/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp new file mode 100644 index 000000000..a3890df43 --- /dev/null +++ b/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp @@ -0,0 +1,176 @@ +#include "MAX17048Sensor.h" + +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) + +MAX17048Singleton *MAX17048Singleton::GetInstance() +{ + if (pinstance == nullptr) { + pinstance = new MAX17048Singleton(); + } + return pinstance; +} + +MAX17048Singleton::MAX17048Singleton() {} + +MAX17048Singleton::~MAX17048Singleton() {} + +MAX17048Singleton *MAX17048Singleton::pinstance{nullptr}; + +bool MAX17048Singleton::runOnce(TwoWire *theWire) +{ + initialized = begin(theWire); + LOG_DEBUG("MAX17048Sensor::runOnce %s\n", initialized ? "began ok" : "begin failed"); + return initialized; +} + +bool MAX17048Singleton::isBatteryCharging() +{ + float volts = cellVoltage(); + if (isnan(volts)) { + LOG_DEBUG("MAX17048Sensor::isBatteryCharging is not connected\n"); + return 0; + } + + MAX17048ChargeSample sample; + sample.chargeRate = chargeRate(); // charge/discharge rate in percent/hr + sample.cellPercent = cellPercent(); // state of charge in percent 0 to 100 + chargeSamples.push(sample); // save a sample into a fifo buffer + + // Keep the fifo buffer trimmed + while (chargeSamples.size() > MAX17048_CHARGING_SAMPLES) + chargeSamples.pop(); + + // Based on the past n samples, is the lipo charging, discharging or idle + if (chargeSamples.front().chargeRate > MAX17048_CHARGING_MINIMUM_RATE && + chargeSamples.back().chargeRate > MAX17048_CHARGING_MINIMUM_RATE) { + if (chargeSamples.front().cellPercent > chargeSamples.back().cellPercent) + chargeState = MAX17048ChargeState::EXPORT; + else if (chargeSamples.front().cellPercent < chargeSamples.back().cellPercent) + chargeState = MAX17048ChargeState::IMPORT; + else + chargeState = MAX17048ChargeState::IDLE; + } else { + chargeState = MAX17048ChargeState::IDLE; + } + + LOG_DEBUG("MAX17048Sensor::isBatteryCharging %s volts: %.3f soc: %.3f rate: %.3f\n", chargeLabels[chargeState], volts, + sample.cellPercent, sample.chargeRate); + return chargeState == MAX17048ChargeState::IMPORT; +} + +uint16_t MAX17048Singleton::getBusVoltageMv() +{ + float volts = cellVoltage(); + if (isnan(volts)) { + LOG_DEBUG("MAX17048Sensor::getBusVoltageMv is not connected\n"); + return 0; + } + LOG_DEBUG("MAX17048Sensor::getBusVoltageMv %.3fmV\n", volts); + return (uint16_t)(volts * 1000.0f); +} + +uint8_t MAX17048Singleton::getBusBatteryPercent() +{ + float soc = cellPercent(); + LOG_DEBUG("MAX17048Sensor::getBusBatteryPercent %.1f%%\n", soc); + return clamp(static_cast(round(soc)), static_cast(0), static_cast(100)); +} + +uint16_t MAX17048Singleton::getTimeToGoSecs() +{ + float rate = chargeRate(); // charge/discharge rate in percent/hr + float soc = cellPercent(); // state of charge in percent 0 to 100 + soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100% + float ttg = ((100.0f - soc) / rate) * 3600.0f; // calculate seconds to charge/discharge + LOG_DEBUG("MAX17048Sensor::getTimeToGoSecs %.0f seconds\n", ttg); + return (uint16_t)ttg; +} + +bool MAX17048Singleton::isBatteryConnected() +{ + float volts = cellVoltage(); + if (isnan(volts)) { + LOG_DEBUG("MAX17048Sensor::isBatteryConnected is not connected\n"); + return false; + } + + // if a valid voltage is returned, then battery must be connected + return true; +} + +bool MAX17048Singleton::isExternallyPowered() +{ + float volts = cellVoltage(); + if (isnan(volts)) { + // if the battery is not connected then there must be external power + LOG_DEBUG("MAX17048Sensor::isExternallyPowered battery is\n"); + return true; + } + // if the bus voltage is over MAX17048_BUS_POWER_VOLTS, then the external power + // is assumed to be connected + LOG_DEBUG("MAX17048Sensor::isExternallyPowered %s connected\n", volts >= MAX17048_BUS_POWER_VOLTS ? "is" : "is not"); + return volts >= MAX17048_BUS_POWER_VOLTS; +} + +#if (HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY)) + +MAX17048Sensor::MAX17048Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MAX17048, "MAX17048") {} + +int32_t MAX17048Sensor::runOnce() +{ + if (isInitialized()) { + LOG_INFO("Init sensor: %s is already initialised\n", sensorName); + return true; + } + + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + // Get a singleton instance and initialise the max17048 + if (max17048 == nullptr) { + max17048 = MAX17048Singleton::GetInstance(); + } + status = max17048->runOnce(nodeTelemetrySensorsMap[sensorType].second); + return initI2CSensor(); +} + +void MAX17048Sensor::setup() {} + +bool MAX17048Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + LOG_DEBUG("MAX17048Sensor::getMetrics id: %i\n", measurement->which_variant); + + float volts = max17048->cellVoltage(); + if (isnan(volts)) { + LOG_DEBUG("MAX17048Sensor::getMetrics battery is not connected\n"); + return false; + } + + float rate = max17048->chargeRate(); // charge/discharge rate in percent/hr + float soc = max17048->cellPercent(); // state of charge in percent 0 to 100 + soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100% + float ttg = (100.0f - soc) / rate; // calculate hours to charge/discharge + + LOG_DEBUG("MAX17048Sensor::getMetrics volts: %.3fV soc: %.1f%% ttg: %.1f hours\n", volts, soc, ttg); + if ((int)measurement->which_variant == meshtastic_Telemetry_power_metrics_tag) { + measurement->variant.power_metrics.has_ch1_voltage = true; + measurement->variant.power_metrics.ch1_voltage = volts; + } else if ((int)measurement->which_variant == meshtastic_Telemetry_device_metrics_tag) { + measurement->variant.device_metrics.has_battery_level = true; + measurement->variant.device_metrics.has_voltage = true; + measurement->variant.device_metrics.battery_level = static_cast(round(soc)); + measurement->variant.device_metrics.voltage = volts; + } + return true; +} + +uint16_t MAX17048Sensor::getBusVoltageMv() +{ + return max17048->getBusVoltageMv(); +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/MAX17048Sensor.h b/src/modules/Telemetry/Sensor/MAX17048Sensor.h new file mode 100644 index 000000000..20dca324c --- /dev/null +++ b/src/modules/Telemetry/Sensor/MAX17048Sensor.h @@ -0,0 +1,110 @@ +#pragma once + +#ifndef MAX17048_SENSOR_H +#define MAX17048_SENSOR_H + +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) + +// Samples to store in a buffer to determine if the battery is charging or discharging +#define MAX17048_CHARGING_SAMPLES 3 + +// Threshold to determine if the battery is on charge, in percent/hour +#define MAX17048_CHARGING_MINIMUM_RATE 1.0f + +// Threshold to determine if the board has bus power +#define MAX17048_BUS_POWER_VOLTS 4.195f + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include "VoltageSensor.h" + +#include "meshUtils.h" +#include +#include + +struct MAX17048ChargeSample { + float cellPercent; + float chargeRate; +}; + +enum MAX17048ChargeState { IDLE, EXPORT, IMPORT }; + +// Singleton wrapper for the Adafruit_MAX17048 class +class MAX17048Singleton : public Adafruit_MAX17048 +{ + private: + static MAX17048Singleton *pinstance; + bool initialized = false; + std::queue chargeSamples; + MAX17048ChargeState chargeState = IDLE; + const String chargeLabels[3] = {F("idle"), F("export"), F("import")}; + + protected: + MAX17048Singleton(); + ~MAX17048Singleton(); + + public: + // Create a singleton instance (not thread safe) + static MAX17048Singleton *GetInstance(); + + // Singletons should not be cloneable. + MAX17048Singleton(MAX17048Singleton &other) = delete; + + // Singletons should not be assignable. + void operator=(const MAX17048Singleton &) = delete; + + // Initialise the sensor (not thread safe) + virtual bool runOnce(TwoWire *theWire = &Wire); + + // Get the current bus voltage + uint16_t getBusVoltageMv(); + + // Get the state of charge in percent 0 to 100 + uint8_t getBusBatteryPercent(); + + // Calculate the seconds to charge/discharge + uint16_t getTimeToGoSecs(); + + // Returns true if the battery sensor has started + inline virtual bool isInitialised() { return initialized; }; + + // Returns true if the battery is currently on charge (not thread safe) + bool isBatteryCharging(); + + // Returns true if a battery is actually connected + bool isBatteryConnected(); + + // Returns true if there is bus or external power connected + bool isExternallyPowered(); +}; + +#if (HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY)) + +class MAX17048Sensor : public TelemetrySensor, VoltageSensor +{ + private: + MAX17048Singleton *max17048 = nullptr; + + protected: + virtual void setup() override; + + public: + MAX17048Sensor(); + + // Initialise the sensor + virtual int32_t runOnce() override; + + // Get the current bus voltage and state of charge + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; + + // Get the current bus voltage + virtual uint16_t getBusVoltageMv() override; +}; + +#endif + +#endif + +#endif \ No newline at end of file diff --git a/src/power.h b/src/power.h index a4307ee07..19a4f1228 100644 --- a/src/power.h +++ b/src/power.h @@ -48,6 +48,11 @@ extern INA219Sensor ina219Sensor; extern INA3221Sensor ina3221Sensor; #endif +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#include "modules/Telemetry/Sensor/MAX17048Sensor.h" +extern MAX17048Sensor max17048Sensor; +#endif + #if HAS_RAKPROT && !defined(ARCH_PORTDUINO) #include "../variants/rak2560/RAK9154Sensor.h" extern RAK9154Sensor rak9154Sensor; @@ -82,6 +87,8 @@ class Power : private concurrency::OSThread bool axpChipInit(); /// Setup a simple ADC input based battery sensor bool analogInit(); + /// Setup a Lipo battery level sensor + bool lipoInit(); private: // open circuit voltage lookup table From 9456c42fc0981cba2159b8ddeef75cd5405f9048 Mon Sep 17 00:00:00 2001 From: David <2941290+dhskinner@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:25:31 +1000 Subject: [PATCH 192/252] Refactor AccelerometerThread.h (#4831) * Initial upload * Tidy up * Update ICM20948Sensor.cpp * Update AccelerometerThread.h * Initial upload * Tidy up * Update ICM20948Sensor.cpp * Update AccelerometerThread.h --------- Co-authored-by: Ben Meadors --- platformio.ini | 3 +- src/AccelerometerThread.h | 319 ------------------------------- src/configuration.h | 2 + src/detect/ScanI2C.cpp | 4 +- src/detect/ScanI2C.h | 10 +- src/detect/ScanI2CTwoWire.cpp | 21 +- src/main.cpp | 7 +- src/main.h | 6 +- src/modules/AdminModule.cpp | 4 +- src/motion/AccelerometerThread.h | 149 +++++++++++++++ src/motion/BMA423Sensor.cpp | 62 ++++++ src/motion/BMA423Sensor.h | 26 +++ src/motion/BMX160Sensor.cpp | 100 ++++++++++ src/motion/BMX160Sensor.h | 41 ++++ src/motion/ICM20948Sensor.cpp | 186 ++++++++++++++++++ src/motion/ICM20948Sensor.h | 96 ++++++++++ src/motion/LIS3DHSensor.cpp | 36 ++++ src/motion/LIS3DHSensor.h | 24 +++ src/motion/LSM6DS3Sensor.cpp | 33 ++++ src/motion/LSM6DS3Sensor.h | 28 +++ src/motion/MPU6050Sensor.cpp | 31 +++ src/motion/MPU6050Sensor.h | 24 +++ src/motion/MotionSensor.cpp | 79 ++++++++ src/motion/MotionSensor.h | 85 ++++++++ src/motion/STK8XXXSensor.cpp | 40 ++++ src/motion/STK8XXXSensor.h | 37 ++++ 26 files changed, 1116 insertions(+), 337 deletions(-) delete mode 100644 src/AccelerometerThread.h create mode 100755 src/motion/AccelerometerThread.h create mode 100755 src/motion/BMA423Sensor.cpp create mode 100755 src/motion/BMA423Sensor.h create mode 100755 src/motion/BMX160Sensor.cpp create mode 100755 src/motion/BMX160Sensor.h create mode 100755 src/motion/ICM20948Sensor.cpp create mode 100755 src/motion/ICM20948Sensor.h create mode 100755 src/motion/LIS3DHSensor.cpp create mode 100755 src/motion/LIS3DHSensor.h create mode 100755 src/motion/LSM6DS3Sensor.cpp create mode 100755 src/motion/LSM6DS3Sensor.h create mode 100755 src/motion/MPU6050Sensor.cpp create mode 100755 src/motion/MPU6050Sensor.h create mode 100755 src/motion/MotionSensor.cpp create mode 100755 src/motion/MotionSensor.h create mode 100755 src/motion/STK8XXXSensor.cpp create mode 100755 src/motion/STK8XXXSensor.h diff --git a/platformio.ini b/platformio.ini index 81632ae0e..b3898ba93 100644 --- a/platformio.ini +++ b/platformio.ini @@ -149,6 +149,7 @@ lib_deps = adafruit/Adafruit SHT4x Library@^1.0.4 adafruit/Adafruit TSL2591 Library@^1.4.5 sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@^1.0.5 + sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@^1.2.13 ClosedCube OPT3001@^1.1.2 emotibit/EmotiBit MLX90632@^1.0.8 dfrobot/DFRobot_RTU@^1.0.3 @@ -162,4 +163,4 @@ lib_deps = https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee - https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 + https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 \ No newline at end of file diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h deleted file mode 100644 index 629d63c6a..000000000 --- a/src/AccelerometerThread.h +++ /dev/null @@ -1,319 +0,0 @@ -#pragma once -#include "configuration.h" - -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - -#include "PowerFSM.h" -#include "concurrency/OSThread.h" -#include "main.h" -#include "power.h" - -#include -#include -#include -#ifdef STK8XXX_INT -#include -#endif -#include -#include -#include -#ifdef RAK_4631 -#include "Fusion/Fusion.h" -#include "graphics/Screen.h" -#include "graphics/ScreenFonts.h" -#include -#endif - -#define ACCELEROMETER_CHECK_INTERVAL_MS 100 -#define ACCELEROMETER_CLICK_THRESHOLD 40 - -volatile static bool STK_IRQ; - -static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) -{ - Wire.beginTransmission(address); - Wire.write(reg); - Wire.endTransmission(); - Wire.requestFrom((uint8_t)address, (uint8_t)len); - uint8_t i = 0; - while (Wire.available()) { - data[i++] = Wire.read(); - } - return 0; // Pass -} - -static inline int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) -{ - Wire.beginTransmission(address); - Wire.write(reg); - Wire.write(data, len); - return (0 != Wire.endTransmission()); -} - -class AccelerometerThread : public concurrency::OSThread -{ - public: - explicit AccelerometerThread(ScanI2C::DeviceType type) : OSThread("AccelerometerThread") - { - if (accelerometer_found.port == ScanI2C::I2CPort::NO_I2C) { - LOG_DEBUG("AccelerometerThread disabling due to no sensors found\n"); - disable(); - return; - } - acceleremoter_type = type; -#ifndef RAK_4631 - if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) { - LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n"); - disable(); - return; - } -#endif - init(); - } - - void start() - { - init(); - setIntervalFromNow(0); - }; - - protected: - int32_t runOnce() override - { - canSleep = true; // Assume we should not keep the board awake - - if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) { - wakeScreen(); - } else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && STK_IRQ) { - STK_IRQ = false; - if (config.display.wake_on_tap_or_motion) { - wakeScreen(); - } - } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) { - uint8_t click = lis.getClick(); - if (!config.device.double_tap_as_button_press) { - wakeScreen(); - } - - if (config.device.double_tap_as_button_press && (click & 0x20)) { - buttonPress(); - return 500; - } - } else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.readIrqStatus() != DEV_WIRE_NONE) { - if (bmaSensor.isTilt() || bmaSensor.isDoubleTap()) { - wakeScreen(); - return 500; - } -#ifdef RAK_4631 - } else if (acceleremoter_type == ScanI2C::DeviceType::BMX160) { - sBmx160SensorData_t magAccel; - sBmx160SensorData_t gAccel; - - /* Get a new sensor event */ - bmx160.getAllData(&magAccel, NULL, &gAccel); - - // expirimental calibrate routine. Limited to between 10 and 30 seconds after boot - if (millis() > 12 * 1000 && millis() < 30 * 1000) { - if (!showingScreen) { - showingScreen = true; - screen->startAlert((FrameCallback)drawFrameCalibration); - } - if (magAccel.x > highestX) - highestX = magAccel.x; - if (magAccel.x < lowestX) - lowestX = magAccel.x; - if (magAccel.y > highestY) - highestY = magAccel.y; - if (magAccel.y < lowestY) - lowestY = magAccel.y; - if (magAccel.z > highestZ) - highestZ = magAccel.z; - if (magAccel.z < lowestZ) - lowestZ = magAccel.z; - } else if (showingScreen && millis() >= 30 * 1000) { - showingScreen = false; - screen->endAlert(); - } - - int highestRealX = highestX - (highestX + lowestX) / 2; - - magAccel.x -= (highestX + lowestX) / 2; - magAccel.y -= (highestY + lowestY) / 2; - magAccel.z -= (highestZ + lowestZ) / 2; - FusionVector ga, ma; - ga.axis.x = -gAccel.x; // default location for the BMX160 is on the rear of the board - ga.axis.y = -gAccel.y; - ga.axis.z = gAccel.z; - ma.axis.x = -magAccel.x; - ma.axis.y = -magAccel.y; - ma.axis.z = magAccel.z * 3; - - // If we're set to one of the inverted positions - if (config.display.compass_orientation > meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270) { - ma = FusionAxesSwap(ma, FusionAxesAlignmentNXNYPZ); - ga = FusionAxesSwap(ga, FusionAxesAlignmentNXNYPZ); - } - - float heading = FusionCompassCalculateHeading(FusionConventionNed, ga, ma); - - switch (config.display.compass_orientation) { - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0_INVERTED: - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0: - break; - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90: - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED: - heading += 90; - break; - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180: - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED: - heading += 180; - break; - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270: - case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED: - heading += 270; - break; - } - - screen->setHeading(heading); - -#endif - } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) { - wakeScreen(); - return 500; - } - - return ACCELEROMETER_CHECK_INTERVAL_MS; - } - - private: - void init() - { - LOG_DEBUG("AccelerometerThread initializing\n"); - - if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) { - LOG_DEBUG("MPU6050 initializing\n"); - // setup motion detection - mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ); - mpu.setMotionDetectionThreshold(1); - mpu.setMotionDetectionDuration(20); - mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized. - mpu.setInterruptPinPolarity(true); -#ifdef STK8XXX_INT - } else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && stk8baxx.STK8xxx_Initialization(STK8xxx_VAL_RANGE_2G)) { - STK_IRQ = false; - LOG_DEBUG("STX8BAxx initialized\n"); - stk8baxx.STK8xxx_Anymotion_init(); - pinMode(STK8XXX_INT, INPUT_PULLUP); - attachInterrupt( - digitalPinToInterrupt(STK8XXX_INT), [] { STK_IRQ = true; }, RISING); -#endif - } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) { - LOG_DEBUG("LIS3DH initializing\n"); - lis.setRange(LIS3DH_RANGE_2_G); - // Adjust threshold, higher numbers are less sensitive - lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD); - } else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && - bmaSensor.begin(accelerometer_found.address, &readRegister, &writeRegister)) { - LOG_DEBUG("BMA423 initializing\n"); - bmaSensor.configAccelerometer(bmaSensor.RANGE_2G, bmaSensor.ODR_100HZ, bmaSensor.BW_NORMAL_AVG4, - bmaSensor.PERF_CONTINUOUS_MODE); - bmaSensor.enableAccelerometer(); - bmaSensor.configInterrupt(BMA4_LEVEL_TRIGGER, BMA4_ACTIVE_HIGH, BMA4_PUSH_PULL, BMA4_OUTPUT_ENABLE, - BMA4_INPUT_DISABLE); - -#ifdef BMA423_INT - pinMode(BMA4XX_INT, INPUT); - attachInterrupt( - BMA4XX_INT, - [] { - // Set interrupt to set irq value to true - BMA_IRQ = true; - }, - RISING); // Select the interrupt mode according to the actual circuit -#endif - -#ifdef T_WATCH_S3 - // Need to raise the wrist function, need to set the correct axis - bmaSensor.setReampAxes(bmaSensor.REMAP_TOP_LAYER_RIGHT_CORNER); -#else - bmaSensor.setReampAxes(bmaSensor.REMAP_BOTTOM_LAYER_BOTTOM_LEFT_CORNER); -#endif - // bmaSensor.enableFeature(bmaSensor.FEATURE_STEP_CNTR, true); - bmaSensor.enableFeature(bmaSensor.FEATURE_TILT, true); - bmaSensor.enableFeature(bmaSensor.FEATURE_WAKEUP, true); - // bmaSensor.resetPedometer(); - - // Turn on feature interrupt - bmaSensor.enablePedometerIRQ(); - bmaSensor.enableTiltIRQ(); - // It corresponds to isDoubleClick interrupt - bmaSensor.enableWakeupIRQ(); -#ifdef RAK_4631 - } else if (acceleremoter_type == ScanI2C::DeviceType::BMX160 && bmx160.begin()) { - bmx160.ODR_Config(BMX160_ACCEL_ODR_100HZ, BMX160_GYRO_ODR_100HZ); // set output data rate - -#endif - } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.begin_I2C(accelerometer_found.address)) { - LOG_DEBUG("LSM6DS3 initializing\n"); - // Default threshold of 2G, less sensitive options are 4, 8 or 16G - lsm.setAccelRange(LSM6DS_ACCEL_RANGE_2_G); -#ifndef LSM6DS3_WAKE_THRESH -#define LSM6DS3_WAKE_THRESH 20 -#endif - lsm.enableWakeup(config.display.wake_on_tap_or_motion, 1, LSM6DS3_WAKE_THRESH); - // Duration is number of occurances needed to trigger, higher threshold is less sensitive - } - } - void wakeScreen() - { - if (powerFSM.getState() == &stateDARK) { - LOG_INFO("Tap or motion detected. Turning on screen\n"); - powerFSM.trigger(EVENT_INPUT); - } - } - - void buttonPress() - { - LOG_DEBUG("Double-tap detected. Firing button press\n"); - powerFSM.trigger(EVENT_PRESS); - } - - ScanI2C::DeviceType acceleremoter_type; - Adafruit_MPU6050 mpu; - Adafruit_LIS3DH lis; -#ifdef STK8XXX_INT - STK8xxx stk8baxx; -#endif - Adafruit_LSM6DS3TRC lsm; - SensorBMA423 bmaSensor; - bool BMA_IRQ = false; -#ifdef RAK_4631 - bool showingScreen = false; - RAK_BMX160 bmx160; - float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0; - - static void drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) - { - int x_offset = display->width() / 2; - int y_offset = display->height() <= 80 ? 0 : 32; - display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(FONT_MEDIUM); - display->drawString(x, y, "Calibrating\nCompass"); - int16_t compassX = 0, compassY = 0; - uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight()); - - // coordinates for the center of the compass/circle - if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { - compassX = x + display->getWidth() - compassDiam / 2 - 5; - compassY = y + display->getHeight() / 2; - } else { - compassX = x + display->getWidth() - compassDiam / 2 - 5; - compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2; - } - display->drawCircle(compassX, compassY, compassDiam / 2); - screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); - } -#endif -}; - -#endif \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 60d5a18ac..55206bf4e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -151,6 +151,8 @@ along with this program. If not, see . #define BMA423_ADDR 0x19 #define LSM6DS3_ADDR 0x6A #define BMX160_ADDR 0x69 +#define ICM20948_ADDR 0x69 +#define ICM20948_ADDR_ALT 0x68 // ----------------------------------------------------------------------------- // LED diff --git a/src/detect/ScanI2C.cpp b/src/detect/ScanI2C.cpp index eaba62a78..a9d70edaa 100644 --- a/src/detect/ScanI2C.cpp +++ b/src/detect/ScanI2C.cpp @@ -37,8 +37,8 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const { - ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX}; - return firstOfOrNONE(6, types); + ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948}; + return firstOfOrNONE(7, types); } ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 50959411b..3b49026ce 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -57,7 +57,8 @@ class ScanI2C DFROBOT_LARK, NAU7802, FT6336U, - STK8BAXX + STK8BAXX, + ICM20948 } DeviceType; // typedef uint8_t DeviceAddress; @@ -68,8 +69,9 @@ class ScanI2C } I2CPort; typedef struct DeviceAddress { - I2CPort port; - uint8_t address; + // set default values for ADDRESS_NONE + I2CPort port = I2CPort::NO_I2C; + uint8_t address = 0; explicit DeviceAddress(I2CPort port, uint8_t address); DeviceAddress(); @@ -120,4 +122,4 @@ class ScanI2C private: bool shouldSuppressScreen = false; -}; +}; \ No newline at end of file diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 285210c94..43340765a 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -382,10 +382,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n") SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found\n") - SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n") - SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n"); - SCAN_SIMPLE_CASE(BMX160_ADDR, BMX160, "BMX160 accelerometer found\n"); SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n"); SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found\n"); @@ -398,6 +395,24 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found\n"); SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found\n"); + case ICM20948_ADDR: // same as BMX160_ADDR + case ICM20948_ADDR_ALT: // same as MPU6050_ADDR + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); + if (registerValue == 0xEA) { + type = ICM20948; + LOG_INFO("ICM20948 9-dof motion processor found\n"); + break; + } else if (addr.address == BMX160_ADDR) { + type = BMX160; + LOG_INFO("BMX160 accelerometer found\n"); + break; + } else { + type = MPU6050; + LOG_INFO("MPU6050 accelerometer found\n"); + break; + } + break; + default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); } diff --git a/src/main.cpp b/src/main.cpp index c93cff85f..c2d275177 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,8 +101,8 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr; #include "AmbientLightingThread.h" #include "PowerFSMThread.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR -#include "AccelerometerThread.h" +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#include "motion/AccelerometerThread.h" AccelerometerThread *accelerometerThread = nullptr; #endif @@ -574,6 +574,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948) i2cScanner.reset(); #endif @@ -647,7 +648,7 @@ void setup() #endif #if !MESHTASTIC_EXCLUDE_I2C -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) if (acc_info.type != ScanI2C::DeviceType::NONE) { accelerometerThread = new AccelerometerThread(acc_info.type); } diff --git a/src/main.h b/src/main.h index 52a3fff1f..5722f7cf0 100644 --- a/src/main.h +++ b/src/main.h @@ -56,8 +56,8 @@ extern AudioThread *audioThread; // Global Screen singleton. extern graphics::Screen *screen; -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR -#include "AccelerometerThread.h" +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#include "motion/AccelerometerThread.h" extern AccelerometerThread *accelerometerThread; #endif @@ -86,4 +86,4 @@ void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), rp2040Setup(), clearB meshtastic_DeviceMetadata getDeviceMetadata(); // We default to 4MHz SPI, SPI mode 0 -extern SPISettings spiSettings; +extern SPISettings spiSettings; \ No newline at end of file diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 48048b054..389a0db8d 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -34,8 +34,8 @@ #include "modules/PositionModule.h" #endif -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR -#include "AccelerometerThread.h" +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#include "motion/AccelerometerThread.h" #endif AdminModule *adminModule; diff --git a/src/motion/AccelerometerThread.h b/src/motion/AccelerometerThread.h new file mode 100755 index 000000000..f9cbb49a1 --- /dev/null +++ b/src/motion/AccelerometerThread.h @@ -0,0 +1,149 @@ +#pragma once +#ifndef _ACCELEROMETER_H_ +#define _ACCELEROMETER_H_ + +#include "configuration.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include "../concurrency/OSThread.h" +#include "BMA423Sensor.h" +#include "BMX160Sensor.h" +#include "ICM20948Sensor.h" +#include "LIS3DHSensor.h" +#include "LSM6DS3Sensor.h" +#include "MPU6050Sensor.h" +#include "MotionSensor.h" +#include "STK8XXXSensor.h" + +extern ScanI2C::DeviceAddress accelerometer_found; + +class AccelerometerThread : public concurrency::OSThread +{ + private: + MotionSensor *sensor = nullptr; + bool isInitialised = false; + + public: + explicit AccelerometerThread(ScanI2C::FoundDevice foundDevice) : OSThread("AccelerometerThread") + { + device = foundDevice; + init(); + } + + explicit AccelerometerThread(ScanI2C::DeviceType type) : AccelerometerThread(ScanI2C::FoundDevice{type, accelerometer_found}) + { + } + + void start() + { + init(); + setIntervalFromNow(0); + }; + + protected: + int32_t runOnce() override + { + // Assume we should not keep the board awake + canSleep = true; + + if (isInitialised) + return sensor->runOnce(); + + return MOTION_SENSOR_CHECK_INTERVAL_MS; + } + + private: + ScanI2C::FoundDevice device; + + void init() + { + if (isInitialised) + return; + + if (device.address.port == ScanI2C::I2CPort::NO_I2C || device.address.address == 0 || device.type == ScanI2C::NONE) { + LOG_DEBUG("AccelerometerThread disabling due to no sensors found\n"); + disable(); + return; + } + +#ifndef RAK_4631 + if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) { + LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n"); + disable(); + return; + } +#endif + + switch (device.type) { + case ScanI2C::DeviceType::BMA423: + sensor = new BMA423Sensor(device); + break; + case ScanI2C::DeviceType::MPU6050: + sensor = new MPU6050Sensor(device); + break; + case ScanI2C::DeviceType::BMX160: + sensor = new BMX160Sensor(device); + break; + case ScanI2C::DeviceType::LIS3DH: + sensor = new LIS3DHSensor(device); + break; + case ScanI2C::DeviceType::LSM6DS3: + sensor = new LSM6DS3Sensor(device); + break; + case ScanI2C::DeviceType::STK8BAXX: + sensor = new STK8XXXSensor(device); + break; + case ScanI2C::DeviceType::ICM20948: + sensor = new ICM20948Sensor(device); + break; + default: + disable(); + return; + } + + isInitialised = sensor->init(); + if (!isInitialised) { + clean(); + } + LOG_DEBUG("AccelerometerThread::init %s\n", isInitialised ? "ok" : "failed"); + } + + // Copy constructor (not implemented / included to avoid cppcheck warnings) + AccelerometerThread(const AccelerometerThread &other) : OSThread::OSThread("AccelerometerThread") { this->copy(other); } + + // Destructor (included to avoid cppcheck warnings) + virtual ~AccelerometerThread() { clean(); } + + // Copy assignment (not implemented / included to avoid cppcheck warnings) + AccelerometerThread &operator=(const AccelerometerThread &other) + { + this->copy(other); + return *this; + } + + // Take a very shallow copy (does not copy OSThread state nor the sensor object) + // If for some reason this is ever used, make sure to call init() after any copy + void copy(const AccelerometerThread &other) + { + if (this != &other) { + clean(); + this->device = ScanI2C::FoundDevice(other.device.type, + ScanI2C::DeviceAddress(other.device.address.port, other.device.address.address)); + } + } + + // Cleanup resources + void clean() + { + isInitialised = false; + if (sensor != nullptr) { + delete sensor; + sensor = nullptr; + } + } +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/BMA423Sensor.cpp b/src/motion/BMA423Sensor.cpp new file mode 100755 index 000000000..ec07b7c40 --- /dev/null +++ b/src/motion/BMA423Sensor.cpp @@ -0,0 +1,62 @@ +#include "BMA423Sensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +using namespace MotionSensorI2C; + +BMA423Sensor::BMA423Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +bool BMA423Sensor::init() +{ + if (sensor.begin(deviceAddress(), &MotionSensorI2C::readRegister, &MotionSensorI2C::writeRegister)) { + sensor.configAccelerometer(sensor.RANGE_2G, sensor.ODR_100HZ, sensor.BW_NORMAL_AVG4, sensor.PERF_CONTINUOUS_MODE); + sensor.enableAccelerometer(); + sensor.configInterrupt(BMA4_LEVEL_TRIGGER, BMA4_ACTIVE_HIGH, BMA4_PUSH_PULL, BMA4_OUTPUT_ENABLE, BMA4_INPUT_DISABLE); + +#ifdef BMA423_INT + pinMode(BMA4XX_INT, INPUT); + attachInterrupt( + BMA4XX_INT, + [] { + // Set interrupt to set irq value to true + BMA_IRQ = true; + }, + RISING); // Select the interrupt mode according to the actual circuit +#endif + +#ifdef T_WATCH_S3 + // Need to raise the wrist function, need to set the correct axis + sensor.setReampAxes(sensor.REMAP_TOP_LAYER_RIGHT_CORNER); +#else + sensor.setReampAxes(sensor.REMAP_BOTTOM_LAYER_BOTTOM_LEFT_CORNER); +#endif + // sensor.enableFeature(sensor.FEATURE_STEP_CNTR, true); + sensor.enableFeature(sensor.FEATURE_TILT, true); + sensor.enableFeature(sensor.FEATURE_WAKEUP, true); + // sensor.resetPedometer(); + + // Turn on feature interrupt + sensor.enablePedometerIRQ(); + sensor.enableTiltIRQ(); + + // It corresponds to isDoubleClick interrupt + sensor.enableWakeupIRQ(); + LOG_DEBUG("BMA423Sensor::init ok\n"); + return true; + } + LOG_DEBUG("BMA423Sensor::init failed\n"); + return false; +} + +int32_t BMA423Sensor::runOnce() +{ + if (sensor.readIrqStatus() != DEV_WIRE_NONE) { + if (sensor.isTilt() || sensor.isDoubleTap()) { + wakeScreen(); + return 500; + } + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif \ No newline at end of file diff --git a/src/motion/BMA423Sensor.h b/src/motion/BMA423Sensor.h new file mode 100755 index 000000000..0bc0ddf8c --- /dev/null +++ b/src/motion/BMA423Sensor.h @@ -0,0 +1,26 @@ +#pragma once +#ifndef _BMA423_SENSOR_H_ +#define _BMA423_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include +#include + +class BMA423Sensor : public MotionSensor +{ + private: + SensorBMA423 sensor; + volatile bool BMA_IRQ = false; + + public: + explicit BMA423Sensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/BMX160Sensor.cpp b/src/motion/BMX160Sensor.cpp new file mode 100755 index 000000000..f18c4b586 --- /dev/null +++ b/src/motion/BMX160Sensor.cpp @@ -0,0 +1,100 @@ +#include "BMX160Sensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +BMX160Sensor::BMX160Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +#ifdef RAK_4631 + +// screen is defined in main.cpp +extern graphics::Screen *screen; + +bool BMX160Sensor::init() +{ + if (sensor.begin()) { + // set output data rate + sensor.ODR_Config(BMX160_ACCEL_ODR_100HZ, BMX160_GYRO_ODR_100HZ); + LOG_DEBUG("BMX160Sensor::init ok\n"); + return true; + } + LOG_DEBUG("BMX160Sensor::init failed\n"); + return false; +} + +int32_t BMX160Sensor::runOnce() +{ + sBmx160SensorData_t magAccel; + sBmx160SensorData_t gAccel; + + /* Get a new sensor event */ + sensor.getAllData(&magAccel, NULL, &gAccel); + + // experimental calibrate routine. Limited to between 10 and 30 seconds after boot + if (millis() > 12 * 1000 && millis() < 30 * 1000) { + if (!showingScreen) { + showingScreen = true; + screen->startAlert((FrameCallback)drawFrameCalibration); + } + if (magAccel.x > highestX) + highestX = magAccel.x; + if (magAccel.x < lowestX) + lowestX = magAccel.x; + if (magAccel.y > highestY) + highestY = magAccel.y; + if (magAccel.y < lowestY) + lowestY = magAccel.y; + if (magAccel.z > highestZ) + highestZ = magAccel.z; + if (magAccel.z < lowestZ) + lowestZ = magAccel.z; + } else if (showingScreen && millis() >= 30 * 1000) { + showingScreen = false; + screen->endAlert(); + } + + int highestRealX = highestX - (highestX + lowestX) / 2; + + magAccel.x -= (highestX + lowestX) / 2; + magAccel.y -= (highestY + lowestY) / 2; + magAccel.z -= (highestZ + lowestZ) / 2; + FusionVector ga, ma; + ga.axis.x = -gAccel.x; // default location for the BMX160 is on the rear of the board + ga.axis.y = -gAccel.y; + ga.axis.z = gAccel.z; + ma.axis.x = -magAccel.x; + ma.axis.y = -magAccel.y; + ma.axis.z = magAccel.z * 3; + + // If we're set to one of the inverted positions + if (config.display.compass_orientation > meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270) { + ma = FusionAxesSwap(ma, FusionAxesAlignmentNXNYPZ); + ga = FusionAxesSwap(ga, FusionAxesAlignmentNXNYPZ); + } + + float heading = FusionCompassCalculateHeading(FusionConventionNed, ga, ma); + + switch (config.display.compass_orientation) { + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0_INVERTED: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0: + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED: + heading += 90; + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED: + heading += 180; + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED: + heading += 270; + break; + } + screen->setHeading(heading); + + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/BMX160Sensor.h b/src/motion/BMX160Sensor.h new file mode 100755 index 000000000..26f477271 --- /dev/null +++ b/src/motion/BMX160Sensor.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef _BMX160_SENSOR_H_ +#define _BMX160_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#ifdef RAK_4631 + +#include "Fusion/Fusion.h" +#include + +class BMX160Sensor : public MotionSensor +{ + private: + RAK_BMX160 sensor; + bool showingScreen = false; + float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0; + + public: + explicit BMX160Sensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#else + +// Stub +class BMX160Sensor : public MotionSensor +{ + public: + explicit BMX160Sensor(ScanI2C::FoundDevice foundDevice); +}; + +#endif + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/ICM20948Sensor.cpp b/src/motion/ICM20948Sensor.cpp new file mode 100755 index 000000000..d16968e06 --- /dev/null +++ b/src/motion/ICM20948Sensor.cpp @@ -0,0 +1,186 @@ +#include "ICM20948Sensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +// Flag when an interrupt has been detected +volatile static bool ICM20948_IRQ = false; + +// Interrupt service routine +void ICM20948SetInterrupt() +{ + ICM20948_IRQ = true; +} + +ICM20948Sensor::ICM20948Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +bool ICM20948Sensor::init() +{ + // Initialise the sensor + sensor = ICM20948Singleton::GetInstance(); + if (!sensor->init(device)) + return false; + + // Enable simple Wake on Motion + return sensor->setWakeOnMotion(); +} + +#ifdef ICM_20948_INT_PIN + +int32_t ICM20948Sensor::runOnce() +{ + // Wake on motion using hardware interrupts - this is the most efficient way to check for motion + if (ICM20948_IRQ) { + ICM20948_IRQ = false; + sensor->clearInterrupts(); + wakeScreen(); + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#else + +int32_t ICM20948Sensor::runOnce() +{ + // Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above) + auto status = sensor->setBank(0); + if (sensor->status != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::isWakeOnMotion failed to set bank - %s\n", sensor->statusString()); + return MOTION_SENSOR_CHECK_INTERVAL_MS; + } + + ICM_20948_INT_STATUS_t int_stat; + status = sensor->read(AGB0_REG_INT_STATUS, (uint8_t *)&int_stat, sizeof(ICM_20948_INT_STATUS_t)); + if (status != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::isWakeOnMotion failed to read interrupts - %s\n", sensor->statusString()); + return MOTION_SENSOR_CHECK_INTERVAL_MS; + } + + if (int_stat.WOM_INT != 0) { + // Wake up! + wakeScreen(); + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif + +// ---------------------------------------------------------------------- +// ICM20948Singleton +// ---------------------------------------------------------------------- + +// Get a singleton wrapper for an Sparkfun ICM_20948_I2C +ICM20948Singleton *ICM20948Singleton::GetInstance() +{ + if (pinstance == nullptr) { + pinstance = new ICM20948Singleton(); + } + return pinstance; +} + +ICM20948Singleton::ICM20948Singleton() {} + +ICM20948Singleton::~ICM20948Singleton() {} + +ICM20948Singleton *ICM20948Singleton::pinstance{nullptr}; + +// Initialise the ICM20948 Sensor +bool ICM20948Singleton::init(ScanI2C::FoundDevice device) +{ +#ifdef ICM_20948_DEBUG + // Set ICM_20948_DEBUG to enable helpful debug messages on Serial + enableDebugging(); +#endif + +// startup +#ifdef Wire1 + ICM_20948_Status_e status = + begin(device.address.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire, device.address.address == ICM20948_ADDR ? 1 : 0); +#else + ICM_20948_Status_e status = begin(Wire, device.address.address == ICM20948_ADDR ? 1 : 0); +#endif + if (status != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::init begin - %s\n", statusString()); + return false; + } + + // SW reset to make sure the device starts in a known state + if (swReset() != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::init reset - %s\n", statusString()); + return false; + } + delay(200); + + // Now wake the sensor up + if (sleep(false) != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::init wake - %s\n", statusString()); + return false; + } + + if (lowPower(false) != ICM_20948_Stat_Ok) { + LOG_DEBUG("ICM20948Sensor::init high power - %s\n", statusString()); + return false; + } + +#ifdef ICM_20948_INT_PIN + + // Active low + cfgIntActiveLow(true); + LOG_DEBUG("ICM20948Sensor::init set cfgIntActiveLow - %s\n", statusString()); + + // Push-pull + cfgIntOpenDrain(false); + LOG_DEBUG("ICM20948Sensor::init set cfgIntOpenDrain - %s\n", statusString()); + + // If enabled, *ANY* read will clear the INT_STATUS register. + cfgIntAnyReadToClear(true); + LOG_DEBUG("ICM20948Sensor::init set cfgIntAnyReadToClear - %s\n", statusString()); + + // Latch the interrupt until cleared + cfgIntLatch(true); + LOG_DEBUG("ICM20948Sensor::init set cfgIntLatch - %s\n", statusString()); + + // Set up an interrupt pin with an internal pullup for active low + pinMode(ICM_20948_INT_PIN, INPUT_PULLUP); + + // Set up an interrupt service routine + attachInterrupt(ICM_20948_INT_PIN, ICM20948SetInterrupt, FALLING); + +#endif + return true; +} + +#ifdef ICM_20948_DMP_IS_ENABLED + +// Stub +bool ICM20948Sensor::initDMP() +{ + return false; +} + +#endif + +bool ICM20948Singleton::setWakeOnMotion() +{ + // Set WoM threshold in milli G's + auto status = WOMThreshold(ICM_20948_WOM_THRESHOLD); + if (status != ICM_20948_Stat_Ok) + return false; + + // Enable WoM Logic mode 1 = Compare the current sample with the previous sample + status = WOMLogic(true, 1); + LOG_DEBUG("ICM20948Sensor::init set WOMLogic - %s\n", statusString()); + if (status != ICM_20948_Stat_Ok) + return false; + + // Enable interrupts on WakeOnMotion + status = intEnableWOM(true); + LOG_DEBUG("ICM20948Sensor::init set intEnableWOM - %s\n", statusString()); + return status == ICM_20948_Stat_Ok; + + // Clear any current interrupts + ICM20948_IRQ = false; + clearInterrupts(); + return true; +} + +#endif \ No newline at end of file diff --git a/src/motion/ICM20948Sensor.h b/src/motion/ICM20948Sensor.h new file mode 100755 index 000000000..d5e246c8d --- /dev/null +++ b/src/motion/ICM20948Sensor.h @@ -0,0 +1,96 @@ +#pragma once +#ifndef _ICM_20948_SENSOR_H_ +#define _ICM_20948_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include + +// Set the default gyro scale - dps250, dps500, dps1000, dps2000 +#ifndef ICM_20948_MPU_GYRO_SCALE +#define ICM_20948_MPU_GYRO_SCALE dps250 +#endif + +// Set the default accelerometer scale - gpm2, gpm4, gpm8, gpm16 +#ifndef ICM_20948_MPU_ACCEL_SCALE +#define ICM_20948_MPU_ACCEL_SCALE gpm2 +#endif + +// Define a threshold for Wake on Motion Sensing (0mg to 1020mg) +#ifndef ICM_20948_WOM_THRESHOLD +#define ICM_20948_WOM_THRESHOLD 16U +#endif + +// Define a pin in variant.h to use interrupts to read the ICM-20948 +#ifndef ICM_20948_WOM_THRESHOLD +#define ICM_20948_INT_PIN 255 +#endif + +// Uncomment this line to enable helpful debug messages on Serial +// #define ICM_20948_DEBUG 1 + +// Uncomment this line to enable the onboard digital motion processor (to be added in a future PR) +// #define ICM_20948_DMP_IS_ENABLED 1 + +// Check for a mandatory compiler flag to use the DMP (to be added in a future PR) +#ifdef ICM_20948_DMP_IS_ENABLED +#ifndef ICM_20948_USE_DMP +#error To use the digital motion processor, please either set the compiler flag ICM_20948_USE_DMP or uncomment line 29 (#define ICM_20948_USE_DMP) in ICM_20948_C.h +#endif +#endif + +// The I2C address of the Accelerometer (if found) from main.cpp +extern ScanI2C::DeviceAddress accelerometer_found; + +// Singleton wrapper for the Sparkfun ICM_20948_I2C class +class ICM20948Singleton : public ICM_20948_I2C +{ + private: + static ICM20948Singleton *pinstance; + + protected: + ICM20948Singleton(); + ~ICM20948Singleton(); + + public: + // Create a singleton instance (not thread safe) + static ICM20948Singleton *GetInstance(); + + // Singletons should not be cloneable. + ICM20948Singleton(ICM20948Singleton &other) = delete; + + // Singletons should not be assignable. + void operator=(const ICM20948Singleton &) = delete; + + // Initialise the motion sensor singleton for normal operation + bool init(ScanI2C::FoundDevice device); + + // Enable Wake on Motion interrupts (sensor must be initialised first) + bool setWakeOnMotion(); + +#ifdef ICM_20948_DMP_IS_ENABLED + // Initialise the motion sensor singleton for digital motion processing + bool initDMP(); +#endif +}; + +class ICM20948Sensor : public MotionSensor +{ + private: + ICM20948Singleton *sensor = nullptr; + + public: + explicit ICM20948Sensor(ScanI2C::FoundDevice foundDevice); + + // Initialise the motion sensor + virtual bool init() override; + + // Called each time our sensor gets a chance to run + virtual int32_t runOnce() override; +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/LIS3DHSensor.cpp b/src/motion/LIS3DHSensor.cpp new file mode 100755 index 000000000..e2df60b1c --- /dev/null +++ b/src/motion/LIS3DHSensor.cpp @@ -0,0 +1,36 @@ +#include "LIS3DHSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +LIS3DHSensor::LIS3DHSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +bool LIS3DHSensor::init() +{ + if (sensor.begin(deviceAddress())) { + sensor.setRange(LIS3DH_RANGE_2_G); + // Adjust threshold, higher numbers are less sensitive + sensor.setClick(config.device.double_tap_as_button_press ? 2 : 1, MOTION_SENSOR_CHECK_INTERVAL_MS); + LOG_DEBUG("LIS3DHSensor::init ok\n"); + return true; + } + LOG_DEBUG("LIS3DHSensor::init failed\n"); + return false; +} + +int32_t LIS3DHSensor::runOnce() +{ + if (sensor.getClick() > 0) { + uint8_t click = sensor.getClick(); + if (!config.device.double_tap_as_button_press) { + wakeScreen(); + } + + if (config.device.double_tap_as_button_press && (click & 0x20)) { + buttonPress(); + return 500; + } + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif \ No newline at end of file diff --git a/src/motion/LIS3DHSensor.h b/src/motion/LIS3DHSensor.h new file mode 100755 index 000000000..603d195a8 --- /dev/null +++ b/src/motion/LIS3DHSensor.h @@ -0,0 +1,24 @@ +#pragma once +#ifndef _LIS3DH_SENSOR_H_ +#define _LIS3DH_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include + +class LIS3DHSensor : public MotionSensor +{ + private: + Adafruit_LIS3DH sensor; + + public: + explicit LIS3DHSensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/LSM6DS3Sensor.cpp b/src/motion/LSM6DS3Sensor.cpp new file mode 100755 index 000000000..64ef9a23b --- /dev/null +++ b/src/motion/LSM6DS3Sensor.cpp @@ -0,0 +1,33 @@ +#include "LSM6DS3Sensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +LSM6DS3Sensor::LSM6DS3Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +bool LSM6DS3Sensor::init() +{ + if (sensor.begin_I2C(deviceAddress())) { + + // Default threshold of 2G, less sensitive options are 4, 8 or 16G + sensor.setAccelRange(LSM6DS_ACCEL_RANGE_2_G); + + // Duration is number of occurances needed to trigger, higher threshold is less sensitive + sensor.enableWakeup(config.display.wake_on_tap_or_motion, 1, LSM6DS3_WAKE_THRESH); + + LOG_DEBUG("LSM6DS3Sensor::init ok\n"); + return true; + } + LOG_DEBUG("LSM6DS3Sensor::init failed\n"); + return false; +} + +int32_t LSM6DS3Sensor::runOnce() +{ + if (sensor.shake()) { + wakeScreen(); + return 500; + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif \ No newline at end of file diff --git a/src/motion/LSM6DS3Sensor.h b/src/motion/LSM6DS3Sensor.h new file mode 100755 index 000000000..77069ef3c --- /dev/null +++ b/src/motion/LSM6DS3Sensor.h @@ -0,0 +1,28 @@ +#pragma once +#ifndef _LSM6DS3_SENSOR_H_ +#define _LSM6DS3_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#ifndef LSM6DS3_WAKE_THRESH +#define LSM6DS3_WAKE_THRESH 20 +#endif + +#include + +class LSM6DS3Sensor : public MotionSensor +{ + private: + Adafruit_LSM6DS3TRC sensor; + + public: + explicit LSM6DS3Sensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/MPU6050Sensor.cpp b/src/motion/MPU6050Sensor.cpp new file mode 100755 index 000000000..77aaca46d --- /dev/null +++ b/src/motion/MPU6050Sensor.cpp @@ -0,0 +1,31 @@ +#include "MPU6050Sensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +MPU6050Sensor::MPU6050Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +bool MPU6050Sensor::init() +{ + if (sensor.begin(deviceAddress())) { + // setup motion detection + sensor.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ); + sensor.setMotionDetectionThreshold(1); + sensor.setMotionDetectionDuration(20); + sensor.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized. + sensor.setInterruptPinPolarity(true); + LOG_DEBUG("MPU6050Sensor::init ok\n"); + return true; + } + LOG_DEBUG("MPU6050Sensor::init failed\n"); + return false; +} + +int32_t MPU6050Sensor::runOnce() +{ + if (sensor.getMotionInterruptStatus()) { + wakeScreen(); + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif \ No newline at end of file diff --git a/src/motion/MPU6050Sensor.h b/src/motion/MPU6050Sensor.h new file mode 100755 index 000000000..2e6eafecd --- /dev/null +++ b/src/motion/MPU6050Sensor.h @@ -0,0 +1,24 @@ +#pragma once +#ifndef _MPU6050_SENSOR_H_ +#define _MPU6050_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include + +class MPU6050Sensor : public MotionSensor +{ + private: + Adafruit_MPU6050 sensor; + + public: + explicit MPU6050Sensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp new file mode 100755 index 000000000..20e396bba --- /dev/null +++ b/src/motion/MotionSensor.cpp @@ -0,0 +1,79 @@ +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +// screen is defined in main.cpp +extern graphics::Screen *screen; + +MotionSensor::MotionSensor(ScanI2C::FoundDevice foundDevice) +{ + device.address.address = foundDevice.address.address; + device.address.port = foundDevice.address.port; + device.type = foundDevice.type; + LOG_DEBUG("MotionSensor::MotionSensor port: %s address: 0x%x type: %d\n", + devicePort() == ScanI2C::I2CPort::WIRE1 ? "Wire1" : "Wire", (uint8_t)deviceAddress(), deviceType()); +} + +ScanI2C::DeviceType MotionSensor::deviceType() +{ + return device.type; +} + +uint8_t MotionSensor::deviceAddress() +{ + return device.address.address; +} + +ScanI2C::I2CPort MotionSensor::devicePort() +{ + return device.address.port; +} + +#ifdef RAK_4631 +void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + // int x_offset = display->width() / 2; + // int y_offset = display->height() <= 80 ? 0 : 32; + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_MEDIUM); + display->drawString(x, y, "Calibrating\nCompass"); + int16_t compassX = 0, compassY = 0; + uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight()); + + // coordinates for the center of the compass/circle + if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { + compassX = x + display->getWidth() - compassDiam / 2 - 5; + compassY = y + display->getHeight() / 2; + } else { + compassX = x + display->getWidth() - compassDiam / 2 - 5; + compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2; + } + display->drawCircle(compassX, compassY, compassDiam / 2); + screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); +} +#endif + +#if !MESHTASTIC_EXCLUDE_POWER_FSM +void MotionSensor::wakeScreen() +{ + if (powerFSM.getState() == &stateDARK) { + LOG_DEBUG("MotionSensor::wakeScreen detected\n"); + powerFSM.trigger(EVENT_INPUT); + } +} + +void MotionSensor::buttonPress() +{ + LOG_DEBUG("MotionSensor::buttonPress detected\n"); + powerFSM.trigger(EVENT_PRESS); +} + +#else + +void MotionSensor::wakeScreen() {} + +void MotionSensor::buttonPress() {} + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/MotionSensor.h b/src/motion/MotionSensor.h new file mode 100755 index 000000000..0f7f3479b --- /dev/null +++ b/src/motion/MotionSensor.h @@ -0,0 +1,85 @@ +#pragma once +#ifndef _MOTION_SENSOR_H_ +#define _MOTION_SENSOR_H_ + +#define MOTION_SENSOR_CHECK_INTERVAL_MS 100 +#define MOTION_SENSOR_CLICK_THRESHOLD 40 + +#include "../configuration.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#include "../PowerFSM.h" +#include "../detect/ScanI2C.h" +#include "../graphics/Screen.h" +#include "../graphics/ScreenFonts.h" +#include "../power.h" + +// Base class for motion processing +class MotionSensor +{ + public: + explicit MotionSensor(ScanI2C::FoundDevice foundDevice); + virtual ~MotionSensor(){}; + + // Get the device type + ScanI2C::DeviceType deviceType(); + + // Get the device address + uint8_t deviceAddress(); + + // Get the device port + ScanI2C::I2CPort devicePort(); + + // Initialise the motion sensor + inline virtual bool init() { return false; }; + + // The method that will be called each time our sensor gets a chance to run + // Returns the desired period for next invocation (or RUN_SAME for no change) + // Refer to /src/concurrency/OSThread.h for more information + inline virtual int32_t runOnce() { return MOTION_SENSOR_CHECK_INTERVAL_MS; }; + + protected: + // Turn on the screen when a tap or motion is detected + virtual void wakeScreen(); + + // Register a button press when a double-tap is detected + virtual void buttonPress(); + +#ifdef RAK_4631 + // draw an OLED frame (currently only used by the RAK4631 BMX160 sensor) + static void drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); +#endif + + ScanI2C::FoundDevice device; +}; + +namespace MotionSensorI2C +{ + +static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) +{ + Wire.beginTransmission(address); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom((uint8_t)address, (uint8_t)len); + uint8_t i = 0; + while (Wire.available()) { + data[i++] = Wire.read(); + } + return 0; // Pass +} + +static inline int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) +{ + Wire.beginTransmission(address); + Wire.write(reg); + Wire.write(data, len); + return (0 != Wire.endTransmission()); +} + +} // namespace MotionSensorI2C + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/STK8XXXSensor.cpp b/src/motion/STK8XXXSensor.cpp new file mode 100755 index 000000000..d4d69ef99 --- /dev/null +++ b/src/motion/STK8XXXSensor.cpp @@ -0,0 +1,40 @@ +#include "STK8XXXSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +STK8XXXSensor::STK8XXXSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} + +#ifdef STK8XXX_INT + +volatile static bool STK_IRQ; + +bool STK8XXXSensor::init() +{ + if (sensor.STK8xxx_Initialization(STK8xxx_VAL_RANGE_2G)) { + STK_IRQ = false; + sensor.STK8xxx_Anymotion_init(); + pinMode(STK8XXX_INT, INPUT_PULLUP); + attachInterrupt( + digitalPinToInterrupt(STK8XXX_INT), [] { STK_IRQ = true; }, RISING); + + LOG_DEBUG("STK8XXXSensor::init ok\n"); + return true; + } + LOG_DEBUG("STK8XXXSensor::init failed\n"); + return false; +} + +int32_t STK8XXXSensor::runOnce() +{ + if (STK_IRQ) { + STK_IRQ = false; + if (config.display.wake_on_tap_or_motion) { + wakeScreen(); + } + } + return MOTION_SENSOR_CHECK_INTERVAL_MS; +} + +#endif + +#endif \ No newline at end of file diff --git a/src/motion/STK8XXXSensor.h b/src/motion/STK8XXXSensor.h new file mode 100755 index 000000000..190b916b4 --- /dev/null +++ b/src/motion/STK8XXXSensor.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef _STK8XXX_SENSOR_H_ +#define _STK8XXX_SENSOR_H_ + +#include "MotionSensor.h" + +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C + +#ifdef STK8XXX_INT + +#include + +class STK8XXXSensor : public MotionSensor +{ + private: + STK8xxx sensor; + + public: + explicit STK8XXXSensor(ScanI2C::FoundDevice foundDevice); + virtual bool init() override; + virtual int32_t runOnce() override; +}; + +#else + +// Stub +class STK8XXXSensor : public MotionSensor +{ + public: + explicit STK8XXXSensor(ScanI2C::FoundDevice foundDevice); +}; + +#endif + +#endif + +#endif \ No newline at end of file From 9d7938f57047b8af0bea7cf9422029bd518133d8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 06:25:56 -0500 Subject: [PATCH 193/252] [create-pull-request] automated change (#4865) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- .../generated/meshtastic/module_config.pb.cpp | 1 + .../generated/meshtastic/module_config.pb.h | 45 ++++++++++++++----- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/protobufs b/protobufs index eb915e71f..6ac91926c 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit eb915e71fc907bef97d98760aa4c6c18698b6c32 +Subproject commit 6ac91926c201c15c429cb5d41684f0f40cb7dce8 diff --git a/src/mesh/generated/meshtastic/module_config.pb.cpp b/src/mesh/generated/meshtastic/module_config.pb.cpp index 88a771d5b..e1c33e2c1 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.cpp +++ b/src/mesh/generated/meshtastic/module_config.pb.cpp @@ -60,3 +60,4 @@ PB_BIND(meshtastic_RemoteHardwarePin, meshtastic_RemoteHardwarePin, AUTO) + diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index 2e1985660..d4b82c93b 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -19,6 +19,23 @@ typedef enum _meshtastic_RemoteHardwarePinType { meshtastic_RemoteHardwarePinType_DIGITAL_WRITE = 2 } meshtastic_RemoteHardwarePinType; +typedef enum _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType { + /* Event is triggered if pin is low */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW = 0, + /* Event is triggered if pin is high */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH = 1, + /* Event is triggered when pin goes high to low */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_FALLING_EDGE = 2, + /* Event is triggered when pin goes low to high */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_RISING_EDGE = 3, + /* Event is triggered on every pin state change, low is considered to be + "active" */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_LOW = 4, + /* Event is triggered on every pin state change, high is considered to be + "active" */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH = 5 +} meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType; + /* Baudrate for codec2 voice */ typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud { meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0, @@ -144,11 +161,13 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig { typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { /* Whether the Module is enabled */ bool enabled; - /* Interval in seconds of how often we can send a message to the mesh when a state change is detected */ + /* Interval in seconds of how often we can send a message to the mesh when a + trigger event is detected */ uint32_t minimum_broadcast_secs; - /* Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes - When set to 0, only state changes will be broadcasted - Works as a sort of status heartbeat for peace of mind */ + /* Interval in seconds of how often we should send a message to the mesh + with the current state regardless of trigger events When set to 0, only + trigger events will be broadcasted Works as a sort of status heartbeat + for peace of mind */ uint32_t state_broadcast_secs; /* Send ASCII bell with alert message Useful for triggering ext. notification on bell */ @@ -159,9 +178,8 @@ typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig { char name[20]; /* GPIO pin to monitor for state changes */ uint8_t monitor_pin; - /* Whether or not the GPIO pin state detection is triggered on HIGH (1) - Otherwise LOW (0) */ - bool detection_triggered_high; + /* The type of trigger event to be used */ + meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType detection_trigger_type; /* Whether or not use INPUT_PULLUP mode for GPIO pin Only applicable if the board uses pull-up resistors on the pin */ bool use_pullup; @@ -427,6 +445,10 @@ extern "C" { #define _meshtastic_RemoteHardwarePinType_MAX meshtastic_RemoteHardwarePinType_DIGITAL_WRITE #define _meshtastic_RemoteHardwarePinType_ARRAYSIZE ((meshtastic_RemoteHardwarePinType)(meshtastic_RemoteHardwarePinType_DIGITAL_WRITE+1)) +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_LOW +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MAX meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH +#define _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_ARRAYSIZE ((meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType)(meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_EITHER_EDGE_ACTIVE_HIGH+1)) + #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MAX meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B #define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_AudioConfig_Audio_Baud)(meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1)) @@ -448,6 +470,7 @@ extern "C" { +#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_trigger_type_ENUMTYPE meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType #define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud @@ -473,7 +496,7 @@ extern "C" { #define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0} +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_default {0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} @@ -489,7 +512,7 @@ extern "C" { #define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0} -#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0} +#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_zero {0, 0, 0, 0} #define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0} @@ -523,7 +546,7 @@ extern "C" { #define meshtastic_ModuleConfig_DetectionSensorConfig_send_bell_tag 4 #define meshtastic_ModuleConfig_DetectionSensorConfig_name_tag 5 #define meshtastic_ModuleConfig_DetectionSensorConfig_monitor_pin_tag 6 -#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_triggered_high_tag 7 +#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_trigger_type_tag 7 #define meshtastic_ModuleConfig_DetectionSensorConfig_use_pullup_tag 8 #define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1 #define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2 @@ -688,7 +711,7 @@ X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \ X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \ X(a, STATIC, SINGULAR, STRING, name, 5) \ X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \ -X(a, STATIC, SINGULAR, BOOL, detection_triggered_high, 7) \ +X(a, STATIC, SINGULAR, UENUM, detection_trigger_type, 7) \ X(a, STATIC, SINGULAR, BOOL, use_pullup, 8) #define meshtastic_ModuleConfig_DetectionSensorConfig_CALLBACK NULL #define meshtastic_ModuleConfig_DetectionSensorConfig_DEFAULT NULL From d1138d51e56c14320edadcb31c0f7b116bbb1367 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Wed, 25 Sep 2024 23:27:04 +1200 Subject: [PATCH 194/252] Wrangle module frames with I2C keyboard (#4817) * Only suppress UI nav if module using keyboard input * CardKB combo to dismiss text message and waypoint Currently assigned to Fn + Delete --- src/graphics/Screen.cpp | 58 +++++++++++++++++++++++++---- src/graphics/Screen.h | 8 +++- src/input/InputBroker.h | 1 + src/input/kbI2cBase.cpp | 1 + src/mesh/MeshModule.h | 3 +- src/modules/CannedMessageModule.cpp | 20 ++++++++++ src/modules/CannedMessageModule.h | 1 + 7 files changed, 82 insertions(+), 10 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 19b20e8dc..f8a64cc61 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -48,6 +48,7 @@ along with this program. If not, see . #include "modules/AdminModule.h" #include "modules/ExternalNotificationModule.h" #include "modules/TextMessageModule.h" +#include "modules/WaypointModule.h" #include "sleep.h" #include "target_specific.h" @@ -2112,8 +2113,13 @@ void Screen::setFrames(FrameFocus focus) // Check if the module being drawn has requested focus // We will honor this request later, if setFrames was triggered by a UIFrameEvent MeshModule *m = *i; - if (m->isRequestingFocus()) + if (m->isRequestingFocus()) { fsi.positions.focusedModule = numframes; + } + + // Identify the position of specific modules, if we need to know this later + if (m == waypointModule) + fsi.positions.waypoint = numframes; numframes++; } @@ -2132,8 +2138,8 @@ void Screen::setFrames(FrameFocus focus) #endif // If we have a text message - show it next, unless it's a phone message and we aren't using any special modules - fsi.positions.textMessage = numframes; if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { + fsi.positions.textMessage = numframes; normalFrames[numframes++] = drawTextMessageFrame; } @@ -2235,6 +2241,31 @@ void Screen::setFrameImmediateDraw(FrameCallback *drawFrames) setFastFramerate(); } +// Dismisses the currently displayed screen frame, if possible +// Relevant for text message, waypoint, others in future? +// Triggered with a CardKB keycombo +void Screen::dismissCurrentFrame() +{ + uint8_t currentFrame = ui->getUiState()->currentFrame; + bool dismissed = false; + + if (currentFrame == framesetInfo.positions.textMessage && devicestate.has_rx_text_message) { + LOG_INFO("Dismissing Text Message\n"); + devicestate.has_rx_text_message = false; + dismissed = true; + } + + else if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) { + LOG_DEBUG("Dismissing Waypoint\n"); + devicestate.has_rx_waypoint = false; + dismissed = true; + } + + // If we did make changes to dismiss, we now need to regenerate the frameset + if (dismissed) + setFrames(); +} + void Screen::handleStartFirmwareUpdateScreen() { LOG_DEBUG("showing firmware screen\n"); @@ -2747,12 +2778,23 @@ int Screen::handleInputEvent(const InputEvent *event) } #endif - if (showingNormalScreen && moduleFrames.size() == 0) { - // LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source); - if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { - showPrevFrame(); - } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { - showNextFrame(); + // Use left or right input from a keyboard to move between frames, + // so long as a mesh module isn't using these events for some other purpose + if (showingNormalScreen) { + + // Ask any MeshModules if they're handling keyboard input right now + bool inputIntercepted = false; + for (MeshModule *module : moduleFrames) { + if (module->interceptingKeyboardInput()) + inputIntercepted = true; + } + + // If no modules are using the input, move between frames + if (!inputIntercepted) { + if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) + showPrevFrame(); + else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) + showNextFrame(); } } diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 021b11bda..b2e6e905b 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -454,6 +454,9 @@ class Screen : public concurrency::OSThread void setWelcomeFrames(); + // Dismiss the currently focussed frame, if possible (e.g. text message, waypoint) + void dismissCurrentFrame(); + #ifdef USE_EINK /// Draw an image to remain on E-Ink display after screen off void setScreensaverFrames(FrameCallback einkScreensaver = NULL); @@ -503,11 +506,14 @@ class Screen : public concurrency::OSThread void handleStartFirmwareUpdateScreen(); // Info collected by setFrames method. - // Index location of specific frames. Used to apply the FrameFocus parameter of setFrames + // Index location of specific frames. + // - Used to apply the FrameFocus parameter of setFrames + // - Used to dismiss the currently shown frame (txt; waypoint) by CardKB combo struct FramesetInfo { struct FramePositions { uint8_t fault = 0; uint8_t textMessage = 0; + uint8_t waypoint = 0; uint8_t focusedModule = 0; uint8_t log = 0; uint8_t settings = 0; diff --git a/src/input/InputBroker.h b/src/input/InputBroker.h index 082268f0a..17c621c8a 100644 --- a/src/input/InputBroker.h +++ b/src/input/InputBroker.h @@ -11,6 +11,7 @@ #define INPUT_BROKER_MSG_GPS_TOGGLE 0x9e #define INPUT_BROKER_MSG_MUTE_TOGGLE 0xac #define INPUT_BROKER_MSG_SEND_PING 0xaf +#define INPUT_BROKER_MSG_DISMISS_FRAME 0x8b #define INPUT_BROKER_MSG_LEFT 0xb4 #define INPUT_BROKER_MSG_UP 0xb5 #define INPUT_BROKER_MSG_DOWN 0xb6 diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 1d8154bcf..4fbca76e5 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -296,6 +296,7 @@ int32_t KbI2cBase::runOnce() case 0xac: // fn+m INPUT_BROKER_MSG_MUTE_TOGGLE case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING + case 0x8b: // fn+del INPUT_BROKEN_MSG_DISMISS_FRAME // just pass those unmodified e.inputEvent = ANYKEY; e.kbchar = c; diff --git a/src/mesh/MeshModule.h b/src/mesh/MeshModule.h index c341b301a..7929ba972 100644 --- a/src/mesh/MeshModule.h +++ b/src/mesh/MeshModule.h @@ -79,7 +79,8 @@ class MeshModule meshtastic_AdminMessage *response); #if HAS_SCREEN virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } - virtual bool isRequestingFocus(); // Checked by screen, when regenerating frameset + virtual bool isRequestingFocus(); // Checked by screen, when regenerating frameset + virtual bool interceptingKeyboardInput() { return false; } // Can screen use keyboard for nav, or is module handling input? #endif protected: const char *name; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index a1b9c4dc0..d4d112f90 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -276,6 +276,13 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) showTemporaryMessage("Node Info \nUpdate Sent"); } break; + case INPUT_BROKER_MSG_DISMISS_FRAME: // fn+del: dismiss screen frames like text or waypoint + // Avoid opening the canned message screen frame + // We're only handling the keypress here by convention, this has nothing to do with canned messages + this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + // Attempt to close whatever frame is currently shown on display + screen->dismissCurrentFrame(); + return 0; default: // pass the pressed key // LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); @@ -935,6 +942,19 @@ void CannedMessageModule::drawEnterIcon(OLEDDisplay *display, int x, int y, floa #endif +// Indicate to screen class that module is handling keyboard input specially (at certain times) +// This prevents the left & right keys being used for nav. between screen frames during text entry. +bool CannedMessageModule::interceptingKeyboardInput() +{ + switch (runState) { + case CANNED_MESSAGE_RUN_STATE_DISABLED: + case CANNED_MESSAGE_RUN_STATE_INACTIVE: + return false; + default: + return true; + } +} + void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { char buffer[50]; diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 368574c40..e9dc2bda0 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -114,6 +114,7 @@ class CannedMessageModule : public SinglePortModule, public ObservableshouldDraw(); } virtual Observable *getUIFrameObservable() override { return this; } virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; + virtual bool interceptingKeyboardInput() override; virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request, meshtastic_AdminMessage *response) override; From a7c379961a8606be6101c3ee0d1954d53bc61139 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 07:01:15 -0500 Subject: [PATCH 195/252] New detection sensor trigger type value --- src/mesh/NodeDB.cpp | 2 +- src/modules/DetectionSensorModule.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2820cafd4..869729890 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -472,7 +472,7 @@ void NodeDB::installDefaultModuleConfig() moduleConfig.has_detection_sensor = true; moduleConfig.detection_sensor.enabled = false; - moduleConfig.detection_sensor.detection_triggered_high = true; + moduleConfig.detection_sensor.detection_trigger_type = meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; moduleConfig.detection_sensor.minimum_broadcast_secs = 45; moduleConfig.has_ambient_lighting = true; diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 670fd3208..cb63b2c1a 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -108,5 +108,5 @@ bool DetectionSensorModule::hasDetectionEvent() { bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin); // LOG_DEBUG("Detection Sensor Module: Current state: %i\n", currentState); - return moduleConfig.detection_sensor.detection_triggered_high ? currentState : !currentState; + return moduleConfig.detection_sensor.detection_trigger_type ? currentState : !currentState; } \ No newline at end of file From 6e1616375e3406f5969ab5a1b83723f4293c7da6 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 07:25:45 -0500 Subject: [PATCH 196/252] Trunk update --- .trunk/trunk.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index b20a1ec95..7905ed355 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -8,27 +8,27 @@ plugins: uri: https://github.com/trunk-io/plugins lint: enabled: - - trufflehog@3.81.9 + - trufflehog@3.82.4 - yamllint@1.35.1 - - bandit@1.7.9 - - checkov@3.2.238 + - bandit@1.7.10 + - checkov@3.2.255 - terrascan@1.19.1 - - trivy@0.54.1 + - trivy@0.55.2 #- trufflehog@3.63.2-rc0 - taplo@0.9.3 - - ruff@0.6.2 + - ruff@0.6.7 - isort@5.13.2 - - markdownlint@0.41.0 + - markdownlint@0.42.0 - oxipng@9.1.2 - svgo@3.3.2 - - actionlint@1.7.1 + - actionlint@1.7.2 - flake8@7.1.1 - hadolint@2.12.0 - shfmt@3.6.0 - shellcheck@0.10.0 - black@24.8.0 - git-diff-check - - gitleaks@8.18.4 + - gitleaks@8.19.2 - clang-format@16.0.3 - prettier@3.3.3 ignore: From 9dd769586f1444b9c83ae17132873046c3316a32 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 08:40:33 -0500 Subject: [PATCH 197/252] Version --- .trunk/trunk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 7905ed355..b19f96bb5 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 1.22.3 + version: 1.22.5 plugins: sources: - id: trunk From 26112ba0017606704f06127717810332ba3ee6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 25 Sep 2024 18:56:17 +0200 Subject: [PATCH 198/252] Support T3S3 LR1121 variant --- src/FSCommon.cpp | 6 +++--- src/detect/LoRaRadioType.h | 3 ++- src/main.cpp | 31 ++++++++++++++++++++------- src/mesh/InterfacesTemplates.cpp | 1 + src/mesh/LR1120Interface.cpp | 5 +++++ src/mesh/LR1120Interface.h | 1 + src/mesh/LR1121Interface.cpp | 14 +++++++++++++ src/mesh/LR1121Interface.h | 14 +++++++++++++ src/mesh/LR11x0Interface.cpp | 36 ++++++++++++++++++++++++++------ variants/tlora_t3s3_v1/variant.h | 17 +++++++++++++++ 10 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 src/mesh/LR1121Interface.cpp create mode 100644 src/mesh/LR1121Interface.h diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index d6a542808..24d3f477e 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -370,8 +370,8 @@ void setupSDCard() } uint64_t cardSize = SD.cardSize() / (1024 * 1024); - LOG_DEBUG("SD Card Size: %lluMB\n", cardSize); - LOG_DEBUG("Total space: %llu MB\n", SD.totalBytes() / (1024 * 1024)); - LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024)); + LOG_DEBUG("SD Card Size: %lu MB\n", (uint32_t)cardSize); + LOG_DEBUG("Total space: %lu MB\n", (uint32_t)(SD.totalBytes() / (1024 * 1024))); + LOG_DEBUG("Used space: %lu MB\n", (uint32_t)(SD.usedBytes() / (1024 * 1024))); #endif } \ No newline at end of file diff --git a/src/detect/LoRaRadioType.h b/src/detect/LoRaRadioType.h index 3975153b5..a059a3668 100644 --- a/src/detect/LoRaRadioType.h +++ b/src/detect/LoRaRadioType.h @@ -10,7 +10,8 @@ enum LoRaRadioType { LLCC68_RADIO, SX1280_RADIO, LR1110_RADIO, - LR1120_RADIO + LR1120_RADIO, + LR1121_RADIO }; extern LoRaRadioType radioType; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c2d275177..fa032a209 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,6 +71,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr; #include "LLCC68Interface.h" #include "LR1110Interface.h" #include "LR1120Interface.h" +#include "LR1121Interface.h" #include "RF95Interface.h" #include "SX1262Interface.h" #include "SX1268Interface.h" @@ -880,7 +881,7 @@ void setup() #endif #if defined(RF95_IRQ) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1); if (!rIf->init()) { LOG_WARN("Failed to find RF95 radio\n"); @@ -894,7 +895,7 @@ void setup() #endif #if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && !defined(TCXO_OPTIONAL) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find SX1262 radio\n"); @@ -908,7 +909,7 @@ void setup() #endif #if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && defined(TCXO_OPTIONAL) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { // Try using the specified TCXO voltage rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { @@ -924,7 +925,7 @@ void setup() } } - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { // If specified TCXO voltage fails, attempt to use DIO3 as a reference instea rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { @@ -942,7 +943,7 @@ void setup() #endif #if defined(USE_SX1268) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find SX1268 radio\n"); @@ -956,7 +957,7 @@ void setup() #endif #if defined(USE_LLCC68) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find LLCC68 radio\n"); @@ -970,7 +971,7 @@ void setup() #endif #if defined(USE_LR1110) - if (!rIf) { + if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN); if (!rIf->init()) { LOG_WARN("Failed to find LR1110 radio\n"); @@ -978,6 +979,7 @@ void setup() rIf = NULL; } else { LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n"); + radioType = LR1110_RADIO; } } #endif @@ -991,6 +993,21 @@ void setup() rIf = NULL; } else { LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n"); + radioType = LR1120_RADIO; + } + } +#endif + +#if defined(USE_LR1121) + if (!rIf) { + rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESER_PIN, LR1121_BUSY_PIN); + if (!rIf->init()) { + LOG_WARN("Failed to find LR1121 radio\n"); + delete rIf; + rIf = NULL; + } else { + LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio\n"); + radioType = LR1121_RADIO; } } #endif diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp index f2cac8028..329f0b48e 100644 --- a/src/mesh/InterfacesTemplates.cpp +++ b/src/mesh/InterfacesTemplates.cpp @@ -14,6 +14,7 @@ template class SX126xInterface; template class SX128xInterface; template class LR11x0Interface; template class LR11x0Interface; +template class LR11x0Interface; #ifdef ARCH_STM32WL template class SX126xInterface; #endif diff --git a/src/mesh/LR1120Interface.cpp b/src/mesh/LR1120Interface.cpp index 94f3568f7..07e9e508d 100644 --- a/src/mesh/LR1120Interface.cpp +++ b/src/mesh/LR1120Interface.cpp @@ -6,4 +6,9 @@ LR1120Interface::LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R RADIOLIB_PIN_TYPE busy) : LR11x0Interface(hal, cs, irq, rst, busy) { +} + +bool LR1120Interface::wideLora() +{ + return true; } \ No newline at end of file diff --git a/src/mesh/LR1120Interface.h b/src/mesh/LR1120Interface.h index fc59293ec..a03fa0b20 100644 --- a/src/mesh/LR1120Interface.h +++ b/src/mesh/LR1120Interface.h @@ -10,4 +10,5 @@ class LR1120Interface : public LR11x0Interface public: LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy); + bool wideLora() override; }; \ No newline at end of file diff --git a/src/mesh/LR1121Interface.cpp b/src/mesh/LR1121Interface.cpp new file mode 100644 index 000000000..0d6bba6ea --- /dev/null +++ b/src/mesh/LR1121Interface.cpp @@ -0,0 +1,14 @@ +#include "LR1121Interface.h" +#include "configuration.h" +#include "error.h" + +LR1121Interface::LR1121Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : LR11x0Interface(hal, cs, irq, rst, busy) +{ +} + +bool LR1121Interface::wideLora() +{ + return true; +} \ No newline at end of file diff --git a/src/mesh/LR1121Interface.h b/src/mesh/LR1121Interface.h new file mode 100644 index 000000000..32a6f9492 --- /dev/null +++ b/src/mesh/LR1121Interface.h @@ -0,0 +1,14 @@ +#pragma once + +#include "LR11x0Interface.h" + +/** + * Our adapter for LR1121 wideband radios + */ +class LR1121Interface : public LR11x0Interface +{ + public: + LR1121Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); + bool wideLora() override; +}; \ No newline at end of file diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index e237c354f..9e911107a 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -10,8 +10,14 @@ // 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 LR11x0 power config forgotten) -#ifndef LR11X0_MAX_POWER -#define LR11X0_MAX_POWER 22 +#ifndef LR1110_MAX_POWER +#define LR1110_MAX_POWER 22 +#endif + +// the 2.4G part maxes at 13dBm + +#ifndef LR1120_MAX_POWER +#define LR1120_MAX_POWER 13 #endif template @@ -47,8 +53,12 @@ template bool LR11x0Interface::init() RadioLibInterface::init(); - if (power > LR11X0_MAX_POWER) // Clamp power to maximum defined level - power = LR11X0_MAX_POWER; + if (power > LR1110_MAX_POWER) // Clamp power to maximum defined level + power = LR1110_MAX_POWER; + + if ((power > LR1120_MAX_POWER) && + (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) // clamp again if wide freq range + power = LR1120_MAX_POWER; limitPower(); @@ -65,6 +75,18 @@ template bool LR11x0Interface::init() {LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE, }; +#elif defined(TLORA_T3S3_V1) + static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, + RADIOLIB_NC}; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, + }; + #else // set RF switch configuration for Wio WM1110 @@ -174,8 +196,10 @@ template bool LR11x0Interface::reconfigure() if (err != RADIOLIB_ERR_NONE) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); - if (power > LR11X0_MAX_POWER) // This chip has lower power limits than some - power = LR11X0_MAX_POWER; + if (power > LR1110_MAX_POWER) // This chip has lower power limits than some + power = LR1110_MAX_POWER; + if ((power > LR1120_MAX_POWER) && (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) // 2.4G power limit + power = LR1120_MAX_POWER; err = lora.setOutputPower(power); assert(err == RADIOLIB_ERR_NONE); diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h index 8a1af1ec2..ca10ef5fb 100644 --- a/variants/tlora_t3s3_v1/variant.h +++ b/variants/tlora_t3s3_v1/variant.h @@ -24,6 +24,7 @@ #define USE_RF95 // RFM95/SX127x #define USE_SX1262 #define USE_SX1280 +#define USE_LR1121 #define LORA_SCK 5 #define LORA_MISO 3 @@ -60,3 +61,19 @@ #define SX128X_TXEN 10 #define SX128X_MAX_POWER 3 #endif + +// LR1121 +#ifdef USE_LR1121 +#define LR1121_IRQ_PIN 36 +#define LR1121_NRESER_PIN LORA_RESET +#define LR1121_BUSY_PIN LORA_DIO2 +#define LR1121_SPI_NSS_PIN LORA_CS +#define LR1121_SPI_SCK_PIN LORA_SCK +#define LR1121_SPI_MOSI_PIN LORA_MOSI +#define LR1121_SPI_MISO_PIN LORA_MISO +#define LR11X0_DIO3_TCXO_VOLTAGE 3.0 +#define LR11X0_DIO_AS_RF_SWITCH +#endif + +#define HAS_SDCARD // Have SPI interface SD card slot +#define SDCARD_USE_SPI1 \ No newline at end of file From ed4527cfa529e423cfbabf3990c48efcd713eba0 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Wed, 25 Sep 2024 14:44:05 +0200 Subject: [PATCH 199/252] address review comments --- src/modules/DetectionSensorModule.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 285aba582..eb13616de 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -86,7 +86,8 @@ int32_t DetectionSensorModule::runOnce() // LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin)); - if ((millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs)) { + if (!Throttle::isWithinTimespanMs(lastSentToMesh, + Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs))) { bool isDetected = hasDetectionEvent(); DetectionSensorTriggerVerdict verdict = handlers[moduleConfig.detection_sensor.detection_trigger_type](wasDetected, isDetected); @@ -106,8 +107,9 @@ int32_t DetectionSensorModule::runOnce() // of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state // change detections. if (moduleConfig.detection_sensor.state_broadcast_secs > 0 && - (millis() - lastSentToMesh) >= Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, - default_telemetry_broadcast_interval_secs)) { + !Throttle::isWithinTimespanMs(lastSentToMesh, + Default::getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs, + default_telemetry_broadcast_interval_secs))) { sendCurrentStateMessage(hasDetectionEvent()); return DELAYED_INTERVAL; } From 4128d75ad4b2ab0f3d55040f85ea2f8a77991d7f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 13:50:00 -0500 Subject: [PATCH 200/252] IS_ONE_OF macro to make long chains of conditions more concise and easy to follow (#4860) * Is one of macro * Moar * Whoops * Trunk * isOneOf function backed macro --- src/gps/GPS.cpp | 15 +++++++-------- src/main.cpp | 7 ++++--- src/mesh/NodeDB.h | 1 + src/meshUtils.cpp | 15 +++++++++++++++ src/meshUtils.h | 9 ++++++++- src/modules/PositionModule.cpp | 5 +++-- src/modules/Telemetry/DeviceTelemetry.cpp | 5 +++-- src/platform/nrf52/main-nrf52.cpp | 9 +++++---- 8 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 285f3a2fd..b13ca4b06 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -7,6 +7,7 @@ #include "PowerMon.h" #include "RTC.h" #include "Throttle.h" +#include "meshUtils.h" #include "main.h" // pmu_found #include "sleep.h" @@ -511,7 +512,7 @@ bool GPS::setup() delay(250); _serial_gps->write("$CFGMSG,6,1,0\r\n"); delay(250); - } else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) { + } else if (IS_ONE_OF(gnssModel, GNSS_MODEL_AG3335, GNSS_MODEL_AG3352)) { _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC @@ -553,7 +554,7 @@ bool GPS::setup() } else { LOG_INFO("GNSS module configuration saved!\n"); } - } else if (gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || gnssModel == GNSS_MODEL_UBLOX9) { + } else if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9)) { if (gnssModel == GNSS_MODEL_UBLOX7) { LOG_DEBUG("Setting GPS+SBAS\n"); msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7); @@ -826,8 +827,7 @@ void GPS::setPowerPMU(bool on) void GPS::setPowerUBLOX(bool on, uint32_t sleepMs) { // Abort: if not UBLOX hardware - if (!(gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || - gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)) + if (!IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10)) return; // If waking @@ -910,8 +910,7 @@ void GPS::down() // If not, fallback to GPS_HARDSLEEP instead bool softsleepSupported = false; // U-blox is supported via PMREQ - if (gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || - gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10) + if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10)) softsleepSupported = true; #ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin softsleepSupported = true; @@ -987,8 +986,8 @@ int32_t GPS::runOnce() setConnected(); } else { if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) && - (gnssModel == GNSS_MODEL_UBLOX6 || gnssModel == GNSS_MODEL_UBLOX7 || gnssModel == GNSS_MODEL_UBLOX8 || - gnssModel == GNSS_MODEL_UBLOX9 || gnssModel == GNSS_MODEL_UBLOX10)) { + IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, + GNSS_MODEL_UBLOX10)) { // reset the GPS on next bootup if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) { LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n"); diff --git a/src/main.cpp b/src/main.cpp index c2d275177..87a4db97c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,6 +32,7 @@ #include "graphics/Screen.h" #include "main.h" #include "mesh/generated/meshtastic/config.pb.h" +#include "meshUtils.h" #include "modules/Modules.h" #include "shutdown.h" #include "sleep.h" @@ -627,9 +628,9 @@ void setup() #endif // only play start melody when role is not tracker or sensor - if (config.power.is_power_saving == true && (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || - config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER || - config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)) + if (config.power.is_power_saving == true && + IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER, + meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR)) LOG_DEBUG("Tracker/Sensor: Skipping start melody\n"); else playStartMelody(); diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index c94a7653c..c3ebf3c6e 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -2,6 +2,7 @@ #include "Observer.h" #include +#include #include #include diff --git a/src/meshUtils.cpp b/src/meshUtils.cpp index 4819f6ed7..853193a12 100644 --- a/src/meshUtils.cpp +++ b/src/meshUtils.cpp @@ -80,4 +80,19 @@ bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes) return false; } return true; +} + +bool isOneOf(int item, int count, ...) +{ + va_list args; + va_start(args, count); + bool found = false; + for (int i = 0; i < count; ++i) { + if (item == va_arg(args, int)) { + found = true; + break; + } + } + va_end(args); + return found; } \ No newline at end of file diff --git a/src/meshUtils.h b/src/meshUtils.h index ce063cb6a..aff3976f4 100644 --- a/src/meshUtils.h +++ b/src/meshUtils.h @@ -1,5 +1,8 @@ #pragma once #include "DebugConfiguration.h" +#include +#include +#include #include /// C++ v17+ clamp function, limits a given value to a range defined by lo and hi @@ -17,4 +20,8 @@ char *strnstr(const char *s, const char *find, size_t slen); void printBytes(const char *label, const uint8_t *p, size_t numbytes); // is the memory region filled with a single character? -bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes); \ No newline at end of file +bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes); + +bool isOneOf(int item, int count, ...); + +#define IS_ONE_OF(item, ...) isOneOf(item, sizeof((int[]){__VA_ARGS__}) / sizeof(int), __VA_ARGS__) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 4ba09385d..6ae990bab 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -12,6 +12,7 @@ #include "gps/GeoCoord.h" #include "main.h" #include "mesh/compression/unishox2.h" +#include "meshUtils.h" #include "meshtastic/atak.pb.h" #include "sleep.h" #include "target_specific.h" @@ -347,8 +348,8 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha service->sendToMesh(p, RX_SRC_LOCAL, true); - if ((config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || - config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) && + if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER, + meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) && config.power.is_power_saving) { LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n"); sleepOnNextExecution = true; diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 04789af5e..dd5067784 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -11,14 +11,15 @@ #include "main.h" #include #include +#include #define MAGIC_USB_BATTERY_LEVEL 101 int32_t DeviceTelemetryModule::runOnce() { refreshUptime(); - bool isImpoliteRole = config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR || - config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER; + bool isImpoliteRole = + IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_SENSOR, meshtastic_Config_DeviceConfig_Role_ROUTER); if (((lastSentToMesh == 0) || ((uptimeLastMs - lastSentToMesh) >= Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.device_update_interval, diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp index b28640e65..4023a3cb9 100644 --- a/src/platform/nrf52/main-nrf52.cpp +++ b/src/platform/nrf52/main-nrf52.cpp @@ -12,6 +12,7 @@ #include "PowerMon.h" #include "error.h" #include "main.h" +#include "meshUtils.h" #ifdef BQ25703A_ADDR #include "BQ25713.h" @@ -157,6 +158,7 @@ void nrf52Loop() #ifdef USE_SEMIHOSTING #include +#include /** * Note: this variable is in BSS and therfore false by default. But the gdbinit @@ -261,10 +263,9 @@ void cpuDeepSleep(uint32_t msecToWake) // Sleepy trackers or sensors can low power "sleep" // Don't enter this if we're sleeping portMAX_DELAY, since that's a shutdown event if (msecToWake != portMAX_DELAY && - (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || - config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER || - config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) && - config.power.is_power_saving == true) { + (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER, + meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR) && + config.power.is_power_saving == true)) { sd_power_mode_set(NRF_POWER_MODE_LOWPWR); delay(msecToWake); NVIC_SystemReset(); From d4e8452c60822226755b506685b4a0c6e7bae188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 25 Sep 2024 20:51:11 +0200 Subject: [PATCH 201/252] Tbeams have no ADC (#4871) --- src/Power.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Power.cpp b/src/Power.cpp index bbb6cd2c3..c71d17586 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -147,6 +147,8 @@ using namespace meshtastic; */ static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor +#ifdef BATTERY_PIN + static void adcEnable() { #ifdef ADC_CTRL // enable adc voltage divider when we need to read @@ -171,6 +173,8 @@ static void adcDisable() #endif } +#endif + /** * A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input */ From ac5edf867c64fc1724e01c2ac3d19a0e0501212c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 13:55:04 -0500 Subject: [PATCH 202/252] Create SECURITY.md (#4868) --- SECURITY.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..74be2c181 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,12 @@ +# Security Policy + +## Supported Versions + +| Firmware Version | Supported | +| ------------------- | ------------------ | +| 2.5.x | :white_check_mark: | +| <= 2.4.x | :x: | + +## Reporting a Vulnerability + +We support the private reporting of potential security vulnerabilities. Please go to the Security tab to file a report with a description of the potential vulnerability and reproduction scripts (preferred) or steps, and our developers will review. From 51e4b364b0b1d23813507cf1ee26fec088fb4b27 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 16:18:45 -0500 Subject: [PATCH 203/252] Trunk things --- .devcontainer/devcontainer.json | 9 +++------ .devcontainer/setup.sh | 2 +- .github/workflows/tests.yml | 8 ++++---- SECURITY.md | 8 ++++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e45fd5d93..d83d052b0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -13,16 +13,13 @@ }, "customizations": { "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "platformio.platformio-ide", - ] + "extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"] } }, // Use 'forwardPorts' to make a list of ports inside the container available locally. - "forwardPorts": [ 4403 ], + "forwardPorts": [4403], // Run commands to prepare the container for use - "postCreateCommand": ".devcontainer/setup.sh", + "postCreateCommand": ".devcontainer/setup.sh" } diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index 866a4a417..0b2665f84 100755 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -1,3 +1,3 @@ #!/usr/bin/env sh -git submodule update --init \ No newline at end of file +git submodule update --init diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 925b91215..241598fd0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -65,7 +65,7 @@ jobs: # - uses: actions/setup-python@v5 # with: # python-version: '3.10' - + # pipx install "setuptools<72" - name: Upgrade python tools shell: bash @@ -76,10 +76,10 @@ jobs: - name: Install PlatformIO from script shell: bash - run: | + run: | curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py python3 get-platformio.py - + - name: Upgrade platformio shell: bash run: | @@ -90,7 +90,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 18 - + - name: Setup pnpm uses: pnpm/action-setup@v4 with: diff --git a/SECURITY.md b/SECURITY.md index 74be2c181..fb4d9005a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,10 +2,10 @@ ## Supported Versions -| Firmware Version | Supported | -| ------------------- | ------------------ | -| 2.5.x | :white_check_mark: | -| <= 2.4.x | :x: | +| Firmware Version | Supported | +| ---------------- | ------------------ | +| 2.5.x | :white_check_mark: | +| <= 2.4.x | :x: | ## Reporting a Vulnerability From baf9cf5a5998fbc6b280c7f18debfd57285e7ed8 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 16:19:18 -0500 Subject: [PATCH 204/252] Encapsulate RadioLibInterface receive IRQ logic (#4866) * Encapsulate RadioLibInterface receive IRQ logic * More concise * Trunk --- src/mesh/LR11x0Interface.cpp | 25 ++----------------- src/mesh/LR11x0Interface.h | 3 --- src/mesh/RadioLibInterface.cpp | 22 ++++++++++++++++ src/mesh/RadioLibInterface.h | 4 +++ src/mesh/SX126xInterface.cpp | 24 +----------------- src/mesh/SX126xInterface.h | 3 --- src/mesh/SX128xInterface.cpp | 23 +---------------- src/mesh/SX128xInterface.h | 3 --- .../Telemetry/EnvironmentTelemetry.cpp | 1 - 9 files changed, 30 insertions(+), 78 deletions(-) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index e237c354f..2ec659b06 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -272,29 +272,8 @@ template bool LR11x0Interface::isActivelyReceiving() { // 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(); - bool detected = (irq & (RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED)); - // Handle false detections - if (detected) { - if (!activeReceiveStart) { - activeReceiveStart = millis(); - } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && - !(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID)) { - // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false preamble detection.\n"); - return false; - } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { - // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false header detection.\n"); - return false; - } - } - - // if (detected) LOG_DEBUG("rx detected\n"); - return detected; + return receiveDetected(lora.getIrqStatus(), RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID, + RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED); } template bool LR11x0Interface::sleep() diff --git a/src/mesh/LR11x0Interface.h b/src/mesh/LR11x0Interface.h index 9272f43f0..5711b1f7f 100644 --- a/src/mesh/LR11x0Interface.h +++ b/src/mesh/LR11x0Interface.h @@ -65,7 +65,4 @@ template class LR11x0Interface : public RadioLibInterface virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override; virtual void setStandby() override; - - private: - uint32_t activeReceiveStart = 0; }; diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 6cdb3b99e..0968a6d89 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -129,6 +129,28 @@ bool RadioLibInterface::canSendImmediately() return true; } +bool RadioLibInterface::receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag) +{ + bool detected = (irq & (syncWordHeaderValidFlag | preambleDetectedFlag)); + // Handle false detections + if (detected) { + if (!activeReceiveStart) { + activeReceiveStart = millis(); + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && !(irq & syncWordHeaderValidFlag)) { + // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag + activeReceiveStart = 0; + LOG_DEBUG("Ignore false preamble detection.\n"); + return false; + } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { + // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag + activeReceiveStart = 0; + LOG_DEBUG("Ignore false header detection.\n"); + return false; + } + } + return detected; +} + /// Send a packet (possibly by enquing in a private fifo). This routine will /// later free() the packet to pool. This routine is not allowed to stall because it is called from /// bluetooth comms code. If the txmit queue is empty it might return an error diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index edcbb394f..13bef851a 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -167,6 +167,10 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified meshtastic_QueueStatus getQueueStatus(); protected: + uint32_t activeReceiveStart = 0; + + bool receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag); + /** Do any hardware setup needed on entry into send configuration for the radio. * Subclasses can customize, but must also call this base method */ virtual void configHardwareForSend(); diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 2c6096062..ad1ceeeeb 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -316,29 +316,7 @@ 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 // received and handled the interrupt for reading the packet/handling errors. - - uint16_t irq = lora.getIrqFlags(); - bool detected = (irq & (RADIOLIB_SX126X_IRQ_HEADER_VALID | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED)); - // Handle false detections - if (detected) { - if (!activeReceiveStart) { - activeReceiveStart = millis(); - } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && - !(irq & RADIOLIB_SX126X_IRQ_HEADER_VALID)) { - // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false preamble detection.\n"); - return false; - } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { - // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false header detection.\n"); - return false; - } - } - - // if (detected) LOG_DEBUG("rx detected\n"); - return detected; + return receiveDetected(lora.getIrqFlags(), RADIOLIB_SX126X_IRQ_HEADER_VALID, RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED); } template bool SX126xInterface::sleep() diff --git a/src/mesh/SX126xInterface.h b/src/mesh/SX126xInterface.h index b392cd3e4..c437080c4 100644 --- a/src/mesh/SX126xInterface.h +++ b/src/mesh/SX126xInterface.h @@ -67,7 +67,4 @@ template class SX126xInterface : public RadioLibInterface virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override; virtual void setStandby() override; - - private: - uint32_t activeReceiveStart = 0; }; diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index 270356e26..5c740099c 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -290,28 +290,7 @@ template bool SX128xInterface::isChannelActive() /** Could we send right now (i.e. either not actively receiving or transmitting)? */ template bool SX128xInterface::isActivelyReceiving() { - uint16_t irq = lora.getIrqStatus(); - bool detected = (irq & (RADIOLIB_SX128X_IRQ_HEADER_VALID | RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED)); - - // Handle false detections - if (detected) { - if (!activeReceiveStart) { - activeReceiveStart = millis(); - } else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && - !(irq & RADIOLIB_SX128X_IRQ_HEADER_VALID)) { - // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false preamble detection.\n"); - return false; - } else if (Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) { - // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag - activeReceiveStart = 0; - LOG_DEBUG("Ignore false header detection.\n"); - return false; - } - } - - return detected; + return receiveDetected(lora.getIrqStatus(), RADIOLIB_SX128X_IRQ_HEADER_VALID, RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED); } template bool SX128xInterface::sleep() diff --git a/src/mesh/SX128xInterface.h b/src/mesh/SX128xInterface.h index f7fd35b25..bba31dab4 100644 --- a/src/mesh/SX128xInterface.h +++ b/src/mesh/SX128xInterface.h @@ -67,7 +67,4 @@ template class SX128xInterface : public RadioLibInterface virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override; virtual void setStandby() override; - - private: - uint32_t activeReceiveStart = 0; }; diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 969529881..8f891593a 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -158,7 +158,6 @@ int32_t EnvironmentTelemetryModule::runOnce() result = bme680Sensor.runTrigger(); } - uint32_t now = millis(); if (((lastSentToMesh == 0) || !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( moduleConfig.telemetry.environment_update_interval, From 118809fbfc2bc71782be2d8ba3216766358fdf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 00:13:04 +0200 Subject: [PATCH 205/252] Account for size of Envelope when allocating buffer. (#4819) * Account for size of Envelope when allocating buffer. INFO | 09:29:20 568 [mqtt] Subscribing to msh/2/e/LongFast/+ INFO | 09:29:20 568 [mqtt] Subscribing to msh/2/json/LongFast/+ INFO | 09:29:20 568 [mqtt] Subscribing to msh/2/e/PKI/+ DEBUG | 09:29:20 568 [mqtt] Publishing enqueued MQTT message ERROR | 09:29:20 568 [mqtt] Panic: can't encode protobuf reason='bytes size exceeded' assert failed: size_t pb_encode_to_bytes(uint8_t*, size_t, const pb_msgdesc_t*, const void*) mesh-pb-constants.cpp:18 (0) * save some mem --- src/mqtt/MQTT.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 56af9f663..2ce5cd755 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -32,6 +32,9 @@ static MemoryDynamic staticMqttPool; Allocator &mqttPool = staticMqttPool; +// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets +static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for channel name and 16 for nodeid + void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length) { mqtt->onReceive(topic, payload, length); @@ -482,9 +485,7 @@ void MQTT::publishQueuedMessages() { if (!mqttQueue.isEmpty()) { LOG_DEBUG("Publishing enqueued MQTT message\n"); - // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets meshtastic_ServiceEnvelope *env = mqttQueue.dequeuePtr(0); - static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env); std::string topic; if (env->packet->pki_encrypted) { @@ -570,8 +571,6 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & } if (moduleConfig.mqtt.proxy_to_client_enabled || this->isConnectedDirectly()) { - // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets - static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env); std::string topic = cryptTopic + channelId + "/" + owner.id; LOG_DEBUG("MQTT Publish %s, %u bytes\n", topic.c_str(), numBytes); @@ -666,8 +665,6 @@ void MQTT::perhapsReportToMap() &meshtastic_MapReport_msg, &mapReport); se->packet = mp; - // FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets - static uint8_t bytes[meshtastic_MqttClientProxyMessage_size]; size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, se); LOG_INFO("MQTT Publish map report to %s\n", mapTopic.c_str()); From 12481b568ab2d7cd16b0a42161024583c03d269f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 02:09:06 +0200 Subject: [PATCH 206/252] fix a lot of nuisances reported by cppcheck (#4872) * fix a lot of nuisances reported by cppcheck * fix portduino --- src/SafeFile.h | 2 +- src/gps/GPS.cpp | 2 +- src/graphics/Screen.cpp | 2 +- src/mesh/CryptoEngine.cpp | 4 ++-- src/mesh/ProtobufModule.h | 2 +- src/mesh/aes-ccm.cpp | 2 +- src/mesh/compression/unishox2.cpp | 4 ++-- src/meshUtils.cpp | 3 +-- src/modules/AdminModule.cpp | 4 ++-- src/modules/AdminModule.h | 4 ++-- src/modules/CannedMessageModule.cpp | 8 ++++---- src/modules/Telemetry/EnvironmentTelemetry.cpp | 2 +- src/modules/Telemetry/PowerTelemetry.cpp | 2 +- src/modules/TraceRouteModule.cpp | 2 +- src/modules/WaypointModule.cpp | 2 +- src/mqtt/MQTT.cpp | 4 ++-- src/platform/nrf52/BLEDfuScure.cpp | 3 +-- src/serialization/JSONValue.cpp | 16 ++++++++-------- 18 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/SafeFile.h b/src/SafeFile.h index 7088074cd..61361d312 100644 --- a/src/SafeFile.h +++ b/src/SafeFile.h @@ -24,7 +24,7 @@ class SafeFile : public Print { public: - SafeFile(char const *filepath, bool fullAtomic = false); + explicit SafeFile(char const *filepath, bool fullAtomic = false); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buffer, size_t size); diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index b13ca4b06..569254d02 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -405,9 +405,9 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t bool GPS::setup() { - int msglen = 0; if (!didSerialInit) { + int msglen = 0; if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) { // if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate. diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index f8a64cc61..f95146318 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -2201,7 +2201,7 @@ void Screen::setFrames(FrameFocus focus) case FOCUS_PRESERVE: // If we can identify which type of frame "originalPosition" was, can move directly to it in the new frameset - FramesetInfo &oldFsi = this->framesetInfo; + const FramesetInfo &oldFsi = this->framesetInfo; if (originalPosition == oldFsi.positions.log) ui->switchToFrame(fsi.positions.log); else if (originalPosition == oldFsi.positions.settings) diff --git a/src/mesh/CryptoEngine.cpp b/src/mesh/CryptoEngine.cpp index 79666b321..f705bae03 100644 --- a/src/mesh/CryptoEngine.cpp +++ b/src/mesh/CryptoEngine.cpp @@ -167,12 +167,12 @@ bool CryptoEngine::setDHKey(uint32_t nodeNum) void CryptoEngine::hash(uint8_t *bytes, size_t numBytes) { SHA256 hash; - size_t posn, len; + size_t posn; uint8_t size = numBytes; uint8_t inc = 16; hash.reset(); for (posn = 0; posn < size; posn += inc) { - len = size - posn; + size_t len = size - posn; if (len > inc) len = inc; hash.update(bytes + posn, len); diff --git a/src/mesh/ProtobufModule.h b/src/mesh/ProtobufModule.h index 3b438ebeb..e4d4e5c09 100644 --- a/src/mesh/ProtobufModule.h +++ b/src/mesh/ProtobufModule.h @@ -108,7 +108,7 @@ template class ProtobufModule : protected SinglePortModule T *decoded = NULL; if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) { memset(&scratch, 0, sizeof(scratch)); - auto &p = mp.decoded; + const meshtastic_Data &p = mp.decoded; if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) { decoded = &scratch; } else { diff --git a/src/mesh/aes-ccm.cpp b/src/mesh/aes-ccm.cpp index cd18ae6c5..b9af14fdb 100644 --- a/src/mesh/aes-ccm.cpp +++ b/src/mesh/aes-ccm.cpp @@ -95,7 +95,7 @@ static void aes_ccm_encr(size_t L, const uint8_t *in, size_t len, uint8_t *out, *out++ ^= *in++; } } -static void aes_ccm_encr_auth(size_t M, uint8_t *x, uint8_t *a, uint8_t *auth) +static void aes_ccm_encr_auth(size_t M, const uint8_t *x, uint8_t *a, uint8_t *auth) { size_t i; uint8_t tmp[AES_BLOCK_SIZE]; diff --git a/src/mesh/compression/unishox2.cpp b/src/mesh/compression/unishox2.cpp index 4e239d489..9fc012a76 100644 --- a/src/mesh/compression/unishox2.cpp +++ b/src/mesh/compression/unishox2.cpp @@ -339,7 +339,7 @@ int32_t readUTF8(const char *in, int len, int l, int *utf8len) /// This is also used for Unicode strings \n /// This is a crude implementation that is not optimized. Assuming only short strings \n /// are encoded, this is not much of an issue. -int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, uint8_t *state, const uint8_t usx_hcodes[], +int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, const uint8_t *state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { int j, k; @@ -383,7 +383,7 @@ int matchOccurance(const char *in, int len, int l, char *out, int olen, int *ol, /// This is also used for Unicode strings \n /// This is a crude implementation that is not optimized. Assuming only short strings \n /// are encoded, this is not much of an issue. -int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, struct us_lnk_lst *prev_lines, uint8_t *state, +int matchLine(const char *in, int len, int l, char *out, int olen, int *ol, struct us_lnk_lst *prev_lines, const uint8_t *state, const uint8_t usx_hcodes[], const uint8_t usx_hcode_lens[]) { int last_ol = *ol; diff --git a/src/meshUtils.cpp b/src/meshUtils.cpp index 853193a12..2789a143c 100644 --- a/src/meshUtils.cpp +++ b/src/meshUtils.cpp @@ -60,10 +60,9 @@ char *strnstr(const char *s, const char *find, size_t slen) void printBytes(const char *label, const uint8_t *p, size_t numbytes) { - char *messageBuffer; int labelSize = strlen(label); if (labelSize < 100 && numbytes < 64) { - messageBuffer = new char[labelSize + (numbytes * 3) + 2]; + char *messageBuffer = new char[labelSize + (numbytes * 3) + 2]; strncpy(messageBuffer, label, labelSize); for (size_t i = 0; i < numbytes; i++) snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]); diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 389a0db8d..09311abda 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -1026,7 +1026,7 @@ bool AdminModule::checkPassKey(meshtastic_AdminMessage *res) memcmp(res->session_passkey.bytes, session_passkey, 8) == 0); } -bool AdminModule::messageIsResponse(meshtastic_AdminMessage *r) +bool AdminModule::messageIsResponse(const meshtastic_AdminMessage *r) { if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_owner_response_tag || @@ -1043,7 +1043,7 @@ bool AdminModule::messageIsResponse(meshtastic_AdminMessage *r) return false; } -bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r) +bool AdminModule::messageIsRequest(const meshtastic_AdminMessage *r) { if (r->which_payload_variant == meshtastic_AdminMessage_get_channel_request_tag || r->which_payload_variant == meshtastic_AdminMessage_get_owner_request_tag || diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index 328e1c824..d6c0a7343 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -55,8 +55,8 @@ class AdminModule : public ProtobufModule, public Obser void setPassKey(meshtastic_AdminMessage *res); bool checkPassKey(meshtastic_AdminMessage *res); - bool messageIsResponse(meshtastic_AdminMessage *r); - bool messageIsRequest(meshtastic_AdminMessage *r); + bool messageIsResponse(const meshtastic_AdminMessage *r); + bool messageIsRequest(const meshtastic_AdminMessage *r); }; extern AdminModule *adminModule; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index d4d112f90..e38b7e063 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -78,16 +78,16 @@ int CannedMessageModule::splitConfiguredMessages() int messageIndex = 0; int i = 0; - String messages = cannedMessageModuleConfig.messages; + String canned_messages = cannedMessageModuleConfig.messages; #if defined(T_WATCH_S3) || defined(RAK14014) - String separator = messages.length() ? "|" : ""; + String separator = canned_messages.length() ? "|" : ""; - messages = "[---- Free Text ----]" + separator + messages; + canned_messages = "[---- Free Text ----]" + separator + canned_messages; #endif // collect all the message parts - strncpy(this->messageStore, messages.c_str(), sizeof(this->messageStore)); + strncpy(this->messageStore, canned_messages.c_str(), sizeof(this->messageStore)); // The first message points to the beginning of the store. this->messages[messageIndex++] = this->messageStore; diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 8f891593a..ac291c4ab 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -216,7 +216,7 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket); const char *lastSender = getSenderShortName(*lastMeasurementPacket); - auto &p = lastMeasurementPacket->decoded; + const meshtastic_Data &p = lastMeasurementPacket->decoded; if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) { display->drawString(x, y, "Measurement Error"); LOG_ERROR("Unable to decode last packet"); diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 6130c2c83..d31892042 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -122,7 +122,7 @@ void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *s uint32_t agoSecs = GetTimeyWimeySinceMeshPacket(lastMeasurementPacket); const char *lastSender = getSenderShortName(*lastMeasurementPacket); - auto &p = lastMeasurementPacket->decoded; + const meshtastic_Data &p = lastMeasurementPacket->decoded; if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) { display->setFont(FONT_SMALL); display->drawString(x, y += _fontHeight(FONT_MEDIUM), "Measurement Error"); diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp index 23b4f1ccf..1f652dbf6 100644 --- a/src/modules/TraceRouteModule.cpp +++ b/src/modules/TraceRouteModule.cpp @@ -11,7 +11,7 @@ bool TraceRouteModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, m void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r) { - auto &incoming = p.decoded; + const meshtastic_Data &incoming = p.decoded; // Insert unknown hops if necessary insertUnknownHops(p, r, !incoming.request_id); diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index e1974db73..628d7f62c 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -89,7 +89,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); // Decode the waypoint - meshtastic_MeshPacket &mp = devicestate.rx_waypoint; + const meshtastic_MeshPacket &mp = devicestate.rx_waypoint; meshtastic_Waypoint wp; memset(&wp, 0, sizeof(wp)); if (!pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) { diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 2ce5cd755..891d4b549 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -184,8 +184,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) // PKI messages get accepted even if we can't decrypt if (router && p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && strcmp(e.channel_id, "PKI") == 0) { - meshtastic_NodeInfoLite *tx = nodeDB->getMeshNode(getFrom(p)); - meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to); + const meshtastic_NodeInfoLite *tx = nodeDB->getMeshNode(getFrom(p)); + const meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to); // Only accept PKI messages to us, or if we have both the sender and receiver in our nodeDB, as then it's // likely they discovered each other via a channel we have downlink enabled for if (p->to == nodeDB->getNodeNum() || (tx && tx->has_user && rx && rx->has_user)) diff --git a/src/platform/nrf52/BLEDfuScure.cpp b/src/platform/nrf52/BLEDfuScure.cpp index 8f7a327c4..82cb8905a 100644 --- a/src/platform/nrf52/BLEDfuScure.cpp +++ b/src/platform/nrf52/BLEDfuScure.cpp @@ -48,11 +48,10 @@ extern "C" void bootloader_util_app_start(uint32_t start_addr); static uint16_t crc16(const uint8_t *data_p, uint8_t length) { - uint8_t x; uint16_t crc = 0xFFFF; while (length--) { - x = crc >> 8 ^ *data_p++; + uint8_t x = crc >> 8 ^ *data_p++; x ^= x >> 4; crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); } diff --git a/src/serialization/JSONValue.cpp b/src/serialization/JSONValue.cpp index 51e0c1a3b..b2e9575bf 100644 --- a/src/serialization/JSONValue.cpp +++ b/src/serialization/JSONValue.cpp @@ -37,14 +37,14 @@ #define FREE_ARRAY(x) \ { \ JSONArray::iterator iter; \ - for (iter = x.begin(); iter != x.end(); iter++) { \ + for (iter = x.begin(); iter != x.end(); ++iter) { \ delete *iter; \ } \ } #define FREE_OBJECT(x) \ { \ JSONObject::iterator iter; \ - for (iter = x.begin(); iter != x.end(); iter++) { \ + for (iter = x.begin(); iter != x.end(); ++iter) { \ delete (*iter).second; \ } \ } @@ -430,7 +430,7 @@ JSONValue::JSONValue(const JSONValue &m_source) JSONArray source_array = *m_source.array_value; JSONArray::iterator iter; array_value = new JSONArray(); - for (iter = source_array.begin(); iter != source_array.end(); iter++) + for (iter = source_array.begin(); iter != source_array.end(); ++iter) array_value->push_back(new JSONValue(**iter)); break; } @@ -439,7 +439,7 @@ JSONValue::JSONValue(const JSONValue &m_source) JSONObject source_object = *m_source.object_value; object_value = new JSONObject(); JSONObject::iterator iter; - for (iter = source_object.begin(); iter != source_object.end(); iter++) { + for (iter = source_object.begin(); iter != source_object.end(); ++iter) { std::string name = (*iter).first; (*object_value)[name] = new JSONValue(*((*iter).second)); } @@ -462,12 +462,12 @@ JSONValue::~JSONValue() { if (type == JSONType_Array) { JSONArray::iterator iter; - for (iter = array_value->begin(); iter != array_value->end(); iter++) + for (iter = array_value->begin(); iter != array_value->end(); ++iter) delete *iter; delete array_value; } else if (type == JSONType_Object) { JSONObject::iterator iter; - for (iter = object_value->begin(); iter != object_value->end(); iter++) { + for (iter = object_value->begin(); iter != object_value->end(); ++iter) { delete (*iter).second; } delete object_value; @@ -722,7 +722,7 @@ std::vector JSONValue::ObjectKeys() const while (iter != object_value->end()) { keys.push_back(iter->first); - iter++; + ++iter; } } @@ -865,7 +865,7 @@ std::string JSONValue::StringifyString(const std::string &str) str_out += chr; } - iter++; + ++iter; } str_out += "\""; From 14019f2afa093174a6e1fbf6ef3a0b2154fc997d Mon Sep 17 00:00:00 2001 From: Szetya Date: Thu, 26 Sep 2024 02:09:27 +0200 Subject: [PATCH 207/252] Update WaypointModule.cpp (#4870) In INVERTED display mode, the compass ring was not visible. --- src/modules/WaypointModule.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index 628d7f62c..8194c3d01 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -170,17 +170,17 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, else strncpy(distStr, "? km", sizeof(distStr)); } - + + // Draw compass circle + display->drawCircle(compassX, compassY, compassDiam / 2); + // Undo color-inversion, if set prior to drawing header // Unsure of expected behavior? For now: copy drawNodeInfo if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->setColor(BLACK); } - - // Draw compass circle - display->drawCircle(compassX, compassY, compassDiam / 2); - + // Must be after distStr is populated screen->drawColumns(display, x, y, fields); } -#endif \ No newline at end of file +#endif From 9bebad2dbe3650c133d6efac5e028d52ce7fa12a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 25 Sep 2024 19:54:14 -0500 Subject: [PATCH 208/252] Trunkt --- src/modules/WaypointModule.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index 8194c3d01..a4611e780 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -170,16 +170,16 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, else strncpy(distStr, "? km", sizeof(distStr)); } - + // Draw compass circle display->drawCircle(compassX, compassY, compassDiam / 2); - + // Undo color-inversion, if set prior to drawing header // Unsure of expected behavior? For now: copy drawNodeInfo if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->setColor(BLACK); } - + // Must be after distStr is populated screen->drawColumns(display, x, y, fields); } From 833d7f65bcffbbc991c4b3891541303b9a4e145c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 10:18:45 +0200 Subject: [PATCH 209/252] fix toolchains between old and new ESP32 --- arch/esp32/esp32c6.ini | 2 +- src/configuration.h | 3 +++ src/mesh/wifi/WiFiAPClient.cpp | 4 ++++ src/sleep.cpp | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini index 65c63b299..fad9f3865 100644 --- a/arch/esp32/esp32c6.ini +++ b/arch/esp32/esp32c6.ini @@ -1,6 +1,6 @@ [esp32c6_base] extends = esp32_base -platform = https://github.com/Jason2866/platform-espressif32.git#d8d8f1bcf4bfcae82db2bef70a2b0014f1d2bc13 +platform = https://github.com/Jason2866/platform-espressif32.git#92cd8e2ed8ec8392b32adc89451aecfcbbaa1726 build_flags = ${arduino_base.build_flags} -Wall diff --git a/src/configuration.h b/src/configuration.h index 55206bf4e..3cd93ec83 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -69,6 +69,9 @@ along with this program. If not, see . #ifndef RTC_DATA_ATTR #define RTC_DATA_ATTR #endif +#ifndef EXT_RAM_BSS_ATTR +#define EXT_RAM_BSS_ATTR EXT_RAM_ATTR +#endif // ----------------------------------------------------------------------------- // Regulatory overrides diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index b9535a0b2..c835878d3 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -310,8 +310,12 @@ static void WiFiEvent(WiFiEvent_t event) onNetworkConnected(); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) LOG_INFO("Obtained Local IP6 address: %s\n", WiFi.linkLocalIPv6().toString().c_str()); LOG_INFO("Obtained GlobalIP6 address: %s\n", WiFi.globalIPv6().toString().c_str()); +#else + LOG_INFO("Obtained IP6 address: %s\n", WiFi.localIPv6().toString().c_str()); +#endif break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: LOG_INFO("Lost IP address and IP address is reset to 0\n"); diff --git a/src/sleep.cpp b/src/sleep.cpp index 9554c1ba4..60f83f537 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -451,8 +451,11 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r */ void enableModemSleep() { +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) static esp_pm_config_t esp32_config; // filled with zeros because bss - +#else + static esp_pm_config_esp32_t esp32_config; // filled with zeros because bss +#endif #if CONFIG_IDF_TARGET_ESP32S3 esp32_config.max_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; #elif CONFIG_IDF_TARGET_ESP32S2 From b4bdf604f551d7584abe4babcd4eda0a554edc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 11:08:49 +0200 Subject: [PATCH 210/252] tryfix --- src/mesh/api/ServerAPI.cpp | 4 ++++ src/mqtt/MQTT.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 097f4fa21..8717123f6 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,7 +45,11 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) auto client = U::accept(); +#else + auto client = U::available(); +#endif if (client) { // Close any previous connection (see FIXME in header file) if (openAPI) { diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 4fc0f1989..deb5c182b 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -329,7 +329,7 @@ void MQTT::reconnect() mqttPassword = moduleConfig.mqtt.password; } #if HAS_WIFI && !defined(ARCH_PORTDUINO) -#ifndef CONFIG_IDF_TARGET_ESP32C6 +#if !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(RPI_PICO) if (moduleConfig.mqtt.tls_enabled) { // change default for encrypted to 8883 try { From 11c17ec78c8ab2270b178be1a5425640397810c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 11:39:35 +0200 Subject: [PATCH 211/252] oh well --- src/mesh/api/ServerAPI.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp index 8717123f6..42217428d 100644 --- a/src/mesh/api/ServerAPI.cpp +++ b/src/mesh/api/ServerAPI.cpp @@ -45,8 +45,12 @@ template void APIServerPort::init() template int32_t APIServerPort::runOnce() { +#ifdef ARCH_ESP32 #if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) auto client = U::accept(); +#else + auto client = U::available(); +#endif #else auto client = U::available(); #endif From 8f84a96b6985c586a901ccd443fc2cf25478141f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 12:12:08 +0200 Subject: [PATCH 212/252] refactor: typo fix in macro definition --- src/main.cpp | 4 ++-- variants/ME25LS01-4Y10TD/variant.h | 2 +- variants/ME25LS01-4Y10TD_e-ink/variant.h | 2 +- variants/tracker-t1000-e/variant.h | 2 +- variants/wio-sdk-wm1110/variant.h | 2 +- variants/wio-t1000-s/variant.h | 2 +- variants/wio-tracker-wm1110/variant.h | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 87a4db97c..cbde2ce39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -972,7 +972,7 @@ void setup() #if defined(USE_LR1110) if (!rIf) { - rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN); + rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN); if (!rIf->init()) { LOG_WARN("Failed to find LR1110 radio\n"); delete rIf; @@ -985,7 +985,7 @@ void setup() #if defined(USE_LR1120) if (!rIf) { - rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESER_PIN, LR1120_BUSY_PIN); + rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN); if (!rIf->init()) { LOG_WARN("Failed to find LR1120 radio\n"); delete rIf; diff --git a/variants/ME25LS01-4Y10TD/variant.h b/variants/ME25LS01-4Y10TD/variant.h index 715de8ee6..0da391f0b 100644 --- a/variants/ME25LS01-4Y10TD/variant.h +++ b/variants/ME25LS01-4Y10TD/variant.h @@ -94,7 +94,7 @@ extern "C" { #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK diff --git a/variants/ME25LS01-4Y10TD_e-ink/variant.h b/variants/ME25LS01-4Y10TD_e-ink/variant.h index 0b2b13068..105f9b873 100644 --- a/variants/ME25LS01-4Y10TD_e-ink/variant.h +++ b/variants/ME25LS01-4Y10TD_e-ink/variant.h @@ -117,7 +117,7 @@ static const uint8_t SCK = PIN_SPI_SCK; #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK diff --git a/variants/tracker-t1000-e/variant.h b/variants/tracker-t1000-e/variant.h index 470edd08c..b8eb59b31 100644 --- a/variants/tracker-t1000-e/variant.h +++ b/variants/tracker-t1000-e/variant.h @@ -93,7 +93,7 @@ extern "C" { #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK diff --git a/variants/wio-sdk-wm1110/variant.h b/variants/wio-sdk-wm1110/variant.h index 8f66b1f8c..b6e5c79df 100644 --- a/variants/wio-sdk-wm1110/variant.h +++ b/variants/wio-sdk-wm1110/variant.h @@ -95,7 +95,7 @@ extern "C" { #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK diff --git a/variants/wio-t1000-s/variant.h b/variants/wio-t1000-s/variant.h index fa6ea4abc..8894a40c5 100644 --- a/variants/wio-t1000-s/variant.h +++ b/variants/wio-t1000-s/variant.h @@ -94,7 +94,7 @@ extern "C" { #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK diff --git a/variants/wio-tracker-wm1110/variant.h b/variants/wio-tracker-wm1110/variant.h index de7da9911..32e84485d 100644 --- a/variants/wio-tracker-wm1110/variant.h +++ b/variants/wio-tracker-wm1110/variant.h @@ -91,7 +91,7 @@ extern "C" { #define USE_LR1110 #define LR1110_IRQ_PIN LORA_DIO1 -#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_NRESET_PIN LORA_RESET #define LR1110_BUSY_PIN LORA_DIO2 #define LR1110_SPI_NSS_PIN LORA_CS #define LR1110_SPI_SCK_PIN LORA_SCK From a32233bb92635d15a3998f19269bd6f57834f784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 26 Sep 2024 12:15:37 +0200 Subject: [PATCH 213/252] fixa de typo too --- src/main.cpp | 2 +- variants/tlora_t3s3_v1/variant.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c1ce1cd0c..4e16f565f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1001,7 +1001,7 @@ void setup() #if defined(USE_LR1121) if (!rIf) { - rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESER_PIN, LR1121_BUSY_PIN); + rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN); if (!rIf->init()) { LOG_WARN("Failed to find LR1121 radio\n"); delete rIf; diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h index ca10ef5fb..babe44a58 100644 --- a/variants/tlora_t3s3_v1/variant.h +++ b/variants/tlora_t3s3_v1/variant.h @@ -65,7 +65,7 @@ // LR1121 #ifdef USE_LR1121 #define LR1121_IRQ_PIN 36 -#define LR1121_NRESER_PIN LORA_RESET +#define LR1121_NRESET_PIN LORA_RESET #define LR1121_BUSY_PIN LORA_DIO2 #define LR1121_SPI_NSS_PIN LORA_CS #define LR1121_SPI_SCK_PIN LORA_SCK From 4794cdb12004fc2cb17369297c0b087f546ef3f9 Mon Sep 17 00:00:00 2001 From: TheMalkavien Date: Fri, 27 Sep 2024 00:44:11 +0200 Subject: [PATCH 214/252] Fix (some ?) memory alignment issues on the crypto part - resulting in crashes or strange behavior (#4867) * Replace multiple potentially non aligned pointer dereference (#4855) First step to fix some Crypto crashes or strange behaviors * Makes the two Crypto byte buffers aligned (#4855) Fix #4855, and probably multiple Crypto problems depending on hardware --------- Co-authored-by: Ben Meadors Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com> --- src/mesh/CryptoEngine.cpp | 18 +++++++++--------- src/mesh/Router.cpp | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mesh/CryptoEngine.cpp b/src/mesh/CryptoEngine.cpp index f705bae03..f9d7b4ad2 100644 --- a/src/mesh/CryptoEngine.cpp +++ b/src/mesh/CryptoEngine.cpp @@ -70,8 +70,8 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ long extraNonceTmp = random(); auth = bytesOut + numBytes; extraNonce = (uint32_t *)(auth + 8); - *extraNonce = extraNonceTmp; - LOG_INFO("Random nonce value: %d\n", *extraNonce); + memcpy(extraNonce, &extraNonceTmp, 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; + LOG_INFO("Random nonce value: %d\n", extraNonceTmp); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode); if (node->num < 1 || node->user.public_key.size == 0) { LOG_DEBUG("Node %d or their public_key not found\n", toNode); @@ -80,14 +80,14 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ if (!crypto->setDHKey(toNode)) { return false; } - initNonce(fromNode, packetNum, *extraNonce); + initNonce(fromNode, packetNum, extraNonceTmp); // Calculate the shared secret with the destination node and encrypt printBytes("Attempting encrypt using nonce: ", nonce, 13); printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8); aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut, auth); // this can write up to 15 bytes longer than numbytes past bytesOut - *extraNonce = extraNonceTmp; + memcpy(extraNonce, &extraNonceTmp, 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; return true; } @@ -100,12 +100,12 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut) { uint8_t *auth; // set to last 8 bytes of text? - uint32_t *extraNonce; + uint32_t extraNonce; // pointer was not really used auth = bytes + numBytes - 12; - extraNonce = (uint32_t *)(auth + 8); - LOG_INFO("Random nonce value: %d\n", *extraNonce); + memcpy(&extraNonce, auth +8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8); + LOG_INFO("Random nonce value: %d\n", extraNonce); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode); - + if (node == nullptr || node->num < 1 || node->user.public_key.size == 0) { LOG_DEBUG("Node or its public key not found in database\n"); return false; @@ -115,7 +115,7 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size if (!crypto->setDHKey(fromNode)) { return false; } - initNonce(fromNode, packetNum, *extraNonce); + initNonce(fromNode, packetNum, extraNonce); printBytes("Attempting decrypt using nonce: ", nonce, 13); printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8); return aes_ccm_ad(shared_key, 32, nonce, 8, bytes, numBytes - 12, nullptr, 0, auth, bytesOut); diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index a993ee7c0..f06f54165 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -36,8 +36,8 @@ static MemoryDynamic staticPool; Allocator &packetPool = staticPool; -static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1]; -static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1]; +static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__)); +static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__)); /** * Constructor From 5f6d9c3e27b1bc3d85b0b729ee924399dc4b7486 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 26 Sep 2024 19:33:08 -0500 Subject: [PATCH 215/252] Add pkc test (#4878) * Add a second delay() to get the unit tests running on Rak4631 * Add test_PKC_Decrypt * Remove cruft from test case --- src/mesh/CryptoEngine.cpp | 2 ++ test/test_crypto/test_main.cpp | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/mesh/CryptoEngine.cpp b/src/mesh/CryptoEngine.cpp index f9d7b4ad2..7b5c8f2bd 100644 --- a/src/mesh/CryptoEngine.cpp +++ b/src/mesh/CryptoEngine.cpp @@ -102,6 +102,7 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size uint8_t *auth; // set to last 8 bytes of text? uint32_t extraNonce; // pointer was not really used auth = bytes + numBytes - 12; +#ifndef PIO_UNIT_TESTING memcpy(&extraNonce, auth +8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8); LOG_INFO("Random nonce value: %d\n", extraNonce); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode); @@ -115,6 +116,7 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size if (!crypto->setDHKey(fromNode)) { return false; } +#endif initNonce(fromNode, packetNum, extraNonce); printBytes("Attempting decrypt using nonce: ", nonce, 13); printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8); diff --git a/test/test_crypto/test_main.cpp b/test/test_crypto/test_main.cpp index 0c820178a..cbe366048 100644 --- a/test/test_crypto/test_main.cpp +++ b/test/test_crypto/test_main.cpp @@ -98,7 +98,44 @@ void test_DH25519(void) HexToBytes(private_key, "18630f93598637c35da623a74559cf944374a559114c7937811041fc8605564a"); crypto->setDHPrivateKey(private_key); TEST_ASSERT(!crypto->setDHPublicKey(public_key)); // Weak public key results in 0 shared key + + HexToBytes(public_key, "f7e13a1a067d2f4e1061bf9936fde5be6b0c2494a8f809cbac7f290ef719e91c"); + HexToBytes(private_key, "10300724f3bea134eb1575245ef26ff9b8ccd59849cd98ce1a59002fe1d5986c"); + HexToBytes(expected_shared, "24becd5dfed9e9289ba2e15b82b0d54f8e9aacb72f5e4248c58d8d74b451ce76"); + crypto->setDHPrivateKey(private_key); + TEST_ASSERT(crypto->setDHPublicKey(public_key)); + crypto->hash(crypto->shared_key, 32); + TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 32); } + +void test_PKC_Decrypt(void) +{ + uint8_t private_key[32]; + uint8_t public_key[32]; + uint8_t expected_shared[32]; + uint8_t expected_decrypted[32]; + uint8_t radioBytes[128] __attribute__((__aligned__)); + uint8_t decrypted[128] __attribute__((__aligned__)); + uint8_t expected_nonce[16]; + + uint32_t fromNode; + HexToBytes(public_key, "db18fc50eea47f00251cb784819a3cf5fc361882597f589f0d7ff820e8064457"); + HexToBytes(private_key, "a00330633e63522f8a4d81ec6d9d1e6617f6c8ffd3a4c698229537d44e522277"); + HexToBytes(expected_shared, "777b1545c9d6f9a2"); + HexToBytes(expected_decrypted, "08011204746573744800"); + HexToBytes(radioBytes, "8c646d7a2909000062d6b2136b00000040df24abfcc30a17a3d9046726099e796a1c036a792b"); + HexToBytes(expected_nonce, "62d6b213036a792b2909000000"); + fromNode = 0x0929; + crypto->setDHPrivateKey(private_key); + TEST_ASSERT(crypto->setDHPublicKey(public_key)); + crypto->hash(crypto->shared_key, 32); + crypto->decryptCurve25519(fromNode, 0x13b2d662, 22, radioBytes + 16, decrypted); + TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 8); + TEST_ASSERT_EQUAL_MEMORY(expected_nonce, crypto->nonce, 13); + + TEST_ASSERT_EQUAL_MEMORY(expected_decrypted, decrypted, 10); +} + void test_AES_CTR(void) { uint8_t expected[32]; @@ -137,6 +174,7 @@ void setup() RUN_TEST(test_ECB_AES256); RUN_TEST(test_DH25519); RUN_TEST(test_AES_CTR); + RUN_TEST(test_PKC_Decrypt); } void loop() From 30356dcd970cef2c33e8cbf74ddcf7ba71a6c66c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 26 Sep 2024 19:46:17 -0500 Subject: [PATCH 216/252] Retroactive trunkinate --- src/mesh/CryptoEngine.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mesh/CryptoEngine.cpp b/src/mesh/CryptoEngine.cpp index 7b5c8f2bd..535e11e9b 100644 --- a/src/mesh/CryptoEngine.cpp +++ b/src/mesh/CryptoEngine.cpp @@ -70,7 +70,8 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ long extraNonceTmp = random(); auth = bytesOut + numBytes; extraNonce = (uint32_t *)(auth + 8); - memcpy(extraNonce, &extraNonceTmp, 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; + memcpy(extraNonce, &extraNonceTmp, + 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; LOG_INFO("Random nonce value: %d\n", extraNonceTmp); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode); if (node->num < 1 || node->user.public_key.size == 0) { @@ -87,7 +88,8 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8); aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut, auth); // this can write up to 15 bytes longer than numbytes past bytesOut - memcpy(extraNonce, &extraNonceTmp, 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; + memcpy(extraNonce, &extraNonceTmp, + 4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp; return true; } @@ -99,14 +101,14 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_ */ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut) { - uint8_t *auth; // set to last 8 bytes of text? + uint8_t *auth; // set to last 8 bytes of text? uint32_t extraNonce; // pointer was not really used auth = bytes + numBytes - 12; #ifndef PIO_UNIT_TESTING - memcpy(&extraNonce, auth +8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8); + memcpy(&extraNonce, auth + 8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8); LOG_INFO("Random nonce value: %d\n", extraNonce); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode); - + if (node == nullptr || node->num < 1 || node->user.public_key.size == 0) { LOG_DEBUG("Node or its public key not found in database\n"); return false; From 743fc2e812ff1c7ec40dcbdb1bc1656565febd87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 09:07:14 +0200 Subject: [PATCH 217/252] Update radiolib, fixes CRC bug on SX127x and improves LR11xx support --- platformio.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index b3898ba93..799645306 100644 --- a/platformio.ini +++ b/platformio.ini @@ -88,7 +88,9 @@ monitor_speed = 115200 monitor_filters = direct lib_deps = - jgromes/RadioLib@~7.0.0 + ;jgromes/RadioLib@~7.0.0 + ;7.0.1pre needed for LR1121 support and SX127x CRC Bugfix + https://github.com/jgromes/RadioLib.git#42ae7c92ed584317d7206cfc463ba6260295dbbc https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 From 40932ea06c55d2441ff239fce37de04bc0e6f55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:21:34 +0200 Subject: [PATCH 218/252] update ci builder to include a 'quick' command line option that only outputs 3 random devices or check targets --- bin/generate_ci_matrix.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/generate_ci_matrix.py b/bin/generate_ci_matrix.py index 46398dd59..ea2480c58 100755 --- a/bin/generate_ci_matrix.py +++ b/bin/generate_ci_matrix.py @@ -6,6 +6,7 @@ import configparser import json import os import sys +import random rootdir = "variants/" @@ -39,5 +40,7 @@ for subdir, dirs, files in os.walk(rootdir): "check" in options ): outlist.append(section) - -print(json.dumps(outlist)) +if ("quick" in options): + print(json.dumps(random.sample(outlist, 3))) +else: + print(json.dumps(outlist)) From 39febad63057fd21c8b2a87ed6bcb8872449a646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:25:37 +0200 Subject: [PATCH 219/252] only sample a few builds for CI runs --- .github/workflows/main_matrix.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index ca9f1d37f..bb42f2246 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -20,7 +20,33 @@ on: workflow_dispatch: jobs: + setup-quick: + if: ${{ github.event_name != 'workflow_dispatch' }} + strategy: + fail-fast: false + matrix: + arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, stm32, check] + runs-on: ubuntu-latest + steps: + - id: checkout + uses: actions/checkout@v4 + name: Checkout base + - id: jsonStep + run: | + TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick) + echo "$TARGETS" + echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT + outputs: + esp32: ${{ steps.jsonStep.outputs.esp32 }} + esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }} + esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }} + nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }} + rp2040: ${{ steps.jsonStep.outputs.rp2040 }} + stm32: ${{ steps.jsonStep.outputs.stm32 }} + check: ${{ steps.jsonStep.outputs.check }} + setup: + if: ${{ github.event_name == 'workflow_dispatch' }} strategy: fail-fast: false matrix: From c35d780236fe235721910e74923367a7568e5397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:27:57 +0200 Subject: [PATCH 220/252] only randominze for at least 3 elements --- bin/generate_ci_matrix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/generate_ci_matrix.py b/bin/generate_ci_matrix.py index ea2480c58..4d8759ecc 100755 --- a/bin/generate_ci_matrix.py +++ b/bin/generate_ci_matrix.py @@ -40,7 +40,7 @@ for subdir, dirs, files in os.walk(rootdir): "check" in options ): outlist.append(section) -if ("quick" in options): +if ("quick" in options) & (len(outlist) > 3): print(json.dumps(random.sample(outlist, 3))) else: print(json.dumps(outlist)) From bdb998c7637ab153cc704b407b86b1e5d3f8a786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:33:16 +0200 Subject: [PATCH 221/252] pick either setup or setup-quick as valid --- .github/workflows/main_matrix.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index bb42f2246..730241f50 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -71,13 +71,15 @@ jobs: check: ${{ steps.jsonStep.outputs.check }} check: - needs: setup + needs: [ setup, setup-quick ] strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.check) }} runs-on: ubuntu-latest - if: ${{ github.event_name != 'workflow_dispatch' }} + if: | + always() + && ${{ github.event_name != 'workflow_dispatch' }} steps: - uses: actions/checkout@v4 - name: Build base @@ -87,7 +89,8 @@ jobs: run: bin/check-all.sh ${{ matrix.board }} build-esp32: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32) }} @@ -96,7 +99,8 @@ jobs: board: ${{ matrix.board }} build-esp32-s3: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }} @@ -105,7 +109,8 @@ jobs: board: ${{ matrix.board }} build-esp32-c3: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }} @@ -114,7 +119,8 @@ jobs: board: ${{ matrix.board }} build-nrf52: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }} @@ -123,7 +129,8 @@ jobs: board: ${{ matrix.board }} build-rpi2040: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.rp2040) }} @@ -132,7 +139,8 @@ jobs: board: ${{ matrix.board }} build-stm32: - needs: setup + needs: [ setup, setup-quick ] + if: always() strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.stm32) }} From e02a7d1c68c9efaa7c2d5ed521d7ac2df6680bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:36:00 +0200 Subject: [PATCH 222/252] test if quick is working at all --- .github/workflows/main_matrix.yml | 53 ++++++------------------------- 1 file changed, 10 insertions(+), 43 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 730241f50..ffe777f7e 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -20,8 +20,8 @@ on: workflow_dispatch: jobs: - setup-quick: - if: ${{ github.event_name != 'workflow_dispatch' }} + setup: + if: ${{ github.event_name == 'workflow_dispatch' }} strategy: fail-fast: false matrix: @@ -45,41 +45,14 @@ jobs: stm32: ${{ steps.jsonStep.outputs.stm32 }} check: ${{ steps.jsonStep.outputs.check }} - setup: - if: ${{ github.event_name == 'workflow_dispatch' }} - strategy: - fail-fast: false - matrix: - arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, stm32, check] - runs-on: ubuntu-latest - steps: - - id: checkout - uses: actions/checkout@v4 - name: Checkout base - - id: jsonStep - run: | - TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) - echo "$TARGETS" - echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT - outputs: - esp32: ${{ steps.jsonStep.outputs.esp32 }} - esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }} - esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }} - nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }} - rp2040: ${{ steps.jsonStep.outputs.rp2040 }} - stm32: ${{ steps.jsonStep.outputs.stm32 }} - check: ${{ steps.jsonStep.outputs.check }} - check: - needs: [ setup, setup-quick ] + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.check) }} runs-on: ubuntu-latest - if: | - always() - && ${{ github.event_name != 'workflow_dispatch' }} + if: ${{ github.event_name != 'workflow_dispatch' }} steps: - uses: actions/checkout@v4 - name: Build base @@ -89,8 +62,7 @@ jobs: run: bin/check-all.sh ${{ matrix.board }} build-esp32: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32) }} @@ -99,8 +71,7 @@ jobs: board: ${{ matrix.board }} build-esp32-s3: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }} @@ -109,8 +80,7 @@ jobs: board: ${{ matrix.board }} build-esp32-c3: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }} @@ -119,8 +89,7 @@ jobs: board: ${{ matrix.board }} build-nrf52: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }} @@ -129,8 +98,7 @@ jobs: board: ${{ matrix.board }} build-rpi2040: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.rp2040) }} @@ -139,8 +107,7 @@ jobs: board: ${{ matrix.board }} build-stm32: - needs: [ setup, setup-quick ] - if: always() + needs: setup strategy: fail-fast: false matrix: ${{ fromJson(needs.setup.outputs.stm32) }} From 747046d3351d8ae0a74862e6c294c37e9348405f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:37:15 +0200 Subject: [PATCH 223/252] nope --- .github/workflows/main_matrix.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index ffe777f7e..87ba8cf85 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -21,7 +21,6 @@ on: jobs: setup: - if: ${{ github.event_name == 'workflow_dispatch' }} strategy: fail-fast: false matrix: From ae14ca78703eee9ec4a5c342ff16f21139106041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 10:42:27 +0200 Subject: [PATCH 224/252] the name is somewhat misleading --- .github/workflows/build_stm32.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_stm32.yml b/.github/workflows/build_stm32.yml index 6858812e1..e78178db3 100644 --- a/.github/workflows/build_stm32.yml +++ b/.github/workflows/build_stm32.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Build Raspberry Pi 2040 + - name: Build STM32WL id: build uses: ./.github/actions/build-variant with: From ef223b1195453f89edef1edbc3ff933e835037d2 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Sep 2024 14:55:55 -0500 Subject: [PATCH 225/252] use delete[] to avoid leaking memory (#4883) --- src/meshUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meshUtils.cpp b/src/meshUtils.cpp index 2789a143c..e98a6f1ce 100644 --- a/src/meshUtils.cpp +++ b/src/meshUtils.cpp @@ -68,7 +68,7 @@ void printBytes(const char *label, const uint8_t *p, size_t numbytes) snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]); strcpy(messageBuffer + labelSize + numbytes * 3, "\n"); LOG_DEBUG(messageBuffer); - delete messageBuffer; + delete[] messageBuffer; } } From 482361b2521f1bf28f830f1fe9e5fa85b0ec058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 27 Sep 2024 22:56:42 +0200 Subject: [PATCH 226/252] Fix CAD IRQ setting credited to @GUVWAF --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 799645306..3cdac2ec7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -90,7 +90,7 @@ monitor_filters = direct lib_deps = ;jgromes/RadioLib@~7.0.0 ;7.0.1pre needed for LR1121 support and SX127x CRC Bugfix - https://github.com/jgromes/RadioLib.git#42ae7c92ed584317d7206cfc463ba6260295dbbc + https://github.com/jgromes/RadioLib.git#98ad30eb103d22bb7e75f3cc900597403b0cfb1f https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 @@ -165,4 +165,4 @@ lib_deps = https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee - https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 \ No newline at end of file + https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 From fd1b68513a4f8bb305ffd84d2bf88aecdb3937a3 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Sep 2024 19:29:44 -0500 Subject: [PATCH 227/252] Add sx126x_ant_sw for Native (#4887) Co-authored-by: Ben Meadors --- bin/config-dist.yaml | 3 ++- src/mesh/SX126xInterface.cpp | 4 ++++ src/platform/portduino/PortduinoGlue.cpp | 11 ++++++++++- src/platform/portduino/PortduinoGlue.h | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index 5590ed3b0..3a470b7bb 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -9,6 +9,7 @@ Lora: # IRQ: 16 # Busy: 20 # Reset: 18 +# SX126X_ANT_SW: 6 # Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME! # CS: 7 @@ -153,4 +154,4 @@ Webserver: General: MaxNodes: 200 - MaxMessageQueue: 100 + MaxMessageQueue: 100 \ No newline at end of file diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index ad1ceeeeb..0ca5ef984 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -52,6 +52,10 @@ template bool SX126xInterface::init() float tcxoVoltage = 0; if (settingsMap[dio3_tcxo_voltage]) tcxoVoltage = 1.8; + if (settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { + digitalWrite(settingsMap[sx126x_ant_sw], HIGH); + pinMode(settingsMap[sx126x_ant_sw], OUTPUT); + } // FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE #elif !defined(SX126X_DIO3_TCXO_VOLTAGE) float tcxoVoltage = diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index dc143c661..44f4d5227 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -80,6 +80,7 @@ void portduinoSetup() irq, busy, reset, + sx126x_ant_sw, txen, rxen, displayDC, @@ -180,6 +181,7 @@ void portduinoSetup() settingsMap[reset] = yamlConfig["Lora"]["Reset"].as(RADIOLIB_NC); settingsMap[txen] = yamlConfig["Lora"]["TXen"].as(RADIOLIB_NC); settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as(RADIOLIB_NC); + settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as(RADIOLIB_NC); settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as(0); settingsMap[ch341Quirk] = yamlConfig["Lora"]["ch341_quirk"].as(false); settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as(2000000); @@ -305,6 +307,8 @@ void portduinoSetup() gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. // Need to bind all the configured GPIO pins so they're not simulated + // TODO: Can we do this in the for loop above? + // TODO: If one of these fails, we should log and terminate if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) { if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) { settingsMap[cs] = RADIOLIB_NC; @@ -325,6 +329,11 @@ void portduinoSetup() settingsMap[reset] = RADIOLIB_NC; } } + if (settingsMap.count(sx126x_ant_sw) > 0 && settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[sx126x_ant_sw], gpioChipName) != ERRNO_OK) { + settingsMap[sx126x_ant_sw] = RADIOLIB_NC; + } + } if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) { if (initGPIOPin(settingsMap[user], gpioChipName) != ERRNO_OK) { settingsMap[user] = RADIOLIB_NC; @@ -391,4 +400,4 @@ int initGPIOPin(int pinNum, const std::string gpioChipName) #else return ERRNO_OK; #endif -} +} \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 3fee1db40..59956cb59 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -8,6 +8,7 @@ enum configNames { irq, busy, reset, + sx126x_ant_sw, txen, rxen, dio2_as_rf_switch, @@ -63,4 +64,4 @@ enum { level_error, level_warn, level_info, level_debug, level_trace }; extern std::map settingsMap; extern std::map settingsStrings; extern std::ofstream traceFile; -int initGPIOPin(int pinNum, std::string gpioChipname); +int initGPIOPin(int pinNum, std::string gpioChipname); \ No newline at end of file From 0e0811eccdd9f92311568d72a4336152d2b50eff Mon Sep 17 00:00:00 2001 From: Ken Piper Date: Fri, 27 Sep 2024 19:31:05 -0500 Subject: [PATCH 228/252] Implement GPIO pin allowlist (#4882) --- src/modules/RemoteHardwareModule.cpp | 41 ++++++++++++++++++++++------ src/modules/RemoteHardwareModule.h | 3 ++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index f6b8b2e90..43612e450 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -15,26 +15,44 @@ // a max of one change per 30 seconds #define WATCH_INTERVAL_MSEC (30 * 1000) +// Tests for access to read from or write to a specified GPIO pin +static bool pinAccessAllowed(uint64_t mask, uint8_t pin) +{ + // If undefined pin access is allowed, don't check the pin and just return true + if (moduleConfig.remote_hardware.allow_undefined_pin_access) { + return true; + } + + // Test to see if the pin is in the list of allowed pins and return true if found + if (mask & (1ULL << pin)) { + return true; + } + + return false; +} + /// Set pin modes for every set bit in a mask -static void pinModes(uint64_t mask, uint8_t mode) +static void pinModes(uint64_t mask, uint8_t mode, uint64_t maskAvailable) { for (uint64_t i = 0; i < NUM_GPIOS; i++) { if (mask & (1ULL << i)) { - pinMode(i, mode); + if (pinAccessAllowed(maskAvailable, i)) { + pinMode(i, mode); + } } } } /// Read all the pins mentioned in a mask -static uint64_t digitalReads(uint64_t mask) +static uint64_t digitalReads(uint64_t mask, uint64_t maskAvailable) { uint64_t res = 0; - pinModes(mask, INPUT_PULLUP); + pinModes(mask, INPUT_PULLUP, maskAvailable); for (uint64_t i = 0; i < NUM_GPIOS; i++) { uint64_t m = 1ULL << i; - if (mask & m) { + if (mask & m && pinAccessAllowed(maskAvailable, i)) { if (digitalRead(i)) { res |= m; } @@ -50,6 +68,11 @@ RemoteHardwareModule::RemoteHardwareModule() { // restrict to the gpio channel for rx boundChannel = Channels::gpioChannel; + + // Pull available pin allowlist from config and build a bitmask out of it for fast comparisons later + for (uint8_t i = 0; i < 4; i++) { + availablePins += 1ULL << moduleConfig.remote_hardware.available_pins[i].gpio_pin; + } } bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &req, meshtastic_HardwareMessage *pptr) @@ -63,10 +86,10 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r // Print notification to LCD screen screen->print("Write GPIOs\n"); - pinModes(p.gpio_mask, OUTPUT); + pinModes(p.gpio_mask, OUTPUT, availablePins); for (uint8_t i = 0; i < NUM_GPIOS; i++) { uint64_t mask = 1ULL << i; - if (p.gpio_mask & mask) { + if (p.gpio_mask & mask && pinAccessAllowed(availablePins, i)) { digitalWrite(i, (p.gpio_value & mask) ? 1 : 0); } } @@ -79,7 +102,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r if (screen) screen->print("Read GPIOs\n"); - uint64_t res = digitalReads(p.gpio_mask); + uint64_t res = digitalReads(p.gpio_mask, availablePins); // Send the reply meshtastic_HardwareMessage r = meshtastic_HardwareMessage_init_default; @@ -121,7 +144,7 @@ int32_t RemoteHardwareModule::runOnce() if (moduleConfig.remote_hardware.enabled && watchGpios) { if (!Throttle::isWithinTimespanMs(lastWatchMsec, WATCH_INTERVAL_MSEC)) { - uint64_t curVal = digitalReads(watchGpios); + uint64_t curVal = digitalReads(watchGpios, availablePins); lastWatchMsec = millis(); if (curVal != previousWatch) { diff --git a/src/modules/RemoteHardwareModule.h b/src/modules/RemoteHardwareModule.h index dd39f5b69..4dc31d405 100644 --- a/src/modules/RemoteHardwareModule.h +++ b/src/modules/RemoteHardwareModule.h @@ -17,6 +17,9 @@ class RemoteHardwareModule : public ProtobufModule, /// The timestamp of our last watch event (we throttle watches to 1 change every 30 seconds) uint32_t lastWatchMsec = 0; + /// A bitmask of GPIOs that are exposed to the mesh if undefined access is not enabled + uint64_t availablePins = 0; + public: /** Constructor * name is for debugging output From 884e3f2e35ab1eee98748da0f90f83b4ced372d6 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 27 Sep 2024 20:03:51 -0500 Subject: [PATCH 229/252] Remove remote hardware from release --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 3cdac2ec7..81aa2041e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -81,6 +81,7 @@ build_flags = -Wno-missing-field-initializers -DRADIOLIB_EXCLUDE_APRS -DRADIOLIB_EXCLUDE_LORAWAN -DMESHTASTIC_EXCLUDE_DROPZONE=1 + -DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1 -DBUILD_EPOCH=$UNIX_TIME ;-D OLED_PL From 8efc15f4d9c4a2b177fdbbc0c3389eb1c5394c8c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 27 Sep 2024 20:09:53 -0500 Subject: [PATCH 230/252] Ignore seen phoneapi packets (#4888) * Ignore PhoneAPI packet if it's been seen * ignoramus * Also keep track of the last 20 packet IDs * Fill * Make this match the nimble one * Add the log too * Ignore zero ID packets * Remove message entirely * TRunkt --- .trunk/trunk.yaml | 2 +- src/mesh/NodeDB.h | 1 + src/mesh/PhoneAPI.cpp | 30 ++++++++++++++++++++++++--- src/mesh/PhoneAPI.h | 3 +++ src/nimble/NimbleBluetooth.cpp | 11 +++++++++- src/platform/nrf52/NRF52Bluetooth.cpp | 11 +++++++++- 6 files changed, 52 insertions(+), 6 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index b19f96bb5..79cd91af5 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -8,7 +8,7 @@ plugins: uri: https://github.com/trunk-io/plugins lint: enabled: - - trufflehog@3.82.4 + - trufflehog@3.82.5 - yamllint@1.35.1 - bandit@1.7.10 - checkov@3.2.255 diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index c3ebf3c6e..1be61759a 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -8,6 +8,7 @@ #include "MeshTypes.h" #include "NodeStatus.h" +#include "configuration.h" #include "mesh-pb-constants.h" #include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 103572990..ecc5effe9 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -8,6 +8,7 @@ #include "FSCommon.h" #include "MeshService.h" #include "NodeDB.h" +#include "PacketHistory.h" #include "PhoneAPI.h" #include "PowerFSM.h" #include "RadioInterface.h" @@ -31,6 +32,7 @@ PhoneAPI::PhoneAPI() { lastContactMsec = millis(); + std::fill(std::begin(recentToRadioPacketIds), std::end(recentToRadioPacketIds), 0); } PhoneAPI::~PhoneAPI() @@ -109,8 +111,6 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); // As long as the phone keeps talking to us, don't let the radio go to sleep lastContactMsec = millis(); - // return (lastContactMsec != 0) && - memset(&toRadioScratch, 0, sizeof(toRadioScratch)); if (pb_decode_from_bytes(buf, bufLength, &meshtastic_ToRadio_msg, &toRadioScratch)) { switch (toRadioScratch.which_payload_variant) { @@ -572,12 +572,35 @@ void PhoneAPI::sendNotification(meshtastic_LogRecord_Level level, uint32_t reply service->sendClientNotification(cn); } +bool PhoneAPI::wasSeenRecently(uint32_t id) +{ + for (int i = 0; i < 20; i++) { + if (recentToRadioPacketIds[i] == id) { + return true; + } + if (recentToRadioPacketIds[i] == 0) { + recentToRadioPacketIds[i] = id; + return false; + } + } + // If the array is full, shift all elements to the left and add the new id at the end + memmove(recentToRadioPacketIds, recentToRadioPacketIds + 1, (19) * sizeof(uint32_t)); + recentToRadioPacketIds[19] = id; + return false; +} + /** * Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool */ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) { printPacket("PACKET FROM PHONE", &p); + + if (p.id > 0 && wasSeenRecently(p.id)) { + LOG_DEBUG("Ignoring packet from phone, already seen recently\n"); + return false; + } + if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] && Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) { LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); @@ -586,7 +609,8 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) } else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] && Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) { LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum); - sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds"); + // FIXME: Figure out why this continues to happen + // sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds"); return false; } lastPortNumToRadio[p.decoded.portnum] = millis(); diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index cf6f55416..3247fee5c 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -52,6 +52,7 @@ class PhoneAPI // Hashmap of timestamps for last time we received a packet on the API per portnum std::unordered_map lastPortNumToRadio; + uint32_t recentToRadioPacketIds[20]; // Last 20 ToRadio MeshPacket IDs we have seen /** * Each packet sent to the phone has an incrementing count @@ -159,6 +160,8 @@ class PhoneAPI /// begin a new connection void handleStartConfig(); + bool wasSeenRecently(uint32_t packetId); + /** * Handle a packet that the phone wants us to send. We can write to it but can not keep a reference to it * @return true true if a packet was queued for sending diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 03fa80415..eedfe1a71 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -44,6 +44,9 @@ static BluetoothPhoneAPI *bluetoothPhoneAPI; * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) */ +// Last ToRadio value received from the phone +static uint8_t lastToRadio[MAX_TO_FROM_RADIO_SIZE]; + class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks { virtual void onWrite(NimBLECharacteristic *pCharacteristic) @@ -51,7 +54,13 @@ class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks LOG_INFO("To Radio onwrite\n"); auto val = pCharacteristic->getValue(); - bluetoothPhoneAPI->handleToRadio(val.data(), val.length()); + if (memcmp(lastToRadio, val.data(), val.length()) != 0) { + LOG_DEBUG("New ToRadio packet\n"); + memcpy(lastToRadio, val.data(), val.length()); + bluetoothPhoneAPI->handleToRadio(val.data(), val.length()); + } else { + LOG_DEBUG("Dropping duplicate ToRadio packet we just saw\n"); + } } }; diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index ec3ff3e8d..fbc0728d7 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -141,10 +141,19 @@ void onFromRadioAuthorize(uint16_t conn_hdl, BLECharacteristic *chr, ble_gatts_e } authorizeRead(conn_hdl); } +// Last ToRadio value received from the phone +static uint8_t lastToRadio[MAX_TO_FROM_RADIO_SIZE]; + void onToRadioWrite(uint16_t conn_hdl, BLECharacteristic *chr, uint8_t *data, uint16_t len) { LOG_INFO("toRadioWriteCb data %p, len %u\n", data, len); - bluetoothPhoneAPI->handleToRadio(data, len); + if (memcmp(lastToRadio, data, len) != 0) { + LOG_DEBUG("New ToRadio packet\n"); + memcpy(lastToRadio, data, len); + bluetoothPhoneAPI->handleToRadio(data, len); + } else { + LOG_DEBUG("Dropping duplicate ToRadio packet we just saw\n"); + } } void setupMeshService(void) From 36a66df923d99b2d2bd6287c2a9fd8f8009802e3 Mon Sep 17 00:00:00 2001 From: David Huang Date: Fri, 27 Sep 2024 21:52:12 -0500 Subject: [PATCH 231/252] Don't log "Setting DIO2 as RF switch" unless we're actually going to do it. Also, if there's an error setting DIO2, log the error code. --- src/mesh/SX126xInterface.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 0ca5ef984..30024daf0 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -103,21 +103,19 @@ template bool SX126xInterface::init() LOG_DEBUG("Current limit set to %f\n", currentLimit); LOG_DEBUG("Current limit set result %d\n", res); -#ifdef SX126X_DIO2_AS_RF_SWITCH - LOG_DEBUG("Setting DIO2 as RF switch\n"); - bool dio2AsRfSwitch = true; -#elif defined(ARCH_PORTDUINO) - bool dio2AsRfSwitch = false; - if (settingsMap[dio2_as_rf_switch]) { - LOG_DEBUG("Setting DIO2 as RF switch\n"); - dio2AsRfSwitch = true; - } -#else - LOG_DEBUG("Setting DIO2 as not RF switch\n"); - bool dio2AsRfSwitch = false; -#endif if (res == RADIOLIB_ERR_NONE) { +#ifdef SX126X_DIO2_AS_RF_SWITCH + bool dio2AsRfSwitch = true; +#elif defined(ARCH_PORTDUINO) + bool dio2AsRfSwitch = false; + if (settingsMap[dio2_as_rf_switch]) { + dio2AsRfSwitch = true; + } +#else + bool dio2AsRfSwitch = false; +#endif res = lora.setDio2AsRfSwitch(dio2AsRfSwitch); + LOG_DEBUG("Set DIO2 as %sRF switch, result: %d\n", dio2AsRfSwitch ? "" : "not ", res); } // 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 From 7f59cb54ef2187673ef43c273ccf9557156bffc6 Mon Sep 17 00:00:00 2001 From: David Huang Date: Fri, 27 Sep 2024 23:35:57 -0500 Subject: [PATCH 232/252] Instead of having LipoBatteryLevel forward requests to AnalogBatteryLevel if there's no Lipo sensor, just have lipoInit return false. The forwarding didn't work because it never called analogInit. --- src/Power.cpp | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index c71d17586..6ed937648 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -1068,10 +1068,9 @@ bool Power::axpChipInit() #if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) /** - * Wrapper class for an I2C MAX17048 Lipo battery sensor. If there is no - * I2C sensor present, the class falls back to analog battery sensing + * Wrapper class for an I2C MAX17048 Lipo battery sensor. */ -class LipoBatteryLevel : public AnalogBatteryLevel +class LipoBatteryLevel : public HasBatteryLevel { private: MAX17048Singleton *max17048 = nullptr; @@ -1096,52 +1095,27 @@ class LipoBatteryLevel : public AnalogBatteryLevel /** * Battery state of charge, from 0 to 100 or -1 for unknown */ - virtual int getBatteryPercent() override - { - if (!max17048->isInitialised()) - return AnalogBatteryLevel::getBatteryPercent(); - return max17048->getBusBatteryPercent(); - } + virtual int getBatteryPercent() override { return max17048->getBusBatteryPercent(); } /** * The raw voltage of the battery in millivolts, or NAN if unknown */ - virtual uint16_t getBattVoltage() override - { - if (!max17048->isInitialised()) - return AnalogBatteryLevel::getBattVoltage(); - return max17048->getBusVoltageMv(); - } + virtual uint16_t getBattVoltage() override { return max17048->getBusVoltageMv(); } /** * return true if there is a battery installed in this unit */ - virtual bool isBatteryConnect() override - { - if (!max17048->isInitialised()) - return AnalogBatteryLevel::isBatteryConnect(); - return max17048->isBatteryConnected(); - } + virtual bool isBatteryConnect() override { return max17048->isBatteryConnected(); } /** * return true if there is an external power source detected */ - virtual bool isVbusIn() override - { - if (!max17048->isInitialised()) - return AnalogBatteryLevel::isVbusIn(); - return max17048->isExternallyPowered(); - } + virtual bool isVbusIn() override { return max17048->isExternallyPowered(); } /** * return true if the battery is currently charging */ - virtual bool isCharging() override - { - if (!max17048->isInitialised()) - return AnalogBatteryLevel::isCharging(); - return max17048->isBatteryCharging(); - } + virtual bool isCharging() override { return max17048->isBatteryCharging(); } }; LipoBatteryLevel lipoLevel; @@ -1153,6 +1127,8 @@ bool Power::lipoInit() { bool result = lipoLevel.runOnce(); LOG_DEBUG("Power::lipoInit lipo sensor is %s\n", result ? "ready" : "not ready yet"); + if (!result) + return false; batteryLevel = &lipoLevel; return true; } From 48fa9f2242641e27a51b2f928f99ee648529194e Mon Sep 17 00:00:00 2001 From: GUVWAF Date: Sat, 28 Sep 2024 09:34:37 +0200 Subject: [PATCH 233/252] Only check threshold if GPS softsleep is supported --- src/gps/GPS.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 569254d02..fdad2b24b 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -916,20 +916,22 @@ void GPS::down() softsleepSupported = true; #endif - // How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP? - // Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050 - // https://www.desmos.com/calculator/6gvjghoumr - // This is not particularly accurate, but probably an impromevement over a single, fixed threshold - uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22)); - LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep\n", hardsleepThreshold / 1000); - - // If update interval too short: softsleep (if supported by hardware) - if (softsleepSupported && updateInterval < hardsleepThreshold) - setPowerState(GPS_SOFTSLEEP, sleepTime); + if (softsleepSupported) { + // How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP? + // Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050 + // https://www.desmos.com/calculator/6gvjghoumr + // This is not particularly accurate, but probably an impromevement over a single, fixed threshold + uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22)); + LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep\n", hardsleepThreshold / 1000); + // If update interval too short: softsleep (if supported by hardware) + if (updateInterval < hardsleepThreshold) { + setPowerState(GPS_SOFTSLEEP, sleepTime); + return; + } + } // If update interval long enough (or softsleep unsupported): hardsleep instead - else - setPowerState(GPS_HARDSLEEP, sleepTime); + setPowerState(GPS_HARDSLEEP, sleepTime); } } From 5ff265c196ad1015f9ab537d330b307e266cc372 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Sep 2024 21:13:53 -0500 Subject: [PATCH 234/252] First stab at enabling store and forward for Native --- src/memGet.cpp | 4 ++++ src/modules/{esp32 => }/StoreForwardModule.cpp | 12 ++++++++---- src/modules/{esp32 => }/StoreForwardModule.h | 0 3 files changed, 12 insertions(+), 4 deletions(-) rename src/modules/{esp32 => }/StoreForwardModule.cpp (98%) rename src/modules/{esp32 => }/StoreForwardModule.h (100%) diff --git a/src/memGet.cpp b/src/memGet.cpp index e982ef7ee..ef1102f1e 100644 --- a/src/memGet.cpp +++ b/src/memGet.cpp @@ -57,6 +57,8 @@ uint32_t MemGet::getFreePsram() { #ifdef ARCH_ESP32 return ESP.getFreePsram(); +#elif defined(ARCH_PORTDUINO) + return 4194252; #else return 0; #endif @@ -71,6 +73,8 @@ uint32_t MemGet::getPsramSize() { #ifdef ARCH_ESP32 return ESP.getPsramSize(); +#elif defined(ARCH_PORTDUINO) + return 4194252; #else return 0; #endif diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/StoreForwardModule.cpp similarity index 98% rename from src/modules/esp32/StoreForwardModule.cpp rename to src/modules/StoreForwardModule.cpp index 51ec2a942..29fbd8d92 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/StoreForwardModule.cpp @@ -35,7 +35,7 @@ uint32_t heartbeatInterval = 60; // Default to 60 seconds, adjust as needed int32_t StoreForwardModule::runOnce() { -#ifdef ARCH_ESP32 +#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) if (moduleConfig.store_forward.enabled && is_server) { // Send out the message queue. if (this->busy) { @@ -82,8 +82,12 @@ void StoreForwardModule::populatePSRAM() uint32_t numberOfPackets = (this->records ? this->records : (((memGet.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct))); this->records = numberOfPackets; - +#if defined(ARCH_ESP32) this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct))); +#elif defined(ARCH_PORTDUINO) + this->packetHistory = static_cast(calloc(numberOfPackets, sizeof(PacketHistoryStruct))); + +#endif LOG_DEBUG("*** After PSRAM initialization: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(), memGet.getPsramSize()); @@ -376,7 +380,7 @@ void StoreForwardModule::statsSend(uint32_t to) */ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &mp) { -#ifdef ARCH_ESP32 +#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) if (moduleConfig.store_forward.enabled) { if ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) { @@ -559,7 +563,7 @@ StoreForwardModule::StoreForwardModule() ProtobufModule("StoreForward", meshtastic_PortNum_STORE_FORWARD_APP, &meshtastic_StoreAndForward_msg) { -#ifdef ARCH_ESP32 +#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) isPromiscuous = true; // Brown chicken brown cow diff --git a/src/modules/esp32/StoreForwardModule.h b/src/modules/StoreForwardModule.h similarity index 100% rename from src/modules/esp32/StoreForwardModule.h rename to src/modules/StoreForwardModule.h From 6e1aa52723d21319e620a535b39ede23f9270ad9 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Sep 2024 21:22:27 -0500 Subject: [PATCH 235/252] More store-n-forward on native --- src/graphics/Screen.cpp | 5 +++-- src/mesh/MeshService.h | 4 ++-- src/mesh/NodeDB.cpp | 3 ++- src/modules/Modules.cpp | 5 ++++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index f95146318..d14dd95a9 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -58,10 +58,11 @@ along with this program. If not, see . #ifdef ARCH_ESP32 #include "esp_task_wdt.h" -#include "modules/esp32/StoreForwardModule.h" +#include "modules/StoreForwardModule.h" #endif #if ARCH_PORTDUINO +#include "modules/StoreForwardModule.h" #include "platform/portduino/PortduinoGlue.h" #endif @@ -2822,4 +2823,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg) } // namespace graphics #else graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {} -#endif // HAS_SCREEN +#endif // HAS_SCREEN \ No newline at end of file diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index e78c2be2c..b91fedada 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -13,9 +13,9 @@ #if defined(ARCH_PORTDUINO) && !HAS_RADIO #include "../platform/portduino/SimRadio.h" #endif -#ifdef ARCH_ESP32 +#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) #if !MESHTASTIC_EXCLUDE_STOREFORWARD -#include "modules/esp32/StoreForwardModule.h" +#include "modules/StoreForwardModule.h" #endif #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 869729890..6c554b538 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -32,12 +32,13 @@ #if HAS_WIFI #include "mesh/wifi/WiFiAPClient.h" #endif -#include "modules/esp32/StoreForwardModule.h" +#include "modules/StoreForwardModule.h" #include #include #endif #ifdef ARCH_PORTDUINO +#include "modules/StoreForwardModule.h" #include "platform/portduino/PortduinoGlue.h" #endif diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index eca0e8ac9..eedb3a37d 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -47,6 +47,9 @@ #endif #if ARCH_PORTDUINO #include "input/LinuxInputImpl.h" +#if !MESHTASTIC_EXCLUDE_STOREFORWARD +#include "modules/StoreForwardModule.h" +#endif #endif #if HAS_TELEMETRY #include "modules/Telemetry/DeviceTelemetry.h" @@ -67,7 +70,7 @@ #include "modules/esp32/PaxcounterModule.h" #endif #if !MESHTASTIC_EXCLUDE_STOREFORWARD -#include "modules/esp32/StoreForwardModule.h" +#include "modules/StoreForwardModule.h" #endif #endif #if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) From cc101f9cd251e4f1fbac5fa3ec34a4379e70b707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 12:07:05 +0200 Subject: [PATCH 236/252] run the full suite when run on master --- .github/workflows/main_matrix.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 87ba8cf85..da619fe9f 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -32,7 +32,11 @@ jobs: name: Checkout base - id: jsonStep run: | - TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick) + if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then + TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) + else + TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick) + fi echo "$TARGETS" echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT outputs: From f28f5e07b773238e5e065845b52441efe2d57b19 Mon Sep 17 00:00:00 2001 From: caveman99 <25002+caveman99@users.noreply.github.com> Date: Sat, 28 Sep 2024 11:38:10 +0000 Subject: [PATCH 237/252] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index 6ac91926c..83c78e26e 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 6ac91926c201c15c429cb5d41684f0f40cb7dce8 +Subproject commit 83c78e26e39031ae1c17ba5e50d0898842719c7f diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index b323ddf07..c04f4adb9 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -209,6 +209,8 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_SEEED_XIAO_S3 = 81, /* Nordic nRF52840+Semtech SX1262 LoRa BLE Combo Module. nRF52840+SX1262 MS24SF1 */ meshtastic_HardwareModel_MS24SF1 = 82, + /* Lilygo TLora-C6 with the new ESP32-C6 MCU */ + meshtastic_HardwareModel_TLORA_C6 = 83, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 c650e7d273500a90e610dcc54997a580ab578423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 13:42:32 +0200 Subject: [PATCH 238/252] finish TLora C6 Support, without bluetooth for now --- arch/esp32/esp32c6.ini | 2 +- src/SerialConsole.cpp | 3 ++- src/platform/esp32/architecture.h | 2 ++ variants/tlora_c6/platformio.ini | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini index fad9f3865..3c2165642 100644 --- a/arch/esp32/esp32c6.ini +++ b/arch/esp32/esp32c6.ini @@ -1,6 +1,6 @@ [esp32c6_base] extends = esp32_base -platform = https://github.com/Jason2866/platform-espressif32.git#92cd8e2ed8ec8392b32adc89451aecfcbbaa1726 +platform = https://github.com/Jason2866/platform-espressif32.git#22faa566df8c789000f8136cd8d0aca49617af55 build_flags = ${arduino_base.build_flags} -Wall diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp index 15366d222..fe6ccdefe 100644 --- a/src/SerialConsole.cpp +++ b/src/SerialConsole.cpp @@ -46,7 +46,8 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con Port.setRX(SERIAL2_RX); #endif Port.begin(SERIAL_BAUD); -#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040) +#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040) || \ + defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) time_t timeout = millis(); while (!Port) { if (Throttle::isWithinTimespanMs(timeout, FIVE_SECONDS_MS)) { diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index a2e7dfc4e..01f416629 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -90,6 +90,8 @@ #define HW_VENDOR meshtastic_HardwareModel_TLORA_V2_1_1P6 #elif defined(TLORA_V2_1_18) #define HW_VENDOR meshtastic_HardwareModel_TLORA_V2_1_1P8 +#elif defined(TLORA_C6) +#define HW_VENDOR meshtastic_HardwareModel_TLORA_C6 #elif defined(T_DECK) #define HW_VENDOR meshtastic_HardwareModel_T_DECK #elif defined(T_WATCH_S3) diff --git a/variants/tlora_c6/platformio.ini b/variants/tlora_c6/platformio.ini index 3a8fd2c19..d042cd78b 100644 --- a/variants/tlora_c6/platformio.ini +++ b/variants/tlora_c6/platformio.ini @@ -3,7 +3,6 @@ extends = esp32c6_base board = esp32-c6-devkitm-1 build_flags = ${esp32c6_base.build_flags} - -D PRIVATE_HW -D TLORA_C6 -I variants/tlora_c6 -DARDUINO_USB_CDC_ON_BOOT=1 From da346159f7fff5647b5a8839c2768abfc2645293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 14:01:42 +0200 Subject: [PATCH 239/252] fix overzealous pin definitions --- variants/tlora_c6/variant.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/variants/tlora_c6/variant.h b/variants/tlora_c6/variant.h index e16bfb767..55635fe13 100644 --- a/variants/tlora_c6/variant.h +++ b/variants/tlora_c6/variant.h @@ -1,9 +1,8 @@ #define I2C_SDA 8 // I2C pins for this board #define I2C_SCL 9 -#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost -#define LED_PIN 7 // If defined we will blink this LED -#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module. +#define LED_PIN 7 // If defined we will blink this LED +#define LED_STATE_ON 0 // State when LED is lit #define USE_SX1262 #define LORA_SCK 6 @@ -19,4 +18,4 @@ #define SX126X_RXEN 15 #define SX126X_TXEN 14 #define SX126X_DIO2_AS_RF_SWITCH -#define SX126X_DIO3_TCXO_VOLTAGE 1.8 \ No newline at end of file +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 From 12efedec42ac3d2961e21633fe3890a039fe8d86 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:24:13 +0200 Subject: [PATCH 240/252] Potential fix for bad Rx performance on T1000-E (#4885) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Potential fix for bad Rx performance on T1000-E * validate and refactor RF switching, eliminate godmode --------- Co-authored-by: Thomas Göttgens --- src/mesh/LR11x0Interface.cpp | 74 +++++++------------ variants/ME25LS01-4Y10TD/platformio.ini | 4 +- variants/ME25LS01-4Y10TD/rfswitch.h | 15 ++++ variants/ME25LS01-4Y10TD/variant.h | 1 - variants/ME25LS01-4Y10TD_e-ink/platformio.ini | 4 +- variants/ME25LS01-4Y10TD_e-ink/rfswitch.h | 15 ++++ variants/ME25LS01-4Y10TD_e-ink/variant.h | 3 +- variants/MakePython_nRF52840_eink/variant.h | 2 - variants/MakePython_nRF52840_oled/variant.h | 2 - variants/portduino/variant.h | 3 +- variants/tracker-t1000-e/rfswitch.h | 13 ++++ variants/wio-sdk-wm1110/rfswitch.h | 15 ++++ variants/wio-t1000-s/rfswitch.h | 13 ++++ variants/wio-t1000-s/variant.h | 3 +- variants/wio-tracker-wm1110/rfswitch.h | 15 ++++ 15 files changed, 119 insertions(+), 63 deletions(-) create mode 100644 variants/ME25LS01-4Y10TD/rfswitch.h create mode 100644 variants/ME25LS01-4Y10TD_e-ink/rfswitch.h create mode 100644 variants/tracker-t1000-e/rfswitch.h create mode 100644 variants/wio-sdk-wm1110/rfswitch.h create mode 100644 variants/wio-t1000-s/rfswitch.h create mode 100644 variants/wio-tracker-wm1110/rfswitch.h diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index 2ec659b06..df3b91e23 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -3,6 +3,15 @@ #include "configuration.h" #include "error.h" #include "mesh/NodeDB.h" +#ifdef LR11X0_DIO_AS_RF_SWITCH +#include "rfswitch.h" +#else +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; +static const Module::RfSwitchMode_t rfswitch_table[] = { + {LR11x0::MODE_STBY, {}}, {LR11x0::MODE_RX, {}}, {LR11x0::MODE_TX, {}}, {LR11x0::MODE_TX_HP, {}}, + {LR11x0::MODE_TX_HF, {}}, {LR11x0::MODE_GNSS, {}}, {LR11x0::MODE_WIFI, {}}, END_OF_MODE_TABLE, +}; +#endif #ifdef ARCH_PORTDUINO #include "PortduinoGlue.h" @@ -52,54 +61,6 @@ template bool LR11x0Interface::init() limitPower(); -#ifdef TRACKER_T1000_E // Tracker T1000E uses DIO5, DIO6, DIO7, DIO8 for RF switching - - static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, - RADIOLIB_LR11X0_DIO8, RADIOLIB_NC}; - - static const Module::RfSwitchMode_t rfswitch_table[] = { - // mode DIO5 DIO6 DIO7 DIO8 - {LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH}}, - {LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH}}, - {LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW}}, - {LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE, - }; - -#else - - // set RF switch configuration for Wio WM1110 - // Wio WM1110 uses DIO5 and DIO6 for RF switching - - static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, - RADIOLIB_NC}; - - static const Module::RfSwitchMode_t rfswitch_table[] = { - // mode DIO5 DIO6 - {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, - {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, - {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, - {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, - }; - -#endif - -// We need to do this before begin() call -#ifdef LR11X0_DIO_AS_RF_SWITCH - LOG_DEBUG("Setting DIO RF switch\n"); - bool dioAsRfSwitch = true; -#elif defined(ARCH_PORTDUINO) - bool dioAsRfSwitch = false; - if (settingsMap[dio2_as_rf_switch]) { - LOG_DEBUG("Setting DIO RF switch\n"); - dioAsRfSwitch = true; - } -#else - bool dioAsRfSwitch = false; -#endif - - if (dioAsRfSwitch) - lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); - int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage); // \todo Display actual typename of the adapter, not just `LR11x0` LOG_INFO("LR11x0 init result %d\n", res); @@ -123,6 +84,23 @@ template bool LR11x0Interface::init() // FIXME: May want to set depending on a definition, currently all LR1110 variant files use the DC-DC regulator option if (res == RADIOLIB_ERR_NONE) res = lora.setRegulatorDCDC(); + +#ifdef LR11X0_DIO_AS_RF_SWITCH + bool dioAsRfSwitch = true; +#elif defined(ARCH_PORTDUINO) + bool dioAsRfSwitch = false; + if (settingsMap[dio2_as_rf_switch]) { + dioAsRfSwitch = true; + } +#else + bool dioAsRfSwitch = false; +#endif + + if (dioAsRfSwitch) { + lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + LOG_DEBUG("Setting DIO RF switch\n", res); + } + if (res == RADIOLIB_ERR_NONE) { if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate res = lora.setRxBoostedGainMode(true); diff --git a/variants/ME25LS01-4Y10TD/platformio.ini b/variants/ME25LS01-4Y10TD/platformio.ini index 985919d2d..479a4e79c 100644 --- a/variants/ME25LS01-4Y10TD/platformio.ini +++ b/variants/ME25LS01-4Y10TD/platformio.ini @@ -3,7 +3,7 @@ extends = nrf52840_base board = me25ls01-4y10td board_level = extra ; platform = https://github.com/maxgerhardt/platform-nordicnrf52#cac6fcf943a41accd2aeb4f3659ae297a73f422e -build_flags = ${nrf52840_base.build_flags} -Ivariants/ME25LS01-4Y10TD -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DME25LS01_4Y10TD ;-DRADIOLIB_GODMODE +build_flags = ${nrf52840_base.build_flags} -Ivariants/ME25LS01-4Y10TD -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DME25LS01_4Y10TD -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/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. board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld @@ -12,4 +12,4 @@ lib_deps = ${nrf52840_base.lib_deps} ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) upload_protocol = nrfutil -upload_port = /dev/ttyACM1 +upload_port = /dev/ttyACM1 \ No newline at end of file diff --git a/variants/ME25LS01-4Y10TD/rfswitch.h b/variants/ME25LS01-4Y10TD/rfswitch.h new file mode 100644 index 000000000..cda6364f5 --- /dev/null +++ b/variants/ME25LS01-4Y10TD/rfswitch.h @@ -0,0 +1,15 @@ +#include "RadioLib.h" +#include "nrf.h" + +// set RF switch configuration for Wio WM1110 +// Wio WM1110 uses DIO5 and DIO6 for RF switching + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/ME25LS01-4Y10TD/variant.h b/variants/ME25LS01-4Y10TD/variant.h index 0da391f0b..e772069da 100644 --- a/variants/ME25LS01-4Y10TD/variant.h +++ b/variants/ME25LS01-4Y10TD/variant.h @@ -103,7 +103,6 @@ extern "C" { #define LR11X0_DIO3_TCXO_VOLTAGE 1.6 #define LR11X0_DIO_AS_RF_SWITCH -#define LR11X0_DIO_RF_SWITCH_CONFIG 0x0f, 0x0, 0x09, 0x0B, 0x0A, 0x0, 0x4, 0x0 #define HAS_GPS 0 diff --git a/variants/ME25LS01-4Y10TD_e-ink/platformio.ini b/variants/ME25LS01-4Y10TD_e-ink/platformio.ini index 4e837abd8..f2e3a49e3 100644 --- a/variants/ME25LS01-4Y10TD_e-ink/platformio.ini +++ b/variants/ME25LS01-4Y10TD_e-ink/platformio.ini @@ -3,7 +3,7 @@ extends = nrf52840_base board = me25ls01-4y10td board_level = extra ; platform = https://github.com/maxgerhardt/platform-nordicnrf52#cac6fcf943a41accd2aeb4f3659ae297a73f422e -build_flags = ${nrf52840_base.build_flags} -Ivariants/ME25LS01-4Y10TD_e-ink -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DME25LS01_4Y10TD ;-DRADIOLIB_GODMODE +build_flags = ${nrf52840_base.build_flags} -Ivariants/ME25LS01-4Y10TD_e-ink -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DME25LS01_4Y10TD -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/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. -DEINK_DISPLAY_MODEL=GxEPD2_420_GDEY042T81 @@ -16,4 +16,4 @@ lib_deps = zinggjm/GxEPD2@^1.5.8 ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) upload_protocol = nrfutil -upload_port = /dev/ttyACM1 +upload_port = /dev/ttyACM1 \ No newline at end of file diff --git a/variants/ME25LS01-4Y10TD_e-ink/rfswitch.h b/variants/ME25LS01-4Y10TD_e-ink/rfswitch.h new file mode 100644 index 000000000..cda6364f5 --- /dev/null +++ b/variants/ME25LS01-4Y10TD_e-ink/rfswitch.h @@ -0,0 +1,15 @@ +#include "RadioLib.h" +#include "nrf.h" + +// set RF switch configuration for Wio WM1110 +// Wio WM1110 uses DIO5 and DIO6 for RF switching + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/ME25LS01-4Y10TD_e-ink/variant.h b/variants/ME25LS01-4Y10TD_e-ink/variant.h index 105f9b873..797394ce6 100644 --- a/variants/ME25LS01-4Y10TD_e-ink/variant.h +++ b/variants/ME25LS01-4Y10TD_e-ink/variant.h @@ -126,7 +126,6 @@ static const uint8_t SCK = PIN_SPI_SCK; #define LR11X0_DIO3_TCXO_VOLTAGE 1.6 #define LR11X0_DIO_AS_RF_SWITCH -#define LR11X0_DIO_RF_SWITCH_CONFIG 0x0f, 0x0, 0x09, 0x0B, 0x0A, 0x0, 0x4, 0x0 #define HAS_GPS 0 @@ -159,4 +158,4 @@ static const uint8_t SCK = PIN_SPI_SCK; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif // _VARIANT_ME25LS01_4Y10TD__ +#endif // _VARIANT_ME25LS01_4Y10TD__ \ No newline at end of file diff --git a/variants/MakePython_nRF52840_eink/variant.h b/variants/MakePython_nRF52840_eink/variant.h index 16f803dd2..00c8dc199 100644 --- a/variants/MakePython_nRF52840_eink/variant.h +++ b/variants/MakePython_nRF52840_eink/variant.h @@ -25,8 +25,6 @@ extern "C" { #define NUM_ANALOG_INPUTS (6) #define NUM_ANALOG_OUTPUTS (0) -#define RADIOLIB_GODMODE - // LEDs #define PIN_LED1 (32 + 10) // LED P1.15 #define PIN_LED2 (-1) // diff --git a/variants/MakePython_nRF52840_oled/variant.h b/variants/MakePython_nRF52840_oled/variant.h index a2a5fa80a..28d941171 100644 --- a/variants/MakePython_nRF52840_oled/variant.h +++ b/variants/MakePython_nRF52840_oled/variant.h @@ -25,8 +25,6 @@ extern "C" { #define NUM_ANALOG_INPUTS (6) #define NUM_ANALOG_OUTPUTS (0) -#define RADIOLIB_GODMODE - // LEDs #define PIN_LED1 (32 + 10) // LED P1.15 #define PIN_LED2 (-1) // diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h index 70d7cbd52..b7b39d6e8 100644 --- a/variants/portduino/variant.h +++ b/variants/portduino/variant.h @@ -2,5 +2,4 @@ #define CANNED_MESSAGE_MODULE_ENABLE 1 #define HAS_GPS 1 #define MAX_RX_TOPHONE settingsMap[maxtophone] -#define MAX_NUM_NODES settingsMap[maxnodes] -#define RADIOLIB_GODMODE 1 +#define MAX_NUM_NODES settingsMap[maxnodes] \ No newline at end of file diff --git a/variants/tracker-t1000-e/rfswitch.h b/variants/tracker-t1000-e/rfswitch.h new file mode 100644 index 000000000..e229d77cf --- /dev/null +++ b/variants/tracker-t1000-e/rfswitch.h @@ -0,0 +1,13 @@ +#include "RadioLib.h" +#include "nrf.h" + +static const uint32_t rfswitch_dio_pins[Module::RFSWITCH_MAX_PINS] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, + RADIOLIB_LR11X0_DIO7, RADIOLIB_LR11X0_DIO8, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 DIO8 + {LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; \ No newline at end of file diff --git a/variants/wio-sdk-wm1110/rfswitch.h b/variants/wio-sdk-wm1110/rfswitch.h new file mode 100644 index 000000000..cda6364f5 --- /dev/null +++ b/variants/wio-sdk-wm1110/rfswitch.h @@ -0,0 +1,15 @@ +#include "RadioLib.h" +#include "nrf.h" + +// set RF switch configuration for Wio WM1110 +// Wio WM1110 uses DIO5 and DIO6 for RF switching + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/wio-t1000-s/rfswitch.h b/variants/wio-t1000-s/rfswitch.h new file mode 100644 index 000000000..e229d77cf --- /dev/null +++ b/variants/wio-t1000-s/rfswitch.h @@ -0,0 +1,13 @@ +#include "RadioLib.h" +#include "nrf.h" + +static const uint32_t rfswitch_dio_pins[Module::RFSWITCH_MAX_PINS] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, + RADIOLIB_LR11X0_DIO7, RADIOLIB_LR11X0_DIO8, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 DIO7 DIO8 + {LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH}}, + {LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE, +}; \ No newline at end of file diff --git a/variants/wio-t1000-s/variant.h b/variants/wio-t1000-s/variant.h index 8894a40c5..eb6a34d6c 100644 --- a/variants/wio-t1000-s/variant.h +++ b/variants/wio-t1000-s/variant.h @@ -103,7 +103,6 @@ extern "C" { #define LR11X0_DIO3_TCXO_VOLTAGE 1.6 #define LR11X0_DIO_AS_RF_SWITCH -#define LR11X0_DIO_RF_SWITCH_CONFIG 0x0f, 0x0, 0x09, 0x0B, 0x0A, 0x0, 0x4, 0x0 #define HAS_GPS 1 #define GNSS_AIROHA @@ -158,4 +157,4 @@ extern "C" { * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif // _VARIANT_WIO_SDK_WM1110_ +#endif // _VARIANT_WIO_SDK_WM1110_ \ No newline at end of file diff --git a/variants/wio-tracker-wm1110/rfswitch.h b/variants/wio-tracker-wm1110/rfswitch.h new file mode 100644 index 000000000..cda6364f5 --- /dev/null +++ b/variants/wio-tracker-wm1110/rfswitch.h @@ -0,0 +1,15 @@ +#include "RadioLib.h" +#include "nrf.h" + +// set RF switch configuration for Wio WM1110 +// Wio WM1110 uses DIO5 and DIO6 for RF switching + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; From 06dab4fa135c2ddf53851481d59968209af4c80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 16:26:55 +0200 Subject: [PATCH 241/252] Don't process RX when region unset --- src/mesh/RadioLibInterface.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 0968a6d89..aee43676d 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -167,7 +167,7 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p) } } else { - LOG_WARN("send - lora tx disable because RegionCode_Unset\n"); + LOG_WARN("send - lora tx disabled because RegionCode_Unset\n"); packetPool.release(p); return ERRNO_DISABLED; } @@ -379,6 +379,14 @@ void RadioLibInterface::handleReceiveInterrupt() xmitMsec = getPacketTime(length); +#ifndef DISABLE_WELCOME_UNSET + if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) { + LOG_WARN("recv - lora rx disabled because RegionCode_Unset\n"); + airTime->logAirtime(RX_ALL_LOG, xmitMsec); + return; + } +#endif + int state = iface->readData(radiobuf, length); if (state != RADIOLIB_ERR_NONE) { LOG_ERROR("ignoring received packet due to error=%d\n", state); From 1e8d089c4ea8a56e293a5b6f4a4cd3e02d78617b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 16:40:00 +0200 Subject: [PATCH 242/252] yolo! --- .github/workflows/main_matrix.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index da619fe9f..54e721083 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -1,4 +1,7 @@ name: CI +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true #concurrency: # group: ${{ github.ref }} # cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} From 479b0856b4d9b04628086b70fd02e5f26712bc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 19:07:11 +0200 Subject: [PATCH 243/252] use rfswitch definition and update radiolib --- platformio.ini | 2 +- variants/tlora_t3s3_v1/rfswitch.h | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 variants/tlora_t3s3_v1/rfswitch.h diff --git a/platformio.ini b/platformio.ini index f528a6fde..d781f0b12 100644 --- a/platformio.ini +++ b/platformio.ini @@ -91,7 +91,7 @@ monitor_filters = direct lib_deps = ;jgromes/RadioLib@~7.0.0 ;7.0.1pre needed for LR1121 support and SX127x CRC Bugfix - https://github.com/jgromes/RadioLib.git#98ad30eb103d22bb7e75f3cc900597403b0cfb1f + https://github.com/jgromes/RadioLib.git#38fc7a97a4c195b7c10aa94215a1c53ec18a56ef https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 diff --git a/variants/tlora_t3s3_v1/rfswitch.h b/variants/tlora_t3s3_v1/rfswitch.h new file mode 100644 index 000000000..19080cec6 --- /dev/null +++ b/variants/tlora_t3s3_v1/rfswitch.h @@ -0,0 +1,11 @@ +#include "RadioLib.h" + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; \ No newline at end of file From ec23189407b0c8390d3faf4d5a50354f663bd82c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 28 Sep 2024 13:04:50 -0500 Subject: [PATCH 244/252] Making some board levels extra for uncommon hardware --- variants/monteops_hw1/platformio.ini | 1 + variants/senselora_rp2040/platformio.ini | 1 + variants/tbeam_v07/platformio.ini | 1 + 3 files changed, 3 insertions(+) diff --git a/variants/monteops_hw1/platformio.ini b/variants/monteops_hw1/platformio.ini index 551419abc..4b42dce39 100644 --- a/variants/monteops_hw1/platformio.ini +++ b/variants/monteops_hw1/platformio.ini @@ -1,5 +1,6 @@ ; MonteOps M.Node/M.Backbone/M.Eagle hardware based on hardware variant #1 (RAK4630 based) [env:monteops_hw1] +board_level = extra extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/monteops_hw1 -D MONTEOPS_HW1 diff --git a/variants/senselora_rp2040/platformio.ini b/variants/senselora_rp2040/platformio.ini index c719bd261..852ecbbb9 100644 --- a/variants/senselora_rp2040/platformio.ini +++ b/variants/senselora_rp2040/platformio.ini @@ -1,4 +1,5 @@ [env:senselora_rp2040] +board_level = extra extends = rp2040_base board = rpipico upload_protocol = picotool diff --git a/variants/tbeam_v07/platformio.ini b/variants/tbeam_v07/platformio.ini index 105d65912..0cba92400 100644 --- a/variants/tbeam_v07/platformio.ini +++ b/variants/tbeam_v07/platformio.ini @@ -1,5 +1,6 @@ ; The original TBEAM board without the AXP power chip and a few other changes [env:tbeam0_7] +board_level = extra extends = esp32_base board = ttgo-t-beam build_flags = From 6a355616c7f71b100e0d5d0fe0cf174a106d36f0 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 28 Sep 2024 13:06:01 -0500 Subject: [PATCH 245/252] Another extra --- variants/Dongle_nRF52840-pca10059-v1/platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini index c87f83d39..a98656e86 100644 --- a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini +++ b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini @@ -1,4 +1,5 @@ [env:pca10059_diy_eink] +board_level = extra extends = nrf52840_base board = nordic_pca10059 build_flags = ${nrf52840_base.build_flags} -Ivariants/Dongle_nRF52840-pca10059-v1 -D NORDIC_PCA10059 From 22ecbcb04611b6c00a512ce4b417dc963ed60b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 20:35:48 +0200 Subject: [PATCH 246/252] Create build_esp32_c6.yml --- .github/workflows/build_esp32_c6.yml | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/build_esp32_c6.yml diff --git a/.github/workflows/build_esp32_c6.yml b/.github/workflows/build_esp32_c6.yml new file mode 100644 index 000000000..3be813afa --- /dev/null +++ b/.github/workflows/build_esp32_c6.yml @@ -0,0 +1,35 @@ +name: Build ESP32-C6 + +on: + workflow_call: + inputs: + board: + required: true + type: string + +permissions: read-all + +jobs: + build-esp32-c6: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build ESP32-C6 + id: build + uses: ./.github/actions/build-variant + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + board: ${{ inputs.board }} + remove-debug-flags: >- + ./arch/esp32/esp32.ini + ./arch/esp32/esp32s2.ini + ./arch/esp32/esp32s3.ini + ./arch/esp32/esp32c3.ini + ./arch/esp32/esp32c6.ini + build-script-path: bin/build-esp32.sh + ota-firmware-source: firmware-c3.bin + ota-firmware-target: release/bleota-c3.bin + artifact-paths: | + release/*.bin + release/*.elf From 448afb8345e306dfe040083ded179166db1964ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 20:37:07 +0200 Subject: [PATCH 247/252] Add C6 Target --- .github/workflows/main_matrix.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 54e721083..fc3a944cf 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -46,6 +46,7 @@ jobs: esp32: ${{ steps.jsonStep.outputs.esp32 }} esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }} esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }} + esp32c3: ${{ steps.jsonStep.outputs.esp32c6 }} nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }} rp2040: ${{ steps.jsonStep.outputs.rp2040 }} stm32: ${{ steps.jsonStep.outputs.stm32 }} @@ -93,6 +94,15 @@ jobs: uses: ./.github/workflows/build_esp32_c3.yml with: board: ${{ matrix.board }} + + build-esp32-c6: + needs: setup + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }} + uses: ./.github/workflows/build_esp32_c6.yml + with: + board: ${{ matrix.board }} build-nrf52: needs: setup @@ -151,6 +161,7 @@ jobs: build-esp32, build-esp32-s3, build-esp32-c3, + build-esp32-c6, build-nrf52, build-rpi2040, build-stm32, From 9513c68544a3469d01572c29910454971a967805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 20:37:38 +0200 Subject: [PATCH 248/252] Update main_matrix.yml --- .github/workflows/main_matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index fc3a944cf..adf3891ba 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -46,7 +46,7 @@ jobs: esp32: ${{ steps.jsonStep.outputs.esp32 }} esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }} esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }} - esp32c3: ${{ steps.jsonStep.outputs.esp32c6 }} + esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }} nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }} rp2040: ${{ steps.jsonStep.outputs.rp2040 }} stm32: ${{ steps.jsonStep.outputs.stm32 }} From a542d41ac79f619707c01544a39a6a186fdb6217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 28 Sep 2024 21:59:13 +0200 Subject: [PATCH 249/252] rats, missed one --- .github/workflows/main_matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index adf3891ba..2ca3576aa 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, stm32, check] + arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32, check] runs-on: ubuntu-latest steps: - id: checkout From a70d5ee9d879b8530bc486f7f65b4965e2e25e52 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 28 Sep 2024 15:49:37 -0500 Subject: [PATCH 250/252] Temporarily remove native AGAIN due to gather-artifacts failure --- .github/workflows/main_matrix.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 2ca3576aa..df4929da7 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -94,7 +94,7 @@ jobs: uses: ./.github/workflows/build_esp32_c3.yml with: board: ${{ matrix.board }} - + build-esp32-c6: needs: setup strategy: @@ -137,8 +137,8 @@ jobs: package-raspbian-armv7l: uses: ./.github/workflows/package_raspbian_armv7l.yml - package-native: - uses: ./.github/workflows/package_amd64.yml + # package-native: + # uses: ./.github/workflows/package_amd64.yml after-checks: runs-on: ubuntu-latest @@ -156,8 +156,7 @@ jobs: contents: write pull-requests: write runs-on: ubuntu-latest - needs: - [ + needs: [ build-esp32, build-esp32-s3, build-esp32-c3, @@ -167,7 +166,7 @@ jobs: build-stm32, package-raspbian, package-raspbian-armv7l, - package-native, + # package-native, ] steps: - name: Checkout code @@ -354,15 +353,15 @@ jobs: asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb asset_content_type: application/vnd.debian.binary-package - - name: Add raspbian amd64 .deb - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb - asset_content_type: application/vnd.debian.binary-package + # - name: Add raspbian amd64 .deb + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ github.token }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + # asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + # asset_content_type: application/vnd.debian.binary-package - name: Bump version.properties run: >- From 233962104c5989f50a9589862b5b0ef539d47c55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:12:10 -0500 Subject: [PATCH 251/252] [create-pull-request] automated change (#4897) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 8c8e94bec..5f506ee26 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 5 -build = 3 +build = 4 From 7e0665a5cdc0f13cf26033652a636eb391e804c7 Mon Sep 17 00:00:00 2001 From: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com> Date: Sun, 29 Sep 2024 03:01:20 -0700 Subject: [PATCH 252/252] comment on PR with artifact link (#4896) --- .github/workflows/main_matrix.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index df4929da7..68f7bb31c 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -235,17 +235,11 @@ jobs: path: ./*.elf retention-days: 30 - - name: Create request artifacts - continue-on-error: true # FIXME: Why are we getting 502, but things still work? - if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }} - uses: gavv/pull-request-artifacts@v2.1.0 + - uses: PicoCentauri/comment-artifact@main with: - commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }} - repo-token: ${{ secrets.GITHUB_TOKEN }} - artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }} - artifacts-repo: meshtastic/artifacts - artifacts-branch: device - artifacts: ./firmware-${{ steps.version.outputs.version }}.zip + name: firmware-${{ steps.version.outputs.version }} + description: "Download firmware-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation" + github-token: ${{ secrets.GITHUB_TOKEN }} release-artifacts: runs-on: ubuntu-latest