From 1877a2c5311c2892d032bff5a9cee3d3a99f23f0 Mon Sep 17 00:00:00 2001 From: Ford Jones <107664313+ford-jones@users.noreply.github.com> Date: Fri, 15 Aug 2025 22:31:11 +1200 Subject: [PATCH 01/17] Prompt user to select destination upon launch of canned message module (#7624) Co-authored-by: Jason P --- src/modules/CannedMessageModule.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index b6cb1b0e3..d40dcd24f 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -78,16 +78,15 @@ void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChan lastDestSet = true; // Rest of function unchanged... - // Always select the first real canned message on activation - int firstRealMsgIdx = 0; + // Upon activation, highlight "[Select Destination]" + int selectDestination = 0; for (int i = 0; i < messagesCount; ++i) { - if (strcmp(messages[i], "[Select Destination]") != 0 && strcmp(messages[i], "[Exit]") != 0 && - strcmp(messages[i], "[---- Free Text ----]") != 0) { - firstRealMsgIdx = i; + if (strcmp(messages[i], "[Select Destination]") == 0) { + selectDestination = i; break; } } - currentMessageIndex = firstRealMsgIdx; + currentMessageIndex = selectDestination; // This triggers the canned message list runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; @@ -999,17 +998,16 @@ int32_t CannedMessageModule::runOnce() this->notifyObservers(&e); return 2000; } - // Always highlight the first real canned message when entering the message list + // Highlight [Select Destination] initially when entering the message list else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) { - int firstRealMsgIdx = 0; + int selectDestination = 0; for (int i = 0; i < this->messagesCount; ++i) { - if (strcmp(this->messages[i], "[Select Destination]") != 0 && strcmp(this->messages[i], "[Exit]") != 0 && - strcmp(this->messages[i], "[---- Free Text ----]") != 0) { - firstRealMsgIdx = i; + if (strcmp(this->messages[i], "[Select Destination]") == 0) { + selectDestination = i; break; } } - this->currentMessageIndex = firstRealMsgIdx; + this->currentMessageIndex = selectDestination; e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) { From 062168cd4245d7a12859dbed09b696a01bbe6ea0 Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 15 Aug 2025 07:19:49 -0400 Subject: [PATCH 02/17] Docker: Update Debian images to trixie (#7621) --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index e033b1bba..6a2ddeece 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions -FROM python:3.13-bookworm AS builder +FROM python:3.13-slim-trixie AS builder ARG PIO_ENV=native ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Etc/UTC @@ -36,7 +36,7 @@ RUN curl -L "https://github.com/meshtastic/web/releases/download/v$(cat /tmp/fir ##### PRODUCTION BUILD ############# -FROM debian:bookworm-slim +FROM debian:trixie-slim LABEL org.opencontainers.image.title="Meshtastic" \ org.opencontainers.image.description="Debian Meshtastic daemon and web interface" \ org.opencontainers.image.url="https://meshtastic.org" \ @@ -51,8 +51,8 @@ ENV TZ=Etc/UTC USER root RUN apt-get update && apt-get --no-install-recommends -y install \ - libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev \ - liborcania2.3 libulfius2.7 libssl3 \ + libc-bin libc6 libgpiod3 libyaml-cpp0.8 libi2c0 libuv1t64 libusb-1.0-0-dev \ + liborcania2.3 libulfius2.7t64 libssl3t64 \ libx11-6 libinput10 libxkbcommon-x11-0 \ && apt-get clean && rm -rf /var/lib/apt/lists/* \ && mkdir -p /var/lib/meshtasticd \ From c8694f9f2d6a6bd7b38afd421b753f5faaeb644d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 15 Aug 2025 07:03:14 -0500 Subject: [PATCH 03/17] Fix Tracerouter warnings (#7637) * Static cast to avoid signed comparison * Another one --- src/modules/TraceRouteModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp index f4eccd667..d7df90bb5 100644 --- a/src/modules/TraceRouteModule.cpp +++ b/src/modules/TraceRouteModule.cpp @@ -602,7 +602,7 @@ void TraceRouteModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state int start = 0; int newlinePos = resultText.indexOf('\n', start); - while (newlinePos != -1 || start < resultText.length()) { + while (newlinePos != -1 || start < static_cast(resultText.length())) { String segment; if (newlinePos != -1) { segment = resultText.substring(start, newlinePos); @@ -624,7 +624,7 @@ void TraceRouteModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state int lastGoodBreak = -1; bool lineComplete = false; - for (int i = 0; i < remaining.length(); i++) { + for (int i = 0; i < static_cast(remaining.length()); i++) { char ch = remaining.charAt(i); String testLine = tempLine + ch; From a7be93449eb989b8018bd89277ddfa9ff0ec45ec Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 15 Aug 2025 09:00:09 -0500 Subject: [PATCH 04/17] Spacing --- src/graphics/fonts/OLEDDisplayFontsCS.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/fonts/OLEDDisplayFontsCS.cpp b/src/graphics/fonts/OLEDDisplayFontsCS.cpp index 67208b4d9..8d506e009 100644 --- a/src/graphics/fonts/OLEDDisplayFontsCS.cpp +++ b/src/graphics/fonts/OLEDDisplayFontsCS.cpp @@ -1,3 +1,5 @@ +#ifdef OLED_CS + #include "OLEDDisplayFontsCS.h" // Font generated or edited with the glyphEditor From e1e89a5e620390e1b7b26dfd3457bf1b278f8474 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 15 Aug 2025 09:03:21 -0500 Subject: [PATCH 05/17] Don't include OLED fonts for international character sets by default (#7639) --- src/graphics/ScreenFonts.h | 4 ++-- src/graphics/fonts/EinkDisplayFonts.cpp | 4 ++++ src/graphics/fonts/EinkDisplayFonts.h | 5 +++++ src/graphics/fonts/OLEDDisplayFontsCS.cpp | 4 +++- src/graphics/fonts/OLEDDisplayFontsPL.cpp | 5 ++++- src/graphics/fonts/OLEDDisplayFontsRU.cpp | 6 +++++- src/graphics/fonts/OLEDDisplayFontsUA.cpp | 6 +++++- 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/graphics/ScreenFonts.h b/src/graphics/ScreenFonts.h index 92bdb7641..84ec45977 100644 --- a/src/graphics/ScreenFonts.h +++ b/src/graphics/ScreenFonts.h @@ -16,7 +16,7 @@ #include "graphics/fonts/OLEDDisplayFontsCS.h" #endif -#ifdef CROWPANEL_ESP32S3_5_EPAPER +#if defined(CROWPANEL_ESP32S3_5_EPAPER) && defined(USE_EINK) #include "graphics/fonts/EinkDisplayFonts.h" #endif @@ -85,7 +85,7 @@ #define FONT_LARGE FONT_LARGE_LOCAL // Height: 28 #endif -#if defined(CROWPANEL_ESP32S3_5_EPAPER) +#if defined(CROWPANEL_ESP32S3_5_EPAPER) && defined(USE_EINK) #undef FONT_SMALL #undef FONT_MEDIUM #undef FONT_LARGE diff --git a/src/graphics/fonts/EinkDisplayFonts.cpp b/src/graphics/fonts/EinkDisplayFonts.cpp index cfe2c931f..497b3b389 100644 --- a/src/graphics/fonts/EinkDisplayFonts.cpp +++ b/src/graphics/fonts/EinkDisplayFonts.cpp @@ -1,3 +1,5 @@ +#ifdef USE_EINK + #include "EinkDisplayFonts.h" // Created by https://oleddisplay.squix.ch/ Consider a donation @@ -1182,3 +1184,5 @@ const uint8_t Monospaced_plain_30[] PROGMEM = { 0xF0, 0xFF, 0x01, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x00, 0xFE, 0x03, 0x00, 0xE0, 0x80, 0x7F, 0x00, 0x00, 0xE0, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x10 // 255 }; + +#endif // USE_EINK diff --git a/src/graphics/fonts/EinkDisplayFonts.h b/src/graphics/fonts/EinkDisplayFonts.h index 342525a19..a4a44ba47 100644 --- a/src/graphics/fonts/EinkDisplayFonts.h +++ b/src/graphics/fonts/EinkDisplayFonts.h @@ -1,6 +1,8 @@ #ifndef EINKDISPLAYFONTS_h #define EINKDISPLAYFONTS_h +#ifdef USE_EINK + #ifdef ARDUINO #include #elif __MBED__ @@ -11,4 +13,7 @@ * Monospaced Plain 30 */ extern const uint8_t Monospaced_plain_30[] PROGMEM; + +#endif // USE_EINK + #endif diff --git a/src/graphics/fonts/OLEDDisplayFontsCS.cpp b/src/graphics/fonts/OLEDDisplayFontsCS.cpp index 8d506e009..c8045285e 100644 --- a/src/graphics/fonts/OLEDDisplayFontsCS.cpp +++ b/src/graphics/fonts/OLEDDisplayFontsCS.cpp @@ -1862,4 +1862,6 @@ const uint8_t ArialMT_Plain_24_CS[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0xC0, 0xF0, 0x01, 0x06, 0xC0, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0xC0, 0xC0, 0x1F, 0x00, 0xC0, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 255 -}; \ No newline at end of file +}; + +#endif // OLED_CS \ No newline at end of file diff --git a/src/graphics/fonts/OLEDDisplayFontsPL.cpp b/src/graphics/fonts/OLEDDisplayFontsPL.cpp index 0767e24e7..00f0913fe 100644 --- a/src/graphics/fonts/OLEDDisplayFontsPL.cpp +++ b/src/graphics/fonts/OLEDDisplayFontsPL.cpp @@ -1,4 +1,5 @@ // trunk-ignore-all(clang-format): Preserve long lines +#ifdef OLED_PL #include "OLEDDisplayFontsPL.h" const uint8_t ArialMT_Plain_10_PL[] PROGMEM = { @@ -1310,4 +1311,6 @@ const uint8_t ArialMT_Plain_24_PL[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0x00, 0xF0, 0x01, 0x06, 0x00, 0x80, 0x0F, 0x07, 0x80, 0x00, 0xFE, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x60, 0xC0, 0x1F, 0x00, 0x20, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x00, 0x1C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x03, // 254 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0xC0, 0xF0, 0x01, 0x06, 0xC0, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0xC0, 0xC0, 0x1F, 0x00, 0xC0, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 255 -}; \ No newline at end of file +}; + +#endif // OLED_PL \ No newline at end of file diff --git a/src/graphics/fonts/OLEDDisplayFontsRU.cpp b/src/graphics/fonts/OLEDDisplayFontsRU.cpp index 2b85727c2..3a1159511 100644 --- a/src/graphics/fonts/OLEDDisplayFontsRU.cpp +++ b/src/graphics/fonts/OLEDDisplayFontsRU.cpp @@ -1,3 +1,5 @@ +#ifdef OLED_RU + #include "OLEDDisplayFontsRU.h" // Font generated or edited with the glyphEditor @@ -1762,4 +1764,6 @@ const uint8_t ArialMT_Plain_24_RU[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x00, 0xFC, 0x38, 0x00, 0x00, 0xCC, 0x1D, 0x00, 0x00, 0x8C, 0x0F, 0x00, 0x00, 0x84, 0x03, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFC, 0x3F, // 255 -}; \ No newline at end of file +}; + +#endif // OLED_RU \ No newline at end of file diff --git a/src/graphics/fonts/OLEDDisplayFontsUA.cpp b/src/graphics/fonts/OLEDDisplayFontsUA.cpp index 2a97526ef..8bc56ea94 100644 --- a/src/graphics/fonts/OLEDDisplayFontsUA.cpp +++ b/src/graphics/fonts/OLEDDisplayFontsUA.cpp @@ -1,3 +1,5 @@ +#ifdef OLED_UA + #include "OLEDDisplayFontsUA.h" // Font generated or edited with the glyphEditor @@ -1920,4 +1922,6 @@ const uint8_t ArialMT_Plain_24_UA[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC1, 0x00, 0x00, 0xF0, 0xE3, 0x00, 0x00, 0x38, 0x7B, 0x00, 0x00, 0x18, 0x1A, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0xF8, 0xFF, // 1103 -}; \ No newline at end of file +}; + +#endif // OLED_UA \ No newline at end of file From 8d5ae1d5d26debc5b33f7a260cff029d56078189 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Fri, 15 Aug 2025 19:09:25 +0200 Subject: [PATCH 06/17] Fix marking LoRa transport mechanism (#7634) --- src/mesh/RadioInterface.cpp | 4 +++- src/mesh/Router.cpp | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 99e99922b..c210d5d48 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -666,8 +666,10 @@ void RadioInterface::limitPower(int8_t loraMaxPower) void RadioInterface::deliverToReceiver(meshtastic_MeshPacket *p) { - if (router) + if (router) { + p->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA; router->enqueueReceivedMessage(p); + } } /*** diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 065d627e9..a54dcb976 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -66,7 +66,6 @@ int32_t Router::runOnce() { meshtastic_MeshPacket *mp; while ((mp = fromRadioQueue.dequeuePtr(0)) != NULL) { - mp->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA; // printPacket("handle fromRadioQ", mp); perhapsHandleReceived(mp); } From 4a241deb968470e9b953a16071b8d045aeef6ed9 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 15 Aug 2025 14:41:21 -0500 Subject: [PATCH 07/17] Thinknode button and backlight fixes (#7641) * Thinknode button and backlight fixes * Save backlight value between reboots --- platformio.ini | 4 ++-- src/graphics/Screen.cpp | 20 +++++++++---------- src/graphics/draw/MenuHandler.cpp | 18 ++++++++++++++--- src/input/ButtonThread.cpp | 5 ++++- src/main.cpp | 1 - .../esp32s3/ELECROW-ThinkNode-M5/variant.h | 2 +- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/platformio.ini b/platformio.ini index 62bbf8a24..520ec740e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -61,8 +61,8 @@ monitor_filters = direct lib_deps = # renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master https://github.com/meshtastic/esp8266-oled-ssd1306/archive/0119501e9983bd894830b02f545c377ee08d66fe.zip - # renovate: datasource=custom.pio depName=OneButton packageName=mathertel/library/OneButton - mathertel/OneButton@2.6.1 + # renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master + https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip # renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master https://github.com/meshtastic/arduino-fsm/archive/7db3702bf0cfe97b783d6c72595e3f38e0b19159.zip # renovate: datasource=git-refs depName=meshtastic-TinyGPSPlus packageName=https://github.com/meshtastic/TinyGPSPlus gitBranch=master diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 8d5635f89..88955145a 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -365,9 +365,6 @@ void Screen::doDeepSleep() { #ifdef USE_EINK setOn(false, graphics::UIRenderer::drawDeepSleepFrame); -#ifdef PIN_EINK_EN - digitalWrite(PIN_EINK_EN, LOW); // power off backlight -#endif #else // Without E-Ink display: setOn(false); @@ -391,8 +388,12 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) dispdev->displayOn(); #endif -#ifdef ELECROW_ThinkNode_M5 - io.digitalWrite(PCA_PIN_EINK_EN, HIGH); +#ifdef PIN_EINK_EN + if (uiconfig.screen_brightness == 1) + digitalWrite(PIN_EINK_EN, HIGH); +#elif defined(PCA_PIN_EINK_EN) + if (uiconfig.screen_brightness == 1) + io.digitalWrite(PCA_PIN_EINK_EN, HIGH); #endif #if defined(ST7789_CS) && \ @@ -424,13 +425,10 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver) // eInkScreensaver parameter is usually NULL (default argument), default frame used instead setScreensaverFrames(einkScreensaver); #endif -#ifdef ELECROW_ThinkNode_M1 - if (digitalRead(PIN_EINK_EN) == HIGH) { - digitalWrite(PIN_EINK_EN, LOW); - } -#endif -#ifdef ELECROW_ThinkNode_M5 +#ifdef PIN_EINK_EN + digitalWrite(PIN_EINK_EN, LOW); +#elif defined(PCA_PIN_EINK_EN) io.digitalWrite(PCA_PIN_EINK_EN, LOW); #endif diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index b7bd068c4..fa738309a 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -318,7 +318,7 @@ void menuHandler::homeBaseMenu() static int optionsEnumArray[enumEnd] = {Back}; int options = 1; -#ifdef PIN_EINK_EN +#if defined(PIN_EINK_EN) || defined(PCA_PIN_EINK_EN) optionsArray[options] = "Toggle Backlight"; optionsEnumArray[options++] = Backlight; #else @@ -342,12 +342,24 @@ void menuHandler::homeBaseMenu() bannerOptions.optionsCount = options; bannerOptions.bannerCallback = [](int selected) -> void { if (selected == Backlight) { -#ifdef PIN_EINK_EN - if (digitalRead(PIN_EINK_EN) == HIGH) { +#if defined(PIN_EINK_EN) + if (uiconfig.screen_brightness == 1) { + uiconfig.screen_brightness = 0; digitalWrite(PIN_EINK_EN, LOW); } else { + uiconfig.screen_brightness = 1; digitalWrite(PIN_EINK_EN, HIGH); } + saveUIConfig(); +#elif defined(PCA_PIN_EINK_EN) + if (uiconfig.screen_brightness == 1) { + uiconfig.screen_brightness = 0; + io.digitalWrite(PCA_PIN_EINK_EN, LOW); + } else { + uiconfig.screen_brightness = 1; + io.digitalWrite(PCA_PIN_EINK_EN, HIGH); + } + saveUIConfig(); #endif } else if (selected == Sleep) { screen->setOn(false); diff --git a/src/input/ButtonThread.cpp b/src/input/ButtonThread.cpp index 233bbefe0..f26b3c970 100644 --- a/src/input/ButtonThread.cpp +++ b/src/input/ButtonThread.cpp @@ -92,8 +92,11 @@ bool ButtonThread::initButton(const ButtonConfig &config) if (config.shortLong != INPUT_BROKER_NONE) { _shortLong = config.shortLong; } - +#ifdef USE_EINK + userButton.setDebounceMs(0); +#else userButton.setDebounceMs(1); +#endif userButton.setPressMs(_longPressTime); if (screen) { diff --git a/src/main.cpp b/src/main.cpp index 9e46021c9..c5be175c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -304,7 +304,6 @@ void setup() Wire.begin(48, 47); io.pinMode(PCA_PIN_EINK_EN, OUTPUT); io.pinMode(PCA_PIN_POWER_EN, OUTPUT); - io.digitalWrite(PCA_PIN_EINK_EN, HIGH); io.digitalWrite(PCA_PIN_POWER_EN, HIGH); // io.pinMode(C2_PIN, OUTPUT); #endif diff --git a/variants/esp32s3/ELECROW-ThinkNode-M5/variant.h b/variants/esp32s3/ELECROW-ThinkNode-M5/variant.h index 61d6149d2..a55808170 100644 --- a/variants/esp32s3/ELECROW-ThinkNode-M5/variant.h +++ b/variants/esp32s3/ELECROW-ThinkNode-M5/variant.h @@ -61,7 +61,7 @@ #define LORA_DIO1 SX126X_DIO1 #define USE_EINK -#define PIN_EINK_EN -1 // Note: this is really just backlight power +// Note: this is really just backlight power #define PCA_PIN_EINK_EN 5 // This is the pin number on the GPIO expander #define PIN_EINK_CS 39 #define PIN_EINK_BUSY 42 From 0046d957f1ead3cd4da5632d91c6a2a1fafefc6c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 21:42:51 +0200 Subject: [PATCH 08/17] Update protobufs (#7647) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index e2c0831aa..5dd723fe6 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit e2c0831aa3d34a58a36c2b9fdcb828e58961cbc5 +Subproject commit 5dd723fe6f33a8613ec81acf5e15be26365c7cce diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 1d1ff47e0..ce3722aa7 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -270,6 +270,8 @@ typedef enum _meshtastic_HardwareModel { /* MeshSolar is an integrated power management and communication solution designed for outdoor low-power devices. https://heltec.org/project/meshsolar/ */ meshtastic_HardwareModel_HELTEC_MESH_SOLAR = 108, + /* Lilygo T-Echo Lite */ + meshtastic_HardwareModel_T_ECHO_LITE = 109, /* ------------------------------------------------------------------------------------------------------------------------------------------ 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 a02017a5c8e2f5506e7222babff855e886ee3c1e Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 15 Aug 2025 19:45:41 -0500 Subject: [PATCH 09/17] Remove JSON serialization from most NRF52 targets (#7640) * Remove JSON serialization from most NRF52 targets * Slin networking base down for NRF52 by removing syslog * Update platformio.ini --- arch/nrf52/nrf52.ini | 2 +- platformio.ini | 8 ++++++++ variants/nrf52840/rak2560/platformio.ini | 4 ++-- variants/nrf52840/rak4631/platformio.ini | 2 +- variants/nrf52840/rak4631_eth_gw/platformio.ini | 2 +- variants/nrf52840/rak_wismeshtap/platformio.ini | 2 +- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini index 4a77ec4b2..36effe017 100644 --- a/arch/nrf52/nrf52.ini +++ b/arch/nrf52/nrf52.ini @@ -23,7 +23,7 @@ build_flags = -DMESHTASTIC_EXCLUDE_PAXCOUNTER=1 build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - - - lib_deps= ${arduino_base.lib_deps} diff --git a/platformio.ini b/platformio.ini index 520ec740e..528563def 100644 --- a/platformio.ini +++ b/platformio.ini @@ -102,6 +102,14 @@ lib_deps = # renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog arcao/Syslog@2.0.0 +; Minimal networking libs for nrf52 (excludes Syslog to save flash) +[nrf52_networking_base] +lib_deps = + # renovate: datasource=custom.pio depName=TBPubSubClient packageName=thingsboard/library/TBPubSubClient + thingsboard/TBPubSubClient@2.12.1 + # renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient + arduino-libraries/NTPClient@3.2.1 + [radiolib_base] lib_deps = # renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib diff --git a/variants/nrf52840/rak2560/platformio.ini b/variants/nrf52840/rak2560/platformio.ini index 2b73aca03..edc648b9b 100644 --- a/variants/nrf52840/rak2560/platformio.ini +++ b/variants/nrf52840/rak2560/platformio.ini @@ -11,10 +11,10 @@ build_flags = ${nrf52840_base.build_flags} -DRADIOLIB_EXCLUDE_SX127X=1 -DRADIOLIB_EXCLUDE_LR11X0=1 -DHAS_RAKPROT=1 ; Define if RAk OneWireSerial is used (disables GPS) -build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak2560> + + +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak2560> + + + lib_deps = ${nrf52840_base.lib_deps} - ${networking_base.lib_deps} + ${nrf52_networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/beegee-tokyo/RAK-OneWireSerial/archive/0.0.2.zip debug_tool = jlink diff --git a/variants/nrf52840/rak4631/platformio.ini b/variants/nrf52840/rak4631/platformio.ini index 199e17570..83feaa06c 100644 --- a/variants/nrf52840/rak4631/platformio.ini +++ b/variants/nrf52840/rak4631/platformio.ini @@ -17,7 +17,7 @@ build_flags = ${nrf52840_base.build_flags} build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631> + + + lib_deps = ${nrf52840_base.lib_deps} - ${networking_base.lib_deps} + ${nrf52_networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S/archive/1.0.2.zip rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 diff --git a/variants/nrf52840/rak4631_eth_gw/platformio.ini b/variants/nrf52840/rak4631_eth_gw/platformio.ini index a1c1b4610..79cdb28c7 100644 --- a/variants/nrf52840/rak4631_eth_gw/platformio.ini +++ b/variants/nrf52840/rak4631_eth_gw/platformio.ini @@ -24,7 +24,7 @@ build_flags = ${nrf52840_base.build_flags} -DMESHTASTIC_EXCLUDE_STOREFORWARD=1 -DMESHTASTIC_EXCLUDE_CANNEDMESSAGES=1 -DMESHTASTIC_EXCLUDE_WAYPOINT=1 -build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631_eth_gw> + + + +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631_eth_gw> + + + + lib_deps = ${nrf52840_base.lib_deps} ${networking_base.lib_deps} diff --git a/variants/nrf52840/rak_wismeshtap/platformio.ini b/variants/nrf52840/rak_wismeshtap/platformio.ini index f6ee8fd23..adf301537 100644 --- a/variants/nrf52840/rak_wismeshtap/platformio.ini +++ b/variants/nrf52840/rak_wismeshtap/platformio.ini @@ -18,7 +18,7 @@ build_flags = ${nrf52840_base.build_flags} build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak_wismeshtap> + + + lib_deps = ${nrf52840_base.lib_deps} - ${networking_base.lib_deps} + ${nrf52_networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S/archive/1.0.2.zip rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 From 8e552a9f0c0a67b920062123b120b6034c0dfaa4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Aug 2025 05:57:20 -0500 Subject: [PATCH 10/17] Upgrade trunk (#7626) Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com> --- .trunk/trunk.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index f62255aea..10bb1bd00 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,9 +9,9 @@ plugins: lint: enabled: - checkov@3.2.461 - - renovate@41.63.0 + - renovate@41.71.1 - prettier@3.6.2 - - trufflehog@3.90.3 + - trufflehog@3.90.4 - yamllint@1.37.1 - bandit@1.8.6 - trivy@0.64.1 From c64c196778038c0888a8e31651cd1957c6134586 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 16 Aug 2025 06:10:44 -0500 Subject: [PATCH 11/17] Wait for lead up before enable longlong action (#7648) --- src/buzz/buzz.cpp | 4 ++++ src/input/ButtonThread.cpp | 9 +++++---- src/input/ButtonThread.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp index b09d7a82c..b0d162a44 100644 --- a/src/buzz/buzz.cpp +++ b/src/buzz/buzz.cpp @@ -140,6 +140,10 @@ bool playNextLeadUpNote() playTones(¬e, 1); // Play single note using existing playTones function leadUpNoteIndex++; + + if (leadUpNoteIndex >= leadUpNotesCount) { + return false; // this was the final note + } return true; // Note was played (playTones handles buzzer availability internally) } diff --git a/src/input/ButtonThread.cpp b/src/input/ButtonThread.cpp index f26b3c970..32882f7ae 100644 --- a/src/input/ButtonThread.cpp +++ b/src/input/ButtonThread.cpp @@ -140,8 +140,7 @@ int32_t ButtonThread::runOnce() } // Progressive lead-up sound system - if (buttonCurrentlyPressed && (millis() - buttonPressStartTime) >= BUTTON_LEADUP_MS && - (millis() - buttonPressStartTime) < _longLongPressTime) { + if (buttonCurrentlyPressed && (millis() - buttonPressStartTime) >= BUTTON_LEADUP_MS) { // Start the progressive sequence if not already active if (!leadUpSequenceActive) { @@ -153,13 +152,14 @@ int32_t ButtonThread::runOnce() else if ((millis() - lastLeadUpNoteTime) >= 400) { // 400ms interval between notes if (playNextLeadUpNote()) { lastLeadUpNoteTime = millis(); + } else { + leadUpPlayed = true; } } } // Reset when button is released if (!buttonCurrentlyPressed && buttonWasPressed) { - leadUpPlayed = false; leadUpSequenceActive = false; resetLeadUpSequence(); } @@ -256,12 +256,13 @@ int32_t ButtonThread::runOnce() LOG_INFO("LONG PRESS RELEASE AFTER %u MILLIS", millis() - buttonPressStartTime); if (millis() > 30000 && _longLongPress != INPUT_BROKER_NONE && - (millis() - buttonPressStartTime) >= _longLongPressTime) { + (millis() - buttonPressStartTime) >= _longLongPressTime && leadUpPlayed) { evt.inputEvent = _longLongPress; this->notifyObservers(&evt); } // Reset combination tracking waitingForLongPress = false; + leadUpPlayed = false; break; } diff --git a/src/input/ButtonThread.h b/src/input/ButtonThread.h index bbc8da2a7..c6d6557e2 100644 --- a/src/input/ButtonThread.h +++ b/src/input/ButtonThread.h @@ -92,7 +92,7 @@ class ButtonThread : public Observable, public concurrency:: voidFuncPtr _intRoutine = nullptr; uint16_t _longPressTime = 500; - uint16_t _longLongPressTime = 5000; + uint16_t _longLongPressTime = 3900; int _pinNum = 0; bool _activeLow = true; bool _touchQuirk = false; From d538ad170ce1fc3c7203d7c340d1c307ee873f59 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 17 Aug 2025 05:55:00 -0500 Subject: [PATCH 12/17] Add onboard message for devices with screens (#7655) * Add onboard message for devices with screens * Add message for TFT --- src/graphics/Screen.cpp | 2 +- src/graphics/draw/MenuHandler.cpp | 24 ++++++++++++++++++++++ src/graphics/draw/MenuHandler.h | 2 ++ src/graphics/draw/NotificationRenderer.cpp | 7 ++++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 88955145a..fa71e17d8 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -692,7 +692,7 @@ int32_t Screen::runOnce() #ifndef DISABLE_WELCOME_UNSET if (!NotificationRenderer::isOverlayBannerShowing() && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) { - menuHandler::LoraRegionPicker(0); + menuHandler::OnboardMessage(); } #endif if (!NotificationRenderer::isOverlayBannerShowing() && rebootAtMsec != 0) { diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index fa738309a..512f650ec 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -26,6 +26,27 @@ menuHandler::screenMenus menuHandler::menuQueue = menu_none; bool test_enabled = false; uint8_t test_count = 0; +void menuHandler::OnboardMessage() +{ + static const char *optionsArray[] = {"OK", "Got it!"}; + enum optionsNumbers { OK, got }; + BannerOverlayOptions bannerOptions; +#if HAS_TFT + bannerOptions.message = "Welcome to Meshtastic!\nSwipe to navigate and\nlong press to select\nor open a menu."; +#elif defined(BUTTON_PIN) + bannerOptions.message = "Welcome to Meshtastic!\nClick to navigate and\nlong press to select\nor open a menu."; +#else + bannerOptions.message = "Welcome to Meshtastic!\nUse the Select button\nto open menus\nand make selections."; +#endif + bannerOptions.optionsArrayPtr = optionsArray; + bannerOptions.optionsCount = 2; + bannerOptions.bannerCallback = [](int selected) -> void { + menuHandler::menuQueue = menuHandler::no_timeout_lora_picker; + screen->runNow(); + }; + screen->showOverlayBanner(bannerOptions); +} + void menuHandler::LoraRegionPicker(uint32_t duration) { static const char *optionsArray[] = {"Back", @@ -1132,6 +1153,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display) case lora_picker: LoraRegionPicker(); break; + case no_timeout_lora_picker: + LoraRegionPicker(0); + break; case TZ_picker: TZPicker(); break; diff --git a/src/graphics/draw/MenuHandler.h b/src/graphics/draw/MenuHandler.h index 87a0b055e..b15cf237d 100644 --- a/src/graphics/draw/MenuHandler.h +++ b/src/graphics/draw/MenuHandler.h @@ -10,6 +10,7 @@ class menuHandler enum screenMenus { menu_none, lora_picker, + no_timeout_lora_picker, TZ_picker, twelve_hour_picker, clock_face_picker, @@ -41,6 +42,7 @@ class menuHandler }; static screenMenus menuQueue; + static void OnboardMessage(); static void LoraRegionPicker(uint32_t duration = 30000); static void handleMenuSwitch(OLEDDisplay *display); static void showConfirmationBanner(const char *message, std::function onConfirm); diff --git a/src/graphics/draw/NotificationRenderer.cpp b/src/graphics/draw/NotificationRenderer.cpp index d9cf280ac..3d635e588 100644 --- a/src/graphics/draw/NotificationRenderer.cpp +++ b/src/graphics/draw/NotificationRenderer.cpp @@ -383,7 +383,9 @@ void NotificationRenderer::drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisp uint8_t firstOptionToShow = 0; if (alertBannerOptions > 0) { - if (curSelected > 1 && alertBannerOptions > visibleTotalLines - lineCount) { + if (visibleTotalLines - lineCount == 1) { + firstOptionToShow = curSelected; + } else if (curSelected > 1 && alertBannerOptions > visibleTotalLines - lineCount) { if (curSelected > alertBannerOptions - visibleTotalLines + lineCount) firstOptionToShow = alertBannerOptions - visibleTotalLines + lineCount; else @@ -392,6 +394,9 @@ void NotificationRenderer::drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisp firstOptionToShow = 0; } } + // Useful log line for troubleshooting: + /* LOG_WARN("alertBannerOptions: %u, curSelected: %u, visibleTotalLines: %u, lineCount: %u, firstOptionToShow: %u", + alertBannerOptions, curSelected, visibleTotalLines, lineCount, firstOptionToShow); */ for (int i = firstOptionToShow; i < alertBannerOptions && linesShown < visibleTotalLines; i++, linesShown++) { if (i == curSelected) { From e5e8683cdba133e726033101586c3235a8678893 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 17 Aug 2025 05:56:06 -0500 Subject: [PATCH 13/17] Don't update the NodeDB if the nodeinfo has a mismatching public key (#7652) --- src/mesh/NodeDB.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 79361bb46..97a1e463c 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1631,24 +1631,33 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde printBytes("Incoming Pubkey: ", p.public_key.bytes, 32); // Alert the user if a remote node is advertising public key that matches our own - if (owner.public_key.size == 32 && memcmp(p.public_key.bytes, owner.public_key.bytes, 32) == 0 && !duplicateWarned) { - duplicateWarned = true; - char warning[] = "Remote device %s has advertised your public key. This may indicate a compromised key. You may need " - "to regenerate your public keys."; - LOG_WARN(warning, p.long_name); - meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed(); - cn->level = meshtastic_LogRecord_Level_WARNING; - cn->time = getValidTime(RTCQualityFromNet); - sprintf(cn->message, warning, p.long_name); - service->sendClientNotification(cn); + if (owner.public_key.size == 32 && memcmp(p.public_key.bytes, owner.public_key.bytes, 32) == 0) { + if (!duplicateWarned) { + duplicateWarned = true; + char warning[] = + "Remote device %s has advertised your public key. This may indicate a compromised key. You may need " + "to regenerate your public keys."; + LOG_WARN(warning, p.long_name); + meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed(); + cn->level = meshtastic_LogRecord_Level_WARNING; + cn->time = getValidTime(RTCQualityFromNet); + sprintf(cn->message, warning, p.long_name); + service->sendClientNotification(cn); + } + return false; } } - if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one + if (info->user.public_key.size == 32) { // if we have a key for this user already, don't overwrite with a new one + // if the key doesn't match, don't update nodeDB at all. + if (p.public_key.size != 32 || (memcmp(p.public_key.bytes, info->user.public_key.bytes, 32) != 0)) { + LOG_WARN("Public Key mismatch, dropping NodeInfo"); + return false; + } LOG_INFO("Public Key set for node, not updating!"); // we copy the key into the incoming packet, to prevent overwrite p.public_key.size = 32; memcpy(p.public_key.bytes, info->user.public_key.bytes, 32); - } else if (p.public_key.size > 0) { + } else if (p.public_key.size == 32) { LOG_INFO("Update Node Pubkey!"); } #endif From 9feb1d378edb2847cc12755beac9aa57a10c571f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 17 Aug 2025 13:37:12 +0200 Subject: [PATCH 14/17] Support for T-Echo Lite, credits to @Szetya for doing all the heavy lifting! (#7636) * Support for T-Echo Lite, credts to @Szetya for doing all the heavy lifting! * move define to ini file --- src/BluetoothStatus.h | 8 + src/graphics/EInkDisplay2.cpp | 4 +- src/main.cpp | 4 + src/modules/SerialModule.cpp | 14 +- src/nimble/NimbleBluetooth.cpp | 5 +- src/platform/nrf52/architecture.h | 2 + variants/nrf52840/t-echo-lite/platformio.ini | 25 +++ variants/nrf52840/t-echo-lite/variant.cpp | 44 ++++ variants/nrf52840/t-echo-lite/variant.h | 207 +++++++++++++++++++ 9 files changed, 303 insertions(+), 10 deletions(-) create mode 100644 variants/nrf52840/t-echo-lite/platformio.ini create mode 100644 variants/nrf52840/t-echo-lite/variant.cpp create mode 100644 variants/nrf52840/t-echo-lite/variant.h diff --git a/src/BluetoothStatus.h b/src/BluetoothStatus.h index f6bb43cc2..680aec929 100644 --- a/src/BluetoothStatus.h +++ b/src/BluetoothStatus.h @@ -89,14 +89,22 @@ class BluetoothStatus : public Status case ConnectionState::CONNECTED: LOG_DEBUG("BluetoothStatus CONNECTED"); #ifdef BLE_LED +#ifdef BLE_LED_INVERTED + digitalWrite(BLE_LED, LOW); +#else digitalWrite(BLE_LED, HIGH); +#endif #endif break; case ConnectionState::DISCONNECTED: LOG_DEBUG("BluetoothStatus DISCONNECTED"); #ifdef BLE_LED +#ifdef BLE_LED_INVERTED + digitalWrite(BLE_LED, HIGH); +#else digitalWrite(BLE_LED, LOW); +#endif #endif break; } diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp index a627a42cc..1c9f290b6 100644 --- a/src/graphics/EInkDisplay2.cpp +++ b/src/graphics/EInkDisplay2.cpp @@ -140,13 +140,13 @@ bool EInkDisplay::connect() #endif #endif -#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1) +#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1) || defined(T_ECHO_LITE) { auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1); adafruitDisplay = new GxEPD2_BW(*lowLevel); adafruitDisplay->init(); -#ifdef ELECROW_ThinkNode_M1 +#if defined(ELECROW_ThinkNode_M1) || defined(T_ECHO_LITE) adafruitDisplay->setRotation(4); #else adafruitDisplay->setRotation(3); diff --git a/src/main.cpp b/src/main.cpp index c5be175c4..c53877e37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -325,8 +325,12 @@ void setup() #ifdef BLE_LED pinMode(BLE_LED, OUTPUT); +#ifdef BLE_LED_INVERTED + digitalWrite(BLE_LED, HIGH); +#else digitalWrite(BLE_LED, LOW); #endif +#endif #if defined(T_DECK) // GPIO10 manages all peripheral power supplies diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 39b297965..866497ecc 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -60,7 +60,7 @@ SerialModule *serialModule; SerialModuleRadio *serialModuleRadio; -#if defined(TTGO_T_ECHO) || defined(CANARYONE) || defined(MESHLINK) || defined(ELECROW_ThinkNode_M1) || \ +#if defined(TTGO_T_ECHO) || defined(T_ECHO_LITE) || defined(CANARYONE) || defined(MESHLINK) || defined(ELECROW_ThinkNode_M1) || \ defined(ELECROW_ThinkNode_M5) SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {} static Print *serialPrint = &Serial; @@ -179,8 +179,8 @@ int32_t SerialModule::runOnce() Serial.begin(baud); Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } -#elif !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && \ - !defined(ELECROW_ThinkNode_M5) +#elif !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \ + !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { #ifdef ARCH_RP2040 Serial2.setFIFOSize(RX_BUFFER); @@ -236,8 +236,8 @@ int32_t SerialModule::runOnce() } } -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && \ - !defined(ELECROW_ThinkNode_M5) +#if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \ + !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) { processWXSerial(); @@ -496,8 +496,8 @@ ParsedLine parseLine(const char *line) */ void SerialModule::processWXSerial() { -#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(MESHLINK) && \ - !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) +#if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && \ + !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) static unsigned int lastAveraged = 0; static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static double dir_sum_sin = 0; diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 834184292..95e191c8e 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -223,9 +223,12 @@ void NimbleBluetooth::deinit() LOG_INFO("Disable bluetooth until reboot"); #ifdef BLE_LED +#ifdef BLE_LED_INVERTED + digitalWrite(BLE_LED, HIGH); +#else digitalWrite(BLE_LED, LOW); #endif - +#endif NimBLEDevice::deinit(); #endif } diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index ce42bf849..064bd8ef0 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -60,6 +60,8 @@ #define HW_VENDOR meshtastic_HardwareModel_RAK4631 #elif defined(TTGO_T_ECHO) #define HW_VENDOR meshtastic_HardwareModel_T_ECHO +#elif defined(T_ECHO_LITE) +#define HW_VENDOR meshtastic_HardwareModel_T_ECHO_LITE #elif defined(ELECROW_ThinkNode_M1) #define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M1 #elif defined(NANO_G2_ULTRA) diff --git a/variants/nrf52840/t-echo-lite/platformio.ini b/variants/nrf52840/t-echo-lite/platformio.ini new file mode 100644 index 000000000..68ae59dcb --- /dev/null +++ b/variants/nrf52840/t-echo-lite/platformio.ini @@ -0,0 +1,25 @@ +; Using original screen class +[env:t-echo-lite] +extends = nrf52840_base +board = t-echo +board_check = true +debug_tool = jlink + +# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling. +build_flags = ${nrf52840_base.build_flags} + -Ivariants/nrf52840/t-echo-lite + -D T_ECHO_LITE + -D GPS_POWER_TOGGLE + -D EINK_DISPLAY_MODEL=GxEPD2_122_T61 + -D EINK_WIDTH=192 + -D EINK_HEIGHT=176 + -D USE_EINK + -D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk + -D EINK_LIMIT_FASTREFRESH=20 ; How many consecutive fast-refreshes are permitted + -D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached. + +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/t-echo-lite> +lib_deps = + ${nrf52840_base.lib_deps} + https://github.com/meshtastic/GxEPD2/archive/a05c11c02862624266b61599b0d6ba93e33c6f24.zip +;upload_protocol = fs diff --git a/variants/nrf52840/t-echo-lite/variant.cpp b/variants/nrf52840/t-echo-lite/variant.cpp new file mode 100644 index 000000000..cae079b74 --- /dev/null +++ b/variants/nrf52840/t-echo-lite/variant.cpp @@ -0,0 +1,44 @@ +/* + 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 - pins 0 and 1 are hardwired for xtal and should never be enabled + 0xff, 0xff, 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); + + pinMode(PIN_LED3, OUTPUT); + ledOff(PIN_LED3); +} diff --git a/variants/nrf52840/t-echo-lite/variant.h b/variants/nrf52840/t-echo-lite/variant.h new file mode 100644 index 000000000..2e2cdce72 --- /dev/null +++ b/variants/nrf52840/t-echo-lite/variant.h @@ -0,0 +1,207 @@ +/* + 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_TTGO_EINK_V1_0_ +#define _VARIANT_TTGO_EINK_V1_0_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal 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 (1) +#define NUM_ANALOG_OUTPUTS (0) + +// LEDs +#define PIN_LED1 (32 + 7) // Green LED +#define PIN_LED2 (32 + 5) // Blue LED +// Unused(by firmware) LEDs: +#define PIN_LED3 (32 + 14) // Red LED inside, under the display. + +#define LED_RED PIN_LED3 +#define LED_BLUE PIN_LED2 +#define LED_GREEN PIN_LED1 + +#define BLE_LED LED_BLUE +#define BLE_LED_INVERTED 1 +#define LED_BUILTIN LED_GREEN +#define LED_CONN LED_GREEN +#define LED_STATE_ON 0 // State when LED is lit + +// Buttons +#define PIN_BUTTON1 (0 + 24) +#define PIN_BUTTON2 (0 + 18) // 0.18 is labeled on the board as RESET but we configure it in the bootloader as a regular GPIO + +#define BUTTON_CLICK_MS 400 + +// Analog pins +#define PIN_A0 (0 + 2) // Battery ADC + +#define BATTERY_PIN PIN_A0 + +static const uint8_t A0 = PIN_A0; + +#define ADC_RESOLUTION 14 + +#define ADC_CTRL (0 + 31) +#define ADC_CTRL_ENABLED HIGH + +// NFC +#define PIN_NFC1 (9) +#define PIN_NFC2 (10) + +// Wire Interfaces +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (32 + 4) +#define PIN_WIRE_SCL (32 + 2) + +/* + Internal, PCB PAD interrupt PIN. Currently not used. (Not built in my device) +*/ +// #define PIN_IMU_INT (0 + 16) // Interrupt from the IMU, macro name correct?! + +// External serial flash ZD25WQ32CEIGR +// QSPI Pins +#define PIN_QSPI_SCK (0 + 4) +#define PIN_QSPI_CS (0 + 12) +#define PIN_QSPI_IO0 (0 + 6) // MOSI if using two bit interface +#define PIN_QSPI_IO1 (0 + 8) // MISO if using two bit interface +#define PIN_QSPI_IO2 (32 + 9) // WP if using two bit interface (i.e. not used) +#define PIN_QSPI_IO3 (0 + 26) // HOLD if using two bit interface (i.e. not used) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES ZD25WQ32CEIGR +#define EXTERNAL_FLASH_USE_QSPI + +// Lora radio + +#define USE_SX1262 +// #define USE_SX1268 // currently only available with XS1262. +#define SX126X_CS (0 + 11) +#define SX126X_DIO1 (32 + 8) +#define SX126X_DIO2 (0 + 5) +#define SX126X_BUSY (0 + 14) +#define SX126X_RESET (0 + 7) +#define SX126X_RXEN (32 + 1) +#define SX126X_TXEN (0 + 27) +// #define TCXO_OPTIONAL +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 + +// eink display pins +#define VEXT_ENABLE (32 + 12) +#define VEXT_ON_VALUE LOW +#define PIN_EINK_CS (0 + 22) +#define PIN_EINK_BUSY (0 + 3) +#define PIN_EINK_DC (0 + 21) +#define PIN_EINK_RES (0 + 28) +#define PIN_EINK_SCLK (0 + 19) +#define PIN_EINK_MOSI (0 + 20) + +// Controls power 3V3 for all peripherals (eink + GPS + LoRa + Sensor) +#define PIN_POWER_EN (0 + 30) // 3V3 POWER Enable + +#define PIN_SPI1_MISO (-1) // The display does not use MISO. +#define PIN_SPI1_MOSI PIN_EINK_MOSI +#define PIN_SPI1_SCK PIN_EINK_SCLK + +// GPS pins +// #define GPS_DEBUG +#define GPS_L76K +#define GPS_BAUDRATE 9600 +#define HAS_GPS 1 +// #define PIN_GPS_REINIT (32 + 5) // An output to reset L76K GPS. As per datasheet, low for > 100ms will reset the L76K + +#define PIN_GPS_STANDBY (32 + 10) // An output to wake GPS, low means allow sleep, high means force wake +// Seems to be missing on this new board +#define PIN_GPS_PPS (0 + 29) // Pulse per second input from the GPS +#define GPS_TX_PIN (32 + 15) // This is for bits going TOWARDS the CPU +#define GPS_RX_PIN (32 + 13) // This is for bits going TOWARDS the GPS + +#define GPS_THREAD_INTERVAL 50 + +#define PIN_SERIAL1_RX GPS_TX_PIN +#define PIN_SERIAL1_TX GPS_RX_PIN + +// SPI Interfaces +#define SPI_INTERFACES_COUNT 2 + +// For LORA, SPI 0 +#define PIN_SPI_MISO (0 + 17) +#define PIN_SPI_MOSI (0 + 15) +#define PIN_SPI_SCK (0 + 13) + +// Battery +// The battery sense is hooked to pin A0 (2) +// it is defined in the analogue pin section of this file +// 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 (2.0F) + +// #define NO_EXT_GPIO 1 +// PINs back side +// Batt & solar connector left up corner +/* +------------------------------- +| VDDH, VBAT, 0.23, SCL , 1.06 | +| GND , SDA , 0.09, 0.10, 0.25 | +------------------------------- + -------- + | VDDH | + | GND | + | 1.13 | - Wake Up/standby + | 1.15 | - PPS + | 0.29 | - TX + | 1.10 | - RX + | 1.11 | - EN + -------- +------------------------------- +| 3V3 , GND , 0.16, 1.03, G_WU | 0.16 internal solder pad interrupt PIN, +| G_EN, G_RX, G_TX, GND , PPS | +------------------------------- +*/ + +// To debug via the segger JLINK console rather than the CDC-ACM serial device +// #define USE_SEGGER + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif \ No newline at end of file From 78c5309e9a1195b8b93d49c67c45f65b7e04abab Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:48:24 +0200 Subject: [PATCH 15/17] apply 180 degree hw roration Indicator BaseUI (#7660) --- src/graphics/TFTDisplay.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 3e9bafc6c..24ea6c47a 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -849,9 +849,29 @@ static LGFX *tft = nullptr; #include #include +class PanelInit_ST7701 : public lgfx::Panel_ST7701 +{ + public: + const uint8_t *getInitCommands(uint8_t listno) const override + { + // 180 degree hw rotation: vertical flip, horizontal flip + static constexpr const uint8_t list1[] = {0x36, 1, 0x10, // MADCTL for vertical flip + 0xFF, 5, 0x77, 0x01, 0x00, 0x00, 0x10, // Command2 BK0 SEL + 0xC7, 1, 0x04, // SDIR: X-direction Control (Horizontal Flip) + 0xFF, 5, 0x77, 0x01, 0x00, 0x00, 0x00, // Command2 BK0 DIS + 0xFF, 0xFF}; + switch (listno) { + case 1: + return list1; + default: + return lgfx::Panel_ST7701::getInitCommands(listno); + } + } +}; + class LGFX : public lgfx::LGFX_Device { - lgfx::Panel_ST7701 _panel_instance; + PanelInit_ST7701 _panel_instance; lgfx::Bus_RGB _bus_instance; lgfx::Light_PWM _light_instance; lgfx::Touch_FT5x06 _touch_instance; @@ -1184,9 +1204,9 @@ 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) || defined(SENSECAP_INDICATOR) +#elif defined(T_WATCH_S3) tft->setRotation(2); // T-Watch S3 left-handed orientation -#elif ARCH_PORTDUINO +#elif ARCH_PORTDUINO || defined(SENSECAP_INDICATOR) tft->setRotation(0); // use config.yaml to set rotation #else tft->setRotation(3); // Orient horizontal and wide underneath the silkscreen name label From 36e8dc74f45c6da09e9d4c44bd22320867f6f7ed Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 05:52:02 -0500 Subject: [PATCH 16/17] Upgrade trunk (#7665) Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com> --- .trunk/trunk.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 10bb1bd00..de38e3ec0 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,9 +9,9 @@ plugins: lint: enabled: - checkov@3.2.461 - - renovate@41.71.1 + - renovate@41.74.0 - prettier@3.6.2 - - trufflehog@3.90.4 + - trufflehog@3.90.5 - yamllint@1.37.1 - bandit@1.8.6 - trivy@0.64.1 From 95200e8f6b532d4498cd8e7738109d7996db54b3 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 18 Aug 2025 16:33:52 -0500 Subject: [PATCH 17/17] Adds rfswitch on Portduino (#7663) * Initial attempt to get rfswitch working on Portduino * Make portduino_config global --- src/mesh/LR11x0Interface.cpp | 15 ++++----- src/platform/portduino/PortduinoGlue.cpp | 43 ++++++++++++++++++++++++ src/platform/portduino/PortduinoGlue.h | 10 +++++- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index a20db808e..a0d992c42 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -6,6 +6,10 @@ #include "mesh/NodeDB.h" #ifdef LR11X0_DIO_AS_RF_SWITCH #include "rfswitch.h" +#elif ARCH_PORTDUINO +#include "PortduinoGlue.h" +#define rfswitch_dio_pins portduino_config.rfswitch_dio_pins +#define rfswitch_table portduino_config.rfswitch_table #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[] = { @@ -14,10 +18,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { }; #endif -#ifdef ARCH_PORTDUINO -#include "PortduinoGlue.h" -#endif - // 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) #if ARCH_PORTDUINO @@ -117,17 +117,14 @@ template bool LR11x0Interface::init() #ifdef LR11X0_DIO_AS_RF_SWITCH bool dioAsRfSwitch = true; #elif defined(ARCH_PORTDUINO) - bool dioAsRfSwitch = false; - if (settingsMap[dio2_as_rf_switch]) { - dioAsRfSwitch = true; - } + bool dioAsRfSwitch = portduino_config.has_rfswitch_table; #else bool dioAsRfSwitch = false; #endif if (dioAsRfSwitch) { lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); - LOG_DEBUG("Set DIO RF switch", res); + LOG_DEBUG("Set DIO RF switch"); } if (res == RADIOLIB_ERR_NONE) { diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 5f99ec2c3..ac4e79af1 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -29,6 +29,7 @@ std::map settingsMap; std::map settingsStrings; +portduino_config_struct portduino_config; std::ofstream traceFile; Ch341Hal *ch341Hal = nullptr; char *configPath = nullptr; @@ -553,6 +554,48 @@ bool loadConfig(const char *configPath) } } } + if (yamlConfig["Lora"]["rfswitch_table"]) { + portduino_config.has_rfswitch_table = true; + portduino_config.rfswitch_table[0].mode = LR11x0::MODE_STBY; + portduino_config.rfswitch_table[1].mode = LR11x0::MODE_RX; + portduino_config.rfswitch_table[2].mode = LR11x0::MODE_TX; + portduino_config.rfswitch_table[3].mode = LR11x0::MODE_TX_HP; + portduino_config.rfswitch_table[4].mode = LR11x0::MODE_TX_HF; + portduino_config.rfswitch_table[5].mode = LR11x0::MODE_GNSS; + portduino_config.rfswitch_table[6].mode = LR11x0::MODE_WIFI; + portduino_config.rfswitch_table[7] = END_OF_MODE_TABLE; + + for (int i = 0; i < 5; i++) { + + // set up the pin array first + if (yamlConfig["Lora"]["rfswitch_table"]["pins"][i].as("") == "DIO5") + portduino_config.rfswitch_dio_pins[i] = RADIOLIB_LR11X0_DIO5; + if (yamlConfig["Lora"]["rfswitch_table"]["pins"][i].as("") == "DIO6") + portduino_config.rfswitch_dio_pins[i] = RADIOLIB_LR11X0_DIO6; + if (yamlConfig["Lora"]["rfswitch_table"]["pins"][i].as("") == "DIO7") + portduino_config.rfswitch_dio_pins[i] = RADIOLIB_LR11X0_DIO7; + if (yamlConfig["Lora"]["rfswitch_table"]["pins"][i].as("") == "DIO8") + portduino_config.rfswitch_dio_pins[i] = RADIOLIB_LR11X0_DIO8; + if (yamlConfig["Lora"]["rfswitch_table"]["pins"][i].as("") == "DIO10") + portduino_config.rfswitch_dio_pins[i] = RADIOLIB_LR11X0_DIO10; + + // now fill in the table + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_STBY"][i].as("") == "HIGH") + portduino_config.rfswitch_table[0].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_RX"][i].as("") == "HIGH") + portduino_config.rfswitch_table[1].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_TX"][i].as("") == "HIGH") + portduino_config.rfswitch_table[2].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_TX_HP"][i].as("") == "HIGH") + portduino_config.rfswitch_table[3].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_TX_HF"][i].as("") == "HIGH") + portduino_config.rfswitch_table[4].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_GNSS"][i].as("") == "HIGH") + portduino_config.rfswitch_table[5].values[i] = HIGH; + if (yamlConfig["Lora"]["rfswitch_table"]["MODE_WIFI"][i].as("") == "HIGH") + portduino_config.rfswitch_table[6].values[i] = HIGH; + } + } } if (yamlConfig["GPIO"]) { settingsMap[userButtonPin] = yamlConfig["GPIO"]["User"].as(RADIOLIB_NC); diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 288870eef..64277322a 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -3,6 +3,8 @@ #include #include +#include "LR11x0Interface.h" +#include "Module.h" #include "platform/portduino/USBHal.h" // Product strings for auto-configuration @@ -126,4 +128,10 @@ bool loadConfig(const char *configPath); static bool ends_with(std::string_view str, std::string_view suffix); void getMacAddr(uint8_t *dmac); bool MAC_from_string(std::string mac_str, uint8_t *dmac); -std::string exec(const char *cmd); \ No newline at end of file +std::string exec(const char *cmd); + +extern struct portduino_config_struct { + bool has_rfswitch_table = false; + uint32_t rfswitch_dio_pins[5] = {RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + Module::RfSwitchMode_t rfswitch_table[8]; +} portduino_config; \ No newline at end of file