From 9ab9650248883c11995f4bf2cb6e68a5506bf605 Mon Sep 17 00:00:00 2001 From: Tom <116762865+NomDeTom@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:04:10 +0100 Subject: [PATCH 01/13] Update stale_bot.yml Extend stale period to 60 days, and added a message on stale marking. --- .github/workflows/stale_bot.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index a80619e90..4044278e8 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -19,6 +19,7 @@ jobs: - name: Stale PR+Issues uses: actions/stale@v10.1.0 with: - days-before-stale: 45 + days-before-stale: 60 + stale-issue-message: 'This issue hasn not had any comment or update in the last 2 months. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days.' exempt-issue-labels: pinned,3.0 exempt-pr-labels: pinned,3.0 From 910fe911f80fd713c62166d61e72cede64af53e4 Mon Sep 17 00:00:00 2001 From: Tom <116762865+NomDeTom@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:12:45 +0100 Subject: [PATCH 02/13] Update stale_bot.yml --- .github/workflows/stale_bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index 4044278e8..8a0c61a80 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -20,6 +20,6 @@ jobs: uses: actions/stale@v10.1.0 with: days-before-stale: 60 - stale-issue-message: 'This issue hasn not had any comment or update in the last 2 months. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days.' + stale-issue-message: This issue hasn not had any comment or update in the last 2 months. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. exempt-issue-labels: pinned,3.0 exempt-pr-labels: pinned,3.0 From b8bfed28105c1ea2918449c30ec3ab1802c512dd Mon Sep 17 00:00:00 2001 From: Tom <116762865+NomDeTom@users.noreply.github.com> Date: Tue, 14 Oct 2025 12:37:40 +0100 Subject: [PATCH 03/13] return to 45 days and put a closure message. --- .github/workflows/stale_bot.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index 8a0c61a80..b528f80b2 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -19,7 +19,8 @@ jobs: - name: Stale PR+Issues uses: actions/stale@v10.1.0 with: - days-before-stale: 60 - stale-issue-message: This issue hasn not had any comment or update in the last 2 months. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. + days-before-stale: 45 + stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. + close-issue-message: This issue has not had any comment since the last notice. It has been closed automatically. If this is incorrect, or the issue becomes relevant again, please request that it is reopened. exempt-issue-labels: pinned,3.0 exempt-pr-labels: pinned,3.0 From a6df18e60a78d7ad5600ea920fa0b1063692f5a9 Mon Sep 17 00:00:00 2001 From: Clive Blackledge Date: Wed, 15 Oct 2025 04:08:06 -0700 Subject: [PATCH 04/13] Guarding PhoneAPI node-info staging with mutex to prevent BLE future foot-gun (#8354) * Eliminating foot-gun and placing Phone NodeInfo into a mutex * Swapping over to concurrency::Lock from mutex --- src/mesh/PhoneAPI.cpp | 103 ++++++++++++++++++++++----------- src/mesh/PhoneAPI.h | 3 + src/nimble/NimbleBluetooth.cpp | 2 +- 3 files changed, 72 insertions(+), 36 deletions(-) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 9eeadf5a2..36bd577e1 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -15,6 +15,7 @@ #include "Router.h" #include "SPILock.h" #include "TypeConversions.h" +#include "concurrency/LockGuard.h" #include "main.h" #include "xmodem.h" @@ -71,8 +72,12 @@ void PhoneAPI::handleStartConfig() LOG_DEBUG("Got %d files in manifest", filesManifest.size()); LOG_INFO("Start API client config"); - nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos - nodeInfoQueue.clear(); + // Protect against concurrent BLE callbacks: they run in NimBLE's FreeRTOS task and also touch nodeInfoQueue. + { + concurrency::LockGuard guard(&nodeInfoMutex); + nodeInfoForPhone = {}; + nodeInfoQueue.clear(); + } resetReadIndex(); } @@ -94,8 +99,12 @@ void PhoneAPI::close() onConnectionChanged(false); fromRadioScratch = {}; toRadioScratch = {}; - nodeInfoForPhone = {}; - nodeInfoQueue.clear(); + // Clear cached node info under lock because NimBLE callbacks can still be draining it. + { + concurrency::LockGuard guard(&nodeInfoMutex); + nodeInfoForPhone = {}; + nodeInfoQueue.clear(); + } packetForPhone = NULL; filesManifest.clear(); fromRadioNum = 0; @@ -241,13 +250,20 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) LOG_DEBUG("Send My NodeInfo"); auto us = nodeDB->readNextMeshNode(readIndex); if (us) { - nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us); - nodeInfoForPhone.has_hops_away = false; - nodeInfoForPhone.is_favorite = true; + auto info = TypeConversions::ConvertToNodeInfo(us); + info.has_hops_away = false; + info.is_favorite = true; + { + concurrency::LockGuard guard(&nodeInfoMutex); + nodeInfoForPhone = info; + } fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; - fromRadioScratch.node_info = nodeInfoForPhone; + fromRadioScratch.node_info = info; // Should allow us to resume sending NodeInfo in STATE_SEND_OTHER_NODEINFOS - nodeInfoForPhone.num = 0; + { + concurrency::LockGuard guard(&nodeInfoMutex); + nodeInfoForPhone.num = 0; + } } if (config_nonce == SPECIAL_NONCE_ONLY_NODES) { // If client only wants node info, jump directly to sending nodes @@ -434,23 +450,30 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) case STATE_SEND_OTHER_NODEINFOS: { LOG_DEBUG("Send known nodes"); - if (nodeInfoForPhone.num == 0 && !nodeInfoQueue.empty()) { - // Serve the next cached node without re-reading from the DB iterator. - nodeInfoForPhone = nodeInfoQueue.front(); - nodeInfoQueue.pop_front(); + meshtastic_NodeInfo infoToSend = {}; + { + concurrency::LockGuard guard(&nodeInfoMutex); + if (nodeInfoForPhone.num == 0 && !nodeInfoQueue.empty()) { + // Serve the next cached node without re-reading from the DB iterator. + nodeInfoForPhone = nodeInfoQueue.front(); + nodeInfoQueue.pop_front(); + } + infoToSend = nodeInfoForPhone; + if (infoToSend.num != 0) + nodeInfoForPhone = {}; } - if (nodeInfoForPhone.num != 0) { + if (infoToSend.num != 0) { // Just in case we stored a different user.id in the past, but should never happen going forward - sprintf(nodeInfoForPhone.user.id, "!%08x", nodeInfoForPhone.num); - LOG_DEBUG("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s", nodeInfoForPhone.num, nodeInfoForPhone.last_heard, - nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name); + sprintf(infoToSend.user.id, "!%08x", infoToSend.num); + LOG_DEBUG("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s", infoToSend.num, infoToSend.last_heard, + infoToSend.user.id, infoToSend.user.long_name); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; - fromRadioScratch.node_info = nodeInfoForPhone; - nodeInfoForPhone = {}; + fromRadioScratch.node_info = infoToSend; prefetchNodeInfos(); } else { LOG_DEBUG("Done sending nodeinfo"); + concurrency::LockGuard guard(&nodeInfoMutex); nodeInfoQueue.clear(); state = STATE_SEND_FILEMANIFEST; // Go ahead and send that ID right now @@ -559,20 +582,23 @@ void PhoneAPI::prefetchNodeInfos() { bool added = false; // Keep the queue topped up so BLE reads stay responsive even if DB fetches take a moment. - while (nodeInfoQueue.size() < kNodePrefetchDepth) { - auto nextNode = nodeDB->readNextMeshNode(readIndex); - if (!nextNode) - break; + { + concurrency::LockGuard guard(&nodeInfoMutex); + while (nodeInfoQueue.size() < kNodePrefetchDepth) { + auto nextNode = nodeDB->readNextMeshNode(readIndex); + if (!nextNode) + break; - auto info = TypeConversions::ConvertToNodeInfo(nextNode); - bool isUs = info.num == nodeDB->getNodeNum(); - info.hops_away = isUs ? 0 : info.hops_away; - info.last_heard = isUs ? getValidTime(RTCQualityFromNet) : info.last_heard; - info.snr = isUs ? 0 : info.snr; - info.via_mqtt = isUs ? false : info.via_mqtt; - info.is_favorite = info.is_favorite || isUs; - nodeInfoQueue.push_back(info); - added = true; + auto info = TypeConversions::ConvertToNodeInfo(nextNode); + bool isUs = info.num == nodeDB->getNodeNum(); + info.hops_away = isUs ? 0 : info.hops_away; + info.last_heard = isUs ? getValidTime(RTCQualityFromNet) : info.last_heard; + info.snr = isUs ? 0 : info.snr; + info.via_mqtt = isUs ? false : info.via_mqtt; + info.is_favorite = info.is_favorite || isUs; + nodeInfoQueue.push_back(info); + added = true; + } } if (added) @@ -614,10 +640,17 @@ bool PhoneAPI::available() case STATE_SEND_COMPLETE_ID: return true; - case STATE_SEND_OTHER_NODEINFOS: - if (nodeInfoQueue.empty()) - prefetchNodeInfos(); + case STATE_SEND_OTHER_NODEINFOS: { + concurrency::LockGuard guard(&nodeInfoMutex); + if (nodeInfoQueue.empty()) { + // Drop the lock before prefetching; prefetchNodeInfos() will re-acquire it. + goto PREFETCH_NODEINFO; + } + } return true; // Always say we have something, because we might need to advance our state machine + PREFETCH_NODEINFO: + prefetchNodeInfos(); + return true; case STATE_SEND_PACKETS: { if (!queueStatusPacketForPhone) queueStatusPacketForPhone = service->getQueueStatusForPhone(); diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 692fdd0b9..a8d0faa28 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -1,6 +1,7 @@ #pragma once #include "Observer.h" +#include "concurrency/Lock.h" #include "mesh-pb-constants.h" #include "meshtastic/portnums.pb.h" #include @@ -84,6 +85,8 @@ class PhoneAPI std::deque nodeInfoQueue; // Tunable size of the node info cache so we can keep BLE reads non-blocking. static constexpr size_t kNodePrefetchDepth = 4; + // Protect nodeInfoForPhone + nodeInfoQueue because NimBLE callbacks run in a separate FreeRTOS task. + concurrency::Lock nodeInfoMutex; meshtastic_ToRadio toRadioScratch = { 0}; // this is a static scratch object, any data must be copied elsewhere before returning diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 4b0c33609..eb1d909f1 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -139,7 +139,7 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks { bluetoothPhoneAPI->phoneWants = true; bluetoothPhoneAPI->setIntervalFromNow(0); - std::lock_guard guard(bluetoothPhoneAPI->nimble_mutex); + std::lock_guard guard(bluetoothPhoneAPI->nimble_mutex); // BLE callbacks run in NimBLE task if (!bluetoothPhoneAPI->hasChecked) { // Fetch payload on demand; prefetch keeps this fast for the first read. From 858e8c6fefba6c2fc1da588c5a1ff8335f82e827 Mon Sep 17 00:00:00 2001 From: Mike Weaver Date: Wed, 15 Oct 2025 05:15:57 -0600 Subject: [PATCH 05/13] portduino, handle sdl2 builds (#8355) fix linux native build by adding sdl2 libraries --- variants/native/portduino/platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/native/portduino/platformio.ini b/variants/native/portduino/platformio.ini index 4e6a592de..49a8a71c7 100644 --- a/variants/native/portduino/platformio.ini +++ b/variants/native/portduino/platformio.ini @@ -17,6 +17,7 @@ extends = native_base build_flags = ${native_base.build_flags} !pkg-config --libs libulfius --silence-errors || : !pkg-config --libs openssl --silence-errors || : + !pkg-config --cflags --libs sdl2 --silence-errors || : [env:native-tft] extends = native_base From ec5a54c52377bbbdb13358ae971eeabe37820537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Czaplewski?= <28847593+Paplewski@users.noreply.github.com> Date: Wed, 15 Oct 2025 23:19:47 +0200 Subject: [PATCH 06/13] bind python version to 3.13 (#8362) --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bf1c50982..bc660170c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ "features": { "ghcr.io/devcontainers/features/python:1": { "installTools": true, - "version": "latest" + "version": "3.13" } }, "customizations": { From 865b46ceefb4b096f594baefae9d5c1aa739cef1 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 16 Oct 2025 06:07:38 -0500 Subject: [PATCH 07/13] Ignore MQTT Client Proxy messages while not in sendpackets state (#8358) --- src/mesh/PhoneAPI.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 36bd577e1..51a2bc148 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -159,6 +159,10 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) #if !MESHTASTIC_EXCLUDE_MQTT case meshtastic_ToRadio_mqttClientProxyMessage_tag: LOG_DEBUG("Got MqttClientProxy message"); + if (state != STATE_SEND_PACKETS) { + LOG_WARN("Ignore MqttClientProxy message while completing config handshake"); + break; + } if (mqtt && moduleConfig.mqtt.proxy_to_client_enabled && moduleConfig.mqtt.enabled && (channels.anyMqttEnabled() || moduleConfig.mqtt.map_reporting_enabled)) { mqtt->onClientProxyReceive(toRadioScratch.mqttClientProxyMessage); From 5953b4704e5ef79242b907f88e1dabaa7569951f Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 16 Oct 2025 14:01:04 -0500 Subject: [PATCH 08/13] Force CannedMessages to another node to be a PKI DM (#8373) --- src/modules/CannedMessageModule.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index e9f52bb7d..9f95a9e20 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -255,7 +255,7 @@ void CannedMessageModule::updateDestinationSelectionList() for (size_t i = 0; i < numMeshNodes; ++i) { meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i); - if (!node || node->num == myNodeNum) + if (!node || node->num == myNodeNum || !node->has_user || node->user.public_key.size != 32) continue; const String &nodeName = node->user.long_name; @@ -976,6 +976,8 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha LOG_INFO("Proactively adding %x as favorite node", p->to); nodeDB->set_favorite(true, p->to); screen->setFrames(graphics::Screen::FOCUS_PRESERVE); + p->pki_encrypted = true; + p->channel = 0; } // Send to mesh and phone (even if no phone connected, to track ACKs) From 32ebc70bcad1489e766af441bdeeca03f0115ab3 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 17 Oct 2025 09:01:14 +1100 Subject: [PATCH 09/13] Update exempt labels for stale bot configuration Adds triaged and backlog to the list of exempt labels. --- .github/workflows/stale_bot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index b528f80b2..11ba59386 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -22,5 +22,5 @@ jobs: days-before-stale: 45 stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. close-issue-message: This issue has not had any comment since the last notice. It has been closed automatically. If this is incorrect, or the issue becomes relevant again, please request that it is reopened. - exempt-issue-labels: pinned,3.0 - exempt-pr-labels: pinned,3.0 + exempt-issue-labels: pinned,3.0,triaged,backlog + exempt-pr-labels: pinned,3.0,triaged,backlog From 4df79374b0e220918eaa9c35f4a004653125afd6 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 19 Oct 2025 08:52:03 +1100 Subject: [PATCH 10/13] manual merge stale bot config (#8392) --- .github/workflows/stale_bot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index 441d53ee3..11ba59386 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -20,5 +20,7 @@ jobs: uses: actions/stale@v10.1.0 with: days-before-stale: 45 + stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. + close-issue-message: This issue has not had any comment since the last notice. It has been closed automatically. If this is incorrect, or the issue becomes relevant again, please request that it is reopened. exempt-issue-labels: pinned,3.0,triaged,backlog exempt-pr-labels: pinned,3.0,triaged,backlog From e5d67310d6c6d76881c087b23c243ed6db70803b Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 19 Oct 2025 08:52:56 +1100 Subject: [PATCH 11/13] Master ---> Develop (#8391) * Update exempt labels for stale bot workflow Adds triaged and backlog to the list of exempt labels. * Update meshtastic/web to v2.6.7 (#8381) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update DFRobot_RTU to v1.0.6 (#8387) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update mcr.microsoft.com/devcontainers/cpp Docker tag to v2 (#8375) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * manual merge stale bot config (#8392) --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- bin/web.version | 2 +- platformio.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 30af24bd2..a2c56fad9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,7 +1,7 @@ # trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions -FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12 +FROM mcr.microsoft.com/devcontainers/cpp:2-debian-12 USER root diff --git a/bin/web.version b/bin/web.version index 952f449f1..ba5c9fca6 100644 --- a/bin/web.version +++ b/bin/web.version @@ -1 +1 @@ -2.6.6 \ No newline at end of file +2.6.7 \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 376f6e5a8..7c63ad7ad 100644 --- a/platformio.ini +++ b/platformio.ini @@ -164,7 +164,7 @@ lib_deps = # renovate: datasource=custom.pio depName=QMC5883L Compass packageName=mprograms/library/QMC5883LCompass mprograms/QMC5883LCompass@1.2.3 # renovate: datasource=custom.pio depName=DFRobot_RTU packageName=dfrobot/library/DFRobot_RTU - dfrobot/DFRobot_RTU@1.0.3 + dfrobot/DFRobot_RTU@1.0.6 # renovate: datasource=git-refs depName=DFRobot_RainfallSensor packageName=https://github.com/DFRobot/DFRobot_RainfallSensor gitBranch=master https://github.com/DFRobot/DFRobot_RainfallSensor/archive/38fea5e02b40a5430be6dab39a99a6f6347d667e.zip # renovate: datasource=custom.pio depName=INA226 packageName=robtillaart/library/INA226 From af8407aca9476398de49db15e723088de257275f Mon Sep 17 00:00:00 2001 From: "Daniel.Cao" <144674500+DanielCao0@users.noreply.github.com> Date: Sun, 19 Oct 2025 05:53:39 +0800 Subject: [PATCH 12/13] Board support: RAK3401+RAK13302 1-watt (#8140) * Add RAK3401 variant files * Add SPI configuration for RAK3401 and RAK13302 variants * Refactor SPI pin configuration and clean up variant definitions for RAK3401 * Add TX_GAIN_LORA for RAK13302 Power Amp * Fix merge --------- Co-authored-by: Ben Meadors Co-authored-by: Tom Fifield Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com> --- src/configuration.h | 5 + src/main.cpp | 7 + .../nrf52840/rak3401_1watt/platformio.ini | 31 +++ variants/nrf52840/rak3401_1watt/variant.cpp | 45 ++++ variants/nrf52840/rak3401_1watt/variant.h | 226 ++++++++++++++++++ 5 files changed, 314 insertions(+) create mode 100644 variants/nrf52840/rak3401_1watt/platformio.ini create mode 100644 variants/nrf52840/rak3401_1watt/variant.cpp create mode 100644 variants/nrf52840/rak3401_1watt/variant.h diff --git a/src/configuration.h b/src/configuration.h index c6c8d673c..baf24a636 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -126,6 +126,11 @@ along with this program. If not, see . #define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7 #endif +#ifdef RAK13302 +#define NUM_PA_POINTS 22 +#define TX_GAIN_LORA 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8 +#endif + // Default system gain to 0 if not defined #ifndef TX_GAIN_LORA #define TX_GAIN_LORA 0 diff --git a/src/main.cpp b/src/main.cpp index bb97a1aa6..3801f6f9f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -841,7 +841,14 @@ void setup() SPI.begin(); } #elif !defined(ARCH_ESP32) // ARCH_RP2040 +#if defined(RAK3401) || defined(RAK13302) + pinMode(WB_IO2, OUTPUT); + digitalWrite(WB_IO2, HIGH); + SPI1.setPins(LORA_MISO, LORA_SCK, LORA_MOSI); + SPI1.begin(); +#else SPI.begin(); +#endif #else // ESP32 #if defined(HW_SPI1_DEVICE) diff --git a/variants/nrf52840/rak3401_1watt/platformio.ini b/variants/nrf52840/rak3401_1watt/platformio.ini new file mode 100644 index 000000000..1a915a6b3 --- /dev/null +++ b/variants/nrf52840/rak3401_1watt/platformio.ini @@ -0,0 +1,31 @@ +; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 +[env:rak3401-1watt] +extends = nrf52840_base +board = wiscore_rak4631 +board_check = true +build_flags = ${nrf52840_base.build_flags} + -Ivariants/nrf52840/rak3401_1watt + -D RAK_4631 +; -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. + -D RAK3401 + -D RAK13302 ; RAK 1Watt Power Amplifier + -DRADIOLIB_EXCLUDE_SX128X=1 + -DRADIOLIB_EXCLUDE_SX127X=1 + -DRADIOLIB_EXCLUDE_LR11X0=1 +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak3401_1watt> + +lib_deps = + ${nrf52840_base.lib_deps} + ${networking_base.lib_deps} + melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 + beegee-tokyo/RAK12035_SoilMoisture@^1.0.4 + https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip + +; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) +; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds +;upload_protocol = jlink + +; Allows programming and debug via the RAK NanoDAP as the default debugger tool for the RAK4631 (it is only $10!) +; programming time is about the same as the bootloader version. +; For information on this see the meshtastic developers documentation for "Development on the NRF52" + diff --git a/variants/nrf52840/rak3401_1watt/variant.cpp b/variants/nrf52840/rak3401_1watt/variant.cpp new file mode 100644 index 000000000..e84b60b3b --- /dev/null +++ b/variants/nrf52840/rak3401_1watt/variant.cpp @@ -0,0 +1,45 @@ +/* + 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[] = { + // P0 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + + // P1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; + +void initVariant() +{ + // LED1 & LED2 + pinMode(PIN_LED1, OUTPUT); + ledOff(PIN_LED1); + + pinMode(PIN_LED2, OUTPUT); + ledOff(PIN_LED2); + + // 3V3 Power Rail + pinMode(PIN_3V3_EN, OUTPUT); + digitalWrite(PIN_3V3_EN, HIGH); +} diff --git a/variants/nrf52840/rak3401_1watt/variant.h b/variants/nrf52840/rak3401_1watt/variant.h new file mode 100644 index 000000000..d4bb1a175 --- /dev/null +++ b/variants/nrf52840/rak3401_1watt/variant.h @@ -0,0 +1,226 @@ +/* + 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_RAK3401_ +#define _VARIANT_RAK3401_ + +#define RAK4630 + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal for LF +// define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (6) +#define NUM_ANALOG_OUTPUTS (0) + +// LEDs +#define PIN_LED1 (35) +#define PIN_LED2 (36) + +#define LED_BUILTIN PIN_LED1 +#define LED_CONN PIN_LED2 + +#define LED_GREEN PIN_LED1 +#define LED_BLUE PIN_LED2 + +#define LED_STATE_ON 1 // State when LED is litted + +/* + * Analog pins + */ +#define PIN_A0 (5) +#define PIN_A1 (31) +#define PIN_A2 (28) +#define PIN_A3 (29) +#define PIN_A4 (30) +#define PIN_A5 (31) +#define PIN_A6 (0xff) +#define PIN_A7 (0xff) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +#define ADC_RESOLUTION 14 + +// Other pins +#define WB_I2C1_SDA (13) // SENSOR_SLOT IO_SLOT +#define WB_I2C1_SCL (14) // SENSOR_SLOT IO_SLOT + +#define PIN_AREF (2) +#define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) +#define PIN_NFC2 (10) + +static const uint8_t AREF = PIN_AREF; + +/* + * Serial interfaces + */ +#define PIN_SERIAL1_RX (15) +#define PIN_SERIAL1_TX (16) + +// Connected to Jlink CDC +#define PIN_SERIAL2_RX (8) +#define PIN_SERIAL2_TX (6) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (45) +#define PIN_SPI_MOSI (44) +#define PIN_SPI_SCK (43) + +#define PIN_SPI1_MISO (29) // (0 + 29) +#define PIN_SPI1_MOSI (30) // (0 + 30) +#define PIN_SPI1_SCK (3) // (0 + 3) + +static const uint8_t SS = 42; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * eink display pins + */ +#define PIN_EINK_CS (0 + 26) +#define PIN_EINK_BUSY (0 + 4) +#define PIN_EINK_DC (0 + 17) +#define PIN_EINK_RES (-1) +#define PIN_EINK_SCLK (0 + 3) +#define PIN_EINK_MOSI (0 + 30) // also called SDI + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (WB_I2C1_SDA) +#define PIN_WIRE_SCL (WB_I2C1_SCL) + +// QSPI Pins +#define PIN_QSPI_SCK 3 +#define PIN_QSPI_CS 26 +#define PIN_QSPI_IO0 30 +#define PIN_QSPI_IO1 29 +#define PIN_QSPI_IO2 28 +#define PIN_QSPI_IO3 2 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES IS25LP080D +#define EXTERNAL_FLASH_USE_QSPI + +// 1watt sx1262 RAK13302 +#define HW_SPI1_DEVICE 1 + +#define LORA_SCK PIN_SPI1_SCK +#define LORA_MISO PIN_SPI1_MISO +#define LORA_MOSI PIN_SPI1_MOSI +#define LORA_CS 26 + +#define USE_SX1262 +#define SX126X_CS (26) +#define SX126X_DIO1 (10) +#define SX126X_BUSY (9) +#define SX126X_RESET (4) + +#define SX126X_POWER_EN (21) +// 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 + +// Testing USB detection +#define NRF_APM +// If using a power chip like the INA3221 you can override the default battery voltage channel below +// and comment out NRF_APM to use the INA3221 instead of the USB detection for charging +// #define INA3221_BAT_CH INA3221_CH2 +// #define INA3221_ENV_CH INA3221_CH1 + +// enables 3.3V periphery like GPS or IO Module +// Do not toggle this for GPS power savings +#define PIN_3V3_EN (34) +#define WB_IO2 PIN_3V3_EN + +// RAK1910 GPS module +// If using the wisblock GPS module and pluged into Port A on WisBlock base +// IO1 is hooked to PPS (pin 12 on header) = gpio 17 +// IO2 is hooked to GPS RESET = gpio 34, but it can not be used to this because IO2 is ALSO used to control 3V3_S power (1 is on). +// Therefore must be 1 to keep peripherals powered +// Power is on the controllable 3V3_S rail +// #define PIN_GPS_RESET (34) +// #define PIN_GPS_EN PIN_3V3_EN +#define PIN_GPS_PPS (17) // Pulse per second input from the GPS + +#define GPS_RX_PIN PIN_SERIAL1_RX +#define GPS_TX_PIN PIN_SERIAL1_TX + +// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press + +// RAK12002 RTC Module +#define RV3028_RTC (uint8_t)0b1010010 + +// RAK18001 Buzzer in Slot C +// #define PIN_BUZZER 21 // IO3 is PWM2 +// NEW: set this via protobuf instead! + +// Battery +// The battery sense is hooked to pin A0 (5) +#define BATTERY_PIN PIN_A0 +// and has 12 bit resolution +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define BATTERY_SENSE_RESOLUTION 4096.0 +#undef AREF_VOLTAGE +#define AREF_VOLTAGE 3.0 +#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 +#define ADC_MULTIPLIER 1.73 + +#define HAS_RTC 1 + +#define RAK_4631 1 + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif From e1c259ae32ade6524f43898d65fdc6c2282befe4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 18 Oct 2025 18:21:24 -0500 Subject: [PATCH 13/13] Update protobufs (#8396) Co-authored-by: fifieldt <1287116+fifieldt@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/telemetry.pb.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/protobufs b/protobufs index 38638f19f..4a618380a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 38638f19f84ad886222b484d6bf5a8459aed8c7e +Subproject commit 4a618380a0d80b476bb7f278008f811f456e0a5f diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index a8ca96e95..dec89ba15 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -101,7 +101,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* SEN5X PM SENSORS */ meshtastic_TelemetrySensorType_SEN5X = 43, /* TSL2561 light sensor */ - meshtastic_TelemetrySensorType_TSL2561 = 44 + meshtastic_TelemetrySensorType_TSL2561 = 44, + /* BH1750 light sensor */ + meshtastic_TelemetrySensorType_BH1750 = 45 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -438,8 +440,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET -#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_TSL2561 -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_TSL2561+1)) +#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_BH1750 +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_BH1750+1))