From 409dfe22aea40b58a5702ff5e4bf9947e53fa848 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 2 Jul 2025 20:58:15 -0500 Subject: [PATCH 01/13] Fix Seeed L1 board to enable consistent PIO flashing (#7211) --- boards/seeed_wio_tracker_L1.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/boards/seeed_wio_tracker_L1.json b/boards/seeed_wio_tracker_L1.json index 7c7bc62fa..e2bb93573 100644 --- a/boards/seeed_wio_tracker_L1.json +++ b/boards/seeed_wio_tracker_L1.json @@ -7,7 +7,10 @@ "cpu": "cortex-m4", "extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA", "f_cpu": "64000000L", - "hwids": [["0x2886", "0x1668"]], + "hwids": [ + ["0x2886", "0x1668"], + ["0x2886", "0x1667"] + ], "usb_product": "TRACKER L1", "mcu": "nrf52840", "variant": "seeed_wio_tracker_L1", From 549250b91a6e21c480ade3f6b711e662abaebd6d Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 2 Jul 2025 22:39:29 -0500 Subject: [PATCH 02/13] Good bot -- make array large enough to handle all the possible options --- src/graphics/draw/MenuHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 3681532bb..8995eb4cd 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -352,8 +352,8 @@ void menuHandler::systemBaseMenu() #endif enum optionsNumbers { Back, Beeps, Brightness, Reboot, Color, MUI, Test }; - static const char *optionsArray[6] = {"Back"}; - static int optionsEnumArray[6] = {Back}; + static const char *optionsArray[7] = {"Back"}; + static int optionsEnumArray[7] = {Back}; int options = 1; optionsArray[options] = "Beeps Action"; From 81828c6244daede254cf759a0f2bd939b2e7dd65 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 2 Jul 2025 23:52:55 -0500 Subject: [PATCH 03/13] Don't set non-existent pin on e290 (#7213) * Don't set non-existent pin on e290 * Don't twiddle imaginary pins on the e213, either --- src/graphics/draw/MenuHandler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 8995eb4cd..92954bf2e 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -633,8 +633,7 @@ void menuHandler::BrightnessPickerMenu() if (selected != 0) { // Not "Back" // Apply brightness immediately -#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(HELTEC_VISION_MASTER_E213) || \ - defined(HELTEC_VISION_MASTER_E290) +#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) // For HELTEC devices, use analogWrite to control backlight analogWrite(VTFT_LEDA, uiconfig.screen_brightness); #elif defined(ST7789_CS) From b02e58521dc967b3664e0176bedbf88673cd43ea Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 3 Jul 2025 06:53:27 -0500 Subject: [PATCH 04/13] Add GPIO edge for Native Trackball/Joystick (#7212) Co-authored-by: Ben Meadors --- bin/config.d/display-waveshare-1-44.yaml | 2 +- src/input/TrackballInterruptBase.h | 5 +++++ src/platform/portduino/PortduinoGlue.cpp | 5 +++++ src/platform/portduino/PortduinoGlue.h | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/bin/config.d/display-waveshare-1-44.yaml b/bin/config.d/display-waveshare-1-44.yaml index 1d85a4a3b..d37f6cf6a 100644 --- a/bin/config.d/display-waveshare-1-44.yaml +++ b/bin/config.d/display-waveshare-1-44.yaml @@ -22,5 +22,5 @@ Input: TrackballLeft: 5 TrackballRight: 26 TrackballPress: 13 - + TrackballDirection: FALLING # User: 21 diff --git a/src/input/TrackballInterruptBase.h b/src/input/TrackballInterruptBase.h index 2397839b9..92db8720e 100644 --- a/src/input/TrackballInterruptBase.h +++ b/src/input/TrackballInterruptBase.h @@ -4,8 +4,13 @@ #include "mesh/NodeDB.h" #ifndef TB_DIRECTION +#if ARCH_PORTDUINO +#include "PortduinoGlue.h" +#define TB_DIRECTION (PinStatus) settingsMap[tbDirection] +#else #define TB_DIRECTION RISING #endif +#endif class TrackballInterruptBase : public Observable, public concurrency::OSThread { diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index f582a116d..49d1acb4c 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -642,6 +642,11 @@ bool loadConfig(const char *configPath) settingsMap[tbLeftPin] = yamlConfig["Input"]["TrackballLeft"].as(RADIOLIB_NC); settingsMap[tbRightPin] = yamlConfig["Input"]["TrackballRight"].as(RADIOLIB_NC); settingsMap[tbPressPin] = yamlConfig["Input"]["TrackballPress"].as(RADIOLIB_NC); + if (yamlConfig["Input"]["TrackballDirection"].as("RISING") == "RISING") { + settingsMap[tbDirection] = 4; + } else if (yamlConfig["Input"]["TrackballDirection"].as("RISING") == "FALLING") { + settingsMap[tbDirection] = 3; + } } if (yamlConfig["Webserver"]) { diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 5795f0d8d..e404b7f1c 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -63,6 +63,7 @@ enum configNames { tbLeftPin, tbRightPin, tbPressPin, + tbDirection, spidev, spiSpeed, i2cdev, From 6fa597bc5d80b7f54ac5880727da18e1856744a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:17:42 -0500 Subject: [PATCH 05/13] [create-pull-request] automated change (#7216) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/protobufs b/protobufs index 386fa53c1..584f0a3a3 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 386fa53c1596c8dfc547521f08df107f4cb3a275 +Subproject commit 584f0a3a359103acf0bfce506c1b1fc32c639841 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index ed1849be8..f28daadbd 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -285,7 +285,11 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode { /* Philippines 915mhz */ meshtastic_Config_LoRaConfig_RegionCode_PH_915 = 21, /* Australia / New Zealand 433MHz */ - meshtastic_Config_LoRaConfig_RegionCode_ANZ_433 = 22 + meshtastic_Config_LoRaConfig_RegionCode_ANZ_433 = 22, + /* Kazakhstan 433MHz */ + meshtastic_Config_LoRaConfig_RegionCode_KZ_433 = 23, + /* Kazakhstan 863MHz */ + meshtastic_Config_LoRaConfig_RegionCode_KZ_863 = 24 } meshtastic_Config_LoRaConfig_RegionCode; /* Standard predefined channel settings @@ -681,8 +685,8 @@ extern "C" { #define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1)) #define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET -#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_ANZ_433 -#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_ANZ_433+1)) +#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_KZ_863 +#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_KZ_863+1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST #define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO From f2d3f548242c80dd460924d3da64dee425f759df Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 3 Jul 2025 16:10:35 -0400 Subject: [PATCH 06/13] No routers allowed! (#7220) --- src/modules/AdminModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 12a586cd7..0ba0e1164 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -630,6 +630,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) #if USERPREFS_EVENT_MODE // If we're in event mode, nobody is a Router or Repeater if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || + config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE || config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) { config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; } From 2254d551f4afb8ba1196eed125ec98ff5e3a64b6 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Fri, 4 Jul 2025 08:40:43 +1200 Subject: [PATCH 07/13] Honor custom userPrefs boot-screens in InkHUD (#7217) * Honor custom boot screen from userPrefs.jsonc * Meshtastic logo when powered off, userPrefs logo at boot --------- Co-authored-by: Ben Meadors --- .../InkHUD/Applets/System/Logo/LogoApplet.cpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp index 858b1e132..ecaa7cea3 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp +++ b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp @@ -52,6 +52,40 @@ void InkHUD::LogoApplet::onRender() setTextColor(WHITE); } +#ifdef USERPREFS_OEM_IMAGE_DATA // Custom boot screen, if defined in userPrefs.jsonc + + // Only show the custom screen at startup + // This allows us to draw the usual Meshtastic logo at shutdown + // The effect is similar to the two-stage userPrefs boot screen used by BaseUI + if (millis() < 10 * 1000UL) { + + // Draw the custom logo + const uint8_t logo[] = USERPREFS_OEM_IMAGE_DATA; + drawXBitmap(logoCX - (USERPREFS_OEM_IMAGE_WIDTH / 2), // Left + logoCY - (USERPREFS_OEM_IMAGE_HEIGHT / 2), // Top + logo, // XBM data + USERPREFS_OEM_IMAGE_WIDTH, // Width + USERPREFS_OEM_IMAGE_HEIGHT, // Height + inverted ? WHITE : BLACK // Color + ); + + // Select the largest font which will still comfortably fit the custom text + setFont(fontLarge); + if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width()) + setFont(fontMedium); + if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width()) + setFont(fontSmall); + + // Draw custom text below logo + int16_t logoB = logoCY + (USERPREFS_OEM_IMAGE_HEIGHT / 2); // Bottom of the logo + printAt(X(0.5), logoB + Y(0.1), USERPREFS_OEM_TEXT, CENTER, TOP); + + // Don't draw the normal boot screen, we've already drawn our custom version + return; + } + +#endif + drawLogo(logoCX, logoCY, logoW, logoH, inverted ? WHITE : BLACK); if (!textLeft.empty()) { From 93132fad284464adfc3129eb912aaa7827ad348a Mon Sep 17 00:00:00 2001 From: Jason P Date: Thu, 3 Jul 2025 17:20:51 -0500 Subject: [PATCH 08/13] Battery Layout Updates and Icons Changes (#7221) * Testing battery states with some info lines in the drawCommonHeader * Update logic of USB connected, update images for states * Tweak battery layout for isHighResolution * Hide the magic 101% * Adjust padding for SENSECAP_INDICATOR * Excessive logs are unnecessary as troubleshooting is done. * Reduce excess code - simplify readability * Restore Lightning Bolt for Charging and related alignment issues --------- Co-authored-by: Jonathan Bennett --- src/graphics/SharedUIDisplay.cpp | 94 ++++++++++++++++++----------- src/graphics/draw/ClockRenderer.cpp | 3 + src/graphics/images.h | 5 +- 3 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/graphics/SharedUIDisplay.cpp b/src/graphics/SharedUIDisplay.cpp index 9f2422748..7cd876ac5 100644 --- a/src/graphics/SharedUIDisplay.cpp +++ b/src/graphics/SharedUIDisplay.cpp @@ -99,10 +99,17 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti // === Battery State === int chargePercent = powerStatus->getBatteryChargePercent(); - bool isCharging = powerStatus->getIsCharging() == meshtastic::OptionalBool::OptTrue; - if (chargePercent == 100) { + bool isCharging = powerStatus->getIsCharging(); + bool usbPowered = powerStatus->getHasUSB(); + + if (chargePercent >= 100) { isCharging = false; } + if (chargePercent == 101) { + usbPowered = true; // Forcing this flag on for the express purpose that some devices have no concept of having a USB cable + // plugged in + } + uint32_t now = millis(); #ifndef USE_EINK @@ -115,48 +122,63 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti bool useHorizontalBattery = (isHighResolution && screenW >= screenH); const int textY = y + (highlightHeight - FONT_HEIGHT_SMALL) / 2; + int batteryX = 1; + int batteryY = HEADER_OFFSET_Y + 1; + // === Battery Icons === - if (useHorizontalBattery) { - int batteryX = 2; - int batteryY = HEADER_OFFSET_Y + 3; - display->drawXbm(batteryX, batteryY, 9, 13, batteryBitmap_h_bottom); - display->drawXbm(batteryX + 9, batteryY, 9, 13, batteryBitmap_h_top); - if (isCharging && isBoltVisibleShared) - display->drawXbm(batteryX + 4, batteryY, 9, 13, lightning_bolt_h); - else { - display->drawLine(batteryX + 5, batteryY, batteryX + 10, batteryY); - display->drawLine(batteryX + 5, batteryY + 12, batteryX + 10, batteryY + 12); - int fillWidth = 14 * chargePercent / 100; - display->fillRect(batteryX + 1, batteryY + 1, fillWidth, 11); + if (usbPowered && !isCharging) { // This is a basic check to determine USB Powered is flagged but not charging + batteryX += 1; + batteryY += 2; + if (isHighResolution) { + display->drawXbm(batteryX, batteryY, 19, 12, imgUSB_HighResolution); + batteryX += 20; // Icon + 1 pixel + } else { + display->drawXbm(batteryX, batteryY, 10, 8, imgUSB); + batteryX += 11; // Icon + 1 pixel } } else { - int batteryX = 1; - int batteryY = HEADER_OFFSET_Y + 1; + if (useHorizontalBattery) { + batteryX += 1; + batteryY += 2; + display->drawXbm(batteryX, batteryY, 9, 13, batteryBitmap_h_bottom); + display->drawXbm(batteryX + 9, batteryY, 9, 13, batteryBitmap_h_top); + if (isCharging && isBoltVisibleShared) + display->drawXbm(batteryX + 4, batteryY, 9, 13, lightning_bolt_h); + else { + display->drawLine(batteryX + 5, batteryY, batteryX + 10, batteryY); + display->drawLine(batteryX + 5, batteryY + 12, batteryX + 10, batteryY + 12); + int fillWidth = 14 * chargePercent / 100; + display->fillRect(batteryX + 1, batteryY + 1, fillWidth, 11); + } + batteryX += 18; // Icon + 2 pixels + } else { #ifdef USE_EINK - batteryY += 2; + batteryY += 2; #endif - display->drawXbm(batteryX, batteryY, 7, 11, batteryBitmap_v); - if (isCharging && isBoltVisibleShared) - display->drawXbm(batteryX + 1, batteryY + 3, 5, 5, lightning_bolt_v); - else { - display->drawXbm(batteryX - 1, batteryY + 4, 8, 3, batteryBitmap_sidegaps_v); - int fillHeight = 8 * chargePercent / 100; - int fillY = batteryY - fillHeight; - display->fillRect(batteryX + 1, fillY + 10, 5, fillHeight); + display->drawXbm(batteryX, batteryY, 7, 11, batteryBitmap_v); + if (isCharging && isBoltVisibleShared) + display->drawXbm(batteryX + 1, batteryY + 3, 5, 5, lightning_bolt_v); + else { + display->drawXbm(batteryX - 1, batteryY + 4, 8, 3, batteryBitmap_sidegaps_v); + int fillHeight = 8 * chargePercent / 100; + int fillY = batteryY - fillHeight; + display->fillRect(batteryX + 1, fillY + 10, 5, fillHeight); + } + batteryX += 9; // Icon + 2 pixels } } - // === Battery % Display === - char chargeStr[4]; - snprintf(chargeStr, sizeof(chargeStr), "%d", chargePercent); - int chargeNumWidth = display->getStringWidth(chargeStr); - const int batteryOffset = useHorizontalBattery ? 19 : 9; - const int percentX = x + batteryOffset; - display->drawString(percentX, textY, chargeStr); - display->drawString(percentX + chargeNumWidth - 1, textY, "%"); - if (isBold) { - display->drawString(percentX + 1, textY, chargeStr); - display->drawString(percentX + chargeNumWidth, textY, "%"); + if (chargePercent != 101) { + // === Battery % Display === + char chargeStr[4]; + snprintf(chargeStr, sizeof(chargeStr), "%d", chargePercent); + int chargeNumWidth = display->getStringWidth(chargeStr); + display->drawString(batteryX, textY, chargeStr); + display->drawString(batteryX + chargeNumWidth - 1, textY, "%"); + if (isBold) { + display->drawString(batteryX + 1, textY, chargeStr); + display->drawString(batteryX + chargeNumWidth, textY, "%"); + } } // === Time and Right-aligned Icons === diff --git a/src/graphics/draw/ClockRenderer.cpp b/src/graphics/draw/ClockRenderer.cpp index 7ccb1c03c..8d7e91000 100644 --- a/src/graphics/draw/ClockRenderer.cpp +++ b/src/graphics/draw/ClockRenderer.cpp @@ -283,6 +283,9 @@ void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int1 xOffset += (isHighResolution) ? 32 : 18; } int yOffset = (isHighResolution) ? 3 : 1; +#ifdef SENSECAP_INDICATOR + yOffset -= 3; +#endif if (config.display.use_12h_clock) { display->drawString(startingHourMinuteTextX + xOffset, (display->getHeight() - hourMinuteTextY) - yOffset - 2, isPM ? "pm" : "am"); diff --git a/src/graphics/images.h b/src/graphics/images.h index c5865878a..beef3a1b2 100644 --- a/src/graphics/images.h +++ b/src/graphics/images.h @@ -12,7 +12,10 @@ const uint8_t imgSatellite[] PROGMEM = { 0b00000000, 0b00000000, 0b00000000, 0b00011000, 0b11011011, 0b11111111, 0b11011011, 0b00011000, }; -const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C}; +const uint8_t imgUSB[] PROGMEM = {0x00, 0xfc, 0xf0, 0xfc, 0x88, 0xff, 0x86, 0xfe, 0x85, 0xfe, 0x89, 0xff, 0xf1, 0xfc, 0x00, 0xfc}; +const uint8_t imgUSB_HighResolution[] PROGMEM = {0x00, 0x3e, 0xf8, 0x80, 0x43, 0xf8, 0xc0, 0xc2, 0xff, 0x60, 0x42, 0xfc, + 0x3c, 0xc2, 0xff, 0x22, 0x42, 0xf8, 0x3d, 0x42, 0xf8, 0x22, 0xc2, 0xff, + 0x61, 0x42, 0xfc, 0xc0, 0xc2, 0xff, 0x80, 0x43, 0xf8, 0x00, 0x3e, 0xf8}; const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08, 0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22}; const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C}; From c1431f4f9ad090cd670edaf56b3600403aa4408d Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 3 Jul 2025 18:34:04 -0500 Subject: [PATCH 09/13] Disable low brightness, as this soft-bricks at least the L1 (#7223) --- src/graphics/draw/MenuHandler.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 92954bf2e..6dbba853e 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -602,32 +602,28 @@ void menuHandler::BuzzerModeMenu() void menuHandler::BrightnessPickerMenu() { - static const char *optionsArray[] = {"Back", "Low", "Medium", "High", "Very High"}; + static const char *optionsArray[] = {"Back", "Low", "Medium", "High"}; // Get current brightness level to set initial selection - int currentSelection = 1; // Default to Low + int currentSelection = 1; // Default to Medium if (uiconfig.screen_brightness >= 255) { - currentSelection = 4; // Very High + currentSelection = 3; // Very High } else if (uiconfig.screen_brightness >= 128) { - currentSelection = 3; // High - } else if (uiconfig.screen_brightness >= 64) { - currentSelection = 2; // Medium + currentSelection = 2; // High } else { - currentSelection = 1; // Low + currentSelection = 1; // Medium } BannerOverlayOptions bannerOptions; bannerOptions.message = "Brightness"; bannerOptions.optionsArrayPtr = optionsArray; - bannerOptions.optionsCount = 5; + bannerOptions.optionsCount = 4; bannerOptions.bannerCallback = [](int selected) -> void { - if (selected == 1) { // Low - uiconfig.screen_brightness = 1; - } else if (selected == 2) { // Medium + if (selected == 1) { // Medium uiconfig.screen_brightness = 64; - } else if (selected == 3) { // High + } else if (selected == 2) { // High uiconfig.screen_brightness = 128; - } else if (selected == 4) { // Very High + } else if (selected == 3) { // Very High uiconfig.screen_brightness = 255; } From f13dc5b903067b2d10d85217524b8690946ea68c Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 4 Jul 2025 07:34:46 +0800 Subject: [PATCH 10/13] Add Kazakhstan frequencies (#7209) As reported by @KZ1R , Kazakhstan has frequencies in use for Lora devices that are not covered by our existing band selections. This adds * KZ_433 433.075 - 434.775 MHz <10 mW EIRP, Low Powered Devices (LPD) * KZ_863 863 - 868 MHz <25 mW EIRP, 500kHz channels allowed, must not be used at airfields Legal ref provided in https://github.com/meshtastic/firmware/issues/7204 and verified. https://www.gov.kz/memleket/entities/mdai/press/article/details/6128 Order of the Ministry of Investments and Development of the Republic of Kazakhstan No. 34 dated January 21, 2015. Published on 01 July 2024 19:03 Updated on 01 July 2024 Fixes https://github.com/meshtastic/firmware/issues/7204 --- src/mesh/RadioInterface.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 4db05b4d4..3632378a5 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -161,6 +161,14 @@ const RegionInfo regions[] = { RDEF(PH_433, 433.0f, 434.7f, 100, 0, 10, true, false, false), RDEF(PH_868, 868.0f, 869.4f, 100, 0, 14, true, false, false), RDEF(PH_915, 915.0f, 918.0f, 100, 0, 24, true, false, false), + /* + Kazakhstan + 433.075 - 434.775 MHz <10 mW EIRP, Low Powered Devices (LPD) + 863 - 868 MHz <25 mW EIRP, 500kHz channels allowed, must not be used at airfields + https://github.com/meshtastic/firmware/issues/7204 + */ + RDEF(KZ_433, 433.075f, 434.775f, 100, 0, 10, true, false, false), RDEF(KZ_863, 863.0f, 868.0f, 100, 0, 30, true, false, true), + /* 2.4 GHZ WLAN Band equivalent. Only for SX128x chips. */ @@ -681,4 +689,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) sendingPacket = p; return p->encrypted.size + sizeof(PacketHeader); -} \ No newline at end of file +} From ff4eed08bcb5c0f99fbb8fbcd443d3896e08547a Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Thu, 3 Jul 2025 20:41:17 -0400 Subject: [PATCH 11/13] Fixed --change-mode option since it was broken (#7144) getopts can't parse double-dash options so it had to be done separately. Also fixed where CHANGE_MODE was checked since it wasn't working either. --- bin/device-update.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/bin/device-update.sh b/bin/device-update.sh index 6adfe4e0e..2a39cdef7 100755 --- a/bin/device-update.sh +++ b/bin/device-update.sh @@ -30,6 +30,18 @@ Flash image file to device, leave existing system intact." EOF } +# Check for --change-mode and remove it from arguments +NEW_ARGS="" +for arg in "$@"; do + if [ "$arg" = "--change-mode" ]; then + CHANGE_MODE=true + else + NEW_ARGS="$NEW_ARGS \"\$arg\"" + fi +done + +# Reset positional parameters to filtered list +eval set -- $NEW_ARGS while getopts ":hp:P:f:" opt; do case "${opt}" in @@ -43,9 +55,6 @@ while getopts ":hp:P:f:" opt; do ;; f) FILENAME=${OPTARG} ;; - --change-mode) - CHANGE_MODE=true - ;; *) echo "Invalid flag." show_help >&2 @@ -55,7 +64,7 @@ while getopts ":hp:P:f:" opt; do done shift "$((OPTIND-1))" -if [[ $CHANGE_MODE == true ]]; then +if [ "$CHANGE_MODE" = true ]; then $ESPTOOL_CMD --baud 1200 --after no_reset read_flash_status exit 0 fi From dfb07e8bd2d8a1b8fe4bb03bba460fa3503a7f7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:16:53 -0500 Subject: [PATCH 12/13] chore(deps): update meshtastic-esp32_https_server digest to 3223704 (#7225) --- arch/esp32/esp32.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index cba84181b..faeca342f 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -49,7 +49,7 @@ lib_deps = ${environmental_extra.lib_deps} ${radiolib_base.lib_deps} # renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master - https://github.com/meshtastic/esp32_https_server/archive/896f1771ceb5979987a0b41028bf1b4e7aad419b.zip + https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip # renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino h2zero/NimBLE-Arduino@^1.4.3 # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master From 0f96bd7a26e5a435e90f03492d934121346cf5d2 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 3 Jul 2025 21:31:09 -0500 Subject: [PATCH 13/13] Add Kazakhstan to the BaseUI LoRa chooser (#7224) --- src/graphics/draw/MenuHandler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 6dbba853e..7e5063fef 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -48,12 +48,14 @@ void menuHandler::LoraRegionPicker(uint32_t duration) "PH_433", "PH_868", "PH_915", - "ANZ_433"}; + "ANZ_433", + "KZ_433", + "KZ_863"}; BannerOverlayOptions bannerOptions; bannerOptions.message = "Set the LoRa region"; bannerOptions.durationMs = duration; bannerOptions.optionsArrayPtr = optionsArray; - bannerOptions.optionsCount = 23; + bannerOptions.optionsCount = 25; bannerOptions.InitialSelected = 0; bannerOptions.bannerCallback = [](int selected) -> void { if (selected != 0 && config.lora.region != _meshtastic_Config_LoRaConfig_RegionCode(selected)) {