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]