diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index f62255aea..de38e3ec0 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.74.0
- prettier@3.6.2
- - trufflehog@3.90.3
+ - trufflehog@3.90.5
- yamllint@1.37.1
- bandit@1.8.6
- trivy@0.64.1
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 \
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 62bbf8a24..528563def 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
@@ -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/protobufs b/protobufs
index e2c0831aa..5dd723fe6 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit e2c0831aa3d34a58a36c2b9fdcb828e58961cbc5
+Subproject commit 5dd723fe6f33a8613ec81acf5e15be26365c7cce
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/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/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/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 8d5635f89..fa71e17d8 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
@@ -694,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/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/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp
index 752bf9b23..329f6e5e9 100644
--- a/src/graphics/TFTDisplay.cpp
+++ b/src/graphics/TFTDisplay.cpp
@@ -864,9 +864,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;
@@ -1242,9 +1262,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
diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp
index b7bd068c4..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",
@@ -318,7 +339,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 +363,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);
@@ -1120,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) {
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 67208b4d9..c8045285e 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
@@ -1860,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
diff --git a/src/input/ButtonThread.cpp b/src/input/ButtonThread.cpp
index 233bbefe0..32882f7ae 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) {
@@ -137,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) {
@@ -150,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();
}
@@ -253,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;
diff --git a/src/main.cpp b/src/main.cpp
index 75742e282..2e86e7b68 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
@@ -326,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/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/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
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);
}
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.
------------------------------------------------------------------------------------------------------------------------------------------ */
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) {
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/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;
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/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