From 11309662a98cccc1a03e5c528a4f3258a1ce1ef6 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 20 Aug 2025 09:08:14 -0400
Subject: [PATCH 1/5] Update platformio/espressif32 to v6.12.0 (#7523)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
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 8990053eb..ffeaaf4cb 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -4,7 +4,7 @@ extends = arduino_base
custom_esp32_kind = esp32
platform =
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
- platformio/espressif32@6.11.0
+ platformio/espressif32@6.12.0
build_src_filter =
${arduino_base.build_src_filter} - - - - -
From 57e1725419009a3f10067577de8a14329fd2a5c0 Mon Sep 17 00:00:00 2001
From: Austin
Date: Wed, 20 Aug 2025 10:10:39 -0400
Subject: [PATCH 2/5] Revert "Update platformio/espressif32 to v6.12.0 (#7523)"
(#7695)
This reverts commit 11309662a98cccc1a03e5c528a4f3258a1ce1ef6.
---
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 ffeaaf4cb..8990053eb 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -4,7 +4,7 @@ extends = arduino_base
custom_esp32_kind = esp32
platform =
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
- platformio/espressif32@6.12.0
+ platformio/espressif32@6.11.0
build_src_filter =
${arduino_base.build_src_filter} - - - - -
From 5ce47045e75d967fa0f7bddb0c62eaddece9694d Mon Sep 17 00:00:00 2001
From: Jonathan Bennett
Date: Wed, 20 Aug 2025 12:51:14 -0500
Subject: [PATCH 3/5] Add SDL option to BaseUI on Native (#7568)
* Add SDL option to BaseUI on Native
* Update to latest LovyanGFX PR and use LGFX_SDL define
* Move SDL backend to native-sdl target
---
src/graphics/TFTDisplay.cpp | 62 +++++++++++++++++++++++-
src/graphics/TFTDisplay.h | 1 +
src/main.cpp | 8 ++-
variants/native/portduino/platformio.ini | 20 +++++++-
4 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp
index 24ea6c47a..f8787612f 100644
--- a/src/graphics/TFTDisplay.cpp
+++ b/src/graphics/TFTDisplay.cpp
@@ -667,15 +667,19 @@ static LGFX *tft = nullptr;
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
#elif ARCH_PORTDUINO
#include // Graphics and font library for ST7735 driver chip
+#if defined(LGFX_SDL)
+#include
+#endif
class LGFX : public lgfx::LGFX_Device
{
- lgfx::Panel_Device *_panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::ITouch *_touch_instance;
public:
+ lgfx::Panel_Device *_panel_instance;
+
LGFX(void)
{
if (settingsMap[displayPanel] == st7789)
@@ -694,6 +698,11 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance = new lgfx::Panel_ILI9488;
else if (settingsMap[displayPanel] == hx8357d)
_panel_instance = new lgfx::Panel_HX8357D;
+#if defined(LGFX_SDL)
+ else if (settingsMap[displayPanel] == x11) {
+ _panel_instance = new lgfx::Panel_sdl;
+ }
+#endif
else {
_panel_instance = new lgfx::Panel_NULL;
LOG_ERROR("Unknown display panel configured!");
@@ -754,7 +763,13 @@ class LGFX : public lgfx::LGFX_Device
_touch_instance->config(touch_cfg);
_panel_instance->setTouch(_touch_instance);
}
-
+#if defined(LGFX_SDL)
+ if (settingsMap[displayPanel] == x11) {
+ lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)_panel_instance;
+ sdl_panel_->setup();
+ sdl_panel_->addKeyCodeMapping(SDLK_RETURN, SDL_SCANCODE_KP_ENTER);
+ }
+#endif
setPanel(_panel_instance); // Sets the panel to use.
}
};
@@ -1060,6 +1075,49 @@ void TFTDisplay::display(bool fromBlank)
}
}
+void TFTDisplay::sdlLoop()
+{
+#if defined(LGFX_SDL)
+ static int lastPressed = 0;
+ static int shuttingDown = false;
+ if (settingsMap[displayPanel] == x11) {
+ lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)tft->_panel_instance;
+ if (sdl_panel_->loop() && !shuttingDown) {
+ LOG_WARN("Window Closed!");
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SHUTDOWN, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ }
+
+ // debounce
+ if (lastPressed != 0 && !lgfx::v1::gpio_in(lastPressed))
+ return;
+ if (!lgfx::v1::gpio_in(37)) {
+ lastPressed = 37;
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_RIGHT, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ } else if (!lgfx::v1::gpio_in(36)) {
+ lastPressed = 36;
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_UP, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ } else if (!lgfx::v1::gpio_in(38)) {
+ lastPressed = 38;
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_DOWN, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ } else if (!lgfx::v1::gpio_in(39)) {
+ lastPressed = 39;
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_LEFT, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ } else if (!lgfx::v1::gpio_in(SDL_SCANCODE_KP_ENTER)) {
+ lastPressed = SDL_SCANCODE_KP_ENTER;
+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SELECT, .kbchar = 0, .touchX = 0, .touchY = 0};
+ inputBroker->injectInputEvent(&event);
+ } else {
+ lastPressed = 0;
+ }
+ }
+#endif
+}
+
// Send a command to the display (low level function)
void TFTDisplay::sendCommand(uint8_t com)
{
diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h
index 38cd53ebb..60adfdf7c 100644
--- a/src/graphics/TFTDisplay.h
+++ b/src/graphics/TFTDisplay.h
@@ -23,6 +23,7 @@ class TFTDisplay : public OLEDDisplay
// Write the buffer to the display memory
virtual void display() override { display(false); };
virtual void display(bool fromBlank);
+ void sdlLoop();
// Turn the display upside down
virtual void flipScreenVertically();
diff --git a/src/main.cpp b/src/main.cpp
index c53877e37..ef5f5a721 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1562,7 +1562,13 @@ void loop()
#endif
service->loop();
-
+#if defined(LGFX_SDL)
+ if (screen) {
+ auto dispdev = screen->getDisplayDevice();
+ if (dispdev)
+ static_cast(dispdev)->sdlLoop();
+ }
+#endif
long delayMsec = mainController.runOrDelay();
// We want to sleep as long as possible here - because it saves power
diff --git a/variants/native/portduino/platformio.ini b/variants/native/portduino/platformio.ini
index b8452bb48..62942a80e 100644
--- a/variants/native/portduino/platformio.ini
+++ b/variants/native/portduino/platformio.ini
@@ -25,7 +25,6 @@ build_flags = ${native_base.build_flags} -Os -lX11 -linput -lxkbcommon -ffunctio
-D USE_X11=1
-D HAS_TFT=1
-D HAS_SCREEN=1
-
-D LV_CACHE_DEF_SIZE=6291456
-D LV_BUILD_TEST=0
-D LV_USE_LIBINPUT=1
@@ -41,6 +40,25 @@ build_flags = ${native_base.build_flags} -Os -lX11 -linput -lxkbcommon -ffunctio
build_src_filter =
${native_base.build_src_filter}
+[env:native-sdl]
+extends = native_base
+build_type = release
+lib_deps =
+ ${env.lib_deps}
+ ${networking_base.lib_deps}
+ ${radiolib_base.lib_deps}
+ ${environmental_base.lib_deps}
+ # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
+ rweather/Crypto@0.4.0
+ # renovate: datasource=git-refs depName=libch341-spi-userspace packageName=https://github.com/pine64/libch341-spi-userspace gitBranch=main
+ https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip
+ # renovate: datasource=custom.pio depName=adafruit/Adafruit seesaw Library packageName=adafruit/library/Adafruit seesaw Library
+ adafruit/Adafruit seesaw Library@1.7.9
+ https://github.com/jp-bennett/LovyanGFX/archive/7458f84a126c1f8fdc7b038074f71be903f6e4c0.zip
+build_flags = ${native_base.build_flags}
+ !pkg-config --cflags --libs sdl2 --silence-errors || :
+ -D LGFX_SDL=1
+
[env:native-fb]
extends = native_base
build_type = release
From ce75bf4496fe8900dbe2d443cedef77c53e4fc5a Mon Sep 17 00:00:00 2001
From: Jonathan Bennett
Date: Wed, 20 Aug 2025 14:18:20 -0500
Subject: [PATCH 4/5] Initial stab at rak6421 autoconf (#7691)
* Initial stab at rak6421 autoconf
* trunk
* Add crc check to eeprom autoconf
* Trunk again
---
...421.yaml => lora-RAK6421-13300-slot1.yaml} | 11 +--
bin/config.d/lora-RAK6421-13300-slot2.yaml | 8 ++
src/mesh/NodeDB.cpp | 6 +-
src/platform/portduino/PortduinoGlue.cpp | 98 +++++++++++++++++--
src/platform/portduino/PortduinoGlue.h | 15 ++-
5 files changed, 113 insertions(+), 25 deletions(-)
rename bin/config.d/{lora-RAK6421.yaml => lora-RAK6421-13300-slot1.yaml} (56%)
create mode 100644 bin/config.d/lora-RAK6421-13300-slot2.yaml
diff --git a/bin/config.d/lora-RAK6421.yaml b/bin/config.d/lora-RAK6421-13300-slot1.yaml
similarity index 56%
rename from bin/config.d/lora-RAK6421.yaml
rename to bin/config.d/lora-RAK6421-13300-slot1.yaml
index bbf38a474..6f65f9ccd 100644
--- a/bin/config.d/lora-RAK6421.yaml
+++ b/bin/config.d/lora-RAK6421-13300-slot1.yaml
@@ -9,13 +9,4 @@ Lora:
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
- # CS: 8
-
-
- ### RAK13300in Slot 2 pins
-# IRQ: 18 #IO6
-# Reset: 24 # IO4
-# Busy: 19 # IO5
-# # Ant_sw: 23 # IO3
-# spidev: spidev0.1
-# # CS: 7
\ No newline at end of file
+ # CS: 8
\ No newline at end of file
diff --git a/bin/config.d/lora-RAK6421-13300-slot2.yaml b/bin/config.d/lora-RAK6421-13300-slot2.yaml
new file mode 100644
index 000000000..cbc794d39
--- /dev/null
+++ b/bin/config.d/lora-RAK6421-13300-slot2.yaml
@@ -0,0 +1,8 @@
+Lora:
+ ### RAK13300in Slot 2 pins
+ IRQ: 18 #IO6
+ Reset: 24 # IO4
+ Busy: 19 # IO5
+ # Ant_sw: 23 # IO3
+ spidev: spidev0.1
+ # CS: 7
\ No newline at end of file
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 97a1e463c..18014eb02 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -225,7 +225,11 @@ NodeDB::NodeDB()
memcpy(myNodeInfo.device_id.bytes + sizeof(device_id_start), &device_id_end, sizeof(device_id_end));
myNodeInfo.device_id.size = 16;
// Uncomment below to print the device id
-
+#elif ARCH_PORTDUINO
+ if (portduino_config.has_device_id) {
+ memcpy(myNodeInfo.device_id.bytes, portduino_config.device_id, 16);
+ myNodeInfo.device_id.size = 16;
+ }
#else
// FIXME - implement for other platforms
#endif
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index 3753c944c..929a45d09 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -10,6 +10,7 @@
#include "linux/gpio/LinuxGPIOPin.h"
#include "meshUtils.h"
#include "yaml-cpp/yaml.h"
+#include
#include
#include
#include
@@ -253,16 +254,95 @@ void portduinoSetup()
std::cout << "autoconf: Could not locate CH341 device" << std::endl;
}
// Try Pi HAT+
- std::cout << "autoconf: Looking for Pi HAT+..." << std::endl;
- if (access("/proc/device-tree/hat/product", R_OK) == 0) {
- std::ifstream hatProductFile("/proc/device-tree/hat/product");
- if (hatProductFile.is_open()) {
- hatProductFile.read(autoconf_product, 95);
- hatProductFile.close();
+ if (strlen(autoconf_product) < 6) {
+ std::cout << "autoconf: Looking for Pi HAT+..." << std::endl;
+ if (access("/proc/device-tree/hat/product", R_OK) == 0) {
+ std::ifstream hatProductFile("/proc/device-tree/hat/product");
+ if (hatProductFile.is_open()) {
+ hatProductFile.read(autoconf_product, 95);
+ hatProductFile.close();
+ }
+ std::cout << "autoconf: Found Pi HAT+ " << autoconf_product << " at /proc/device-tree/hat/product" << std::endl;
+ } else {
+ std::cout << "autoconf: Could not locate Pi HAT+ at /proc/device-tree/hat/product" << std::endl;
+ }
+ }
+ // attempt to load autoconf data from an EEPROM on 0x50
+ // RAK6421-13300-S1:aabbcc123456:5ba85807d92138b7519cfb60460573af:3061e8d8
+ // :mac address :<16 random unique bytes in hexidecimal> : crc32
+ // crc32 is calculated on the eeprom string up to but not including the final colon
+ if (strlen(autoconf_product) < 6) {
+ try {
+ char *mac_start = nullptr;
+ char *devID_start = nullptr;
+ char *crc32_start = nullptr;
+ Wire.begin();
+ Wire.beginTransmission(0x50);
+ Wire.write(0x0);
+ Wire.write(0x0);
+ Wire.endTransmission();
+ Wire.requestFrom((uint8_t)0x50, (uint8_t)75);
+ uint8_t i = 0;
+ delay(100);
+ std::string autoconf_raw;
+ while (Wire.available() && i < sizeof(autoconf_product)) {
+ autoconf_product[i] = Wire.read();
+ if (autoconf_product[i] == 0xff) {
+ autoconf_product[i] = 0x0;
+ break;
+ }
+ autoconf_raw += autoconf_product[i];
+ if (autoconf_product[i] == ':') {
+ autoconf_product[i] = 0x0;
+ if (mac_start == nullptr) {
+ mac_start = autoconf_product + i + 1;
+ } else if (devID_start == nullptr) {
+ devID_start = autoconf_product + i + 1;
+ } else if (crc32_start == nullptr) {
+ crc32_start = autoconf_product + i + 1;
+ }
+ }
+ i++;
+ }
+ if (crc32_start != nullptr && strlen(crc32_start) == 8) {
+ std::string crc32_str(crc32_start);
+ uint32_t crc32_value = 0;
+
+ // convert crc32 ascii to raw uint32
+ for (int j = 0; j < 4; j++) {
+ crc32_value += std::stoi(crc32_str.substr(j * 2, 2), nullptr, 16) << (3 - j) * 8;
+ }
+ std::cout << "autoconf: Found eeprom crc " << crc32_start << std::endl;
+
+ // set the autoconf string to blank and short circuit
+ if (crc32_value != crc32Buffer(autoconf_raw.c_str(), i - 9)) {
+ std::cout << "autoconf: crc32 mismatch, dropping " << std::endl;
+ autoconf_product[0] = 0x0;
+ } else {
+ std::cout << "autoconf: Found eeprom data " << autoconf_raw << std::endl;
+ if (mac_start != nullptr) {
+ std::cout << "autoconf: Found mac data " << mac_start << std::endl;
+ if (strlen(mac_start) == 12)
+ settingsStrings[mac_address] = std::string(mac_start);
+ }
+ if (devID_start != nullptr) {
+ std::cout << "autoconf: Found deviceid data " << devID_start << std::endl;
+ if (strlen(devID_start) == 32) {
+ std::string devID_str(devID_start);
+ for (int j = 0; j < 16; j++) {
+ portduino_config.device_id[j] = std::stoi(devID_str.substr(j * 2, 2), nullptr, 16);
+ }
+ portduino_config.has_device_id = true;
+ }
+ }
+ }
+ } else {
+ std::cout << "autoconf: crc32 missing " << std::endl;
+ autoconf_product[0] = 0x0;
+ }
+ } catch (...) {
+ std::cout << "autoconf: Could not locate EEPROM" << std::endl;
}
- std::cout << "autoconf: Found Pi HAT+ " << autoconf_product << " at /proc/device-tree/hat/product" << std::endl;
- } else {
- std::cout << "autoconf: Could not locate Pi HAT+ at /proc/device-tree/hat/product" << std::endl;
}
// Load the config file based on the product string
if (strlen(autoconf_product) > 0) {
diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h
index 6e450c90e..8c36a1180 100644
--- a/src/platform/portduino/PortduinoGlue.h
+++ b/src/platform/portduino/PortduinoGlue.h
@@ -10,11 +10,14 @@
// Product strings for auto-configuration
// {"PRODUCT_STRING", "CONFIG.YAML"}
// YAML paths are relative to `meshtastic/available.d`
-inline const std::unordered_map configProducts = {{"MESHTOAD", "lora-usb-meshtoad-e22.yaml"},
- {"MESHSTICK", "lora-meshstick-1262.yaml"},
- {"MESHADV-PI", "lora-MeshAdv-900M30S.yaml"},
- {"MeshAdv Mini", "lora-MeshAdv-Mini-900M22S.yaml"},
- {"POWERPI", "lora-MeshAdv-900M30S.yaml"}};
+inline const std::unordered_map configProducts = {
+ {"MESHTOAD", "lora-usb-meshtoad-e22.yaml"},
+ {"MESHSTICK", "lora-meshstick-1262.yaml"},
+ {"MESHADV-PI", "lora-MeshAdv-900M30S.yaml"},
+ {"MeshAdv Mini", "lora-MeshAdv-Mini-900M22S.yaml"},
+ {"POWERPI", "lora-MeshAdv-900M30S.yaml"},
+ {"RAK6421-13300-S1", "lora-RAK6421-13300-slot1.yaml"},
+ {"RAK6421-13300-S2", "lora-RAK6421-13300-slot2.yaml"}};
enum configNames {
default_gpiochip,
@@ -135,4 +138,6 @@ extern struct portduino_config_struct {
uint32_t rfswitch_dio_pins[5] = {RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
Module::RfSwitchMode_t rfswitch_table[8];
bool force_simradio = false;
+ bool has_device_id = false;
+ uint8_t device_id[16] = {0};
} portduino_config;
\ No newline at end of file
From 7574bfb7cbeaaf48ce29ef73ac2fcd38692186a6 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 20 Aug 2025 14:18:33 -0500
Subject: [PATCH 5/5] Update meshtastic/device-ui digest to 3dc7cf3 (#7698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
platformio.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index ac30eb32e..cce4d2dcf 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -118,7 +118,7 @@ lib_deps =
[device-ui_base]
lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
- https://github.com/meshtastic/device-ui/archive/8f5094b248c15ea2f9acf19cedfef6d2248fc1ff.zip
+ https://github.com/meshtastic/device-ui/archive/3dc7cf3e233aaa8cc23492cca50541fc099ebfa1.zip
; Common libs for environmental measurements in telemetry module
[environmental_base]