From ac16ccf40c2389b1cd1de8e366a540f44523f292 Mon Sep 17 00:00:00 2001 From: Gareth Coleman <30833824+garethhcoleman@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:41:05 +0100 Subject: [PATCH 01/16] fix for unPhone hangs during boot without sd card present (#3709) * work around sd card hang if not present * comment out the define for HAS_SDCARD --- variants/unphone/variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/unphone/variant.h b/variants/unphone/variant.h index 180fdfe2c..7d5c30f79 100644 --- a/variants/unphone/variant.h +++ b/variants/unphone/variant.h @@ -48,7 +48,7 @@ #undef GPS_RX_PIN #undef GPS_TX_PIN -#define HAS_SDCARD 1 +// #define HAS_SDCARD 1 // causes hang if defined #define SDCARD_CS 43 #define LED_PIN 13 // the red part of the RGB LED From 9baccc80d8b06466d76a3a48ac0e1325af91abb7 Mon Sep 17 00:00:00 2001 From: Oleksandr Podolchak Date: Wed, 24 Apr 2024 16:41:01 +0300 Subject: [PATCH 02/16] Add SX1268 modules support for linux-native (#3702) * Add portduino Ebyte E22 XXXM30S/XXXM33S (sx1268) module support * Add Ebyte E22 XXXM3XS module config * Update comment for sx1268 module * Address review comments --------- Co-authored-by: Ben Meadors --- bin/config-dist.yaml | 9 +++++++++ src/main.cpp | 15 +++++++++++++++ src/platform/portduino/PortduinoGlue.cpp | 3 +++ src/platform/portduino/PortduinoGlue.h | 1 + 4 files changed, 28 insertions(+) diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index f02c2a2c2..05b4a7b0a 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -38,6 +38,15 @@ Lora: # Busy: 20 # Reset: 18 +# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S +# CS: 21 +# IRQ: 16 +# Busy: 20 +# Reset: 18 +# TXen: 6 +# RXen: 12 +# DIO3_TCXO_VOLTAGE: true + # DIO3_TCXO_VOLTAGE: true # the Waveshare Core1262 and others are known to need this setting # TXen: x # TX and RX enable pins diff --git a/src/main.cpp b/src/main.cpp index deaa60f3a..4a663a8a0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -770,6 +770,21 @@ void setup() LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); } } + } else if (settingsMap[use_sx1268]) { + if (!rIf) { + LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str()); + LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings); + rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], + settingsMap[busy]); + if (!rIf->init()) { + LOG_ERROR("Failed to find SX1268 radio\n"); + delete rIf; + rIf = NULL; + exit(EXIT_FAILURE); + } else { + LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n"); + } + } } #elif defined(HW_SPI1_DEVICE) diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index a8c473887..d86ac6677 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -136,6 +136,7 @@ void portduinoSetup() settingsMap[use_sx1262] = false; settingsMap[use_rf95] = false; settingsMap[use_sx1280] = false; + settingsMap[use_sx1268] = false; if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1262") { settingsMap[use_sx1262] = true; @@ -143,6 +144,8 @@ void portduinoSetup() settingsMap[use_rf95] = true; } else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1280") { settingsMap[use_sx1280] = true; + } else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1268") { + settingsMap[use_sx1268] = true; } settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false); settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(false); diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 4d2bcc262..94cdbf2f8 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -13,6 +13,7 @@ enum configNames { dio3_tcxo_voltage, use_rf95, use_sx1280, + use_sx1268, user, gpiochip, spidev, From e3610a2eb1e32350bb9b3adf1a7ced3394c0d024 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 24 Apr 2024 12:47:59 -0500 Subject: [PATCH 03/16] Move to lovyangfx develop for Native --- arch/portduino/portduino.ini | 4 +- src/graphics/TFTDisplay.cpp | 5 +- src/graphics/mesh_bus_spi.cpp | 188 ---------------------------------- src/graphics/mesh_bus_spi.h | 100 ------------------ 4 files changed, 4 insertions(+), 293 deletions(-) delete mode 100644 src/graphics/mesh_bus_spi.cpp delete mode 100644 src/graphics/mesh_bus_spi.h diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 452c34337..4857933ec 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -24,7 +24,7 @@ lib_deps = ${env.lib_deps} ${networking_base.lib_deps} rweather/Crypto@^0.4.0 - lovyan03/LovyanGFX@^1.1.12 + https://github.com/lovyan03/LovyanGFX.git#d35e60f269dfecbb18a8cb0fd07d594c2fb7e7a8 build_flags = ${arduino_base.build_flags} @@ -34,4 +34,4 @@ build_flags = -DPORTDUINO_LINUX_HARDWARE -lbluetooth -lgpiod - -lyaml-cpp + -lyaml-cpp \ No newline at end of file diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 3c28a9e42..b529bf0e4 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -1,7 +1,6 @@ #include "configuration.h" #include "main.h" #if ARCH_PORTDUINO -#include "mesh_bus_spi.h" #include "platform/portduino/PortduinoGlue.h" #endif @@ -340,7 +339,7 @@ static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h class LGFX : public lgfx::LGFX_Device { lgfx::Panel_LCD *_panel_instance; - lgfx::Mesh_Bus_SPI _bus_instance; + lgfx::Bus_SPI _bus_instance; lgfx::ITouch *_touch_instance; @@ -357,7 +356,7 @@ class LGFX : public lgfx::LGFX_Device _panel_instance = new lgfx::Panel_ILI9341; auto buscfg = _bus_instance.config(); buscfg.spi_mode = 0; - _bus_instance.spi_device(DisplaySPI, settingsStrings[displayspidev]); + _bus_instance.spi_device(DisplaySPI); buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable) diff --git a/src/graphics/mesh_bus_spi.cpp b/src/graphics/mesh_bus_spi.cpp deleted file mode 100644 index a9536d490..000000000 --- a/src/graphics/mesh_bus_spi.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// This code has been copied from LovyanGFX to make the SPI device selectable for touchscreens. -// Ideally this could eventually be an inherited class from BUS_SPI, -// but currently too many internal objects are set private. - -#include "configuration.h" -#if ARCH_PORTDUINO -#include "lgfx/v1/misc/pixelcopy.hpp" -#include "main.h" -#include "mesh_bus_spi.h" -#include -#include - -namespace lgfx -{ -inline namespace v1 -{ -//---------------------------------------------------------------------------- - -void Mesh_Bus_SPI::config(const config_t &config) -{ - _cfg = config; - - if (_cfg.pin_dc >= 0) { - pinMode(_cfg.pin_dc, pin_mode_t::output); - gpio_hi(_cfg.pin_dc); - } -} - -bool Mesh_Bus_SPI::init(void) -{ - dc_h(); - pinMode(_cfg.pin_dc, pin_mode_t::output); - if (SPIName != "") - PrivateSPI->begin(SPIName.c_str()); - else - PrivateSPI->begin(); - return true; -} - -void Mesh_Bus_SPI::release(void) -{ - PrivateSPI->end(); -} - -void Mesh_Bus_SPI::spi_device(HardwareSPI *newSPI, std::string newSPIName) -{ - PrivateSPI = newSPI; - SPIName = newSPIName; -} -void Mesh_Bus_SPI::beginTransaction(void) -{ - dc_h(); - SPISettings setting(_cfg.freq_write, MSBFIRST, _cfg.spi_mode); - PrivateSPI->beginTransaction(setting); -} - -void Mesh_Bus_SPI::endTransaction(void) -{ - PrivateSPI->endTransaction(); - dc_h(); -} - -void Mesh_Bus_SPI::beginRead(void) -{ - PrivateSPI->endTransaction(); - // SPISettings setting(_cfg.freq_read, BitOrder::MSBFIRST, _cfg.spi_mode, false); - SPISettings setting(_cfg.freq_read, MSBFIRST, _cfg.spi_mode); - PrivateSPI->beginTransaction(setting); -} - -void Mesh_Bus_SPI::endRead(void) -{ - PrivateSPI->endTransaction(); - beginTransaction(); -} - -void Mesh_Bus_SPI::wait(void) {} - -bool Mesh_Bus_SPI::busy(void) const -{ - return false; -} - -bool Mesh_Bus_SPI::writeCommand(uint32_t data, uint_fast8_t bit_length) -{ - dc_l(); - PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3); - dc_h(); - return true; -} - -void Mesh_Bus_SPI::writeData(uint32_t data, uint_fast8_t bit_length) -{ - PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3); -} - -void Mesh_Bus_SPI::writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t length) -{ - const uint8_t dst_bytes = bit_length >> 3; - uint32_t limit = (dst_bytes == 3) ? 12 : 16; - auto buf = _flip_buffer.getBuffer(512); - size_t fillpos = 0; - reinterpret_cast(buf)[0] = data; - fillpos += dst_bytes; - uint32_t len; - do { - len = ((length - 1) % limit) + 1; - if (limit <= 64) - limit <<= 1; - - while (fillpos < len * dst_bytes) { - memcpy(&buf[fillpos], buf, fillpos); - fillpos += fillpos; - } - - PrivateSPI->transfer(buf, len * dst_bytes); - } while (length -= len); -} - -void Mesh_Bus_SPI::writePixels(pixelcopy_t *param, uint32_t length) -{ - const uint8_t dst_bytes = param->dst_bits >> 3; - uint32_t limit = (dst_bytes == 3) ? 12 : 16; - uint32_t len; - do { - len = ((length - 1) % limit) + 1; - if (limit <= 32) - limit <<= 1; - auto buf = _flip_buffer.getBuffer(len * dst_bytes); - param->fp_copy(buf, 0, len, param); - PrivateSPI->transfer(buf, len * dst_bytes); - } while (length -= len); -} - -void Mesh_Bus_SPI::writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma) -{ - if (dc) - dc_h(); - else - dc_l(); - PrivateSPI->transfer(const_cast(data), length); - if (!dc) - dc_h(); -} - -uint32_t Mesh_Bus_SPI::readData(uint_fast8_t bit_length) -{ - uint32_t res = 0; - bit_length >>= 3; - if (!bit_length) - return res; - int idx = 0; - do { - res |= PrivateSPI->transfer(0) << idx; - idx += 8; - } while (--bit_length); - return res; -} - -bool Mesh_Bus_SPI::readBytes(uint8_t *dst, uint32_t length, bool use_dma) -{ - do { - dst[0] = PrivateSPI->transfer(0); - ++dst; - } while (--length); - return true; -} - -void Mesh_Bus_SPI::readPixels(void *dst, pixelcopy_t *param, uint32_t length) -{ - uint32_t bytes = param->src_bits >> 3; - uint32_t dstindex = 0; - uint32_t len = 4; - uint8_t buf[24]; - param->src_data = buf; - do { - if (len > length) - len = length; - readBytes((uint8_t *)buf, len * bytes, true); - param->src_x = 0; - dstindex = param->fp_copy(dst, dstindex, dstindex + len, param); - length -= len; - } while (length); -} - -} // namespace v1 -} // namespace lgfx -#endif \ No newline at end of file diff --git a/src/graphics/mesh_bus_spi.h b/src/graphics/mesh_bus_spi.h deleted file mode 100644 index 903f7ad9d..000000000 --- a/src/graphics/mesh_bus_spi.h +++ /dev/null @@ -1,100 +0,0 @@ -#if ARCH_PORTDUINO -/*----------------------------------------------------------------------------/ - Lovyan GFX - Graphics library for embedded devices. - -Original Source: - https://github.com/lovyan03/LovyanGFX/ - -Licence: - [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt) - -Author: - [lovyan03](https://twitter.com/lovyan03) - -Contributors: - [ciniml](https://github.com/ciniml) - [mongonta0716](https://github.com/mongonta0716) - [tobozo](https://github.com/tobozo) -/----------------------------------------------------------------------------*/ -#pragma once - -#include - -#include "lgfx/v1/Bus.hpp" -#include "lgfx/v1/platforms/common.hpp" - -namespace lgfx -{ -inline namespace v1 -{ -//---------------------------------------------------------------------------- - -class Mesh_Bus_SPI : public IBus -{ - public: - struct config_t { - uint32_t freq_write = 16000000; - uint32_t freq_read = 8000000; - // bool spi_3wire = true; - // bool use_lock = true; - int16_t pin_sclk = -1; - int16_t pin_miso = -1; - int16_t pin_mosi = -1; - int16_t pin_dc = -1; - uint8_t spi_mode = 0; - }; - - const config_t &config(void) const { return _cfg; } - - void config(const config_t &config); - - bus_type_t busType(void) const override { return bus_type_t::bus_spi; } - - bool init(void) override; - void release(void) override; - void spi_device(HardwareSPI *newSPI, std::string newSPIName); - - void beginTransaction(void) override; - void endTransaction(void) override; - void wait(void) override; - bool busy(void) const override; - - bool writeCommand(uint32_t data, uint_fast8_t bit_length) override; - void writeData(uint32_t data, uint_fast8_t bit_length) override; - void writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t count) override; - void writePixels(pixelcopy_t *param, uint32_t length) override; - void writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma) override; - - void initDMA(void) {} - void flush(void) {} - void addDMAQueue(const uint8_t *data, uint32_t length) override { writeBytes(data, length, true, true); } - void execDMAQueue(void) {} - uint8_t *getDMABuffer(uint32_t length) override { return _flip_buffer.getBuffer(length); } - - void beginRead(void) override; - void endRead(void) override; - uint32_t readData(uint_fast8_t bit_length) override; - bool readBytes(uint8_t *dst, uint32_t length, bool use_dma) override; - void readPixels(void *dst, pixelcopy_t *param, uint32_t length) override; - - private: - HardwareSPI *PrivateSPI; - std::string SPIName; - __attribute__((always_inline)) inline void dc_h(void) { gpio_hi(_cfg.pin_dc); } - __attribute__((always_inline)) inline void dc_l(void) { gpio_lo(_cfg.pin_dc); } - - config_t _cfg; - FlipBuffer _flip_buffer; - bool _need_wait; - uint32_t _mask_reg_dc; - uint32_t _last_apb_freq = -1; - uint32_t _clkdiv_write; - uint32_t _clkdiv_read; - volatile uint32_t *_gpio_reg_dc_h; - volatile uint32_t *_gpio_reg_dc_l; -}; - -//---------------------------------------------------------------------------- -} // namespace v1 -} // namespace lgfx -#endif \ No newline at end of file From c14043f196f7d05060b17ff193a60c269c84a686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Thu, 25 Apr 2024 13:47:39 +0200 Subject: [PATCH 04/16] Split warning into two messages, so we know which one is the case. (#3710) --- src/mqtt/MQTT.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index da1c204b8..8a477d8ad 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -548,7 +548,10 @@ void MQTT::perhapsReportToMap() } else { if (map_position_precision == 0 || (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)) { last_report_to_map = millis(); - LOG_WARN("MQTT Map reporting is enabled, but precision is 0 or no position available.\n"); + if (map_position_precision == 0) + LOG_WARN("MQTT Map reporting is enabled, but precision is 0\n"); + if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) + LOG_WARN("MQTT Map reporting is enabled, but no position available.\n"); return; } From 30fbcabf84b92e4fe84be8fb094c8e3c9be5252c Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 25 Apr 2024 14:23:38 -0500 Subject: [PATCH 05/16] add conffiles to .deb packaging (#3722) --- .github/workflows/package_raspbian.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index dd4133dab..81ff6ee25 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -45,6 +45,7 @@ jobs: - name: build .debpkg run: | + mkdir -p .debpkg/debian mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/etc/meshtasticd @@ -55,6 +56,7 @@ jobs: cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service + echo "etc/meshtasticd/config.yaml" > .debpkg/debian/conffiles - uses: jiro4989/build-deb-action@v3 with: From 5806a266d38ff34a53ee5f7bf456b2f4fa344079 Mon Sep 17 00:00:00 2001 From: thebentern Date: Thu, 25 Apr 2024 20:19:54 +0000 Subject: [PATCH 06/16] [create-pull-request] automated change --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 485f55130..36607a956 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 3 -build = 7 +build = 8 From dfcabba0b2bda6b142108962053c7c36263dcaf3 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Sat, 27 Apr 2024 13:43:09 +1200 Subject: [PATCH 07/16] Prevent overflow when calculating timezones (#3730) --- src/gps/RTC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 85931900f..a2cdb5b30 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -223,7 +223,7 @@ int32_t getTZOffset() now = time(NULL); gmt = gmtime(&now); gmt->tm_isdst = -1; - return (int16_t)difftime(now, mktime(gmt)); + return (int32_t)difftime(now, mktime(gmt)); } /** From f8c3f43ea61d4b6987b31e6e170b3ef56049ac9e Mon Sep 17 00:00:00 2001 From: Andrew Yong Date: Sat, 27 Apr 2024 19:17:17 +0800 Subject: [PATCH 08/16] Fix xiao_ble variant build error due to undefined BATTERY_SENSE_RESOLUTION_BITS (#3732) Define BATTERY_SENSE_RESOLUTION_BITS based on [amoroz's snippet on the Meshtastic forum](https://meshtastic.discourse.group/t/new-1w-diy-variant-xiao-nrf52840-ebyte-e22-900m30s/7904/10). Fixes following build error: ``` src/Power.cpp: In member function 'virtual uint16_t AnalogBatteryLevel::getBattVoltage()': src/Power.cpp:224:79: error: 'BATTERY_SENSE_RESOLUTION_BITS' was not declared in this scope scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw; ``` Signed-off-by: Andrew Yong --- variants/xiao_ble/variant.h | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/xiao_ble/variant.h b/variants/xiao_ble/variant.h index e2b8eb613..77af08278 100644 --- a/variants/xiao_ble/variant.h +++ b/variants/xiao_ble/variant.h @@ -181,6 +181,7 @@ static const uint8_t SCL = PIN_WIRE_SCL; #define BAT_READ \ 14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is // program pin 32 / or P0.31) +#define BATTERY_SENSE_RESOLUTION_BITS 10 #define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED #define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge From a06a01d25ea2f5cdc75e0e5266b542af5e789389 Mon Sep 17 00:00:00 2001 From: Oliver Seiler Date: Sat, 27 Apr 2024 11:35:44 +0000 Subject: [PATCH 09/16] fix #if HAS_TELEMETRY when set to 0 (#3733) --- src/Power.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index d13fd6891..2658b74a4 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel virtual uint16_t getBattVoltage() override { -#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) +#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) if (hasINA()) { LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address); return getINAVoltage(); @@ -360,7 +360,7 @@ class AnalogBatteryLevel : public HasBatteryLevel float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS); uint32_t last_read_time_ms = 0; -#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) +#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) uint16_t getINAVoltage() { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) { From e66aec8223337e6580adf86028ea4f6a5c73e2cd Mon Sep 17 00:00:00 2001 From: jcyrio <50239349+jcyrio@users.noreply.github.com> Date: Sat, 27 Apr 2024 06:54:06 -0700 Subject: [PATCH 10/16] fix typo in comment (#3726) --- src/modules/CannedMessageModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index c80ccc5e7..24e5d28d1 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -239,7 +239,7 @@ int32_t CannedMessageModule::runOnce() UIFrameEvent e = {false, true}; if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) { - // TODO: might have some feedback of sendig state + // TODO: might have some feedback of sending state this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; e.frameChanged = true; this->currentMessageIndex = -1; From e683d8f5525b1b3efd445c296b2cce2b37f7deb5 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 27 Apr 2024 08:55:04 -0500 Subject: [PATCH 11/16] Rebrand "send network ping" to more honest "try send position" with better output (#3737) --- src/ButtonThread.cpp | 7 +++++-- src/mesh/MeshService.cpp | 4 +++- src/mesh/MeshService.h | 5 +++-- src/modules/CannedMessageModule.cpp | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index 206bb7239..e9717521a 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -136,9 +136,12 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_DOUBLE_PRESSED: { LOG_BUTTON("Double press!\n"); service.refreshLocalMeshNode(); - service.sendNetworkPing(NODENUM_BROADCAST, true); + auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true); if (screen) { - screen->print("Sent ad-hoc ping\n"); + if (sentPosition) + screen->print("Sent ad-hoc position\n"); + else + screen->print("Sent ad-hoc nodeinfo\n"); screen->forceDisplay(true); // Force a new UI frame, then force an EInk update } break; diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 2c1969e30..6b8d37975 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -267,7 +267,7 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh } } -void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) +bool MeshService::trySendPosition(NodeNum dest, bool wantReplies) { meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); @@ -278,6 +278,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) if (positionModule) { LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel); positionModule->sendOurPosition(dest, wantReplies, node->channel); + return true; } } else { #endif @@ -286,6 +287,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel); } } + return false; } void MeshService::sendToPhone(meshtastic_MeshPacket *p) diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index 8d1434030..d777b7a01 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -108,8 +108,9 @@ class MeshService void reloadOwner(bool shouldSave = true); /// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least - /// sends our owner - void sendNetworkPing(NodeNum dest, bool wantReplies = false); + /// sends our nodeinfo + /// returns true if we sent a position + bool trySendPosition(NodeNum dest, bool wantReplies = false); /// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after /// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 24e5d28d1..ea7d5029a 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -452,7 +452,7 @@ int32_t CannedMessageModule::runOnce() break; case 0xaf: // fn+space send network ping like double press does service.refreshLocalMeshNode(); - service.sendNetworkPing(NODENUM_BROADCAST, true); + service.trySendPosition(NODENUM_BROADCAST, true); runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; break; default: From 38c4d35a7bd81e5b8ecbec479e4bf5df314e9735 Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:08:25 -0400 Subject: [PATCH 12/16] Add Notification on device screen following feature toggle (#3627) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update CannedMessageModule.h * Update CannedMessageModule.cpp * Update CannedMessageModule.cpp hopefully this fixes the errors on Trunk * Update CannedMessageModule.cpp Changed "Ping Broadcasted" with "Telemetry Update Sent" * tryfix: disable tempmessage again after 2 seconds * fix 2s showtime * Put spelling fix back * Fix build --------- Co-authored-by: Thomas Göttgens Co-authored-by: Ben Meadors --- src/modules/CannedMessageModule.cpp | 36 ++++++++++++++++++++++------- src/modules/CannedMessageModule.h | 6 ++++- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index ea7d5029a..b6267d985 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -233,14 +233,16 @@ int32_t CannedMessageModule::runOnce() { if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) { + temporaryMessage = ""; return INT32_MAX; } // LOG_DEBUG("Check status\n"); UIFrameEvent e = {false, true}; if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) || - (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) { + (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) { // TODO: might have some feedback of sending state this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + temporaryMessage = ""; e.frameChanged = true; this->currentMessageIndex = -1; this->freetext = ""; // clear freetext @@ -434,7 +436,7 @@ int32_t CannedMessageModule::runOnce() } if (screen) screen->forceDisplay(); - runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + showTemporaryMessage("GPS Toggled"); break; // mute (switch off/toggle) external notifications on fn+m @@ -442,18 +444,21 @@ int32_t CannedMessageModule::runOnce() if (moduleConfig.external_notification.enabled == true) { if (externalNotificationModule->getMute()) { externalNotificationModule->setMute(false); - runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + showTemporaryMessage("Notifications \nEnabled"); } else { externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop externalNotificationModule->setMute(true); - runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + showTemporaryMessage("Notifications \nDisabled"); } } break; case 0xaf: // fn+space send network ping like double press does service.refreshLocalMeshNode(); - service.trySendPosition(NODENUM_BROADCAST, true); - runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + if (service.trySendPosition(NODENUM_BROADCAST, true)) { + showTemporaryMessage("Position \nUpdate Sent"); + } else { + showTemporaryMessage("Node Info \nUpdate Sent"); + } break; default: if (this->cursor == this->freetext.length()) { @@ -542,12 +547,27 @@ int CannedMessageModule::getPrevIndex() return this->currentMessageIndex - 1; } } +void CannedMessageModule::showTemporaryMessage(const String &message) +{ + temporaryMessage = message; + UIFrameEvent e = {false, true}; + e.frameChanged = true; + notifyObservers(&e); + runState = CANNED_MESSAGE_RUN_STATE_MESSAGE; + // run this loop again in 2 seconds, next iteration will clear the display + setIntervalFromNow(2000); +} void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { char buffer[50]; - if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) { + if (temporaryMessage.length() != 0) { + LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str()); + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(FONT_MEDIUM); + display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage); + } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) { display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(FONT_MEDIUM); String displayString; @@ -766,4 +786,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor) return result; } -#endif \ No newline at end of file +#endif diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 4802be078..faf1d80f3 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -10,6 +10,7 @@ enum cannedMessageModuleRunState { CANNED_MESSAGE_RUN_STATE_FREETEXT, CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE, CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED, + CANNED_MESSAGE_RUN_STATE_MESSAGE, CANNED_MESSAGE_RUN_STATE_ACTION_SELECT, CANNED_MESSAGE_RUN_STATE_ACTION_UP, CANNED_MESSAGE_RUN_STATE_ACTION_DOWN, @@ -51,6 +52,8 @@ class CannedMessageModule : public SinglePortModule, public Observable Date: Sat, 27 Apr 2024 11:12:52 -0500 Subject: [PATCH 13/16] Tradunkadunk --- src/modules/CannedMessageModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index b6267d985..a8b1b994b 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -455,9 +455,9 @@ int32_t CannedMessageModule::runOnce() case 0xaf: // fn+space send network ping like double press does service.refreshLocalMeshNode(); if (service.trySendPosition(NODENUM_BROADCAST, true)) { - showTemporaryMessage("Position \nUpdate Sent"); + showTemporaryMessage("Position \nUpdate Sent"); } else { - showTemporaryMessage("Node Info \nUpdate Sent"); + showTemporaryMessage("Node Info \nUpdate Sent"); } break; default: From ee4c4ae6c968502888fdb3adb256d1023b397a1b Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 28 Apr 2024 02:15:54 +0300 Subject: [PATCH 14/16] Allow setting hopLimit for MQTT json sendtext and sendposition (#3735) * Fix channel name extraction * Allow setting hopLimit for mqtt sendtext and sendposition --- src/mqtt/MQTT.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 8a477d8ad..508830203 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -54,9 +54,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) JSONObject json; json = json_value->AsObject(); - // parse the channel name from the topic string by looking for "json/" - const char *jsonSlash = "json/"; - char *ptr = strstr(topic, jsonSlash) + sizeof(jsonSlash) + 1; // set pointer to after "json/" + // parse the channel name from the topic string + // the topic has been checked above for having jsonTopic prefix, so just move past it + char *ptr = topic + jsonTopic.length(); ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character meshtastic_Channel sendChannel = channels.getByName(ptr); // We allow downlink JSON packets only on a channel named "mqtt" @@ -76,6 +76,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) p->channel = json["channel"]->AsNumber(); if (json.find("to") != json.end() && json["to"]->IsNumber()) p->to = json["to"]->AsNumber(); + if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber()) + p->hop_limit = json["hopLimit"]->AsNumber(); if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) { memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length()); p->decoded.payload.size = jsonPayloadStr.length(); @@ -105,6 +107,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length) p->channel = json["channel"]->AsNumber(); if (json.find("to") != json.end() && json["to"]->IsNumber()) p->to = json["to"]->AsNumber(); + if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber()) + p->hop_limit = json["hopLimit"]->AsNumber(); p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Position_msg, &pos); // make the Data protobuf from position @@ -907,6 +911,7 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json) { // if "sender" is provided, avoid processing packets we uplinked return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) && + (json.find("hopLimit") != json.end() ? json["hopLimit"]->IsNumber() : true) && // hop limit should be a number (json.find("from") != json.end()) && json["from"]->IsNumber() && (json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us (json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type From 93f77ea7d23a1612887cef09019e1c0ed5d8cd93 Mon Sep 17 00:00:00 2001 From: David Ellefsen <93522+titan098@users.noreply.github.com> Date: Sun, 28 Apr 2024 02:50:15 +0200 Subject: [PATCH 15/16] Update TinyGPSPlus version (#3727) Co-authored-by: Ben Meadors --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index a1082a84a..e178fdb16 100644 --- a/platformio.ini +++ b/platformio.ini @@ -78,7 +78,7 @@ lib_deps = https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306 mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 - https://github.com/meshtastic/TinyGPSPlus.git#964f75a72cccd6b53cd74e4add1f7a42c6f7344d + https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4 https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0 nanopb/Nanopb@^0.4.7 erriez/ErriezCRC32@^1.0.1 From 18e69a0906e173cffa1049ca0954728e1b66b367 Mon Sep 17 00:00:00 2001 From: Andrew Yong Date: Sun, 28 Apr 2024 19:49:26 +0800 Subject: [PATCH 16/16] Update Heltec HT-C62 variant based on HT-DEV-ESP board (#3731) * I2C is not defined in the reference schematic nor HT-DEV-ESP board, remove definition accordingly * There is no screen in the the reference schematic nor HT-DEV-ESP board, change definition accordingly * BUTTON_PIN has a 10 kOhm pullup resistor on HT-DEV-ESP, turning off redundant internal pullup should save some power * LED is connected to GPIO2 on HT-DEV-ESP and is not inverted, update definition accordingly * Remove redundant undef lines for LoRa pins Above changes were built and flashed to my [HT-DEV-ESP_V2 board purchased from Heltec's Taobao store](https://item.taobao.com/item.htm?id=521590063077). Signed-off-by: Andrew Yong --- variants/heltec_esp32c3/variant.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/variants/heltec_esp32c3/variant.h b/variants/heltec_esp32c3/variant.h index 6641f9d21..360d9bf1f 100644 --- a/variants/heltec_esp32c3/variant.h +++ b/variants/heltec_esp32c3/variant.h @@ -1,24 +1,16 @@ -#define I2C_SDA 1 -#define I2C_SCL 0 - #define BUTTON_PIN 9 -#define BUTTON_NEED_PULLUP -// LED flashes brighter +// LED pin on HT-DEV-ESP_V2 and HT-DEV-ESP_V3 // https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf -#define LED_PIN 18 // LED -#define LED_INVERTED 1 +// https://resource.heltec.cn/download/HT-DEV-ESP/HT-DEV-ESP_V3_Sch.pdf +#define LED_PIN 2 // LED +#define LED_INVERTED 0 -#define HAS_SCREEN 1 +#define HAS_SCREEN 0 #define HAS_GPS 0 #undef GPS_RX_PIN #undef GPS_TX_PIN -#undef LORA_SCK -#undef LORA_MISO -#undef LORA_MOSI -#undef LORA_CS - #define USE_SX1262 #define LORA_SCK 10 #define LORA_MISO 6