From c46abe125c2c99728558f4ae4f4857507bdc75e4 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 1 Nov 2025 12:45:11 -0500 Subject: [PATCH 1/5] Skip setting up Lora GPIO lines when using a ch341 radio on native (#8506) --- src/platform/portduino/PortduinoGlue.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index dbc90f9a4..53dece150 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -393,11 +393,17 @@ void portduinoSetup() // Need to bind all the configured GPIO pins so they're not simulated // TODO: If one of these fails, we should log and terminate for (auto i : portduino_config.all_pins) { - if (i->enabled) + // In the case of a ch341 Lora device, we don't want to touch the system GPIO lines for Lora + // Those GPIO are handled in our usermode driver instead. + if (i->config_section == "Lora" && portduino_config.lora_spi_dev == "ch341") { + continue; + } + if (i->enabled) { if (initGPIOPin(i->pin, gpioChipName + std::to_string(i->gpiochip), i->line) != ERRNO_OK) { printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i->line); exit(EXIT_FAILURE); } + } } // Only initialize the radio pins when dealing with real, kernel controlled SPI hardware @@ -423,8 +429,7 @@ int initGPIOPin(int pinNum, const std::string gpioChipName, int line) { #ifdef PORTDUINO_LINUX_HARDWARE std::string gpio_name = "GPIO" + std::to_string(pinNum); - std::cout << gpio_name; - printf("\n"); + std::cout << "Initializing " << gpio_name << " on chip " << gpioChipName << std::endl; try { GPIOPin *csPin; csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), line, gpio_name.c_str()); From bca0e1abde1076ed24d08e5e113fc8789bbc754b Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:48:04 +0100 Subject: [PATCH 2/5] Fix boot on RP2040 by excluding new FreeRTOS task (#8508) --- src/input/InputBroker.cpp | 6 +++--- src/input/InputBroker.h | 4 ++-- src/main.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/input/InputBroker.cpp b/src/input/InputBroker.cpp index c588a9a0f..39fc665c5 100644 --- a/src/input/InputBroker.cpp +++ b/src/input/InputBroker.cpp @@ -5,7 +5,7 @@ InputBroker *inputBroker = nullptr; InputBroker::InputBroker() { -#ifdef HAS_FREE_RTOS +#if defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) inputEventQueue = xQueueCreate(5, sizeof(InputEvent)); pollSoonQueue = xQueueCreate(5, sizeof(InputPollable *)); xTaskCreate(pollSoonWorker, "input-pollSoon", 2 * 1024, this, 10, &pollSoonTask); @@ -17,7 +17,7 @@ void InputBroker::registerSource(Observable *source) this->inputEventObserver.observe(source); } -#ifdef HAS_FREE_RTOS +#if defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) void InputBroker::requestPollSoon(InputPollable *pollable) { if (xPortInIsrContext() == pdTRUE) { @@ -52,7 +52,7 @@ int InputBroker::handleInputEvent(const InputEvent *event) return 0; } -#ifdef HAS_FREE_RTOS +#if defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) void InputBroker::pollSoonWorker(void *p) { InputBroker *instance = (InputBroker *)p; diff --git a/src/input/InputBroker.h b/src/input/InputBroker.h index 192bd7e8b..36328ca64 100644 --- a/src/input/InputBroker.h +++ b/src/input/InputBroker.h @@ -59,7 +59,7 @@ class InputBroker : public Observable InputBroker(); void registerSource(Observable *source); void injectInputEvent(const InputEvent *event) { handleInputEvent(event); } -#ifdef HAS_FREE_RTOS +#if defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) void requestPollSoon(InputPollable *pollable); void queueInputEvent(const InputEvent *event); void processInputEventQueue(); @@ -69,7 +69,7 @@ class InputBroker : public Observable int handleInputEvent(const InputEvent *event); private: -#ifdef HAS_FREE_RTOS +#if defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) QueueHandle_t inputEventQueue; QueueHandle_t pollSoonQueue; TaskHandle_t pollSoonTask; diff --git a/src/main.cpp b/src/main.cpp index 689e80e35..c65482292 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1595,7 +1595,7 @@ void loop() #endif service->loop(); -#if !MESHTASTIC_EXCLUDE_INPUTBROKER && defined(HAS_FREE_RTOS) +#if !MESHTASTIC_EXCLUDE_INPUTBROKER && defined(HAS_FREE_RTOS) && !defined(ARCH_RP2040) if (inputBroker) inputBroker->processInputEventQueue(); #endif From a7796fc7b486af5ce03f3f4740f6d666743ec00c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 1 Nov 2025 21:11:36 -0500 Subject: [PATCH 3/5] Fix dismiss of ext. notification (#8512) * Dismiss all ext notifications with any input broker event * Account for nagging --- src/input/InputBroker.cpp | 8 ++++++++ src/modules/ExternalNotificationModule.cpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/input/InputBroker.cpp b/src/input/InputBroker.cpp index 39fc665c5..7e3ff3de9 100644 --- a/src/input/InputBroker.cpp +++ b/src/input/InputBroker.cpp @@ -1,5 +1,7 @@ #include "InputBroker.h" #include "PowerFSM.h" // needed for event trigger +#include "configuration.h" +#include "modules/ExternalNotificationModule.h" InputBroker *inputBroker = nullptr; @@ -48,6 +50,12 @@ void InputBroker::processInputEventQueue() int InputBroker::handleInputEvent(const InputEvent *event) { powerFSM.trigger(EVENT_INPUT); // todo: not every input should wake, like long hold release + + if (event && event->inputEvent != INPUT_BROKER_NONE && externalNotificationModule && + moduleConfig.external_notification.enabled) { + externalNotificationModule->stopNow(); + } + this->notifyObservers(event); return 0; } diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index b047e04c2..4fe49cc1b 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -325,6 +325,10 @@ void ExternalNotificationModule::stopNow() drv.stop(); #endif + // Prevent the state machine from immediately re-triggering outputs after a manual stop. + isNagging = false; + nagCycleCutoff = UINT32_MAX; + #ifdef HAS_I2S // GPIO0 is used as mclk for I2S audio and set to OUTPUT by the sound library // T-Deck uses GPIO0 as trackball button, so restore the mode From b5b9dc310f8a62fba1d91272adc21b1a94d099cc Mon Sep 17 00:00:00 2001 From: Melon <1523107+Melonbwead@users.noreply.github.com> Date: Sun, 2 Nov 2025 12:09:15 +0000 Subject: [PATCH 4/5] Update device-install.sh to support heltec-v4 (#8509) * Update device-install.sh * Update device-install.sh --- bin/device-install.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/bin/device-install.sh b/bin/device-install.sh index ede75bbba..69e4794ba 100755 --- a/bin/device-install.sh +++ b/bin/device-install.sh @@ -31,21 +31,23 @@ MUIDB_8MB=( "seeed-sensecap-indicator" ) BIGDB_16MB=( - "t-deck" - "mesh-tab" - "t-energy-s3" "dreamcatcher" - "ESP32-S3-Pico" - "m5stack-cores3" - "station-g2" - "t-eth-elite" - "tlora-pager" - "t-watch-s3" "elecrow-adv" + "ESP32-S3-Pico" + "heltec-v4" + "m5stack-cores3" + "mesh-tab" + "station-g2" + "t-deck" + "t-energy-s3" + "t-eth-elite" + "t-watch-s3" + "tlora-pager" ) S3_VARIANTS=( "s3" "-v3" + "-v4" "t-deck" "wireless-paper" "wireless-tracker" From 597fa0b3820e2799cb95c1a5369f3b952b20b4b9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 2 Nov 2025 06:11:47 -0600 Subject: [PATCH 5/5] Add heltec v4 to bat as well --- bin/device-install.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/device-install.bat b/bin/device-install.bat index 9c206d718..519073b08 100755 --- a/bin/device-install.bat +++ b/bin/device-install.bat @@ -15,12 +15,12 @@ SET "LOGCOUNTER=0" SET "BPS_RESET=0" @REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable. -SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone t-eth-elite tlora-pager mesh-tab dreamcatcher ESP32-S3-Pico seeed-sensecap-indicator heltec_capsule_sensor_v3 vision-master icarus tracksenger elecrow-adv" +SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone t-eth-elite tlora-pager mesh-tab dreamcatcher ESP32-S3-Pico seeed-sensecap-indicator heltec_capsule_sensor_v3 vision-master icarus tracksenger elecrow-adv heltec-v4" SET "C3=esp32c3" @REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable. SET "BIGDB_8MB=crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger" SET "MUIDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator" -SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite tlora-pager t-watch-s3 elecrow-adv" +SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite tlora-pager t-watch-s3 elecrow-adv heltec-v4" GOTO getopts :help