diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml
index 795c1b1a09..d4e00b4eda 100644
--- a/.github/ISSUE_TEMPLATE/Bug Report.yml
+++ b/.github/ISSUE_TEMPLATE/Bug Report.yml
@@ -40,10 +40,12 @@ body:
- T-Echo
- Rak4631
- Rak11200
+ - Rak11310
- Heltec v1
- Heltec v2
- Heltec v2.1
- Heltec V3
+ - Raspberry Pi Pico (W)
- Relay v1
- Relay v2
- DIY
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 9ef8f77c65..32f280a045 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -7,7 +7,8 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on
-- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor and the 'clang-format' extension,
- because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines.
+- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
+ because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed.
+- Please also enable "Allow edits by maintainers".
diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index 6194bfe692..caf04fff65 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -33,6 +33,7 @@ jobs:
- board: m5stack-coreink
- board: tbeam-s3-core
- board: tlora-t3s3-v1
+ #- board: rak11310
runs-on: ubuntu-latest
steps:
@@ -103,16 +104,17 @@ jobs:
with:
board: ${{ matrix.board }}
- # build-rpi2040:
- # strategy:
- # fail-fast: false
- # max-parallel: 2
- # matrix:
- # include:
- # - board: pico
- # uses: ./.github/workflows/build_rpi2040.yml
- # with:
- # board: ${{ matrix.board }}
+ build-rpi2040:
+ strategy:
+ fail-fast: false
+ max-parallel: 2
+ matrix:
+ include:
+ - board: pico
+ - board: rak11310
+ uses: ./.github/workflows/build_rpi2040.yml
+ with:
+ board: ${{ matrix.board }}
build-native:
runs-on: ubuntu-latest
@@ -186,7 +188,8 @@ jobs:
gather-artifacts:
runs-on: ubuntu-latest
- needs: [build-esp32, build-esp32-s3, build-nrf52, build-native] #, build-rpi2040]
+ needs:
+ [build-esp32, build-esp32-s3, build-nrf52, build-native, build-rpi2040]
steps:
- name: Checkout code
uses: actions/checkout@v3
diff --git a/.gitignore b/.gitignore
index be3ca33974..89f8ee065e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,4 @@ __pycache__
venv/
release/
.vscode/extensions.json
+/compile_commands.json
diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index 42d55613c3..8805b0716c 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -1,7 +1,7 @@
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
extends = arduino_base
-platform = platformio/espressif32@^6.1.0
+platform = platformio/espressif32@^6.2.0
build_src_filter =
${arduino_base.build_src_filter} - - - - -
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index 0da344199d..7b5e04abbb 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -1,6 +1,6 @@
[nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
-platform = platformio/nordicnrf52@^9.5.0
+platform = platformio/nordicnrf52@^9.6.0
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index 9a3156ba83..d23ed886f2 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -1,6 +1,6 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
-platform = https://github.com/meshtastic/platform-native.git#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5
+platform = https://github.com/meshtastic/platform-native.git#489ff929dca0bb768256ba2de45f95815111490f
framework = arduino
build_src_filter =
@@ -28,4 +28,4 @@ lib_deps =
build_flags =
${arduino_base.build_flags}
-fPIC
- -Isrc/platform/portduino
+ -Isrc/platform/portduino
\ No newline at end of file
diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini
index 77dbfdbc01..5b01367686 100644
--- a/arch/rp2040/rp2040.ini
+++ b/arch/rp2040/rp2040.ini
@@ -1,7 +1,8 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
-platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9f8c10e50b5acd18e7bfd32638199c655be73a5b
+platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
extends = arduino_base
+platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.1
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -20,4 +21,4 @@ lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
jgromes/RadioLib@^6.0.0
- https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
+ https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
\ No newline at end of file
diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini
index 7f4a008cee..5a5edcde39 100644
--- a/arch/stm32/stm32wl5e.ini
+++ b/arch/stm32/stm32wl5e.ini
@@ -1,20 +1,29 @@
[stm32wl5e_base]
-platform = platformio/ststm32@^15.4.1
+platform_packages = platformio/framework-arduinoststm32 @ https://github.com/stm32duino/Arduino_Core_STM32.git#6e3f9910d0122e82a6c3438507dfac3d2fd80a39
+platform = ststm32
board = generic_wl5e
framework = arduino
build_type = debug
+
build_flags =
${arduino_base.build_flags}
-Isrc/platform/stm32wl -g
-
+ -DconfigUSE_CMSIS_RTOS_V2=1
+ -DVECT_TAB_OFFSET=0x08000000
+
build_src_filter =
${arduino_base.build_src_filter} - - - - - - - - - - - - - - -
+board_upload.offset_address = 0x08000000
+upload_protocol = stlink
+
lib_deps =
${env.lib_deps}
jgromes/RadioLib@^6.0.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
+ https://github.com/littlefs-project/littlefs.git#v2.5.1
+ https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
-lib_ignore =
- mathertel/OneButton@^2.0.3
+lib_ignore =
+ https://github.com/mathertel/OneButton#2.1.0
diff --git a/boards/generic_wl5e.json b/boards/generic_wl5e.json
index 433c55b594..5c4bc24a75 100644
--- a/boards/generic_wl5e.json
+++ b/boards/generic_wl5e.json
@@ -20,7 +20,7 @@
"maximum_ram_size": 65536,
"maximum_size": 262144,
"protocol": "cmsis-dap",
- "protocols": ["cmsis-dap"]
+ "protocols": ["cmsis-dap", "stlink"]
},
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST"
diff --git a/boards/wiscore_rak11300.json b/boards/wiscore_rak11300.json
new file mode 100644
index 0000000000..19beee74dd
--- /dev/null
+++ b/boards/wiscore_rak11300.json
@@ -0,0 +1,40 @@
+{
+ "build": {
+ "arduino": {
+ "earlephilhower": {
+ "boot2_source": "boot2_w25q080_2_padded_checksum.S",
+ "usb_vid": "0x2E8A",
+ "usb_pid": "0x000A"
+ }
+ },
+ "core": "earlephilhower",
+ "cpu": "cortex-m0plus",
+ "extra_flags": "-DARDUINO_GENERIC_RP2040 -DRASPBERRY_PI_PICO -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
+ "f_cpu": "133000000L",
+ "hwids": [
+ ["0x2E8A", "0x00C0"],
+ ["0x2E8A", "0x000A"]
+ ],
+ "mcu": "rp2040",
+ "variant": "WisBlock_RAK11300_Board"
+ },
+ "debug": {
+ "jlink_device": "RP2040_M0_0",
+ "openocd_target": "rp2040.cfg",
+ "svd_path": "rp2040.svd"
+ },
+ "frameworks": ["arduino"],
+ "name": "WisBlock RAK11300",
+ "upload": {
+ "maximum_ram_size": 270336,
+ "maximum_size": 2097152,
+ "require_upload_port": true,
+ "native_usb": true,
+ "use_1200bps_touch": true,
+ "wait_for_upload_port": false,
+ "protocol": "picotool",
+ "protocols": ["cmsis-dap", "raspberrypi-swd", "picotool", "picoprobe"]
+ },
+ "url": "https://docs.rakwireless.com/",
+ "vendor": "RAKwireless"
+}
diff --git a/platformio.ini b/platformio.ini
index 2040b75ce6..9abb56b7ae 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -2,17 +2,17 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
-default_envs = tbeam
+;default_envs = tbeam
;default_envs = pico
;default_envs = tbeam-s3-core
;default_envs = tbeam0.7
;default_envs = heltec-v1
-;default_envs = heltec-v2.0
-;default_envs = heltec-v2.1
+;default_envs = heltec-v2_0
+;default_envs = heltec-v2_1
;default_envs = tlora-v1
;default_envs = tlora_v1_3
;default_envs = tlora-v2
-;default_envs = tlora-v2-1-1.6
+;default_envs = tlora-v2-1-1_6
;default_envs = tlora-t3s3-v1
;default_envs = lora-relay-v1 # nrf board
;default_envs = t-echo
@@ -21,17 +21,18 @@ default_envs = tbeam
;default_envs = nano-g1
;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1
-;default_envs = meshtastic-diy-v1.1
+;default_envs = meshtastic-diy-v1_1
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
+default_envs = wio-e5
extra_configs =
arch/*/*.ini
variants/*/platformio.ini
[env]
-extra_scripts = bin/platformio-custom.py
+extra_scripts = bin/platformio-custom.py
; note: we add src to our include search path so that lmic_project_config can override
; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile
@@ -39,8 +40,8 @@ extra_scripts = bin/platformio-custom.py
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers
- -Wno-format
- -Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
+ -Wno-format
+ -Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
@@ -59,8 +60,8 @@ build_flags = -Wno-missing-field-initializers
monitor_speed = 115200
lib_deps =
- https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
- mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
+ https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
+ https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
@@ -87,14 +88,14 @@ lib_deps =
build_flags = ${env.build_flags} -Os -DRADIOLIB_SPI_PARANOID=0
build_src_filter = ${env.build_src_filter} -
-; Common libs for communicating over TCP/IP networks such as MQTT
+; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base]
lib_deps =
knolleary/PubSubClient@^2.8
arduino-libraries/NTPClient@^3.1.0
arcao/Syslog@^2.0.0
-; Common libs for environmental measurements in telemetry module
+; Common libs for environmental measurements in telemetry module
; (not included in native / portduino)
[environmental_base]
lib_deps =
@@ -102,7 +103,7 @@ lib_deps =
adafruit/Adafruit Unified Sensor@^1.1.9
adafruit/Adafruit BMP280 Library@^2.6.6
adafruit/Adafruit BME280 Library@^2.2.2
- boschsensortec/BSEC2 Software Library@^1.3.2200
+ https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.5.2400
boschsensortec/BME68x Sensor Library@^1.1.40407
adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
@@ -112,4 +113,4 @@ lib_deps =
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4
- adafruit/Adafruit LIS3DH@^1.2.4
+ adafruit/Adafruit LIS3DH@^1.2.4
\ No newline at end of file
diff --git a/protobufs b/protobufs
index e84f0cc7ca..5f3daac5fa 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit e84f0cc7cab2879b00085000589b9fd6527d0d68
+Subproject commit 5f3daac5fabdfe2a0561395fed0ba11a38ba3e7e
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index 0a8b2afa58..173566f938 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -51,7 +51,7 @@ class ButtonThread : public concurrency::OSThread
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif
userButton.attachClick(userButtonPressed);
- userButton.setClickTicks(300);
+ userButton.setClickMs(300);
userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed);
@@ -157,7 +157,7 @@ class ButtonThread : public concurrency::OSThread
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
screen->print("Sent ad-hoc ping\n");
- service.refreshMyNodeInfo();
+ service.refreshLocalNodeInfo();
service.sendNetworkPing(NODENUM_BROADCAST, true);
}
diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h
index 36b009ff2a..59ce043bcb 100644
--- a/src/DebugConfiguration.h
+++ b/src/DebugConfiguration.h
@@ -28,6 +28,7 @@
#define DEBUG_PORT (*console) // Serial debug port
#ifdef USE_SEGGER
+#define DEBUG_PORT
#define LOG_DEBUG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_INFO(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_WARN(...) SEGGER_RTT_printf(0, __VA_ARGS__)
diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp
index cc99caed80..150391237b 100644
--- a/src/FSCommon.cpp
+++ b/src/FSCommon.cpp
@@ -57,7 +57,7 @@ bool renameFile(const char *pathFrom, const char *pathTo)
#endif
}
-void listDir(const char *dirname, uint8_t levels, boolean del = false)
+void listDir(const char *dirname, uint8_t levels, bool del = false)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
diff --git a/src/FSCommon.h b/src/FSCommon.h
index 98d3911d77..ef1d3e4c17 100644
--- a/src/FSCommon.h
+++ b/src/FSCommon.h
@@ -13,6 +13,13 @@
#define FILE_O_READ "r"
#endif
+#if defined(ARCH_STM32WL)
+#include "platform/stm32wl/InternalFileSystem.h" // STM32WL version
+#define FSCom InternalFS
+#define FSBegin() FSCom.begin()
+using namespace LittleFS_Namespace;
+#endif
+
#if defined(ARCH_RP2040)
// RP2040
#include "LittleFS.h"
@@ -42,6 +49,6 @@ using namespace Adafruit_LittleFS_Namespace;
void fsInit();
bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo);
-void listDir(const char *dirname, uint8_t levels, boolean del);
+void listDir(const char *dirname, uint8_t levels, bool del);
void rmDir(const char *dirname);
void setupSDCard();
\ No newline at end of file
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index bdfce36ff4..6b760385fc 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -138,8 +138,9 @@ class GPSStatus : public Status
LOG_DEBUG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, speed=%.2f, sats=%d\n", p.timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.ground_speed * 1e-2, p.sats_in_view);
- } else
+ } else {
LOG_DEBUG("No GPS lock\n");
+ }
onNewStatus.notifyObservers(this);
}
return 0;
diff --git a/src/Power.cpp b/src/Power.cpp
index b129fbcd09..37d80a31f1 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -17,12 +17,38 @@
#define DELAY_FOREVER portMAX_DELAY
#endif
+#if defined(BATTERY_PIN) && defined(ARCH_ESP32)
+
+#ifndef BAT_MEASURE_ADC_UNIT // ADC1 is default
+static const adc1_channel_t adc_channel = ADC_CHANNEL;
+static const adc_unit_t unit = ADC_UNIT_1;
+#else // ADC2
+static const adc2_channel_t adc_channel = ADC_CHANNEL;
+static const adc_unit_t unit = ADC_UNIT_2;
+RTC_NOINIT_ATTR uint64_t RTC_reg_b;
+
+#endif // BAT_MEASURE_ADC_UNIT
+
+esp_adc_cal_characteristics_t *adc_characs = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
+#ifndef ADC_ATTENUATION
+static const adc_atten_t atten = ADC_ATTEN_DB_11;
+#else
+static const adc_atten_t atten = ADC_ATTENUATION;
+#endif
+#endif // BATTERY_PIN && ARCH_ESP32
+
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
+INA260Sensor ina260Sensor;
+INA219Sensor ina219Sensor;
+#endif
+
#ifdef HAS_PMU
#include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
#include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL;
#else
+
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
class HasBatteryLevel
@@ -108,6 +134,13 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{
+#if defined(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();
+ }
+#endif
+
#ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2.0
#endif
@@ -128,18 +161,41 @@ class AnalogBatteryLevel : public HasBatteryLevel
// Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
// environment.
uint32_t raw = 0;
+#ifdef ARCH_ESP32
+#ifndef BAT_MEASURE_ADC_UNIT // ADC1
+ for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
+ raw += adc1_get_raw(adc_channel);
+ }
+#else // ADC2
+ int32_t adc_buf = 0;
+ for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
+ // ADC2 wifi bug workaround, see
+ // https://github.com/espressif/arduino-esp32/issues/102
+ WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, RTC_reg_b);
+ SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
+ adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf);
+ raw += adc_buf;
+ }
+#endif // BAT_MEASURE_ADC_UNIT
+#else // !ARCH_ESP32
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
raw += analogRead(BATTERY_PIN);
}
+#endif
raw = raw / BATTERY_SENSE_SAMPLES;
-
float scaled;
+#ifdef ARCH_ESP32
+ scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
+ scaled *= operativeAdcMultiplier;
+#else
#ifndef VBAT_RAW_TO_SCALED
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
#else
scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h
-#endif
- // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
+#endif // VBAT RAW TO SCALED
+#endif // ARCH_ESP32
+ // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
+
last_read_value = scaled;
return scaled;
} else {
@@ -147,7 +203,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
}
#else
return 0;
-#endif
+#endif // BATTERY_PIN
}
/**
@@ -203,6 +259,35 @@ class AnalogBatteryLevel : public HasBatteryLevel
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
float last_read_value = 0.0;
uint32_t last_read_time_ms = 0;
+
+#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
+ uint16_t getINAVoltage()
+ {
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ return ina219Sensor.getBusVoltageMv();
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ return ina260Sensor.getBusVoltageMv();
+ }
+ return 0;
+ }
+
+ bool hasINA()
+ {
+ if (!config.power.device_battery_ina_address) {
+ return false;
+ }
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ if (!ina219Sensor.isInitialized())
+ return ina219Sensor.runOnce() > 0;
+ return ina219Sensor.isRunning();
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ if (!ina260Sensor.isInitialized())
+ return ina260Sensor.runOnce() > 0;
+ return ina260Sensor.isRunning();
+ }
+ return false;
+ }
+#endif
};
AnalogBatteryLevel analogLevel;
@@ -228,25 +313,52 @@ bool Power::analogInit()
// disable any internal pullups
pinMode(BATTERY_PIN, INPUT);
-#ifdef ARCH_ESP32
- // ESP32 needs special analog stuff
- adcAttachPin(BATTERY_PIN);
+#ifndef BATTERY_SENSE_RESOLUTION_BITS
+#define BATTERY_SENSE_RESOLUTION_BITS 10
+#endif
+
+#ifdef ARCH_ESP32 // ESP32 needs special analog stuff
+
+#ifndef ADC_WIDTH // max resolution by default
+ static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
+#else
+ static const adc_bits_width_t width = ADC_WIDTH;
+#endif
+#ifndef BAT_MEASURE_ADC_UNIT // ADC1
+ adc1_config_width(width);
+ adc1_config_channel_atten(adc_channel, atten);
+#else // ADC2
+ adc2_config_channel_atten(adc_channel, atten);
+ // ADC2 wifi bug workaround
+ RTC_reg_b = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG);
+#endif
+ // calibrate ADC
+ esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
+ // show ADC characterization base
+ if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
+ LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse\n");
+ } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
+ LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse\n");
+ } else {
+ LOG_INFO("ADCmod: ADC characterization based on default reference voltage\n");
+ }
+#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3)
+ pinMode(37, OUTPUT); // needed for P channel mosfet to work
+ digitalWrite(37, LOW);
#endif
+#endif // ARCH_ESP32
+
#ifdef ARCH_NRF52
#ifdef VBAT_AR_INTERNAL
analogReference(VBAT_AR_INTERNAL);
#else
analogReference(AR_INTERNAL); // 3.6V
#endif
-#endif
-
-#ifndef BATTERY_SENSE_RESOLUTION_BITS
-#define BATTERY_SENSE_RESOLUTION_BITS 10
-#endif
-
- // adcStart(BATTERY_PIN);
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11
// depending on needed resolution.
+
+#endif // ARCH_NRF52
+
batteryLevel = &analogLevel;
return true;
#else
@@ -302,7 +414,7 @@ void Power::readPowerStatus()
{
if (batteryLevel) {
bool hasBattery = batteryLevel->isBatteryConnect();
- int batteryVoltageMv = 0;
+ uint32_t batteryVoltageMv = 0;
int8_t batteryChargePercent = 0;
if (hasBattery) {
batteryVoltageMv = batteryLevel->getBattVoltage();
@@ -365,8 +477,8 @@ void Power::readPowerStatus()
#endif
- // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in a
- // row
+ // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in
+ // a row
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) {
low_voltage_counter++;
@@ -444,10 +556,10 @@ int32_t Power::runOnce()
* Init the power manager chip
*
* axp192 power
- DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192
- share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
- 30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
- not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
+ DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the
+ axp192 share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this
+ on!) LDO1 30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of
+ days), can not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
*
*/
bool Power::axpChipInit()
@@ -540,81 +652,80 @@ bool Power::axpChipInit()
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
/*The alternative version of T-Beam 1.1 differs from T-Beam V1.1 in that it uses an AXP2101 power chip*/
-#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
- // Unuse power channel
- PMU->disablePowerOutput(XPOWERS_DCDC2);
- PMU->disablePowerOutput(XPOWERS_DCDC3);
- PMU->disablePowerOutput(XPOWERS_DCDC4);
- PMU->disablePowerOutput(XPOWERS_DCDC5);
- PMU->disablePowerOutput(XPOWERS_ALDO1);
- PMU->disablePowerOutput(XPOWERS_ALDO4);
- PMU->disablePowerOutput(XPOWERS_BLDO1);
- PMU->disablePowerOutput(XPOWERS_BLDO2);
- PMU->disablePowerOutput(XPOWERS_DLDO1);
- PMU->disablePowerOutput(XPOWERS_DLDO2);
-
- // GNSS RTC PowerVDD 3300mV
- PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
- PMU->enablePowerOutput(XPOWERS_VBACKUP);
-
- // ESP32 VDD 3300mV
- // ! No need to set, automatically open , Don't close it
- // PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
- // PMU->setProtectedChannel(XPOWERS_DCDC1);
-
- // LoRa VDD 3300mV
- PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO2);
-
- // GNSS VDD 3300mV
- PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO3);
-
-#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
- // t-beam s3 core
- /**
- * gnss module power channel
- * The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during initialization
- */
- PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO4);
-
- // lora radio power channel
- PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO3);
-
- // m.2 interface
- PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
- PMU->enablePowerOutput(XPOWERS_DCDC3);
-
- /**
- * ALDO2 cannot be turned off.
- * It is a necessary condition for sensor communication.
- * It must be turned on to properly access the sensor and screen
- * It is also responsible for the power supply of PCF8563
- */
- PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO2);
-
- // 6-axis , magnetometer ,bme280 , oled screen power channel
- PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
- PMU->enablePowerOutput(XPOWERS_ALDO1);
-
- // sdcard power channle
- PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
- PMU->enablePowerOutput(XPOWERS_BLDO1);
-
- // PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
- // PMU->enablePowerOutput(XPOWERS_DCDC4);
-
- // not use channel
- PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
- PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
- PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
- PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
- PMU->disablePowerOutput(XPOWERS_VBACKUP);
-
-#endif
+ if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
+ // Unuse power channel
+ PMU->disablePowerOutput(XPOWERS_DCDC2);
+ PMU->disablePowerOutput(XPOWERS_DCDC3);
+ PMU->disablePowerOutput(XPOWERS_DCDC4);
+ PMU->disablePowerOutput(XPOWERS_DCDC5);
+ PMU->disablePowerOutput(XPOWERS_ALDO1);
+ PMU->disablePowerOutput(XPOWERS_ALDO4);
+ PMU->disablePowerOutput(XPOWERS_BLDO1);
+ PMU->disablePowerOutput(XPOWERS_BLDO2);
+ PMU->disablePowerOutput(XPOWERS_DLDO1);
+ PMU->disablePowerOutput(XPOWERS_DLDO2);
+
+ // GNSS RTC PowerVDD 3300mV
+ PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
+ PMU->enablePowerOutput(XPOWERS_VBACKUP);
+
+ // ESP32 VDD 3300mV
+ // ! No need to set, automatically open , Don't close it
+ // PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
+ // PMU->setProtectedChannel(XPOWERS_DCDC1);
+
+ // LoRa VDD 3300mV
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO2);
+
+ // GNSS VDD 3300mV
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO3);
+ } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
+ // t-beam s3 core
+ /**
+ * gnss module power channel
+ * The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during
+ * initialization
+ */
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO4);
+
+ // lora radio power channel
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO3);
+
+ // m.2 interface
+ PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
+ PMU->enablePowerOutput(XPOWERS_DCDC3);
+
+ /**
+ * ALDO2 cannot be turned off.
+ * It is a necessary condition for sensor communication.
+ * It must be turned on to properly access the sensor and screen
+ * It is also responsible for the power supply of PCF8563
+ */
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO2);
+
+ // 6-axis , magnetometer ,bme280 , oled screen power channel
+ PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
+ PMU->enablePowerOutput(XPOWERS_ALDO1);
+
+ // sdcard power channle
+ PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
+ PMU->enablePowerOutput(XPOWERS_BLDO1);
+
+ // PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
+ // PMU->enablePowerOutput(XPOWERS_DCDC4);
+
+ // not use channel
+ PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
+ PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
+ PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
+ PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
+ PMU->disablePowerOutput(XPOWERS_VBACKUP);
+ }
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp
index 6804242c23..e2cf942582 100644
--- a/src/PowerFSM.cpp
+++ b/src/PowerFSM.cpp
@@ -35,7 +35,7 @@ static bool isPowered()
static void sdsEnter()
{
- LOG_INFO("Enter state: SDS\n");
+ LOG_DEBUG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs));
}
@@ -44,7 +44,7 @@ extern Power *power;
static void shutdownEnter()
{
- LOG_INFO("Enter state: SHUTDOWN\n");
+ LOG_DEBUG("Enter state: SHUTDOWN\n");
power->shutdown();
}
@@ -135,7 +135,7 @@ static void lsExit()
static void nbEnter()
{
- LOG_INFO("Enter state: NB\n");
+ LOG_DEBUG("Enter state: NB\n");
screen->setOn(false);
setBluetoothEnable(false);
@@ -150,7 +150,7 @@ static void darkEnter()
static void serialEnter()
{
- LOG_INFO("Enter state: SERIAL\n");
+ LOG_DEBUG("Enter state: SERIAL\n");
setBluetoothEnable(false);
screen->setOn(true);
screen->print("Serial connected\n");
@@ -163,7 +163,7 @@ static void serialExit()
static void powerEnter()
{
- LOG_INFO("Enter state: POWER\n");
+ LOG_DEBUG("Enter state: POWER\n");
if (!isPowered()) {
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
LOG_INFO("Loss of power in Powered\n");
@@ -198,7 +198,7 @@ static void powerExit()
static void onEnter()
{
- LOG_INFO("Enter state: ON\n");
+ LOG_DEBUG("Enter state: ON\n");
screen->setOn(true);
setBluetoothEnable(true);
}
@@ -218,7 +218,7 @@ static void screenPress()
static void bootEnter()
{
- LOG_INFO("Enter state: BOOT\n");
+ LOG_DEBUG("Enter state: BOOT\n");
}
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp
index 39ea76c007..0e8e1c798a 100644
--- a/src/RedirectablePrint.cpp
+++ b/src/RedirectablePrint.cpp
@@ -62,6 +62,9 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
{
+ if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, "DEBUG") == 0) {
+ return 0;
+ }
size_t r = 0;
if (!inDebugPrint) {
diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp
index 91b4e2826c..e827dcf3b9 100644
--- a/src/SerialConsole.cpp
+++ b/src/SerialConsole.cpp
@@ -31,7 +31,7 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
// setDestination(&noopPrint); for testing, try turning off 'all' debug output and see what leaks
Port.begin(SERIAL_BAUD);
-#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
+#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040)
time_t timeout = millis();
while (!Port) {
if ((millis() - timeout) < 5000) {
diff --git a/src/airtime.cpp b/src/airtime.cpp
index 7be4c5b0dc..2702ee2bf6 100644
--- a/src/airtime.cpp
+++ b/src/airtime.cpp
@@ -6,20 +6,22 @@ AirTime *airTime = NULL;
// Don't read out of this directly. Use the helper functions.
+uint32_t air_period_tx[PERIODS_TO_LOG];
+uint32_t air_period_rx[PERIODS_TO_LOG];
+
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
if (reportType == TX_LOG) {
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
- myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
+ air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
-
} else if (reportType == RX_LOG) {
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
- myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
+ air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
@@ -55,16 +57,16 @@ void AirTime::airtimeRotatePeriod()
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
- myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
- myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
+ air_period_tx[i + 1] = this->airtimes.periodTX[i];
+ air_period_rx[i + 1] = this->airtimes.periodRX[i];
}
this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0;
- myNodeInfo.air_period_tx[0] = 0;
- myNodeInfo.air_period_rx[0] = 0;
+ air_period_tx[0] = 0;
+ air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
}
@@ -179,18 +181,17 @@ int32_t AirTime::runOnce()
}
// Init airtime windows to all 0
- for (int i = 0; i < myNodeInfo.air_period_rx_count; i++) {
+ for (int i = 0; i < PERIODS_TO_LOG; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;
- // myNodeInfo.air_period_tx[i] = 0;
- // myNodeInfo.air_period_rx[i] = 0;
+ // air_period_tx[i] = 0;
+ // air_period_rx[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
-
} else {
this->airtimeRotatePeriod();
@@ -206,12 +207,6 @@ int32_t AirTime::runOnce()
this->utilizationTX[utilPeriodTX] = 0;
}
-
- // Update channel_utilization every second.
- myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
-
- // Update channel_utilization every second.
- myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
/*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
@@ -223,4 +218,4 @@ int32_t AirTime::runOnce()
LOG_DEBUG("\n");
*/
return (1000 * 1);
-}
+}
\ No newline at end of file
diff --git a/src/concurrency/NotifiedWorkerThread.cpp b/src/concurrency/NotifiedWorkerThread.cpp
index 39a594c5a2..271e3e60d5 100644
--- a/src/concurrency/NotifiedWorkerThread.cpp
+++ b/src/concurrency/NotifiedWorkerThread.cpp
@@ -31,12 +31,14 @@ IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
runASAP = true;
notification = v;
- if (debugNotification)
+ if (debugNotification) {
LOG_DEBUG("setting notification %d\n", v);
+ }
return true;
} else {
- if (debugNotification)
+ if (debugNotification) {
LOG_DEBUG("dropping notification %d\n", v);
+ }
return false;
}
}
@@ -64,8 +66,9 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
if (didIt) { // If we didn't already have something queued, override the delay to be larger
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
- if (debugNotification)
+ if (debugNotification) {
LOG_DEBUG("delaying notification %u\n", delay);
+ }
}
return didIt;
diff --git a/src/concurrency/OSThread.cpp b/src/concurrency/OSThread.cpp
index c71d3510eb..f23cbe1dce 100644
--- a/src/concurrency/OSThread.cpp
+++ b/src/concurrency/OSThread.cpp
@@ -61,14 +61,17 @@ bool OSThread::shouldRun(unsigned long time)
{
bool r = Thread::shouldRun(time);
- if (showRun && r)
+ if (showRun && r) {
LOG_DEBUG("Thread %s: run\n", ThreadName.c_str());
+ }
- if (showWaiting && enabled && !r)
+ if (showWaiting && enabled && !r) {
LOG_DEBUG("Thread %s: wait %lu\n", ThreadName.c_str(), interval);
+ }
- if (showDisabled && !enabled)
+ if (showDisabled && !enabled) {
LOG_DEBUG("Thread %s: disabled\n", ThreadName.c_str());
+ }
return r;
}
diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp
index b7f16734f0..7afb03ee25 100644
--- a/src/detect/ScanI2CTwoWire.cpp
+++ b/src/detect/ScanI2CTwoWire.cpp
@@ -291,7 +291,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
{
- if (address.port == ScanI2C::I2CPort::WIRE1) {
+ if (address.port == ScanI2C::I2CPort::WIRE) {
return &Wire;
} else {
#ifdef I2C_SDA1
diff --git a/src/error.h b/src/error.h
index fc0707cd6e..d16ee6595f 100644
--- a/src/error.h
+++ b/src/error.h
@@ -9,4 +9,4 @@
/// Record an error that should be reported via analytics
void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
- const char *filename = NULL);
+ const char *filename = NULL);
\ No newline at end of file
diff --git a/src/freertosinc.h b/src/freertosinc.h
index c5dfddc8e9..dbe7c40014 100644
--- a/src/freertosinc.h
+++ b/src/freertosinc.h
@@ -12,7 +12,7 @@
#include
#endif
-#if defined(ARDUINO_NRF52_ADAFRUIT)
+#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32)
#define HAS_FREE_RTOS
#include
diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp
index ac11d78f8c..784ecac5d6 100644
--- a/src/gps/NMEAWPL.cpp
+++ b/src/gps/NMEAWPL.cpp
@@ -18,10 +18,11 @@
* -------------------------------------------
*/
-uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name)
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
{
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
- uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(),
+ char type = isCaltopoMode ? 'P' : 'N';
+ uint32_t len = snprintf(buf, bufsz, "$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(), name);
diff --git a/src/gps/NMEAWPL.h b/src/gps/NMEAWPL.h
index a9f00cb140..d597b7ea68 100644
--- a/src/gps/NMEAWPL.h
+++ b/src/gps/NMEAWPL.h
@@ -3,5 +3,5 @@
#include "main.h"
#include
-uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name);
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode = false);
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 2192140915..6b72a5d7d3 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -27,6 +27,7 @@ along with this program. If not, see .
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
+#include "error.h"
#include "gps/GeoCoord.h"
#include "gps/RTC.h"
#include "graphics/images.h"
@@ -352,7 +353,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->setFont(FONT_MEDIUM);
char tempBuf[24];
- snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", myNodeInfo.error_code);
+ snprintf(tempBuf, sizeof(tempBuf), "Critical fault #%d", error_code);
display->drawString(0 + x, 0 + y, tempBuf);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
@@ -711,13 +712,6 @@ static float estimatedHeading(double lat, double lon)
return b;
}
-/// Sometimes we will have Position objects that only have a time, so check for
-/// valid lat/lon
-static bool hasPosition(meshtastic_NodeInfo *n)
-{
- return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
-}
-
static uint16_t getCompassDiam(OLEDDisplay *display)
{
uint16_t diam = 0;
@@ -856,12 +850,12 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
bool hasNodeHeading = false;
- if (ourNode && hasPosition(ourNode)) {
+ if (ourNode && hasValidPosition(ourNode)) {
meshtastic_Position &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
- if (hasPosition(node)) {
+ if (hasValidPosition(node)) {
// display direction toward node
hasNodeHeading = true;
meshtastic_Position &p = node->position;
@@ -892,7 +886,8 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (!hasNodeHeading) {
// direction to node is unknown so display question mark
// Debug info for gps lock errors
- // LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node));
+ // LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasValidPosition(ourNode),
+ // hasValidPosition(node));
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
}
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
@@ -1239,8 +1234,10 @@ void Screen::setFrames()
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
LOG_DEBUG("Showing %d module frames\n", moduleFrames.size());
+#ifdef DEBUG_PORT
int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + moduleFrames.size();
LOG_DEBUG("Total frame count: %d\n", totalFrameCount);
+#endif
// We don't show the node info our our node (if we have it yet - we should)
size_t numnodes = nodeDB.getNumNodes();
@@ -1262,7 +1259,7 @@ void Screen::setFrames()
LOG_DEBUG("Added modules. numframes: %d\n", numframes);
// If we have a critical fault, show it first
- if (myNodeInfo.error_code)
+ if (error_code)
normalFrames[numframes++] = drawCriticalFaultFrame;
// If we have a text message - show it next, unless it's a phone message and we aren't using any special modules
diff --git a/src/main.cpp b/src/main.cpp
index 324422a692..937f9091a6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -59,6 +59,9 @@ NRF52Bluetooth *nrf52Bluetooth;
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#include "SX1280Interface.h"
+#ifdef ARCH_STM32WL
+#include "STM32WLE5JCInterface.h"
+#endif
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h"
#endif
@@ -68,7 +71,7 @@ NRF52Bluetooth *nrf52Bluetooth;
#endif
#include "PowerFSMThread.h"
-#if !defined(ARCH_PORTDUINO)
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "AccelerometerThread.h"
#endif
@@ -260,6 +263,12 @@ void setup()
// We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH);
+
+#ifndef USE_EINK
+ // RAK-12039 set pin for Air quality sensor
+ pinMode(AQ_SET_PIN, OUTPUT);
+ digitalWrite(AQ_SET_PIN, HIGH);
+#endif
#endif
// Currently only the tbeam has a PMU
@@ -347,10 +356,11 @@ void setup()
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
* "found".
*/
+
// Only one supported RGB LED currently
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
-#if !defined(ARCH_PORTDUINO)
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
@@ -439,7 +449,7 @@ void setup()
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
#endif
-#if !defined(ARCH_PORTDUINO)
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type);
}
@@ -447,7 +457,21 @@ void setup()
// Init our SPI controller (must be before screen and lora)
initSPI();
-#ifndef ARCH_ESP32
+#ifdef ARCH_RP2040
+#ifdef HW_SPI1_DEVICE
+ SPI1.setSCK(RF95_SCK);
+ SPI1.setTX(RF95_MOSI);
+ SPI1.setRX(RF95_MISO);
+ pinMode(RF95_NSS, OUTPUT);
+ digitalWrite(RF95_NSS, HIGH);
+ SPI1.begin(false);
+#else // HW_SPI1_DEVICE
+ SPI.setSCK(RF95_SCK);
+ SPI.setTX(RF95_MOSI);
+ SPI.setRX(RF95_MISO);
+ SPI.begin(false);
+#endif // HW_SPI1_DEVICE
+#elif !defined(ARCH_ESP32) // ARCH_RP2040
SPI.begin();
#else
// ESP32
@@ -462,10 +486,11 @@ void setup()
gps = createGps();
- if (gps)
+ if (gps) {
gpsStatus->observe(&gps->newStatus);
- else
+ } else {
LOG_WARN("No GPS found - running without GPS\n");
+ }
nodeStatus->observe(&nodeDB.newStatus);
@@ -508,11 +533,25 @@ void setup()
digitalWrite(SX126X_ANT_SW, 1);
#endif
- // Init LockingHAL first, to use it for radio init
-
+#ifdef HW_SPI1_DEVICE
+ LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
+#else // HW_SPI1_DEVICE
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
+#endif
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
+#if defined(USE_STM32WLx)
+ if (!rIf) {
+ rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
+ if (!rIf->init()) {
+ LOG_WARN("Failed to find STM32WL radio\n");
+ delete rIf;
+ rIf = NULL;
+ } else {
+ LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
+ }
+ }
+#endif
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
if (!rIf) {
@@ -634,12 +673,10 @@ void setup()
else {
router->addInterface(rIf);
- // Calculate and save the bit rate to myNodeInfo
- // TODO: This needs to be added what ever method changes the channel from the phone.
- myNodeInfo.bitrate =
- (float(meshtastic_Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
- 1000;
- LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
+ // Log bit rate to debug output
+ LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
+ (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
+ 1000);
}
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
@@ -660,7 +697,7 @@ bool runASAP;
extern meshtastic_DeviceMetadata getDeviceMetadata()
{
meshtastic_DeviceMetadata deviceMetadata;
- strncpy(deviceMetadata.firmware_version, myNodeInfo.firmware_version, 18);
+ strncpy(deviceMetadata.firmware_version, optstr(APP_VERSION), sizeof(deviceMetadata.firmware_version));
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
@@ -669,6 +706,7 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
deviceMetadata.role = config.device.role;
deviceMetadata.position_flags = config.position.position_flags;
deviceMetadata.hw_model = HW_VENDOR;
+ deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled;
return deviceMetadata;
}
@@ -716,4 +754,4 @@ void loop()
mainDelay.delay(delayMsec);
}
// if (didWake) LOG_DEBUG("wake!\n");
-}
+}
\ No newline at end of file
diff --git a/src/main.h b/src/main.h
index 0d23dd10c8..93baec590b 100644
--- a/src/main.h
+++ b/src/main.h
@@ -38,8 +38,6 @@ extern bool isUSBPowered;
extern ATECCX08A atecc;
#endif
-extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
-
extern int TCPPort; // set by Portduino
// Global Screen singleton.
@@ -69,4 +67,4 @@ void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), clearBonds();
meshtastic_DeviceMetadata getDeviceMetadata();
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
-extern SPISettings spiSettings;
+extern SPISettings spiSettings;
\ No newline at end of file
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
index 5e2cb41ba5..2a0b5ee396 100644
--- a/src/mesh/Channels.cpp
+++ b/src/mesh/Channels.cpp
@@ -108,8 +108,9 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
if (ch.role == meshtastic_Channel_Role_SECONDARY) {
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name);
k = getKey(primaryIndex);
- } else
+ } else {
LOG_WARN("User disabled encryption\n");
+ }
} else if (k.length == 1) {
// Convert the short single byte variants of psk into variant that can be used more generally
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index d8861943e3..1711992778 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -21,6 +21,7 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
{
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p);
+ Router::cancelSending(p->from, p->id); // cancel rebroadcast of this message *if* there was already one
return true;
}
@@ -62,4 +63,4 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
}
// handle the packet as normal
Router::sniffReceived(p, c);
-}
+}
\ No newline at end of file
diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp
index 73b0bdfbc2..c732829e94 100644
--- a/src/mesh/InterfacesTemplates.cpp
+++ b/src/mesh/InterfacesTemplates.cpp
@@ -10,6 +10,9 @@ template class SX126xInterface;
template class SX126xInterface;
template class SX126xInterface;
template class SX128xInterface;
+#ifdef ARCH_STM32WL
+template class SX126xInterface;
+#endif
#if HAS_ETHERNET
#include "api/ethServerAPI.h"
diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp
index d8dbf8a3a5..55948b33fa 100644
--- a/src/mesh/MeshModule.cpp
+++ b/src/mesh/MeshModule.cpp
@@ -179,9 +179,10 @@ void MeshModule::callPlugins(const meshtastic_MeshPacket &mp, RxSource src)
}
}
- if (!moduleFound)
+ if (!moduleFound) {
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
+ }
}
meshtastic_MeshPacket *MeshModule::allocReply()
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index 3b9ae26d24..06d30db4e8 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -239,7 +239,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node);
- if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
+ if (hasValidPosition(node)) {
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);
@@ -266,7 +266,7 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
fromNum++;
}
-meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
+meshtastic_NodeInfo *MeshService::refreshLocalNodeInfo()
{
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
assert(node);
@@ -293,7 +293,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
{
// Update our local node info with our position (even if we don't decide to update anyone else)
- meshtastic_NodeInfo *node = refreshMyNodeInfo();
+ meshtastic_NodeInfo *node = refreshLocalNodeInfo();
meshtastic_Position pos = meshtastic_Position_init_default;
if (newStatus->getHasLock()) {
@@ -312,7 +312,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
}
// Finally add a fresh timestamp and battery level reading
- // I KNOW this is redundant with refreshMyNodeInfo() above, but these are
+ // I KNOW this is redundant with refreshLocalNodeInfo() above, but these are
// inexpensive nonblocking calls and can be refactored in due course
pos.time = getValidTime(RTCQualityGPS);
diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h
index 4314ea3621..96878492be 100644
--- a/src/mesh/MeshService.h
+++ b/src/mesh/MeshService.h
@@ -98,7 +98,7 @@ class MeshService
bool cancelSending(PacketId id);
/// Pull the latest power and time info into my nodeinfo
- meshtastic_NodeInfo *refreshMyNodeInfo();
+ meshtastic_NodeInfo *refreshLocalNodeInfo();
/// Send a packet to the phone
void sendToPhone(meshtastic_MeshPacket *p);
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 5ee839b803..a18d0a7b4d 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -56,6 +56,10 @@ extern void getMacAddr(uint8_t *dmac);
*/
meshtastic_User &owner = devicestate.owner;
+meshtastic_CriticalErrorCode error_code =
+ meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
+uint32_t error_address = 0;
+
static uint8_t ourMacAddr[6];
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
@@ -275,9 +279,6 @@ void NodeDB::installDefaultDeviceState()
devicestate.version = DEVICESTATE_CUR_VER;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
- // default to no GPS, until one has been found by probing
- myNodeInfo.has_gps = false;
- myNodeInfo.message_timeout_msec = FLOOD_EXPIRE_TIME;
generatePacketId(); // FIXME - ugly way to init current_packet_id;
// Init our blank owner info to reasonable defaults
@@ -289,7 +290,6 @@ void NodeDB::installDefaultDeviceState()
snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
snprintf(owner.id, sizeof(owner.id), "!%08x", getNodeNum()); // Default node ID now based on nodenum
- memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
}
void NodeDB::init()
@@ -303,17 +303,12 @@ void NodeDB::init()
int saveWhat = 0;
- myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
-
- myNodeInfo.error_code =
- meshtastic_CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
- myNodeInfo.error_address = 0;
-
// likewise - we always want the app requirements to come from the running appload
- myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
-
+ myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
+ myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't
// keep using that nodenum forever. Crummy guess at our nodenum (but we will check against the nodedb to avoid conflicts)
+ strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
pickNewNodeNum();
// Set our board type so we can share it with others
@@ -324,19 +319,12 @@ void NodeDB::init()
info->user = owner;
info->has_user = true;
- strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
-
#ifdef ARCH_ESP32
Preferences preferences;
preferences.begin("meshtastic", false);
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
preferences.end();
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
-
- /* The ESP32 has a wifi radio. This will need to be modified at some point so
- * the test isn't so simplistic.
- */
- myNodeInfo.has_wifi = true;
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
@@ -349,6 +337,11 @@ void NodeDB::init()
if (channelFileCRC != crc32Buffer(&channelFile, sizeof(channelFile)))
saveWhat |= SEGMENT_CHANNELS;
+ if (!devicestate.node_remote_hardware_pins) {
+ meshtastic_NodeRemoteHardwarePin empty[12] = {meshtastic_RemoteHardwarePin_init_default};
+ memcpy(devicestate.node_remote_hardware_pins, empty, sizeof(empty));
+ }
+
saveToDisk(saveWhat);
}
@@ -468,8 +461,9 @@ void NodeDB::loadFromDisk()
}
}
- if (loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore))
+ if (loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore)) {
LOG_INFO("Loaded OEMStore\n");
+ }
}
/** Save a protobuf from a file, return true for success */
@@ -494,10 +488,12 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
f.close();
// brief window of risk here ;-)
- if (FSCom.exists(filename) && !FSCom.remove(filename))
+ if (FSCom.exists(filename) && !FSCom.remove(filename)) {
LOG_WARN("Can't remove old pref file\n");
- if (!renameFile(filenameTmp.c_str(), filename))
+ }
+ if (!renameFile(filenameTmp.c_str(), filename)) {
LOG_ERROR("Error: can't rename new pref file\n");
+ }
} else {
LOG_ERROR("Can't write prefs\n");
#ifdef ARCH_NRF52
@@ -576,10 +572,10 @@ void NodeDB::saveToDisk(int saveWhat)
}
}
-const meshtastic_NodeInfo *NodeDB::readNextInfo()
+const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
{
- if (readPointer < *numNodes)
- return &nodes[readPointer++];
+ if (readIndex < *numNodes)
+ return &nodes[readIndex++];
else
return NULL;
}
@@ -802,19 +798,19 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
// Print error to screen and serial port
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
- if (filename)
+ if (filename) {
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
- else
+ } else {
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
+ }
// Record error to DB
- myNodeInfo.error_code = code;
- myNodeInfo.error_address = address;
- myNodeInfo.error_count++;
+ error_code = code;
+ error_address = address;
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
#ifdef ARCH_PORTDUINO
LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
-}
+}
\ No newline at end of file
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 541b51f83a..e0744865f6 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -7,6 +7,7 @@
#include "MeshTypes.h"
#include "NodeStatus.h"
#include "mesh-pb-constants.h"
+#include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode
/*
DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
@@ -46,8 +47,6 @@ class NodeDB
meshtastic_NodeInfo *nodes;
pb_size_t *numNodes;
- uint32_t readPointer = 0;
-
public:
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
meshtastic_NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
@@ -104,11 +103,8 @@ class NodeDB
their denial?)
*/
- /// Called from bluetooth when the user wants to start reading the node DB from scratch.
- void resetReadPointer() { readPointer = 0; }
-
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
- const meshtastic_NodeInfo *readNextInfo();
+ const meshtastic_NodeInfo *readNextInfo(uint32_t &readIndex);
/// pick a provisional nodenum we hope no one is using
void pickNewNodeNum();
@@ -217,11 +213,25 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
return defaultInterval * 1000;
}
+/// Sometimes we will have Position objects that only have a time, so check for
+/// valid lat/lon
+static inline bool hasValidPosition(const meshtastic_NodeInfo *n)
+{
+ return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
+}
+
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
*/
extern uint32_t radioGeneration;
+extern meshtastic_CriticalErrorCode error_code;
+
+/*
+ * A numeric error address (nonzero if available)
+ */
+extern uint32_t error_address;
+
#define Module_Config_size \
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index cdda059137..5fc27a2b5a 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -40,9 +40,8 @@ void PhoneAPI::handleStartConfig()
state = STATE_SEND_MY_INFO;
LOG_INFO("Starting API client config\n");
- nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos
- nodeDB.resetReadPointer(); // FIXME, this read pointer should be moved out of nodeDB and into this class - because
- // this will break once we have multiple instances of PhoneAPI running independently
+ nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos
+ resetReadIndex();
}
void PhoneAPI::close()
@@ -144,12 +143,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n");
// If the user has specified they don't want our node to share its location, make sure to tell the phone
// app not to send locations on our behalf.
- myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO;
- service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
+ service.refreshLocalNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
break;
case STATE_SEND_NODEINFO: {
@@ -373,7 +371,7 @@ bool PhoneAPI::available()
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
- nodeInfoForPhone = nodeDB.readNextInfo();
+ nodeInfoForPhone = nodeDB.readNextInfo(readIndex);
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_PACKETS: {
@@ -423,8 +421,9 @@ int PhoneAPI::onNotify(uint32_t newValue)
if (state == STATE_SEND_PACKETS) {
LOG_INFO("Telling client we have new packets %u\n", newValue);
onNowHasData(newValue);
- } else
+ } else {
LOG_DEBUG("(Client not yet interested in packets)\n");
+ }
return 0;
}
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index af8f1be269..2ea4d3a0cf 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -58,6 +58,9 @@ class PhoneAPI
/// Use to ensure that clients don't get confused about old messages from the radio
uint32_t config_nonce = 0;
+ uint32_t readIndex = 0;
+
+ void resetReadIndex() { readIndex = 0; }
public:
PhoneAPI();
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 0d53dc8878..00af93e153 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -232,7 +232,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
delay = random(0, 2 * CWsize) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else {
- delay = random(0, pow(2, CWsize)) * slotTimeMsec;
+ // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
+ delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d\n", delay);
}
@@ -241,6 +242,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
{
+#ifdef DEBUG_PORT
std::string out = DEBUG_PORT.mt_sprintf("%s (id=0x%08x fr=0x%02x to=0x%02x, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id,
p->from & 0xff, p->to & 0xff, p->want_ack, p->hop_limit, p->channel);
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
@@ -283,6 +285,7 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
out += ")";
LOG_DEBUG("%s\n", out.c_str());
+#endif
}
RadioInterface::RadioInterface()
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index 8fd7157183..a74d410903 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -78,8 +78,9 @@ bool RadioLibInterface::canSendImmediately()
bool busyRx = isReceiving && isActivelyReceiving();
if (busyTx || busyRx) {
- if (busyTx)
+ if (busyTx) {
LOG_WARN("Can not send yet, busyTx\n");
+ }
// If we've been trying to send the same packet more than one minute and we haven't gotten a
// TX IRQ from the radio, the radio is probably broken.
if (busyTx && (millis() - lastTxStart > 60000)) {
@@ -88,8 +89,9 @@ bool RadioLibInterface::canSendImmediately()
// reboot in 5 seconds when this condition occurs.
rebootAtMsec = lastTxStart + 65000;
}
- if (busyRx)
+ if (busyRx) {
LOG_WARN("Can not send yet, busyRx\n");
+ }
return false;
} else
return true;
@@ -164,9 +166,9 @@ meshtastic_QueueStatus RadioLibInterface::getQueueStatus()
bool RadioLibInterface::canSleep()
{
bool res = txQueue.empty();
- if (!res) // only print debug messages if we are vetoing sleep
+ if (!res) { // only print debug messages if we are vetoing sleep
LOG_DEBUG("radio wait to sleep, txEmpty=%d\n", res);
-
+ }
return res;
}
@@ -404,4 +406,4 @@ void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
// bits
enableInterrupt(isrTxLevel0);
}
-}
+}
\ No newline at end of file
diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h
index 6635089e5e..4634ca7eec 100644
--- a/src/mesh/RadioLibInterface.h
+++ b/src/mesh/RadioLibInterface.h
@@ -27,6 +27,19 @@ class LockingArduinoHal : public ArduinoHal
void spiEndTransaction() override;
};
+#if defined(USE_STM32WLx)
+/**
+ * A wrapper for the RadioLib STM32WLx_Module class, that doesn't connect any pins as they are virtual
+ */
+class STM32WLx_ModuleWrapper : public STM32WLx_Module
+{
+ public:
+ STM32WLx_ModuleWrapper(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
+ RADIOLIB_PIN_TYPE busy)
+ : STM32WLx_Module(){};
+};
+#endif
+
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
{
/// Used as our notification from the ISR
@@ -56,7 +69,11 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
+#if !defined(USE_STM32WLx)
Module module; // The HW interface to the radio
+#else
+ STM32WLx_ModuleWrapper module;
+#endif
/**
* provides lowest common denominator RadioLib API
diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp
index 7f5c9b7fc4..946a669cc0 100644
--- a/src/mesh/ReliableRouter.cpp
+++ b/src/mesh/ReliableRouter.cpp
@@ -104,13 +104,14 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability)
if (p->want_ack) {
- if (MeshModule::currentReply)
+ if (MeshModule::currentReply) {
LOG_DEBUG("Some other module has replied to this message, no need for a 2nd ack\n");
- else if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
+ } else if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel);
- else
+ } else {
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex());
+ }
}
// We consider an ack to be either a !routing packet with a request ID or a routing packet with !error
diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp
index e85d85450c..156b482093 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -211,8 +211,10 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
float hourlyTxPercent = airTime->utilizationTXPercent();
if (hourlyTxPercent > myRegion->dutyCycle) {
+#ifdef DEBUG_PORT
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
+#endif
meshtastic_Routing_Error err = meshtastic_Routing_Error_DUTY_CYCLE_LIMIT;
if (getFrom(p) == nodeDB.getNodeNum()) { // only send NAK to API, not to the mesh
abortSendAndNak(err, p);
@@ -479,9 +481,9 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
// assert(radioConfig.has_preferences);
bool ignore = is_in_repeated(config.lora.ignore_incoming, p->from);
- if (ignore)
+ if (ignore) {
LOG_DEBUG("Ignoring incoming message, 0x%x is in our ignore list\n", p->from);
- else if (ignore |= shouldFilterReceived(p)) {
+ } else if (ignore |= shouldFilterReceived(p)) {
LOG_DEBUG("Incoming message was filtered 0x%x\n", p->from);
}
diff --git a/src/mesh/STM32WLE5JCInterface.cpp b/src/mesh/STM32WLE5JCInterface.cpp
new file mode 100644
index 0000000000..5b6fd08442
--- /dev/null
+++ b/src/mesh/STM32WLE5JCInterface.cpp
@@ -0,0 +1,45 @@
+#include "STM32WLE5JCInterface.h"
+#include "configuration.h"
+#include "error.h"
+
+#ifndef STM32WLx_MAX_POWER
+#define STM32WLx_MAX_POWER 22
+#endif
+
+#ifdef ARCH_STM32WL
+
+STM32WLE5JCInterface::STM32WLE5JCInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
+ RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy)
+ : SX126xInterface(hal, cs, irq, rst, busy)
+{
+}
+
+bool STM32WLE5JCInterface::init()
+{
+ RadioLibInterface::init();
+
+ lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ if (power == 0)
+ power = STM32WLx_MAX_POWER;
+
+ if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
+ power = STM32WLx_MAX_POWER;
+
+ limitPower();
+
+ int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
+
+ LOG_INFO("STM32WLx init result %d\n", res);
+
+ LOG_INFO("Frequency set to %f\n", getFreq());
+ LOG_INFO("Bandwidth set to %f\n", bw);
+ LOG_INFO("Power output set to %d\n", power);
+
+ if (res == RADIOLIB_ERR_NONE)
+ startReceive(); // start receiving
+
+ return res == RADIOLIB_ERR_NONE;
+}
+
+#endif // ARCH_STM32WL
diff --git a/src/mesh/STM32WLE5JCInterface.h b/src/mesh/STM32WLE5JCInterface.h
new file mode 100644
index 0000000000..73d53d92f9
--- /dev/null
+++ b/src/mesh/STM32WLE5JCInterface.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "SX126xInterface.h"
+
+#ifdef ARCH_STM32WL
+
+/**
+ * Our adapter for STM32WLE5JC radios
+ */
+class STM32WLE5JCInterface : public SX126xInterface
+{
+ public:
+ STM32WLE5JCInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
+ RADIOLIB_PIN_TYPE busy);
+
+ virtual bool init() override;
+};
+
+// https://github.com/Seeed-Studio/LoRaWan-E5-Node/blob/main/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c
+static const float tcxoVoltage = 1.7;
+
+/* https://wiki.seeedstudio.com/LoRa-E5_STM32WLE5JC_Module/
+ * Wio-E5 module ONLY transmits through RFO_HP
+ * Receive: PA4=1, PA5=0
+ * Transmit(high output power, SMPS mode): PA4=0, PA5=1 */
+static const RADIOLIB_PIN_TYPE rfswitch_pins[3] = {PA4, PA5, RADIOLIB_NC};
+
+static const Module::RfSwitchMode_t rfswitch_table[4] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW}}, {STM32WLx::MODE_RX, {HIGH, LOW}}, {STM32WLx::MODE_TX_HP, {LOW, HIGH}}, END_OF_MODE_TABLE};
+
+#endif // ARCH_STM32WL
\ No newline at end of file
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index c26b773f71..495840d50a 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -60,16 +60,19 @@ template bool SX126xInterface::init()
LOG_DEBUG("Current limit set to %f\n", currentLimit);
LOG_DEBUG("Current limit set result %d\n", res);
-#ifdef SX126X_E22
+#if defined(SX126X_E22)
// E22 Emulation explicitly requires DIO2 as RF switch, so set it to TRUE again for good measure. In case somebody defines
// SX126X_TX for an E22 Module
- if (res == RADIOLIB_ERR_NONE)
+ if (res == RADIOLIB_ERR_NONE) {
+ LOG_DEBUG("SX126X_E22 mode enabled. Setting DIO2 as RF Switch\n");
res = lora.setDio2AsRfSwitch(true);
+ }
#endif
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
if (res == RADIOLIB_ERR_NONE) {
+ LOG_DEBUG("SX126X_TX/RX EN pins defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN);
res = lora.setDio2AsRfSwitch(false);
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
}
@@ -176,8 +179,9 @@ template void SX126xInterface::setStandby()
int err = lora.standby();
- if (err != RADIOLIB_ERR_NONE)
+ if (err != RADIOLIB_ERR_NONE) {
LOG_DEBUG("SX126x standby failed with error %d\n", err);
+ }
assert(err == RADIOLIB_ERR_NONE);
diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp
index 691d5dff03..9c3ec3e914 100644
--- a/src/mesh/SX128xInterface.cpp
+++ b/src/mesh/SX128xInterface.cpp
@@ -151,8 +151,9 @@ template void SX128xInterface::setStandby()
int err = lora.standby();
- if (err != RADIOLIB_ERR_NONE)
+ if (err != RADIOLIB_ERR_NONE) {
LOG_ERROR("SX128x standby failed with error %d\n", err);
+ }
assert(err == RADIOLIB_ERR_NONE);
diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h
index 721eec2c01..c08f9183b2 100644
--- a/src/mesh/TypedQueue.h
+++ b/src/mesh/TypedQueue.h
@@ -74,7 +74,7 @@ template class TypedQueue
concurrency::OSThread *reader = NULL;
public:
- TypedQueue(int maxElements) {}
+ explicit TypedQueue(int maxElements) {}
int numFree() { return 1; } // Always claim 1 free, because we can grow to any size
diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp
index 659de05f85..c60e35394e 100644
--- a/src/mesh/eth/ethClient.cpp
+++ b/src/mesh/eth/ethClient.cpp
@@ -98,6 +98,11 @@ static int32_t reconnectETH()
return 5000; // every 5 seconds
}
+static uint32_t bigToLittleEndian(uint32_t value)
+{
+ return ((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000);
+}
+
// Startup Ethernet
bool initEthernet()
{
@@ -126,7 +131,15 @@ bool initEthernet()
status = Ethernet.begin(mac);
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
LOG_INFO("starting Ethernet Static\n");
- Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
+
+ IPAddress ip = IPAddress(bigToLittleEndian(config.network.ipv4_config.ip));
+ IPAddress dns = IPAddress(bigToLittleEndian(config.network.ipv4_config.dns));
+ IPAddress gateway = IPAddress(bigToLittleEndian(config.network.ipv4_config.gateway));
+ IPAddress subnet = IPAddress(bigToLittleEndian(config.network.ipv4_config.subnet));
+
+ Ethernet.begin(mac, ip, dns, gateway, subnet);
+
+ status = 1;
} else {
LOG_INFO("Ethernet Disabled\n");
return false;
diff --git a/src/mesh/generated/meshtastic/admin.pb.c b/src/mesh/generated/meshtastic/admin.pb.c
index c897c17607..92835c89cc 100644
--- a/src/mesh/generated/meshtastic/admin.pb.c
+++ b/src/mesh/generated/meshtastic/admin.pb.c
@@ -12,6 +12,9 @@ PB_BIND(meshtastic_AdminMessage, meshtastic_AdminMessage, 2)
PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO)
+PB_BIND(meshtastic_NodeRemoteHardwarePinsResponse, meshtastic_NodeRemoteHardwarePinsResponse, 2)
+
+
diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h
index 2518f199e6..b6162b8466 100644
--- a/src/mesh/generated/meshtastic/admin.pb.h
+++ b/src/mesh/generated/meshtastic/admin.pb.h
@@ -6,9 +6,10 @@
#include
#include "meshtastic/channel.pb.h"
#include "meshtastic/config.pb.h"
+#include "meshtastic/connection_status.pb.h"
+#include "meshtastic/deviceonly.pb.h"
#include "meshtastic/mesh.pb.h"
#include "meshtastic/module_config.pb.h"
-#include "meshtastic/connection_status.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
@@ -70,6 +71,13 @@ typedef struct _meshtastic_HamParameters {
char short_name[6];
} meshtastic_HamParameters;
+/* Response envelope for node_remote_hardware_pins */
+typedef struct _meshtastic_NodeRemoteHardwarePinsResponse {
+ /* Nodes and their respective remote hardware GPIO pins */
+ pb_size_t node_remote_hardware_pins_count;
+ meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[16];
+} meshtastic_NodeRemoteHardwarePinsResponse;
+
/* This message is handled by the Admin module and is responsible for all settings/channel read/write operations.
This message is used to do settings operations to both remote AND local nodes.
(Prior to 1.2 these operations were done via special ToRadio operations) */
@@ -111,6 +119,10 @@ typedef struct _meshtastic_AdminMessage {
meshtastic_DeviceConnectionStatus get_device_connection_status_response;
/* Setup a node for licensed amateur (ham) radio operation */
meshtastic_HamParameters set_ham_mode;
+ /* Get the mesh's nodes with their available gpio pins for RemoteHardware module use */
+ bool get_node_remote_hardware_pins_request;
+ /* Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use */
+ meshtastic_NodeRemoteHardwarePinsResponse get_node_remote_hardware_pins_response;
/* Set the owner for this node */
meshtastic_User set_owner;
/* Set channels (using the new API).
@@ -168,17 +180,21 @@ extern "C" {
+
/* Initializer values for message structs */
#define meshtastic_AdminMessage_init_default {0, {0}}
#define meshtastic_HamParameters_init_default {"", 0, 0, ""}
+#define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
#define meshtastic_AdminMessage_init_zero {0, {0}}
#define meshtastic_HamParameters_init_zero {"", 0, 0, ""}
+#define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_HamParameters_call_sign_tag 1
#define meshtastic_HamParameters_tx_power_tag 2
#define meshtastic_HamParameters_frequency_tag 3
#define meshtastic_HamParameters_short_name_tag 4
+#define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag 1
#define meshtastic_AdminMessage_get_channel_request_tag 1
#define meshtastic_AdminMessage_get_channel_response_tag 2
#define meshtastic_AdminMessage_get_owner_request_tag 3
@@ -196,6 +212,8 @@ extern "C" {
#define meshtastic_AdminMessage_get_device_connection_status_request_tag 16
#define meshtastic_AdminMessage_get_device_connection_status_response_tag 17
#define meshtastic_AdminMessage_set_ham_mode_tag 18
+#define meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag 19
+#define meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag 20
#define meshtastic_AdminMessage_set_owner_tag 32
#define meshtastic_AdminMessage_set_channel_tag 33
#define meshtastic_AdminMessage_set_config_tag 34
@@ -230,6 +248,8 @@ X(a, STATIC, ONEOF, STRING, (payload_variant,get_ringtone_response,get_ri
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_connection_status_request,get_device_connection_status_request), 16) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_connection_status_response,get_device_connection_status_response), 17) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_ham_mode,set_ham_mode), 18) \
+X(a, STATIC, ONEOF, BOOL, (payload_variant,get_node_remote_hardware_pins_request,get_node_remote_hardware_pins_request), 19) \
+X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_node_remote_hardware_pins_response,get_node_remote_hardware_pins_response), 20) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \
@@ -253,6 +273,7 @@ X(a, STATIC, ONEOF, INT32, (payload_variant,nodedb_reset,nodedb_reset),
#define meshtastic_AdminMessage_payload_variant_get_device_metadata_response_MSGTYPE meshtastic_DeviceMetadata
#define meshtastic_AdminMessage_payload_variant_get_device_connection_status_response_MSGTYPE meshtastic_DeviceConnectionStatus
#define meshtastic_AdminMessage_payload_variant_set_ham_mode_MSGTYPE meshtastic_HamParameters
+#define meshtastic_AdminMessage_payload_variant_get_node_remote_hardware_pins_response_MSGTYPE meshtastic_NodeRemoteHardwarePinsResponse
#define meshtastic_AdminMessage_payload_variant_set_owner_MSGTYPE meshtastic_User
#define meshtastic_AdminMessage_payload_variant_set_channel_MSGTYPE meshtastic_Channel
#define meshtastic_AdminMessage_payload_variant_set_config_MSGTYPE meshtastic_Config
@@ -266,16 +287,25 @@ X(a, STATIC, SINGULAR, STRING, short_name, 4)
#define meshtastic_HamParameters_CALLBACK NULL
#define meshtastic_HamParameters_DEFAULT NULL
+#define meshtastic_NodeRemoteHardwarePinsResponse_FIELDLIST(X, a) \
+X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 1)
+#define meshtastic_NodeRemoteHardwarePinsResponse_CALLBACK NULL
+#define meshtastic_NodeRemoteHardwarePinsResponse_DEFAULT NULL
+#define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
+
extern const pb_msgdesc_t meshtastic_AdminMessage_msg;
extern const pb_msgdesc_t meshtastic_HamParameters_msg;
+extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg
#define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg
+#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
/* Maximum encoded size of messages (where known) */
-#define meshtastic_AdminMessage_size 234
+#define meshtastic_AdminMessage_size 500
#define meshtastic_HamParameters_size 32
+#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h
index e3b6e242d8..99314aef5f 100644
--- a/src/mesh/generated/meshtastic/config.pb.h
+++ b/src/mesh/generated/meshtastic/config.pb.h
@@ -18,7 +18,7 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh. */
meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE = 1,
/* Router device role.
- Mesh packets will prefer to be routed over this node. This node will not be used by client apps.
+ Mesh packets will prefer to be routed over this node. This node will not be used by client apps.
The wifi/ble radios and the oled screen will be put to sleep.
This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. */
meshtastic_Config_DeviceConfig_Role_ROUTER = 2,
@@ -233,6 +233,9 @@ typedef struct _meshtastic_Config_DeviceConfig {
uint32_t node_info_broadcast_secs;
/* Treat double tap interrupt on supported accelerometers as a button press if set to true */
bool double_tap_as_button_press;
+ /* If true, device is considered to be "managed" by a mesh administrator
+ Clients should then limit available configuration and administrative options inside the user interface */
+ bool is_managed;
} meshtastic_Config_DeviceConfig;
/* Position Config */
@@ -290,7 +293,7 @@ typedef struct _meshtastic_Config_PowerConfig {
0 for default of 1 minute */
uint32_t wait_bluetooth_secs;
/* Mesh Super Deep Sleep Timeout Seconds
- While in Light Sleep if this value is exceeded we will lower into super deep sleep
+ While in Light Sleep if this value is exceeded we will lower into super deep sleep
for sds_secs (default 1 year) or a button press
0 for default of two hours, MAXUINT for disabled */
uint32_t mesh_sds_timeout_secs;
@@ -308,6 +311,8 @@ typedef struct _meshtastic_Config_PowerConfig {
While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
0 for default of 10 seconds */
uint32_t min_wake_secs;
+ /* I2C address of INA_2XX to use for reading device battery voltage */
+ uint8_t device_battery_ina_address;
} meshtastic_Config_PowerConfig;
typedef struct _meshtastic_Config_NetworkConfig_IpV4Config {
@@ -353,7 +358,7 @@ typedef struct _meshtastic_Config_DisplayConfig {
/* Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
Potentially useful for devices without user buttons. */
uint32_t auto_screen_carousel_secs;
- /* If this is set, the displayed compass will always point north. if unset, the old behaviour
+ /* If this is set, the displayed compass will always point north. if unset, the old behaviour
(top of display is heading direction) is used. */
bool compass_north_top;
/* Flip screen vertically, for cases that mount the screen upside down */
@@ -416,7 +421,7 @@ typedef struct _meshtastic_Config_LoRaConfig {
If using the hash algorithm the channel number will be: hash(channel_name) %
NUM_CHANNELS (Where num channels depends on the regulatory region). */
uint16_t channel_num;
- /* If true, duty cycle limits will be exceeded and thus you're possibly not following
+ /* If true, duty cycle limits will be exceeded and thus you're possibly not following
the local regulations if you're not a HAM.
Has no effect if the duty cycle of the used region is 100%. */
bool override_duty_cycle;
@@ -529,18 +534,18 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
-#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0}
+#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
+#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
-#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0}
+#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
+#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
@@ -556,6 +561,7 @@ extern "C" {
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_tag 6
#define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
+#define meshtastic_Config_DeviceConfig_is_managed_tag 9
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
@@ -575,6 +581,7 @@ extern "C" {
#define meshtastic_Config_PowerConfig_sds_secs_tag 6
#define meshtastic_Config_PowerConfig_ls_secs_tag 7
#define meshtastic_Config_PowerConfig_min_wake_secs_tag 8
+#define meshtastic_Config_PowerConfig_device_battery_ina_address_tag 9
#define meshtastic_Config_NetworkConfig_IpV4Config_ip_tag 1
#define meshtastic_Config_NetworkConfig_IpV4Config_gateway_tag 2
#define meshtastic_Config_NetworkConfig_IpV4Config_subnet_tag 3
@@ -650,7 +657,8 @@ X(a, STATIC, SINGULAR, UINT32, button_gpio, 4) \
X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \
X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
-X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8)
+X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
+X(a, STATIC, SINGULAR, BOOL, is_managed, 9)
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
@@ -677,7 +685,8 @@ X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 5) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \
-X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
+X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \
+X(a, STATIC, SINGULAR, UINT32, device_battery_ina_address, 9)
#define meshtastic_Config_PowerConfig_CALLBACK NULL
#define meshtastic_Config_PowerConfig_DEFAULT NULL
@@ -765,13 +774,13 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_Config_BluetoothConfig_size 10
-#define meshtastic_Config_DeviceConfig_size 28
+#define meshtastic_Config_DeviceConfig_size 30
#define meshtastic_Config_DisplayConfig_size 28
#define meshtastic_Config_LoRaConfig_size 77
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 195
#define meshtastic_Config_PositionConfig_size 54
-#define meshtastic_Config_PowerConfig_size 43
+#define meshtastic_Config_PowerConfig_size 46
#define meshtastic_Config_size 198
#ifdef __cplusplus
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.c b/src/mesh/generated/meshtastic/deviceonly.pb.c
index f3d27d086d..82c3fc44c5 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.c
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.c
@@ -9,11 +9,20 @@
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 4)
+PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO)
+
+
+PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO)
+
+
PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2)
PB_BIND(meshtastic_OEMStore, meshtastic_OEMStore, 2)
+PB_BIND(meshtastic_NodeRemoteHardwarePin, meshtastic_NodeRemoteHardwarePin, AUTO)
+
+
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h
index d08c18ba9f..48f93da5e4 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.h
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.h
@@ -7,6 +7,8 @@
#include "meshtastic/channel.pb.h"
#include "meshtastic/localonly.pb.h"
#include "meshtastic/mesh.pb.h"
+#include "meshtastic/telemetry.pb.h"
+#include "meshtastic/module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
@@ -24,44 +26,46 @@ typedef enum _meshtastic_ScreenFonts {
} meshtastic_ScreenFonts;
/* Struct definitions */
-/* This message is never sent over the wire, but it is used for serializing DB
- state to flash in the device code
- FIXME, since we write this each time we enter deep sleep (and have infinite
- flash) it would be better to use some sort of append only data structure for
- the receive queue and use the preferences store for the other stuff */
-typedef struct _meshtastic_DeviceState {
- /* Read only settings/info about this node */
- bool has_my_node;
- meshtastic_MyNodeInfo my_node;
- /* My owner info */
- bool has_owner;
- meshtastic_User owner;
+/* Position with static location information only for NodeDBLite */
+typedef struct _meshtastic_PositionLite {
+ /* The new preferred location encoding, multiply by 1e-7 to get degrees
+ in floating point */
+ int32_t latitude_i;
/* TODO: REPLACE */
- pb_size_t node_db_count;
- meshtastic_NodeInfo node_db[80];
- /* Received packets saved for delivery to the phone */
- pb_size_t receive_queue_count;
- meshtastic_MeshPacket receive_queue[1];
- /* We keep the last received text message (only) stored in the device flash,
- so we can show it on the screen.
- Might be null */
- bool has_rx_text_message;
- meshtastic_MeshPacket rx_text_message;
- /* A version integer used to invalidate old save files when we make
- incompatible changes This integer is set at build time and is private to
- NodeDB.cpp in the device code. */
- uint32_t version;
- /* Used only during development.
- Indicates developer is testing and changes should never be saved to flash. */
- bool no_save;
- /* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */
- bool did_gps_reset;
- /* We keep the last received waypoint stored in the device flash,
- so we can show it on the screen.
- Might be null */
- bool has_rx_waypoint;
- meshtastic_MeshPacket rx_waypoint;
-} meshtastic_DeviceState;
+ int32_t longitude_i;
+ /* In meters above MSL (but see issue #359) */
+ int32_t altitude;
+ /* This is usually not sent over the mesh (to save space), but it is sent
+ from the phone so that the local device can set its RTC If it is sent over
+ the mesh (because there are devices on the mesh without GPS), it will only
+ be sent by devices which has a hardware GPS clock.
+ seconds since 1970 */
+ uint32_t time;
+ /* TODO: REPLACE */
+ meshtastic_Position_LocSource location_source;
+} meshtastic_PositionLite;
+
+typedef struct _meshtastic_NodeInfoLite {
+ /* The node number */
+ uint32_t num;
+ /* The user info for this node */
+ bool has_user;
+ meshtastic_User user;
+ /* This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
+ Position.time now indicates the last time we received a POSITION from that node. */
+ bool has_position;
+ meshtastic_PositionLite position;
+ /* Returns the Signal-to-noise ratio (SNR) of the last received message,
+ as measured by the receiver. Return SNR of the last received message in dB */
+ float snr;
+ /* Set to indicate the last time we received a packet from this node */
+ uint32_t last_heard;
+ /* The latest device metrics for the node. */
+ bool has_device_metrics;
+ meshtastic_DeviceMetrics device_metrics;
+ /* local channel index we heard that node on. Only populated if its not the default channel. */
+ uint8_t channel;
+} meshtastic_NodeInfoLite;
/* The on-disk saved channels */
typedef struct _meshtastic_ChannelFile {
@@ -99,6 +103,61 @@ typedef struct _meshtastic_OEMStore {
meshtastic_LocalModuleConfig oem_local_module_config;
} meshtastic_OEMStore;
+/* RemoteHardwarePins associated with a node */
+typedef struct _meshtastic_NodeRemoteHardwarePin {
+ /* The node_num exposing the available gpio pin */
+ uint32_t node_num;
+ /* The the available gpio pin for usage with RemoteHardware module */
+ bool has_pin;
+ meshtastic_RemoteHardwarePin pin;
+} meshtastic_NodeRemoteHardwarePin;
+
+/* This message is never sent over the wire, but it is used for serializing DB
+ state to flash in the device code
+ FIXME, since we write this each time we enter deep sleep (and have infinite
+ flash) it would be better to use some sort of append only data structure for
+ the receive queue and use the preferences store for the other stuff */
+typedef struct _meshtastic_DeviceState {
+ /* Read only settings/info about this node */
+ bool has_my_node;
+ meshtastic_MyNodeInfo my_node;
+ /* My owner info */
+ bool has_owner;
+ meshtastic_User owner;
+ /* Deprecated in 2.1.x
+ Old node_db. See NodeInfoLite node_db_lite */
+ pb_size_t node_db_count;
+ meshtastic_NodeInfo node_db[80];
+ /* Received packets saved for delivery to the phone */
+ pb_size_t receive_queue_count;
+ meshtastic_MeshPacket receive_queue[1];
+ /* We keep the last received text message (only) stored in the device flash,
+ so we can show it on the screen.
+ Might be null */
+ bool has_rx_text_message;
+ meshtastic_MeshPacket rx_text_message;
+ /* A version integer used to invalidate old save files when we make
+ incompatible changes This integer is set at build time and is private to
+ NodeDB.cpp in the device code. */
+ uint32_t version;
+ /* Used only during development.
+ Indicates developer is testing and changes should never be saved to flash. */
+ bool no_save;
+ /* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */
+ bool did_gps_reset;
+ /* We keep the last received waypoint stored in the device flash,
+ so we can show it on the screen.
+ Might be null */
+ bool has_rx_waypoint;
+ meshtastic_MeshPacket rx_waypoint;
+ /* The mesh's nodes with their available gpio pins for RemoteHardware module */
+ pb_size_t node_remote_hardware_pins_count;
+ meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
+ /* New lite version of NodeDB to decrease */
+ pb_size_t node_db_lite_count;
+ meshtastic_NodeInfoLite node_db_lite[80];
+} meshtastic_DeviceState;
+
#ifdef __cplusplus
extern "C" {
@@ -111,27 +170,40 @@ extern "C" {
+#define meshtastic_PositionLite_location_source_ENUMTYPE meshtastic_Position_LocSource
+
+
#define meshtastic_OEMStore_oem_font_ENUMTYPE meshtastic_ScreenFonts
+
/* Initializer values for message structs */
-#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default}
+#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default, meshtastic_NodeInfo_init_default}, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, 0, {meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default}}
+#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
+#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
-#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero}
+#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default}
+#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero, meshtastic_NodeInfo_init_zero}, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, 0, {meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero}}
+#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
+#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
+#define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero}
/* Field tags (for use in manual encoding/decoding) */
-#define meshtastic_DeviceState_my_node_tag 2
-#define meshtastic_DeviceState_owner_tag 3
-#define meshtastic_DeviceState_node_db_tag 4
-#define meshtastic_DeviceState_receive_queue_tag 5
-#define meshtastic_DeviceState_rx_text_message_tag 7
-#define meshtastic_DeviceState_version_tag 8
-#define meshtastic_DeviceState_no_save_tag 9
-#define meshtastic_DeviceState_did_gps_reset_tag 11
-#define meshtastic_DeviceState_rx_waypoint_tag 12
+#define meshtastic_PositionLite_latitude_i_tag 1
+#define meshtastic_PositionLite_longitude_i_tag 2
+#define meshtastic_PositionLite_altitude_tag 3
+#define meshtastic_PositionLite_time_tag 4
+#define meshtastic_PositionLite_location_source_tag 5
+#define meshtastic_NodeInfoLite_num_tag 1
+#define meshtastic_NodeInfoLite_user_tag 2
+#define meshtastic_NodeInfoLite_position_tag 3
+#define meshtastic_NodeInfoLite_snr_tag 4
+#define meshtastic_NodeInfoLite_last_heard_tag 5
+#define meshtastic_NodeInfoLite_device_metrics_tag 6
+#define meshtastic_NodeInfoLite_channel_tag 7
#define meshtastic_ChannelFile_channels_tag 1
#define meshtastic_ChannelFile_version_tag 2
#define meshtastic_OEMStore_oem_icon_width_tag 1
@@ -142,6 +214,19 @@ extern "C" {
#define meshtastic_OEMStore_oem_aes_key_tag 6
#define meshtastic_OEMStore_oem_local_config_tag 7
#define meshtastic_OEMStore_oem_local_module_config_tag 8
+#define meshtastic_NodeRemoteHardwarePin_node_num_tag 1
+#define meshtastic_NodeRemoteHardwarePin_pin_tag 2
+#define meshtastic_DeviceState_my_node_tag 2
+#define meshtastic_DeviceState_owner_tag 3
+#define meshtastic_DeviceState_node_db_tag 4
+#define meshtastic_DeviceState_receive_queue_tag 5
+#define meshtastic_DeviceState_rx_text_message_tag 7
+#define meshtastic_DeviceState_version_tag 8
+#define meshtastic_DeviceState_no_save_tag 9
+#define meshtastic_DeviceState_did_gps_reset_tag 11
+#define meshtastic_DeviceState_rx_waypoint_tag 12
+#define meshtastic_DeviceState_node_remote_hardware_pins_tag 13
+#define meshtastic_DeviceState_node_db_lite_tag 14
/* Struct field encoding specification for nanopb */
#define meshtastic_DeviceState_FIELDLIST(X, a) \
@@ -153,7 +238,9 @@ X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
-X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12)
+X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12) \
+X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 13) \
+X(a, STATIC, REPEATED, MESSAGE, node_db_lite, 14)
#define meshtastic_DeviceState_CALLBACK NULL
#define meshtastic_DeviceState_DEFAULT NULL
#define meshtastic_DeviceState_my_node_MSGTYPE meshtastic_MyNodeInfo
@@ -162,6 +249,31 @@ X(a, STATIC, OPTIONAL, MESSAGE, rx_waypoint, 12)
#define meshtastic_DeviceState_receive_queue_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_rx_text_message_MSGTYPE meshtastic_MeshPacket
#define meshtastic_DeviceState_rx_waypoint_MSGTYPE meshtastic_MeshPacket
+#define meshtastic_DeviceState_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
+#define meshtastic_DeviceState_node_db_lite_MSGTYPE meshtastic_NodeInfoLite
+
+#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, UINT32, num, 1) \
+X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
+X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
+X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
+X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
+X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
+X(a, STATIC, SINGULAR, UINT32, channel, 7)
+#define meshtastic_NodeInfoLite_CALLBACK NULL
+#define meshtastic_NodeInfoLite_DEFAULT NULL
+#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_User
+#define meshtastic_NodeInfoLite_position_MSGTYPE meshtastic_PositionLite
+#define meshtastic_NodeInfoLite_device_metrics_MSGTYPE meshtastic_DeviceMetrics
+
+#define meshtastic_PositionLite_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
+X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
+X(a, STATIC, SINGULAR, INT32, altitude, 3) \
+X(a, STATIC, SINGULAR, FIXED32, time, 4) \
+X(a, STATIC, SINGULAR, UENUM, location_source, 5)
+#define meshtastic_PositionLite_CALLBACK NULL
+#define meshtastic_PositionLite_DEFAULT NULL
#define meshtastic_ChannelFile_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
@@ -184,19 +296,35 @@ X(a, STATIC, OPTIONAL, MESSAGE, oem_local_module_config, 8)
#define meshtastic_OEMStore_oem_local_config_MSGTYPE meshtastic_LocalConfig
#define meshtastic_OEMStore_oem_local_module_config_MSGTYPE meshtastic_LocalModuleConfig
+#define meshtastic_NodeRemoteHardwarePin_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, UINT32, node_num, 1) \
+X(a, STATIC, OPTIONAL, MESSAGE, pin, 2)
+#define meshtastic_NodeRemoteHardwarePin_CALLBACK NULL
+#define meshtastic_NodeRemoteHardwarePin_DEFAULT NULL
+#define meshtastic_NodeRemoteHardwarePin_pin_MSGTYPE meshtastic_RemoteHardwarePin
+
extern const pb_msgdesc_t meshtastic_DeviceState_msg;
+extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg;
+extern const pb_msgdesc_t meshtastic_PositionLite_msg;
extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
extern const pb_msgdesc_t meshtastic_OEMStore_msg;
+extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define meshtastic_DeviceState_fields &meshtastic_DeviceState_msg
+#define meshtastic_NodeInfoLite_fields &meshtastic_NodeInfoLite_msg
+#define meshtastic_PositionLite_fields &meshtastic_PositionLite_msg
#define meshtastic_ChannelFile_fields &meshtastic_ChannelFile_msg
#define meshtastic_OEMStore_fields &meshtastic_OEMStore_msg
+#define meshtastic_NodeRemoteHardwarePin_fields &meshtastic_NodeRemoteHardwarePin_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_ChannelFile_size 638
-#define meshtastic_DeviceState_size 22364
-#define meshtastic_OEMStore_size 3041
+#define meshtastic_DeviceState_size 35056
+#define meshtastic_NodeInfoLite_size 151
+#define meshtastic_NodeRemoteHardwarePin_size 29
+#define meshtastic_OEMStore_size 3152
+#define meshtastic_PositionLite_size 28
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h
index 0cfcb24911..d70acc7fc7 100644
--- a/src/mesh/generated/meshtastic/localonly.pb.h
+++ b/src/mesh/generated/meshtastic/localonly.pb.h
@@ -72,6 +72,9 @@ typedef struct _meshtastic_LocalModuleConfig {
/* The part of the config that is specific to the Remote Hardware module */
bool has_remote_hardware;
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
+ /* The part of the config that is specific to the Neighbor Info module */
+ bool has_neighbor_info;
+ meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
} meshtastic_LocalModuleConfig;
@@ -81,9 +84,9 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0}
-#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default}
+#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default}
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0}
-#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero}
+#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_LocalConfig_device_tag 1
@@ -104,6 +107,7 @@ extern "C" {
#define meshtastic_LocalModuleConfig_version_tag 8
#define meshtastic_LocalModuleConfig_audio_tag 9
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10
+#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
/* Struct field encoding specification for nanopb */
#define meshtastic_LocalConfig_FIELDLIST(X, a) \
@@ -135,7 +139,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \
-X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10)
+X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
+X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
#define meshtastic_LocalModuleConfig_CALLBACK NULL
#define meshtastic_LocalModuleConfig_DEFAULT NULL
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -147,6 +152,7 @@ X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10)
#define meshtastic_LocalModuleConfig_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
+#define meshtastic_LocalModuleConfig_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
@@ -156,8 +162,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
-#define meshtastic_LocalConfig_size 456
-#define meshtastic_LocalModuleConfig_size 439
+#define meshtastic_LocalConfig_size 461
+#define meshtastic_LocalModuleConfig_size 545
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 984939702f..0ed2f8e68d 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -61,6 +61,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
meshtastic_HardwareModel_STATION_G1 = 25,
+ /* RAK11310 (RP2040 + SX1262) */
+ meshtastic_HardwareModel_RAK11310 = 26,
/* ---------------------------------------------------------------------------
Less common/prototype boards listed here (needs one more byte over the air)
--------------------------------------------------------------------------- */
@@ -93,6 +95,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_BETAFPV_2400_TX = 45,
/* BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU */
meshtastic_HardwareModel_BETAFPV_900_NANO_TX = 46,
+ /* Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module */
+ meshtastic_HardwareModel_RPI_PICO = 47,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -368,7 +372,8 @@ typedef struct _meshtastic_User {
/* A VERY short name, ideally two characters.
Suitable for a tiny OLED screen */
char short_name[5];
- /* This is the addr of the radio.
+ /* Deprecated in Meshtastic 2.1.x
+ This is the addr of the radio.
Not populated by the phone, but added by the esp32 when broadcasting */
pb_byte_t macaddr[6];
/* TBEAM, HELTEC, etc...
@@ -574,12 +579,15 @@ typedef struct _meshtastic_MyNodeInfo {
/* Tells the phone what our node number is, default starting value is
lowbyte of macaddr, but it will be fixed if that is already in use */
uint32_t my_node_num;
- /* Note: This flag merely means we detected a hardware GPS in our node.
+ /* Deprecated in 2.1.x (Source from device_metadata)
+ Note: This flag merely means we detected a hardware GPS in our node.
Not the same as UserPreferences.location_sharing */
bool has_gps;
- /* The maximum number of 'software' channels that can be set on this node. */
+ /* Deprecated in 2.1.x
+ The maximum number of 'software' channels that can be set on this node. */
uint32_t max_channels;
- /* 0.0.5 etc... */
+ /* Deprecated in 2.1.x (Source from device_metadata)
+ 0.0.5 etc... */
char firmware_version[18];
/* An error message we'd like to report back to the mothership through analytics.
It indicates a serious bug occurred on the device, the device coped with it,
@@ -596,9 +604,11 @@ typedef struct _meshtastic_MyNodeInfo {
/* The total number of reboots this node has ever encountered
(well - since the last time we discarded preferences) */
uint32_t reboot_count;
- /* Calculated bitrate of the current channel (in Bytes Per Second) */
+ /* Deprecated in 2.1.x
+ Calculated bitrate of the current channel (in Bytes Per Second) */
float bitrate;
- /* How long before we consider a message abandoned and we can clear our
+ /* Deprecated in 2.1.x
+ How long before we consider a message abandoned and we can clear our
caches of any messages in flight Normally quite large to handle the worst case
message delivery time, 5 minutes.
Formerly called FLOOD_EXPIRE_TIME in the device code */
@@ -606,17 +616,22 @@ typedef struct _meshtastic_MyNodeInfo {
/* The minimum app version that can talk to this device.
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
uint32_t min_app_version;
- /* 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
+ /* Deprecated in 2.1.x (Only used on device to keep track of utilization)
+ 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
pb_size_t air_period_tx_count;
uint32_t air_period_tx[8];
- /* 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
+ /* Deprecated in 2.1.x (Only used on device to keep track of utilization)
+ 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
pb_size_t air_period_rx_count;
uint32_t air_period_rx[8];
- /* Is the device wifi capable? */
+ /* Deprecated in 2.1.x (Source from DeviceMetadata instead)
+ Is the device wifi capable? */
bool has_wifi;
- /* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
+ /* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
+ Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
float channel_utilization;
- /* Percent of airtime for transmission used within the last hour. */
+ /* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
+ Percent of airtime for transmission used within the last hour. */
float air_util_tx;
} meshtastic_MyNodeInfo;
@@ -719,6 +734,8 @@ typedef struct _meshtastic_DeviceMetadata {
uint32_t position_flags;
/* Device hardware model */
meshtastic_HardwareModel hw_model;
+ /* Has Remote Hardware enabled */
+ bool hasRemoteHardware;
} meshtastic_DeviceMetadata;
/* Packets from the radio to the phone will appear on the fromRadio characteristic.
@@ -855,7 +872,7 @@ extern "C" {
#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_default {0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}}
#define meshtastic_Neighbor_init_default {0, 0}
-#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN}
+#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0}
#define meshtastic_Position_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0}
#define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
@@ -872,7 +889,7 @@ extern "C" {
#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_zero {0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}}
#define meshtastic_Neighbor_init_zero {0, 0}
-#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN}
+#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_Position_latitude_i_tag 1
@@ -987,6 +1004,7 @@ extern "C" {
#define meshtastic_DeviceMetadata_role_tag 7
#define meshtastic_DeviceMetadata_position_flags_tag 8
#define meshtastic_DeviceMetadata_hw_model_tag 9
+#define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10
#define meshtastic_FromRadio_id_tag 1
#define meshtastic_FromRadio_packet_tag 2
#define meshtastic_FromRadio_my_info_tag 3
@@ -1210,7 +1228,8 @@ X(a, STATIC, SINGULAR, BOOL, hasBluetooth, 5) \
X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6) \
X(a, STATIC, SINGULAR, UENUM, role, 7) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \
-X(a, STATIC, SINGULAR, UENUM, hw_model, 9)
+X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \
+X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10)
#define meshtastic_DeviceMetadata_CALLBACK NULL
#define meshtastic_DeviceMetadata_DEFAULT NULL
@@ -1254,7 +1273,7 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
/* Maximum encoded size of messages (where known) */
#define meshtastic_Compressed_size 243
#define meshtastic_Data_size 270
-#define meshtastic_DeviceMetadata_size 44
+#define meshtastic_DeviceMetadata_size 46
#define meshtastic_FromRadio_size 330
#define meshtastic_LogRecord_size 81
#define meshtastic_MeshPacket_size 321
diff --git a/src/mesh/generated/meshtastic/module_config.pb.c b/src/mesh/generated/meshtastic/module_config.pb.c
index 0878be909d..9352feb177 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.c
+++ b/src/mesh/generated/meshtastic/module_config.pb.c
@@ -15,6 +15,9 @@ PB_BIND(meshtastic_ModuleConfig_MQTTConfig, meshtastic_ModuleConfig_MQTTConfig,
PB_BIND(meshtastic_ModuleConfig_RemoteHardwareConfig, meshtastic_ModuleConfig_RemoteHardwareConfig, AUTO)
+PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
+
+
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)
@@ -36,6 +39,10 @@ PB_BIND(meshtastic_ModuleConfig_TelemetryConfig, meshtastic_ModuleConfig_Telemet
PB_BIND(meshtastic_ModuleConfig_CannedMessageConfig, meshtastic_ModuleConfig_CannedMessageConfig, AUTO)
+PB_BIND(meshtastic_RemoteHardwarePin, meshtastic_RemoteHardwarePin, AUTO)
+
+
+
diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h
index e59d33dd0d..6273a89aed 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.h
+++ b/src/mesh/generated/meshtastic/module_config.pb.h
@@ -10,6 +10,15 @@
#endif
/* Enum definitions */
+typedef enum _meshtastic_RemoteHardwarePinType {
+ /* Unset/unused */
+ meshtastic_RemoteHardwarePinType_UNKNOWN = 0,
+ /* GPIO pin can be read (if it is high / low) */
+ meshtastic_RemoteHardwarePinType_DIGITAL_READ = 1,
+ /* GPIO pin can be written to (high / low) */
+ meshtastic_RemoteHardwarePinType_DIGITAL_WRITE = 2
+} meshtastic_RemoteHardwarePinType;
+
/* Baudrate for codec2 voice */
typedef enum _meshtastic_ModuleConfig_AudioConfig_Audio_Baud {
meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0,
@@ -49,7 +58,9 @@ typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Mode {
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1,
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2,
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3,
- meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA = 4
+ meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA = 4,
+ /* NMEA messages specifically tailored for CalTopo */
+ meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO = 5
} meshtastic_ModuleConfig_SerialConfig_Serial_Mode;
/* TODO: REPLACE */
@@ -103,11 +114,14 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig {
char root[16];
} meshtastic_ModuleConfig_MQTTConfig;
-/* RemoteHardwareModule Config */
-typedef struct _meshtastic_ModuleConfig_RemoteHardwareConfig {
+/* NeighborInfoModule Config */
+typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
/* Whether the Module is enabled */
bool enabled;
-} meshtastic_ModuleConfig_RemoteHardwareConfig;
+ /* Interval in seconds of how often we should try to send our
+ Neighbor Info to the mesh */
+ uint32_t update_interval;
+} meshtastic_ModuleConfig_NeighborInfoConfig;
/* Audio Config for codec2 voice */
typedef struct _meshtastic_ModuleConfig_AudioConfig {
@@ -129,21 +143,24 @@ typedef struct _meshtastic_ModuleConfig_AudioConfig {
/* Serial Config */
typedef struct _meshtastic_ModuleConfig_SerialConfig {
- /* Preferences for the SerialModule
- FIXME - Move this out of UserPreferences and into a section for module configuration. */
+ /* Preferences for the SerialModule */
bool enabled;
/* TODO: REPLACE */
bool echo;
- /* TODO: REPLACE */
+ /* RX pin (should match Arduino gpio pin number) */
uint32_t rxd;
- /* TODO: REPLACE */
+ /* TX pin (should match Arduino gpio pin number) */
uint32_t txd;
- /* TODO: REPLACE */
+ /* Serial baud rate */
meshtastic_ModuleConfig_SerialConfig_Serial_Baud baud;
/* TODO: REPLACE */
uint32_t timeout;
- /* TODO: REPLACE */
+ /* Mode for serial module operation */
meshtastic_ModuleConfig_SerialConfig_Serial_Mode mode;
+ /* Overrides the platform's defacto Serial port instance to use with Serial module config settings
+ This is currently only usable in output modes like NMEA / CalTopo and may behave strangely or not work at all in other modes
+ Existing logging over the Serial Console will still be present */
+ bool override_console_serial_port;
} meshtastic_ModuleConfig_SerialConfig;
/* External Notifications Config */
@@ -208,7 +225,7 @@ typedef struct _meshtastic_ModuleConfig_RangeTestConfig {
bool enabled;
/* Send out range test messages from this node */
uint32_t sender;
- /* Bool value indicating that this node should save a RangeTest.csv file.
+ /* Bool value indicating that this node should save a RangeTest.csv file.
ESP32 Only */
bool save;
} meshtastic_ModuleConfig_RangeTestConfig;
@@ -262,6 +279,27 @@ typedef struct _meshtastic_ModuleConfig_CannedMessageConfig {
bool send_bell;
} meshtastic_ModuleConfig_CannedMessageConfig;
+/* A GPIO pin definition for remote hardware module */
+typedef struct _meshtastic_RemoteHardwarePin {
+ /* GPIO Pin number (must match Arduino) */
+ uint8_t gpio_pin;
+ /* Name for the GPIO pin (i.e. Front gate, mailbox, etc) */
+ char name[15];
+ /* Type of GPIO access available to consumers on the mesh */
+ meshtastic_RemoteHardwarePinType type;
+} meshtastic_RemoteHardwarePin;
+
+/* RemoteHardwareModule Config */
+typedef struct _meshtastic_ModuleConfig_RemoteHardwareConfig {
+ /* Whether the Module is enabled */
+ bool enabled;
+ /* Whether the Module allows consumers to read / write to pins not defined in available_pins */
+ bool allow_undefined_pin_access;
+ /* Exposes the available pins to the mesh for reading and writing */
+ pb_size_t available_pins_count;
+ meshtastic_RemoteHardwarePin available_pins[4];
+} meshtastic_ModuleConfig_RemoteHardwareConfig;
+
/* Module Config */
typedef struct _meshtastic_ModuleConfig {
pb_size_t which_payload_variant;
@@ -284,6 +322,8 @@ typedef struct _meshtastic_ModuleConfig {
meshtastic_ModuleConfig_AudioConfig audio;
/* TODO: REPLACE */
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
+ /* TODO: REPLACE */
+ meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
} payload_variant;
} meshtastic_ModuleConfig;
@@ -293,6 +333,10 @@ extern "C" {
#endif
/* Helper constants for enums */
+#define _meshtastic_RemoteHardwarePinType_MIN meshtastic_RemoteHardwarePinType_UNKNOWN
+#define _meshtastic_RemoteHardwarePinType_MAX meshtastic_RemoteHardwarePinType_DIGITAL_WRITE
+#define _meshtastic_RemoteHardwarePinType_ARRAYSIZE ((meshtastic_RemoteHardwarePinType)(meshtastic_RemoteHardwarePinType_DIGITAL_WRITE+1))
+
#define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT
#define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MAX meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B
#define _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_AudioConfig_Audio_Baud)(meshtastic_ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1))
@@ -302,8 +346,8 @@ extern "C" {
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Baud)(meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT
-#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA
-#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA+1))
+#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO
+#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO+1))
#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE
#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MAX meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK
@@ -312,6 +356,7 @@ extern "C" {
+
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
@@ -325,28 +370,34 @@ extern "C" {
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_press_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
+#define meshtastic_RemoteHardwarePin_type_ENUMTYPE meshtastic_RemoteHardwarePinType
+
/* Initializer values for message structs */
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""}
-#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0}
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
+#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
-#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN}
+#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
+#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""}
-#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0}
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
+#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
-#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN}
+#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
+#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_ModuleConfig_MQTTConfig_enabled_tag 1
@@ -357,7 +408,8 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
-#define meshtastic_ModuleConfig_RemoteHardwareConfig_enabled_tag 1
+#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
+#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
@@ -372,6 +424,7 @@ extern "C" {
#define meshtastic_ModuleConfig_SerialConfig_baud_tag 5
#define meshtastic_ModuleConfig_SerialConfig_timeout_tag 6
#define meshtastic_ModuleConfig_SerialConfig_mode_tag 7
+#define meshtastic_ModuleConfig_SerialConfig_override_console_serial_port_tag 8
#define meshtastic_ModuleConfig_ExternalNotificationConfig_enabled_tag 1
#define meshtastic_ModuleConfig_ExternalNotificationConfig_output_ms_tag 2
#define meshtastic_ModuleConfig_ExternalNotificationConfig_output_tag 3
@@ -412,6 +465,12 @@ extern "C" {
#define meshtastic_ModuleConfig_CannedMessageConfig_enabled_tag 9
#define meshtastic_ModuleConfig_CannedMessageConfig_allow_input_source_tag 10
#define meshtastic_ModuleConfig_CannedMessageConfig_send_bell_tag 11
+#define meshtastic_RemoteHardwarePin_gpio_pin_tag 1
+#define meshtastic_RemoteHardwarePin_name_tag 2
+#define meshtastic_RemoteHardwarePin_type_tag 3
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_enabled_tag 1
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_allow_undefined_pin_access_tag 2
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_tag 3
#define meshtastic_ModuleConfig_mqtt_tag 1
#define meshtastic_ModuleConfig_serial_tag 2
#define meshtastic_ModuleConfig_external_notification_tag 3
@@ -421,6 +480,7 @@ extern "C" {
#define meshtastic_ModuleConfig_canned_message_tag 7
#define meshtastic_ModuleConfig_audio_tag 8
#define meshtastic_ModuleConfig_remote_hardware_tag 9
+#define meshtastic_ModuleConfig_neighbor_info_tag 10
/* Struct field encoding specification for nanopb */
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
@@ -432,7 +492,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.r
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
-X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9)
+X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
+X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10)
#define meshtastic_ModuleConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -444,6 +505,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_vari
#define meshtastic_ModuleConfig_payload_variant_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_ModuleConfig_payload_variant_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
+#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
@@ -458,9 +520,18 @@ X(a, STATIC, SINGULAR, STRING, root, 8)
#define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_RemoteHardwareConfig_FIELDLIST(X, a) \
-X(a, STATIC, SINGULAR, BOOL, enabled, 1)
+X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
+X(a, STATIC, SINGULAR, BOOL, allow_undefined_pin_access, 2) \
+X(a, STATIC, REPEATED, MESSAGE, available_pins, 3)
#define meshtastic_ModuleConfig_RemoteHardwareConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_RemoteHardwareConfig_DEFAULT NULL
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_MSGTYPE meshtastic_RemoteHardwarePin
+
+#define meshtastic_ModuleConfig_NeighborInfoConfig_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
+X(a, STATIC, SINGULAR, UINT32, update_interval, 2)
+#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
+#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
@@ -480,7 +551,8 @@ X(a, STATIC, SINGULAR, UINT32, rxd, 3) \
X(a, STATIC, SINGULAR, UINT32, txd, 4) \
X(a, STATIC, SINGULAR, UENUM, baud, 5) \
X(a, STATIC, SINGULAR, UINT32, timeout, 6) \
-X(a, STATIC, SINGULAR, UENUM, mode, 7)
+X(a, STATIC, SINGULAR, UENUM, mode, 7) \
+X(a, STATIC, SINGULAR, BOOL, override_console_serial_port, 8)
#define meshtastic_ModuleConfig_SerialConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_SerialConfig_DEFAULT NULL
@@ -544,9 +616,17 @@ X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
#define meshtastic_ModuleConfig_CannedMessageConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_CannedMessageConfig_DEFAULT NULL
+#define meshtastic_RemoteHardwarePin_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, UINT32, gpio_pin, 1) \
+X(a, STATIC, SINGULAR, STRING, name, 2) \
+X(a, STATIC, SINGULAR, UENUM, type, 3)
+#define meshtastic_RemoteHardwarePin_CALLBACK NULL
+#define meshtastic_RemoteHardwarePin_DEFAULT NULL
+
extern const pb_msgdesc_t meshtastic_ModuleConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg;
+extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
@@ -554,11 +634,13 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_StoreForwardConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_RangeTestConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_TelemetryConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg;
+extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define meshtastic_ModuleConfig_fields &meshtastic_ModuleConfig_msg
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_msg
+#define meshtastic_ModuleConfig_NeighborInfoConfig_fields &meshtastic_ModuleConfig_NeighborInfoConfig_msg
#define meshtastic_ModuleConfig_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
@@ -566,18 +648,21 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg;
#define meshtastic_ModuleConfig_RangeTestConfig_fields &meshtastic_ModuleConfig_RangeTestConfig_msg
#define meshtastic_ModuleConfig_TelemetryConfig_fields &meshtastic_ModuleConfig_TelemetryConfig_msg
#define meshtastic_ModuleConfig_CannedMessageConfig_fields &meshtastic_ModuleConfig_CannedMessageConfig_msg
+#define meshtastic_RemoteHardwarePin_fields &meshtastic_RemoteHardwarePin_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_ModuleConfig_AudioConfig_size 19
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
#define meshtastic_ModuleConfig_MQTTConfig_size 220
+#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
-#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 2
-#define meshtastic_ModuleConfig_SerialConfig_size 26
+#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
+#define meshtastic_ModuleConfig_SerialConfig_size 28
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
#define meshtastic_ModuleConfig_TelemetryConfig_size 26
#define meshtastic_ModuleConfig_size 223
+#define meshtastic_RemoteHardwarePin_size 21
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h
index ccf94372ed..089d7b59f0 100644
--- a/src/mesh/generated/meshtastic/portnums.pb.h
+++ b/src/mesh/generated/meshtastic/portnums.pb.h
@@ -77,9 +77,9 @@ typedef enum _meshtastic_PortNum {
Maintained by Github user a-f-G-U-C (a Meshtastic contributor)
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS */
meshtastic_PortNum_ZPS_APP = 68,
- /* Used to let multiple instances of Linux native applications communicate
+ /* Used to let multiple instances of Linux native applications communicate
as if they did using their LoRa chip.
- Maintained by GitHub user GUVWAF.
+ Maintained by GitHub user GUVWAF.
Project files at https://github.com/GUVWAF/Meshtasticator */
meshtastic_PortNum_SIMULATOR_APP = 69,
/* Provides a traceroute functionality to show the route a packet towards
diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp
index d5f8877348..ae254e7f7b 100644
--- a/src/modules/AdminModule.cpp
+++ b/src/modules/AdminModule.cpp
@@ -50,6 +50,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
// if handled == false, then let others look at this message also if they want
bool handled = false;
assert(r);
+ bool fromOthers = mp.from != 0 && mp.from != nodeDB.getNodeNum();
switch (r->which_payload_variant) {
@@ -175,6 +176,14 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
handleGetDeviceConnectionStatus(mp);
break;
}
+ case meshtastic_AdminMessage_get_module_config_response_tag: {
+ LOG_INFO("Client is receiving a get_module_config response.\n");
+ if (fromOthers && r->get_module_config_response.which_payload_variant ==
+ meshtastic_AdminMessage_ModuleConfigType_REMOTEHARDWARE_CONFIG) {
+ handleGetModuleConfigResponse(mp, r);
+ }
+ break;
+ }
#ifdef ARCH_PORTDUINO
case meshtastic_AdminMessage_exit_simulator_tag:
LOG_INFO("Exiting simulator\n");
@@ -205,6 +214,29 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
return handled;
}
+void AdminModule::handleGetModuleConfigResponse(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *r)
+{
+ // Skip if it's disabled or no pins are exposed
+ if (!r->get_module_config_response.payload_variant.remote_hardware.enabled ||
+ !r->get_module_config_response.payload_variant.remote_hardware.available_pins) {
+ LOG_DEBUG("Remote hardware module disabled or no vailable_pins. Skipping...\n");
+ return;
+ }
+ for (uint8_t i = 0; i < devicestate.node_remote_hardware_pins_count; i++) {
+ if (devicestate.node_remote_hardware_pins[i].node_num == 0 || !devicestate.node_remote_hardware_pins[i].has_pin) {
+ continue;
+ }
+ for (uint8_t j = 0; j < sizeof(r->get_module_config_response.payload_variant.remote_hardware.available_pins); j++) {
+ auto availablePin = r->get_module_config_response.payload_variant.remote_hardware.available_pins[j];
+ if (i < devicestate.node_remote_hardware_pins_count) {
+ devicestate.node_remote_hardware_pins[i].node_num = mp.from;
+ devicestate.node_remote_hardware_pins[i].pin = availablePin;
+ }
+ i++;
+ }
+ }
+}
+
/**
* Setter methods
*/
@@ -487,6 +519,28 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
}
}
+void AdminModule::handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req)
+{
+ meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
+ r.which_payload_variant = meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag;
+ for (uint8_t i = 0; i < devicestate.node_remote_hardware_pins_count; i++) {
+ if (devicestate.node_remote_hardware_pins[i].node_num == 0 || !devicestate.node_remote_hardware_pins[i].has_pin) {
+ continue;
+ }
+ r.get_node_remote_hardware_pins_response.node_remote_hardware_pins[i] = devicestate.node_remote_hardware_pins[i];
+ }
+ for (uint8_t i = 0; i < moduleConfig.remote_hardware.available_pins_count; i++) {
+ if (!moduleConfig.remote_hardware.available_pins[i].gpio_pin) {
+ continue;
+ }
+ meshtastic_NodeRemoteHardwarePin nodePin = meshtastic_NodeRemoteHardwarePin_init_default;
+ nodePin.node_num = nodeDB.getNodeNum();
+ nodePin.pin = moduleConfig.remote_hardware.available_pins[i];
+ r.get_node_remote_hardware_pins_response.node_remote_hardware_pins[i + 12] = nodePin;
+ }
+ myReply = allocDataProtobuf(r);
+}
+
void AdminModule::handleGetDeviceMetadata(const meshtastic_MeshPacket &req)
{
meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
@@ -499,9 +553,8 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
{
meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
- meshtastic_DeviceConnectionStatus conn;
+ meshtastic_DeviceConnectionStatus conn = meshtastic_DeviceConnectionStatus_init_zero;
- conn.wifi = {0};
#if HAS_WIFI
conn.has_wifi = true;
conn.wifi.has_status = true;
@@ -517,11 +570,8 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
conn.wifi.status.is_mqtt_connected = mqtt && mqtt->connected();
conn.wifi.status.is_syslog_connected = false; // FIXME wire this up
}
-#else
- conn.has_wifi = false;
#endif
- conn.ethernet = {0};
#if HAS_ETHERNET
conn.has_ethernet = true;
conn.ethernet.has_status = true;
@@ -533,8 +583,6 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
} else {
conn.ethernet.status.is_connected = false;
}
-#else
- conn.has_ethernet = false;
#endif
#if HAS_BLUETOOTH
diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h
index 7170e61d62..eb06e7b83d 100644
--- a/src/modules/AdminModule.h
+++ b/src/modules/AdminModule.h
@@ -26,15 +26,18 @@ class AdminModule : public ProtobufModule
bool hasOpenEditTransaction = false;
void saveChanges(int saveWhat, bool shouldReboot = true);
+
/**
* Getters
*/
+ void handleGetModuleConfigResponse(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *p);
void handleGetOwner(const meshtastic_MeshPacket &req);
void handleGetConfig(const meshtastic_MeshPacket &req, uint32_t configType);
void handleGetModuleConfig(const meshtastic_MeshPacket &req, uint32_t configType);
void handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex);
void handleGetDeviceMetadata(const meshtastic_MeshPacket &req);
void handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req);
+ void handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req);
/**
* Setters
*/
diff --git a/src/modules/ExternalNotificationModule.h b/src/modules/ExternalNotificationModule.h
index 7d4f54c2fe..f8ec053dd2 100644
--- a/src/modules/ExternalNotificationModule.h
+++ b/src/modules/ExternalNotificationModule.h
@@ -3,7 +3,7 @@
#include "SinglePortModule.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
-#ifndef ARCH_PORTDUINO
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include
#else
// Noop class for portduino.
diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp
index 5d49a213ef..61de2c265c 100644
--- a/src/modules/Modules.cpp
+++ b/src/modules/Modules.cpp
@@ -22,12 +22,12 @@
#endif
#ifdef ARCH_ESP32
#include "modules/esp32/AudioModule.h"
-#include "modules/esp32/RangeTestModule.h"
#include "modules/esp32/StoreForwardModule.h"
#endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
#include "modules/ExternalNotificationModule.h"
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2)
+#include "modules/RangeTestModule.h"
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "modules/SerialModule.h"
#endif
#endif
@@ -72,20 +72,18 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule();
#endif
#ifdef ARCH_ESP32
// Only run on an esp32 based device.
audioModule = new AudioModule();
- externalNotificationModule = new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule();
-
- new RangeTestModule();
-#elif defined(ARCH_NRF52)
+#endif
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
externalNotificationModule = new ExternalNotificationModule();
+ new RangeTestModule();
#endif
} else {
adminModule = new AdminModule();
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index ade96fb8a4..42066ad5b9 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -56,7 +56,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
meshtastic_MeshPacket *PositionModule::allocReply()
{
- meshtastic_NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position
+ meshtastic_NodeInfo *node = service.refreshLocalNodeInfo(); // should guarantee there is now a position
assert(node->has_position);
node->position.seq_number++;
@@ -112,8 +112,9 @@ meshtastic_MeshPacket *PositionModule::allocReply()
if (getRTCQuality() < RTCQualityDevice) {
LOG_INFO("Stripping time %u from position send\n", p.time);
p.time = 0;
- } else
+ } else {
LOG_INFO("Providing time to mesh %u\n", p.time);
+ }
LOG_INFO("Position reply: time=%i, latI=%i, lonI=-%i\n", p.time, p.latitude_i, p.longitude_i);
@@ -153,7 +154,7 @@ int32_t PositionModule::runOnce()
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
if (airTime->isTxAllowedChannelUtil()) {
- if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
+ if (hasValidPosition(node)) {
lastGpsSend = now;
lastGpsLatitude = node->position.latitude_i;
@@ -170,9 +171,9 @@ int32_t PositionModule::runOnce()
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized or we're a tracker.
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
- meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
+ meshtastic_NodeInfo *node2 = service.refreshLocalNodeInfo(); // should guarantee there is now a position
- if (node2->has_position && (node2->position.latitude_i != 0 || node2->position.longitude_i != 0)) {
+ if (hasValidPosition(node2)) {
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelThreshold =
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/RangeTestModule.cpp
similarity index 94%
rename from src/modules/esp32/RangeTestModule.cpp
rename to src/modules/RangeTestModule.cpp
index e8821f9a09..c1b1e48001 100644
--- a/src/modules/esp32/RangeTestModule.cpp
+++ b/src/modules/RangeTestModule.cpp
@@ -1,4 +1,5 @@
#include "RangeTestModule.h"
+#include "FSCommon.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
@@ -8,7 +9,6 @@
#include "configuration.h"
#include "gps/GeoCoord.h"
#include
-#include
/*
As a sender, I can send packets every n seconds. These packets include an incremented PacketID.
@@ -28,7 +28,7 @@ uint32_t packetSequence = 0;
int32_t RangeTestModule::runOnce()
{
-#ifdef ARCH_ESP32
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
/*
Uncomment the preferences below if you want to use the module
@@ -53,13 +53,13 @@ int32_t RangeTestModule::runOnce()
if (moduleConfig.range_test.sender) {
LOG_INFO("Initializing Range Test Module -- Sender\n");
- return (5000); // Sending first message 5 seconds after initilization.
+ started = millis(); // make a note of when we started
+ return (5000); // Sending first message 5 seconds after initilization.
} else {
LOG_INFO("Initializing Range Test Module -- Receiver\n");
return disable();
// This thread does not need to run as a receiver
}
-
} else {
if (moduleConfig.range_test.sender) {
@@ -77,7 +77,13 @@ int32_t RangeTestModule::runOnce()
rangeTestModuleRadio->sendPayload();
}
- return (senderHeartbeat);
+ // If we have been running for more than 8 hours, turn module back off
+ if (millis() - started > 28800000) {
+ LOG_INFO("Range Test Module - Disabling after 8 hours\n");
+ return disable();
+ } else {
+ return (senderHeartbeat);
+ }
} else {
return disable();
// This thread does not need to run as a receiver
@@ -115,7 +121,7 @@ void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp)
{
-#ifdef ARCH_ESP32
+#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
if (moduleConfig.range_test.enabled) {
@@ -146,7 +152,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
- LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
LOG_DEBUG("n->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -158,7 +163,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("-----------------------------------------\n");
*/
}
-
} else {
LOG_INFO("Range Test Module Disabled\n");
}
@@ -170,6 +174,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
{
+#ifdef ARCH_ESP32
auto &p = mp.decoded;
meshtastic_NodeInfo *n = nodeDB.getNode(getFrom(&mp));
@@ -186,7 +191,6 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n");
LOG_DEBUG("n->user.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_name);
- LOG_DEBUG("n->user.macaddr %X\n", n->user.macaddr);
LOG_DEBUG("n->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -277,6 +281,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
fileToAppend.printf("\"%s\"\n", p.payload.bytes);
fileToAppend.flush();
fileToAppend.close();
+#endif
return 1;
}
diff --git a/src/modules/esp32/RangeTestModule.h b/src/modules/RangeTestModule.h
similarity index 97%
rename from src/modules/esp32/RangeTestModule.h
rename to src/modules/RangeTestModule.h
index 533621d47e..ae2a8f1829 100644
--- a/src/modules/esp32/RangeTestModule.h
+++ b/src/modules/RangeTestModule.h
@@ -9,6 +9,7 @@
class RangeTestModule : private concurrency::OSThread
{
bool firstTime = 1;
+ unsigned long started = 0;
public:
RangeTestModule();
diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp
index c3232d2660..3d4d735b43 100644
--- a/src/modules/RemoteHardwareModule.cpp
+++ b/src/modules/RemoteHardwareModule.cpp
@@ -53,7 +53,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r
{
if (moduleConfig.remote_hardware.enabled) {
auto p = *pptr;
- LOG_INFO("Received RemoteHardware typ=%d\n", p.type);
+ LOG_INFO("Received RemoteHardware type=%d\n", p.type);
switch (p.type) {
case meshtastic_HardwareMessage_Type_WRITE_GPIOS:
diff --git a/src/modules/ReplyModule.cpp b/src/modules/ReplyModule.cpp
index 3bfad28ad6..439f6b7f7f 100644
--- a/src/modules/ReplyModule.cpp
+++ b/src/modules/ReplyModule.cpp
@@ -8,10 +8,12 @@
meshtastic_MeshPacket *ReplyModule::allocReply()
{
assert(currentRequest); // should always be !NULL
+#ifdef DEBUG_PORT
auto req = *currentRequest;
auto &p = req.decoded;
// The incoming message is in p.payload
LOG_INFO("Received message from=0x%0x, id=%d, msg=%.*s\n", req.from, req.id, p.payload.size, p.payload.bytes);
+#endif
screen->print("Sending reply\n");
diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp
index 35b83e6c69..b76f9de486 100644
--- a/src/modules/SerialModule.cpp
+++ b/src/modules/SerialModule.cpp
@@ -39,13 +39,12 @@
KNOWN PROBLEMS
* Until the module is initilized by the startup sequence, the TX pin is in a floating
state. Device connected to that pin may see this as "noise".
- * Will not work on T-Echo and the Linux device targets.
+ * Will not work on Linux device targets.
*/
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128
#define TIMEOUT 250
@@ -58,19 +57,25 @@
SerialModule *serialModule;
SerialModuleRadio *serialModuleRadio;
+#ifdef TTGO_T_ECHO
+SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("SerialModule") {}
+static Print *serialPrint = &Serial;
+#else
SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {}
+static Print *serialPrint = &Serial2;
+#endif
char serialBytes[meshtastic_Constants_DATA_PAYLOAD_LEN];
size_t serialPayloadSize;
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
{
-
switch (moduleConfig.serial.mode) {
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
ourPortNum = meshtastic_PortNum_TEXT_MESSAGE_APP;
break;
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA:
+ case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO:
ourPortNum = meshtastic_PortNum_POSITION_APP;
break;
default:
@@ -95,89 +100,52 @@ int32_t SerialModule::runOnce()
without having to configure it from the PythonAPI or WebUI.
*/
- // moduleConfig.serial.enabled = 1;
+ // moduleConfig.serial.enabled = true;
// moduleConfig.serial.rxd = 35;
// moduleConfig.serial.txd = 15;
+ // moduleConfig.serial.override_console_serial_port = true;
+ // moduleConfig.serial.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO;
// moduleConfig.serial.timeout = 1000;
// moduleConfig.serial.echo = 1;
- if (moduleConfig.serial.enabled && moduleConfig.serial.rxd && moduleConfig.serial.txd) {
+ if (!moduleConfig.serial.enabled)
+ return disable();
+ if (moduleConfig.serial.override_console_serial_port || (moduleConfig.serial.rxd && moduleConfig.serial.txd)) {
if (firstTime) {
-
// Interface with the serial peripheral from in here.
LOG_INFO("Initializing serial peripheral interface\n");
- uint32_t baud = 0;
-
- if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT) {
- baud = 38400;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) {
- baud = 110;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_300) {
- baud = 300;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_600) {
- baud = 600;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200) {
- baud = 1200;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400) {
- baud = 2400;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800) {
- baud = 4800;
+ uint32_t baud = getBaudRate();
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600) {
- baud = 9600;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200) {
- baud = 19200;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400) {
- baud = 38400;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600) {
- baud = 57600;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200) {
- baud = 115200;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400) {
- baud = 230400;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800) {
- baud = 460800;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000) {
- baud = 576000;
-
- } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600) {
- baud = 921600;
+ if (moduleConfig.serial.override_console_serial_port) {
+ Serial.flush();
+ serialPrint = &Serial;
+ // Give it a chance to flush out 💩
+ delay(10);
}
-
#ifdef ARCH_ESP32
- Serial2.setRxBufferSize(RX_BUFFER);
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
+ Serial2.setRxBufferSize(RX_BUFFER);
Serial2.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd);
+ } else {
+ Serial.begin(baud);
+ Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
}
-#else
- if (moduleConfig.serial.rxd && moduleConfig.serial.txd)
+#elif !defined(TTGO_T_ECHO)
+ if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
-
- Serial2.begin(baud, SERIAL_8N1);
-
-#endif
- if (moduleConfig.serial.timeout) {
- Serial2.setTimeout(moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string.
+ Serial2.begin(baud, SERIAL_8N1);
+ Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
} else {
- Serial2.setTimeout(TIMEOUT); // Number of MS to wait to set the timeout for the string.
+ Serial.begin(baud, SERIAL_8N1);
+ Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
}
-
+#else
+ Serial.begin(baud, SERIAL_8N1);
+ Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
+#endif
serialModuleRadio = new SerialModuleRadio();
firstTime = 0;
@@ -186,9 +154,7 @@ int32_t SerialModule::runOnce()
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
emitRebooted();
}
-
} else {
-
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
return runOncePart();
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
@@ -196,16 +162,29 @@ int32_t SerialModule::runOnce()
if (millis() - lastNmeaTime > 2000) {
lastNmeaTime = millis();
printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position);
- Serial2.printf("%s", outbuf);
+ serialPrint->printf("%s", outbuf);
}
- } else {
+ } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
+ if (millis() - lastNmeaTime > 10000) {
+ lastNmeaTime = millis();
+ uint32_t readIndex = 0;
+ const meshtastic_NodeInfo *tempNodeInfo = nodeDB.readNextInfo(readIndex);
+ while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
+ printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
+ serialPrint->printf("%s", outbuf);
+ tempNodeInfo = nodeDB.readNextInfo(readIndex);
+ }
+ }
+ }
+#ifndef TTGO_T_ECHO
+ else {
while (Serial2.available()) {
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
serialModuleRadio->sendPayload();
}
}
+#endif
}
-
return (10);
} else {
return disable();
@@ -262,23 +241,23 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
if (lastRxID != mp.id) {
lastRxID = mp.id;
// LOG_DEBUG("* * Message came this device\n");
- // Serial2.println("* * Message came this device");
- Serial2.printf("%s", p.payload.bytes);
+ // serialPrint->println("* * Message came this device");
+ serialPrint->printf("%s", p.payload.bytes);
}
}
-
} else {
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT ||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
- Serial2.printf("%s", p.payload.bytes);
+ serialPrint->printf("%s", p.payload.bytes);
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) {
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
String sender = (node && node->has_user) ? node->user.short_name : "???";
- Serial2.println();
- Serial2.printf("%s: %s", sender, p.payload.bytes);
- Serial2.println();
- } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
+ serialPrint->println();
+ serialPrint->printf("%s: %s", sender, p.payload.bytes);
+ serialPrint->println();
+ } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA ||
+ moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
// Decode the Payload some more
meshtastic_Position scratch;
meshtastic_Position *decoded = NULL;
@@ -288,12 +267,49 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
decoded = &scratch;
}
// send position packet as WPL to the serial port
- printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name);
- Serial2.printf("%s", outbuf);
+ printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name,
+ moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO);
+ serialPrint->printf("%s", outbuf);
}
}
}
}
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}
+
+uint32_t SerialModule::getBaudRate()
+{
+ if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) {
+ return 110;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_300) {
+ return 300;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_600) {
+ return 600;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200) {
+ return 1200;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400) {
+ return 2400;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800) {
+ return 4800;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600) {
+ return 9600;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200) {
+ return 19200;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400) {
+ return 38400;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600) {
+ return 57600;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200) {
+ return 115200;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400) {
+ return 230400;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800) {
+ return 460800;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000) {
+ return 576000;
+ } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600) {
+ return 921600;
+ }
+ return BAUD;
+}
#endif
diff --git a/src/modules/SerialModule.h b/src/modules/SerialModule.h
index cc696316d4..562ccd42b8 100644
--- a/src/modules/SerialModule.h
+++ b/src/modules/SerialModule.h
@@ -8,8 +8,7 @@
#include
#include
-#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
- !defined(CONFIG_IDF_TARGET_ESP32C3)
+#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread
{
@@ -25,6 +24,9 @@ class SerialModule : public StreamAPI, private concurrency::OSThread
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override;
+
+ private:
+ uint32_t getBaudRate();
};
extern SerialModule *serialModule;
diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp
index de74c0bf94..f87ea504bc 100644
--- a/src/modules/Telemetry/AirQualityTelemetry.cpp
+++ b/src/modules/Telemetry/AirQualityTelemetry.cpp
@@ -59,6 +59,7 @@ int32_t AirQualityTelemetryModule::runOnce()
bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{
if (t->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) {
+#ifdef DEBUG_PORT
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): pm10_standard=%i, pm25_standard=%i, pm100_standard=%i\n", sender,
@@ -68,7 +69,7 @@ bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPack
LOG_INFO(" | PM1.0(Environmental)=%i, PM2.5(Environmental)=%i, PM10.0(Environmental)=%i\n",
t->variant.air_quality_metrics.pm10_environmental, t->variant.air_quality_metrics.pm25_environmental,
t->variant.air_quality_metrics.pm100_environmental);
-
+#endif
// release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr)
packetPool.release(lastMeasurementPacket);
diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp
index 199a90209e..4ef5a9a138 100644
--- a/src/modules/Telemetry/DeviceTelemetry.cpp
+++ b/src/modules/Telemetry/DeviceTelemetry.cpp
@@ -31,12 +31,13 @@ int32_t DeviceTelemetryModule::runOnce()
bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{
if (t->which_variant == meshtastic_Telemetry_device_metrics_tag) {
+#ifdef DEBUG_PORT
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n", sender,
t->variant.device_metrics.air_util_tx, t->variant.device_metrics.channel_utilization,
t->variant.device_metrics.battery_level, t->variant.device_metrics.voltage);
-
+#endif
nodeDB.updateTelemetry(getFrom(&mp), *t, RX_SRC_RADIO);
}
return false; // Let others look at this message also if they want
@@ -49,14 +50,14 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
t.time = getTime();
t.which_variant = meshtastic_Telemetry_device_metrics_tag;
- t.variant.device_metrics.air_util_tx = myNodeInfo.air_util_tx;
+ t.variant.device_metrics.air_util_tx = airTime->utilizationTXPercent();
if (powerStatus->getIsCharging()) {
t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL;
} else {
t.variant.device_metrics.battery_level = powerStatus->getBatteryChargePercent();
}
- t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
+ t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent();
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
@@ -77,4 +78,4 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
return true;
-}
+}
\ No newline at end of file
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index 3b8a7dda1b..5cdc4bf4dc 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -7,6 +7,7 @@
#include "Router.h"
#include "configuration.h"
#include "main.h"
+#include "power.h"
#include
#include
@@ -14,8 +15,6 @@
#include "Sensor/BME280Sensor.h"
#include "Sensor/BME680Sensor.h"
#include "Sensor/BMP280Sensor.h"
-#include "Sensor/INA219Sensor.h"
-#include "Sensor/INA260Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/SHT31Sensor.h"
@@ -25,8 +24,6 @@ BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor;
MCP9808Sensor mcp9808Sensor;
-INA260Sensor ina260Sensor;
-INA219Sensor ina219Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor;
@@ -52,7 +49,7 @@ SHT31Sensor sht31Sensor;
int32_t EnvironmentTelemetryModule::runOnce()
{
- int32_t result = INT32_MAX;
+ uint32_t result = UINT32_MAX;
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
@@ -83,23 +80,22 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = bme680Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
- if (ina260Sensor.hasSensor())
- result = ina260Sensor.runOnce();
- if (ina219Sensor.hasSensor())
- result = ina219Sensor.runOnce();
if (shtc3Sensor.hasSensor())
result = shtc3Sensor.runOnce();
- if (lps22hbSensor.hasSensor()) {
+ if (lps22hbSensor.hasSensor())
result = lps22hbSensor.runOnce();
- }
if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce();
}
return result;
} else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
- if (!moduleConfig.telemetry.environment_measurement_enabled)
- return result;
+ if (!moduleConfig.telemetry.environment_measurement_enabled) {
+ return disable();
+ } else {
+ if (bme680Sensor.hasSensor())
+ result = bme680Sensor.runTrigger();
+ }
uint32_t now = millis();
if (((lastSentToMesh == 0) ||
@@ -107,13 +103,15 @@ int32_t EnvironmentTelemetryModule::runOnce()
airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = now;
- } else if (service.isToPhoneQueueEmpty()) {
+ } else if (((lastSentToPhone == 0) || ((now - lastSentToPhone) >= sendToPhoneIntervalMs)) &&
+ (service.isToPhoneQueueEmpty())) {
// Just send to phone when it's not our time to send to mesh yet
// Only send while queue is empty (phone assumed connected)
sendTelemetry(NODENUM_BROADCAST, true);
+ lastSentToPhone = now;
}
}
- return sendToPhoneIntervalMs;
+ return min(sendToPhoneIntervalMs, result);
}
bool EnvironmentTelemetryModule::wantUIFrame()
@@ -183,6 +181,7 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{
if (t->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
+#ifdef DEBUG_PORT
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, "
@@ -190,7 +189,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature, t->variant.environment_metrics.voltage);
-
+#endif
// release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr)
packetPool.release(lastMeasurementPacket);
@@ -204,6 +203,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{
meshtastic_Telemetry m;
+ bool valid = false;
m.time = getTime();
m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
@@ -215,50 +215,52 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
m.variant.environment_metrics.voltage = 0;
if (sht31Sensor.hasSensor())
- sht31Sensor.getMetrics(&m);
+ valid = sht31Sensor.getMetrics(&m);
if (lps22hbSensor.hasSensor())
- lps22hbSensor.getMetrics(&m);
+ valid = lps22hbSensor.getMetrics(&m);
if (shtc3Sensor.hasSensor())
- shtc3Sensor.getMetrics(&m);
+ valid = shtc3Sensor.getMetrics(&m);
if (bmp280Sensor.hasSensor())
- bmp280Sensor.getMetrics(&m);
+ valid = bmp280Sensor.getMetrics(&m);
if (bme280Sensor.hasSensor())
- bme280Sensor.getMetrics(&m);
+ valid = bme280Sensor.getMetrics(&m);
if (bme680Sensor.hasSensor())
- bme680Sensor.getMetrics(&m);
+ valid = bme680Sensor.getMetrics(&m);
if (mcp9808Sensor.hasSensor())
- mcp9808Sensor.getMetrics(&m);
+ valid = mcp9808Sensor.getMetrics(&m);
if (ina219Sensor.hasSensor())
- ina219Sensor.getMetrics(&m);
+ valid = ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor())
- ina260Sensor.getMetrics(&m);
-
- LOG_INFO(
- "(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
- m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
- m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
- m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
-
- sensor_read_error_count = 0;
-
- meshtastic_MeshPacket *p = allocDataProtobuf(m);
- p->to = dest;
- p->decoded.want_response = false;
- if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)
- p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
- else
- p->priority = meshtastic_MeshPacket_Priority_MIN;
- // release previous packet before occupying a new spot
- if (lastMeasurementPacket != nullptr)
- packetPool.release(lastMeasurementPacket);
-
- lastMeasurementPacket = packetPool.allocCopy(*p);
- if (phoneOnly) {
- LOG_INFO("Sending packet to phone\n");
- service.sendToPhone(p);
- } else {
- LOG_INFO("Sending packet to mesh\n");
- service.sendToMesh(p, RX_SRC_LOCAL, true);
+ valid = ina260Sensor.getMetrics(&m);
+
+ if (valid) {
+ LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, "
+ "voltage=%f\n",
+ m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
+ m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
+ m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
+
+ sensor_read_error_count = 0;
+
+ meshtastic_MeshPacket *p = allocDataProtobuf(m);
+ p->to = dest;
+ p->decoded.want_response = false;
+ if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)
+ p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
+ else
+ p->priority = meshtastic_MeshPacket_Priority_MIN;
+ // release previous packet before occupying a new spot
+ if (lastMeasurementPacket != nullptr)
+ packetPool.release(lastMeasurementPacket);
+
+ lastMeasurementPacket = packetPool.allocCopy(*p);
+ if (phoneOnly) {
+ LOG_INFO("Sending packet to phone\n");
+ service.sendToPhone(p);
+ } else {
+ LOG_INFO("Sending packet to mesh\n");
+ service.sendToMesh(p, RX_SRC_LOCAL, true);
+ }
}
- return true;
-}
+ return valid;
+}
\ No newline at end of file
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.h b/src/modules/Telemetry/EnvironmentTelemetry.h
index 3340f87513..d6cd2137fa 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.h
+++ b/src/modules/Telemetry/EnvironmentTelemetry.h
@@ -39,5 +39,6 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
meshtastic_MeshPacket *lastMeasurementPacket;
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0;
+ uint32_t lastSentToPhone = 0;
uint32_t sensor_read_error_count = 0;
};
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
index 43e4c03863..5b32645e67 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
@@ -6,21 +6,41 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
+int32_t BME680Sensor::runTrigger()
+{
+ if (!bme680.run()) {
+ checkStatus("runTrigger");
+ }
+ return 35;
+}
+
int32_t BME680Sensor::runOnce()
{
- LOG_INFO("Init sensor: %s with the BSEC Library\n", sensorName);
+
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire);
+ if (!bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire))
+ checkStatus("begin");
+
if (bme680.status == BSEC_OK) {
- bme680.setConfig(Default_H2S_NonH2S_config);
- loadState();
- bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
status = 1;
+ if (!bme680.setConfig(bsec_config_iaq)) {
+ checkStatus("setConfig");
+ status = 0;
+ }
+ loadState();
+ if (!bme680.updateSubscription(sensorList, ARRAY_LEN(sensorList), BSEC_SAMPLE_RATE_LP)) {
+ checkStatus("updateSubscription");
+ status = 0;
+ }
+ LOG_INFO("Init sensor: %s with the BSEC Library version %d.%d.%d.%d \n", sensorName, bme680.version.major,
+ bme680.version.minor, bme680.version.major_bugfix, bme680.version.minor_bugfix);
} else {
status = 0;
}
+ if (status == 0)
+ LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d\n", bme680.status);
return initI2CSensor();
}
@@ -29,8 +49,8 @@ void BME680Sensor::setup() {}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
- bme680.run();
-
+ if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
+ return false;
measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal;
measurement->variant.environment_metrics.relative_humidity =
bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal;
@@ -92,10 +112,12 @@ void BME680Sensor::updateState()
file.flush();
file.close();
// brief window of risk here ;-)
- if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName))
+ if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName)) {
LOG_WARN("Can't remove old state file\n");
- if (!renameFile(filenameTmp.c_str(), bsecConfigFileName))
+ }
+ if (!renameFile(filenameTmp.c_str(), bsecConfigFileName)) {
LOG_ERROR("Error: can't rename new state file\n");
+ }
} else {
LOG_INFO("Can't write %s state (File: %s).\n", sensorName, bsecConfigFileName);
@@ -104,4 +126,17 @@ void BME680Sensor::updateState()
#else
LOG_ERROR("ERROR: Filesystem not implemented\n");
#endif
-}
\ No newline at end of file
+}
+
+void BME680Sensor::checkStatus(String functionName)
+{
+ if (bme680.status < BSEC_OK)
+ LOG_ERROR("%s BSEC2 code: %s\n", functionName.c_str(), String(bme680.status).c_str());
+ else if (bme680.status > BSEC_OK)
+ LOG_WARN("%s BSEC2 code: %s\n", functionName.c_str(), String(bme680.status).c_str());
+
+ if (bme680.sensor.status < BME68X_OK)
+ LOG_ERROR("%s BME68X code: %s\n", functionName.c_str(), String(bme680.sensor.status).c_str());
+ else if (bme680.sensor.status > BME68X_OK)
+ LOG_WARN("%s BME68X code: %s\n", functionName.c_str(), String(bme680.sensor.status).c_str());
+}
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h
index 6b45a76f43..06e24b1a9d 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.h
@@ -4,7 +4,7 @@
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
-#include "config/Default_H2S_NonH2S/Default_H2S_NonH2S.h"
+#include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
class BME680Sensor : virtual public TelemetrySensor
{
@@ -17,24 +17,22 @@ class BME680Sensor : virtual public TelemetrySensor
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
uint16_t stateUpdateCounter = 0;
- bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ,
- BSEC_OUTPUT_STATIC_IAQ,
- BSEC_OUTPUT_CO2_EQUIVALENT,
- BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
- BSEC_OUTPUT_RAW_TEMPERATURE,
- BSEC_OUTPUT_RAW_PRESSURE,
- BSEC_OUTPUT_RAW_HUMIDITY,
- BSEC_OUTPUT_RAW_GAS,
- BSEC_OUTPUT_STABILIZATION_STATUS,
- BSEC_OUTPUT_RUN_IN_STATUS,
- BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
- BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
- BSEC_OUTPUT_GAS_PERCENTAGE};
+ bsecSensor sensorList[9] = {BSEC_OUTPUT_IAQ,
+ BSEC_OUTPUT_RAW_TEMPERATURE,
+ BSEC_OUTPUT_RAW_PRESSURE,
+ BSEC_OUTPUT_RAW_HUMIDITY,
+ BSEC_OUTPUT_RAW_GAS,
+ BSEC_OUTPUT_STABILIZATION_STATUS,
+ BSEC_OUTPUT_RUN_IN_STATUS,
+ BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
+ BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY};
void loadState();
void updateState();
+ void checkStatus(String functionName);
public:
BME680Sensor();
+ int32_t runTrigger();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.cpp b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
index bffa1e3677..1dd7f7f2c8 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
@@ -12,8 +12,12 @@ int32_t INA219Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
- status = ina219.begin();
+ if (!ina219.success()) {
+ ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
+ status = ina219.begin();
+ } else {
+ status = ina219.success();
+ }
return initI2CSensor();
}
@@ -24,4 +28,9 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
+}
+
+uint16_t INA219Sensor::getBusVoltageMv()
+{
+ return lround(ina219.getBusVoltage_V() * 1000);
}
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.h b/src/modules/Telemetry/Sensor/INA219Sensor.h
index dc6c0a5afd..f11a571ccc 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.h
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
+#include "VoltageSensor.h"
#include
-class INA219Sensor : virtual public TelemetrySensor
+class INA219Sensor : virtual public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA219 ina219;
@@ -14,4 +15,5 @@ class INA219Sensor : virtual public TelemetrySensor
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
+ virtual uint16_t getBusVoltageMv() override;
};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.cpp b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
index ee0256e621..034fecca0b 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
@@ -12,7 +12,10 @@ int32_t INA260Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
+
+ if (!status) {
+ status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
+ }
return initI2CSensor();
}
@@ -24,4 +27,9 @@ bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
+}
+
+uint16_t INA260Sensor::getBusVoltageMv()
+{
+ return lround(ina260.readBusVoltage());
}
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.h b/src/modules/Telemetry/Sensor/INA260Sensor.h
index 1dcb596e62..8ea5326973 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.h
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
+#include "VoltageSensor.h"
#include
-class INA260Sensor : virtual public TelemetrySensor
+class INA260Sensor : virtual public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
@@ -14,4 +15,5 @@ class INA260Sensor : virtual public TelemetrySensor
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
+ virtual uint16_t getBusVoltageMv() override;
};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.h b/src/modules/Telemetry/Sensor/TelemetrySensor.h
index 7a579ef5c4..dec81e0614 100644
--- a/src/modules/Telemetry/Sensor/TelemetrySensor.h
+++ b/src/modules/Telemetry/Sensor/TelemetrySensor.h
@@ -1,9 +1,9 @@
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
-#include "main.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
+extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor
{
@@ -18,6 +18,7 @@ class TelemetrySensor
const char *sensorName;
meshtastic_TelemetrySensorType sensorType;
unsigned status;
+ bool initialized = false;
int32_t initI2CSensor()
{
@@ -28,6 +29,7 @@ class TelemetrySensor
LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName);
setup();
}
+ initialized = true;
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
virtual void setup();
@@ -36,5 +38,8 @@ class TelemetrySensor
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; }
virtual int32_t runOnce() = 0;
+ virtual bool isInitialized() { return initialized; }
+ virtual bool isRunning() { return status > 0; }
+
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
-};
+};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/VoltageSensor.h b/src/modules/Telemetry/Sensor/VoltageSensor.h
new file mode 100644
index 0000000000..f2f28fb062
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/VoltageSensor.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class VoltageSensor
+{
+ public:
+ virtual uint16_t getBusVoltageMv() = 0;
+};
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c
new file mode 100644
index 0000000000..1f27e6c69c
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c
@@ -0,0 +1,82 @@
+#include "bsec_iaq.h"
+
+const uint8_t bsec_config_iaq[1974] = {
+ 0, 0, 4, 2, 189, 1, 0, 0, 0, 0, 0, 0, 158, 7, 0, 0, 176, 0, 1, 0, 0, 192, 168, 71, 64,
+ 49, 119, 76, 0, 0, 97, 69, 0, 0, 97, 69, 137, 65, 0, 191, 205, 204, 204, 190, 0, 0, 64, 191, 225, 122,
+ 148, 190, 10, 0, 3, 0, 0, 0, 96, 64, 23, 183, 209, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 205, 204, 204, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, 82, 73, 157, 188, 95, 41, 203, 61, 118, 224,
+ 108, 63, 155, 230, 125, 63, 191, 14, 124, 63, 0, 0, 160, 65, 0, 0, 32, 66, 0, 0, 160, 65, 0, 0, 32,
+ 66, 0, 0, 32, 66, 0, 0, 160, 65, 0, 0, 32, 66, 0, 0, 160, 65, 8, 0, 2, 0, 236, 81, 133, 66,
+ 16, 0, 3, 0, 10, 215, 163, 60, 10, 215, 35, 59, 10, 215, 35, 59, 13, 0, 5, 0, 0, 0, 0, 0, 100,
+ 35, 41, 29, 86, 88, 0, 9, 0, 229, 208, 34, 62, 0, 0, 0, 0, 0, 0, 0, 0, 218, 27, 156, 62, 225,
+ 11, 67, 64, 0, 0, 160, 64, 0, 0, 0, 0, 0, 0, 0, 0, 94, 75, 72, 189, 93, 254, 159, 64, 66, 62,
+ 160, 191, 0, 0, 0, 0, 0, 0, 0, 0, 33, 31, 180, 190, 138, 176, 97, 64, 65, 241, 99, 190, 0, 0, 0,
+ 0, 0, 0, 0, 0, 167, 121, 71, 61, 165, 189, 41, 192, 184, 30, 189, 64, 12, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 13, 5, 11, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
+ 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 10, 10, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 88, 1, 254,
+ 0, 2, 1, 5, 48, 117, 100, 0, 44, 1, 112, 23, 151, 7, 132, 3, 197, 0, 92, 4, 144, 1, 64, 1, 64,
+ 1, 144, 1, 48, 117, 48, 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 48, 117, 100, 0,
+ 100, 0, 48, 117, 48, 117, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 100, 0, 100, 0, 100, 0, 100, 0, 48,
+ 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 100, 0, 100, 0, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44,
+ 1, 44, 1, 44, 1, 44, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 112, 23, 112, 23, 112, 23, 112, 23,
+ 8, 7, 8, 7, 8, 7, 8, 7, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, 255, 255,
+ 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 220, 5, 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 5, 10, 5,
+ 0, 2, 0, 10, 0, 30, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 64, 1, 100, 0, 100, 0,
+ 100, 0, 200, 0, 200, 0, 200, 0, 64, 1, 64, 1, 64, 1, 10, 0, 0, 0, 0, 0, 21, 122, 0, 0};
diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h
new file mode 100644
index 0000000000..cdd209ae5d
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h
@@ -0,0 +1,3 @@
+#include
+
+extern const uint8_t bsec_config_iaq[1974];
diff --git a/src/modules/TextMessageModule.cpp b/src/modules/TextMessageModule.cpp
index 0fa175a144..8ff034fa93 100644
--- a/src/modules/TextMessageModule.cpp
+++ b/src/modules/TextMessageModule.cpp
@@ -7,8 +7,10 @@ TextMessageModule *textMessageModule;
ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
{
+#ifdef DEBUG_PORT
auto &p = mp.decoded;
LOG_INFO("Received text msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
+#endif
// We only store/display messages destined for us.
// Keep a copy of the most recent text message.
diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp
index 14396266dd..f26c40d2f0 100644
--- a/src/modules/TraceRouteModule.cpp
+++ b/src/modules/TraceRouteModule.cpp
@@ -47,6 +47,7 @@ void TraceRouteModule::appendMyID(meshtastic_RouteDiscovery *updated)
void TraceRouteModule::printRoute(meshtastic_RouteDiscovery *r, uint32_t origin, uint32_t dest)
{
+#ifdef DEBUG_PORT
LOG_INFO("Route traced:\n");
LOG_INFO("0x%x --> ", origin);
for (uint8_t i = 0; i < r->route_count; i++) {
@@ -56,6 +57,7 @@ void TraceRouteModule::printRoute(meshtastic_RouteDiscovery *r, uint32_t origin,
LOG_INFO("0x%x\n", dest);
else
LOG_INFO("...\n");
+#endif
}
meshtastic_MeshPacket *TraceRouteModule::allocReply()
diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp
index f95bdec34f..83485c8eee 100644
--- a/src/modules/WaypointModule.cpp
+++ b/src/modules/WaypointModule.cpp
@@ -7,8 +7,10 @@ WaypointModule *waypointModule;
ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp)
{
+#ifdef DEBUG_PORT
auto &p = mp.decoded;
LOG_INFO("Received waypoint msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
+#endif
// We only store/display messages destined for us.
// Keep a copy of the most recent text message.
diff --git a/src/modules/esp32/AudioModule.cpp b/src/modules/esp32/AudioModule.cpp
index e6a975119f..4a154878d4 100644
--- a/src/modules/esp32/AudioModule.cpp
+++ b/src/modules/esp32/AudioModule.cpp
@@ -195,8 +195,9 @@ int32_t AudioModule::runOnce()
.tx_desc_auto_clear = true,
.fixed_mclk = 0};
res = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_ERROR("Failed to install I2S driver: %d\n", res);
+ }
const i2s_pin_config_t pin_config = {
.bck_io_num = moduleConfig.audio.i2s_sck,
@@ -204,12 +205,14 @@ int32_t AudioModule::runOnce()
.data_out_num = moduleConfig.audio.i2s_din ? moduleConfig.audio.i2s_din : I2S_PIN_NO_CHANGE,
.data_in_num = moduleConfig.audio.i2s_sd ? moduleConfig.audio.i2s_sd : I2S_PIN_NO_CHANGE};
res = i2s_set_pin(I2S_PORT, &pin_config);
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_ERROR("Failed to set I2S pin config: %d\n", res);
+ }
res = i2s_start(I2S_PORT);
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_ERROR("Failed to start I2S: %d\n", res);
+ }
radio_state = RadioState::rx;
diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp
index 38e9836694..767e1fb2bb 100644
--- a/src/modules/esp32/StoreForwardModule.cpp
+++ b/src/modules/esp32/StoreForwardModule.cpp
@@ -36,8 +36,6 @@ int32_t StoreForwardModule::runOnce()
this->packetHistoryTXQueue_index++;
}
}
- LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
-
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
lastHeartbeat = millis();
LOG_INFO("*** Sending heartbeat\n");
@@ -266,7 +264,6 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
storeForwardModule->historyAdd(mp);
LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent);
}
-
} else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
auto &p = mp.decoded;
meshtastic_StoreAndForward scratch;
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index bd1a856418..532a2d1258 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -461,8 +461,9 @@ std::string MQTT::downstreamPacketToJson(meshtastic_MeshPacket *mp)
msgPayload["current"] = new JSONValue(decoded->variant.environment_metrics.current);
}
jsonObj["payload"] = new JSONValue(msgPayload);
- } else
+ } else {
LOG_ERROR("Error decoding protobuf for telemetry message!\n");
+ }
};
break;
}
@@ -479,8 +480,9 @@ std::string MQTT::downstreamPacketToJson(meshtastic_MeshPacket *mp)
msgPayload["shortname"] = new JSONValue(decoded->short_name);
msgPayload["hardware"] = new JSONValue(decoded->hw_model);
jsonObj["payload"] = new JSONValue(msgPayload);
- } else
+ } else {
LOG_ERROR("Error decoding protobuf for nodeinfo message!\n");
+ }
};
break;
}
@@ -503,6 +505,15 @@ std::string MQTT::downstreamPacketToJson(meshtastic_MeshPacket *mp)
if ((int)decoded->altitude) {
msgPayload["altitude"] = new JSONValue((int)decoded->altitude);
}
+ if ((int)decoded->ground_speed) {
+ msgPayload["ground_speed"] = new JSONValue((int)decoded->ground_speed);
+ }
+ if (int(decoded->ground_track)) {
+ msgPayload["ground_track"] = new JSONValue((int)decoded->ground_track);
+ }
+ if (int(decoded->sats_in_view)) {
+ msgPayload["sats_in_view"] = new JSONValue((int)decoded->sats_in_view);
+ }
jsonObj["payload"] = new JSONValue(msgPayload);
} else {
LOG_ERROR("Error decoding protobuf for position message!\n");
diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h
index da2d9d9055..7a1e9ba490 100644
--- a/src/platform/esp32/architecture.h
+++ b/src/platform/esp32/architecture.h
@@ -39,6 +39,9 @@
#ifndef HAS_CPU_SHUTDOWN
#define HAS_CPU_SHUTDOWN 1
#endif
+#ifndef DEFAULT_VREF
+#define DEFAULT_VREF 1100
+#endif
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
#define HAS_PMU
@@ -132,4 +135,4 @@
#define RF95_NSS 18
#endif
-#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
+#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
\ No newline at end of file
diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp
index 36ddefeb40..c630aa13b7 100644
--- a/src/platform/nrf52/main-nrf52.cpp
+++ b/src/platform/nrf52/main-nrf52.cpp
@@ -172,6 +172,10 @@ void cpuDeepSleep(uint32_t msecToWake)
setBluetoothEnable(false);
#ifdef RAK4630
digitalWrite(PIN_3V3_EN, LOW);
+#ifndef USE_EINK
+ // RAK-12039 set pin for Air quality sensor
+ digitalWrite(AQ_SET_PIN, LOW);
+#endif
#endif
// FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per
@@ -197,4 +201,4 @@ void clearBonds()
nrf52Bluetooth->setup();
}
nrf52Bluetooth->clearBonds();
-}
+}
\ No newline at end of file
diff --git a/src/platform/rp2040/architecture.h b/src/platform/rp2040/architecture.h
index c5a2ecdecf..772e4b1afe 100644
--- a/src/platform/rp2040/architecture.h
+++ b/src/platform/rp2040/architecture.h
@@ -2,6 +2,18 @@
#define ARCH_RP2040
-#if defined(PRIVATE_HW)
-#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
+#ifndef HAS_TELEMETRY
+#define HAS_TELEMETRY 1
+#endif
+#ifndef HAS_SENSOR
+#define HAS_SENSOR 1
+#endif
+#ifndef HAS_RADIO
+#define HAS_RADIO 1
+#endif
+
+#if defined(RPI_PICO)
+#define HW_VENDOR meshtastic_HardwareModel_RPI_PICO
+#elif defined(RAK11310)
+#define HW_VENDOR meshtastic_HardwareModel_RAK11310
#endif
\ No newline at end of file
diff --git a/src/platform/rp2040/main-rp2040.cpp b/src/platform/rp2040/main-rp2040.cpp
index af200f9617..5e24bf03c9 100644
--- a/src/platform/rp2040/main-rp2040.cpp
+++ b/src/platform/rp2040/main-rp2040.cpp
@@ -21,10 +21,10 @@ void getMacAddr(uint8_t *dmac)
{
pico_unique_board_id_t src;
pico_get_unique_board_id(&src);
- dmac[5] = src.id[0];
- dmac[4] = src.id[1];
- dmac[3] = src.id[2];
- dmac[2] = src.id[3];
- dmac[1] = src.id[4];
- dmac[0] = src.id[5];
-}
+ dmac[5] = src.id[7];
+ dmac[4] = src.id[6];
+ dmac[3] = src.id[5];
+ dmac[2] = src.id[4];
+ dmac[1] = src.id[3];
+ dmac[0] = src.id[2];
+}
\ No newline at end of file
diff --git a/src/platform/stm32wl/InternalFileSystem.cpp b/src/platform/stm32wl/InternalFileSystem.cpp
new file mode 100644
index 0000000000..950ceb0cd4
--- /dev/null
+++ b/src/platform/stm32wl/InternalFileSystem.cpp
@@ -0,0 +1,141 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "InternalFileSystem.h"
+#include
+
+//--------------------------------------------------------------------+
+// LFS Disk IO
+//--------------------------------------------------------------------+
+
+static inline uint32_t lba2addr(uint32_t block)
+{
+ return ((uint32_t)LFS_FLASH_ADDR) + block * LFS_BLOCK_SIZE;
+}
+
+static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block) + off;
+ uint8_t prom;
+
+ for (int i = 0; i < size; i++) {
+ prom = EEPROM.read(addr + i);
+ memcpy((char *)buffer + i, &prom, 1);
+ }
+ return 0;
+}
+
+// Program a region in a block. The block must have previously
+// been erased. Negative error codes are propogated to the user.
+// May return LFS_ERR_CORRUPT if the block should be considered bad.
+static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block) + off;
+ uint8_t prom;
+
+ for (int i = 0; i < size; i++) {
+ memcpy(&prom, (char *)buffer + i, 1);
+ EEPROM.update(addr + i, prom);
+ }
+ return 0;
+}
+
+// Erase a block. A block must be erased before being programmed.
+// The state of an erased block is undefined. Negative error codes
+// are propogated to the user.
+// May return LFS_ERR_CORRUPT if the block should be considered bad.
+static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
+{
+ (void)c;
+
+ uint32_t addr = lba2addr(block);
+
+ // implement as write 0xff to whole block address
+ for (int i = 0; i < LFS_BLOCK_SIZE; i++) {
+ EEPROM.update(addr, 0xff);
+ }
+
+ return 0;
+}
+
+// Sync the state of the underlying block device. Negative error codes
+// are propogated to the user.
+static int _internal_flash_sync(const struct lfs_config *c)
+{
+ // we don't use a ram cache, this is a noop
+ return 0;
+}
+
+static struct lfs_config _InternalFSConfig = {.context = NULL,
+
+ .read = _internal_flash_read,
+ .prog = _internal_flash_prog,
+ .erase = _internal_flash_erase,
+ .sync = _internal_flash_sync,
+
+ .read_size = LFS_CACHE_SIZE,
+ .prog_size = LFS_CACHE_SIZE,
+ .block_size = LFS_BLOCK_SIZE,
+ .block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
+ .block_cycles =
+ 500, // protection against wear leveling (suggested values between 100-1000)
+ .cache_size = LFS_CACHE_SIZE,
+ .lookahead_size = LFS_CACHE_SIZE,
+
+ .read_buffer = lfs_read_buffer,
+ .prog_buffer = lfs_prog_buffer,
+ .lookahead_buffer = lfs_lookahead_buffer};
+
+InternalFileSystem InternalFS;
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+InternalFileSystem::InternalFileSystem(void) : LittleFS(&_InternalFSConfig) {}
+
+bool InternalFileSystem::begin(void)
+{
+ // failed to mount, erase all sector then format and mount again
+ if (!LittleFS::begin()) {
+ // Erase all sectors of internal flash region for Filesystem.
+ // implement as write 0xff to whole block address
+ for (uint32_t addr = LFS_FLASH_ADDR; addr < (LFS_FLASH_ADDR + LFS_FLASH_TOTAL_SIZE); addr++) {
+ EEPROM.update(addr, 0xff);
+ }
+
+ // lfs format
+ this->format();
+
+ // mount again if still failed, give up
+ if (!LittleFS::begin())
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/platform/stm32wl/InternalFileSystem.h b/src/platform/stm32wl/InternalFileSystem.h
new file mode 100644
index 0000000000..66344194e1
--- /dev/null
+++ b/src/platform/stm32wl/InternalFileSystem.h
@@ -0,0 +1,54 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef INTERNALFILESYSTEM_H_
+#define INTERNALFILESYSTEM_H_
+
+#include "LittleFS.h"
+
+// The EEPROM Library assumes our usable flash area starts at logical 0
+#define LFS_FLASH_ADDR 0
+
+// use the built in EEPROM emulation. Total Size is 2Kbyte
+#define LFS_BLOCK_SIZE 128 // min. block size is 128 to fit CTZ pointers
+#define LFS_CACHE_SIZE 16
+
+#define LFS_FLASH_TOTAL_SIZE FLASH_PAGE_SIZE
+
+static uint8_t lfs_read_buffer[LFS_CACHE_SIZE] = {0};
+static uint8_t lfs_prog_buffer[LFS_CACHE_SIZE] = {0};
+static uint8_t lfs_lookahead_buffer[LFS_CACHE_SIZE] = {0};
+
+class InternalFileSystem : public LittleFS
+{
+ public:
+ InternalFileSystem(void);
+
+ // overwrite to also perform low level format (sector erase of whole flash region)
+ bool begin(void);
+};
+
+extern InternalFileSystem InternalFS;
+
+#endif /* INTERNALFILESYSTEM_H_ */
diff --git a/src/platform/stm32wl/LittleFS.cpp b/src/platform/stm32wl/LittleFS.cpp
new file mode 100644
index 0000000000..b1267d88a6
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS.cpp
@@ -0,0 +1,258 @@
+#include
+#include
+
+#include "LittleFS.h"
+
+using namespace LittleFS_Namespace;
+
+//--------------------------------------------------------------------+
+// Implementation
+//--------------------------------------------------------------------+
+
+LittleFS::LittleFS(void) : LittleFS(NULL) {}
+
+LittleFS::LittleFS(struct lfs_config *cfg)
+{
+ memset(&_lfs, 0, sizeof(_lfs));
+ _lfs_cfg = cfg;
+ _mounted = false;
+ _mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
+}
+
+LittleFS::~LittleFS() {}
+
+// Initialize and mount the file system
+// Return true if mounted successfully else probably corrupted.
+// User should format the disk and try again
+bool LittleFS::begin(struct lfs_config *cfg)
+{
+ _lockFS();
+
+ bool ret;
+ // not a loop, just an quick way to short-circuit on error
+ do {
+ if (_mounted) {
+ ret = true;
+ break;
+ }
+ if (cfg) {
+ _lfs_cfg = cfg;
+ }
+ if (nullptr == _lfs_cfg) {
+ ret = false;
+ break;
+ }
+ // actually attempt to mount, and log error if one occurs
+ int err = lfs_mount(&_lfs, _lfs_cfg);
+ PRINT_LFS_ERR(err);
+ _mounted = (err == LFS_ERR_OK);
+ ret = _mounted;
+ } while (0);
+
+ _unlockFS();
+ return ret;
+}
+
+// Tear down and unmount file system
+void LittleFS::end(void)
+{
+ _lockFS();
+
+ if (_mounted) {
+ _mounted = false;
+ int err = lfs_unmount(&_lfs);
+ PRINT_LFS_ERR(err);
+ (void)err;
+ }
+
+ _unlockFS();
+}
+
+bool LittleFS::format(void)
+{
+ _lockFS();
+
+ int err = LFS_ERR_OK;
+ bool attemptMount = _mounted;
+ // not a loop, just an quick way to short-circuit on error
+ do {
+ // if already mounted: umount first -> format -> remount
+ if (_mounted) {
+ _mounted = false;
+ err = lfs_unmount(&_lfs);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+ }
+ err = lfs_format(&_lfs, _lfs_cfg);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+
+ if (attemptMount) {
+ err = lfs_mount(&_lfs, _lfs_cfg);
+ if (LFS_ERR_OK != err) {
+ PRINT_LFS_ERR(err);
+ break;
+ }
+ _mounted = true;
+ }
+ // success!
+ } while (0);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Open a file or folder
+LittleFS_Namespace::File LittleFS::open(char const *filepath, uint8_t mode)
+{
+ // No lock is required here ... the File() object will synchronize with the mutex provided
+ return LittleFS_Namespace::File(filepath, mode, *this);
+}
+
+// Check if file or folder exists
+bool LittleFS::exists(char const *filepath)
+{
+ struct lfs_info info;
+ _lockFS();
+
+ bool ret = (0 == lfs_stat(&_lfs, filepath, &info));
+
+ _unlockFS();
+ return ret;
+}
+
+// Create a directory, create intermediate parent if needed
+bool LittleFS::mkdir(char const *filepath)
+{
+ bool ret = true;
+ const char *slash = filepath;
+ if (slash[0] == '/')
+ slash++; // skip root '/'
+
+ _lockFS();
+
+ // make intermediate parent directory(ies)
+ while (NULL != (slash = strchr(slash, '/'))) {
+ char parent[slash - filepath + 1] = {0};
+ memcpy(parent, filepath, slash - filepath);
+
+ int rc = lfs_mkdir(&_lfs, parent);
+ if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
+ PRINT_LFS_ERR(rc);
+ ret = false;
+ break;
+ }
+ slash++;
+ }
+ // make the final requested directory
+ if (ret) {
+ int rc = lfs_mkdir(&_lfs, filepath);
+ if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
+ PRINT_LFS_ERR(rc);
+ ret = false;
+ }
+ }
+
+ _unlockFS();
+ return ret;
+}
+
+// Remove a file
+bool LittleFS::remove(char const *filepath)
+{
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Rename a file
+bool LittleFS::rename(char const *oldfilepath, char const *newfilepath)
+{
+ _lockFS();
+
+ int err = lfs_rename(&_lfs, oldfilepath, newfilepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Remove a folder
+bool LittleFS::rmdir(char const *filepath)
+{
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+// Remove a folder recursively
+bool LittleFS::rmdir_r(char const *filepath)
+{
+ /* adafruit: lfs is modified to remove non-empty folder,
+ According to below issue, comment these 2 line won't corrupt filesystem
+ at least when using LFS v1. If moving to LFS v2, see tracked issue
+ to see if issues (such as the orphans in threaded linked list) are resolved.
+ https://github.com/ARMmbed/littlefs/issues/43
+ */
+ _lockFS();
+
+ int err = lfs_remove(&_lfs, filepath);
+ PRINT_LFS_ERR(err);
+
+ _unlockFS();
+ return LFS_ERR_OK == err;
+}
+
+//------------- Debug -------------//
+#if CFG_DEBUG
+
+const char *dbg_strerr_lfs(int32_t err)
+{
+ switch (err) {
+ case LFS_ERR_OK:
+ return "LFS_ERR_OK";
+ case LFS_ERR_IO:
+ return "LFS_ERR_IO";
+ case LFS_ERR_CORRUPT:
+ return "LFS_ERR_CORRUPT";
+ case LFS_ERR_NOENT:
+ return "LFS_ERR_NOENT";
+ case LFS_ERR_EXIST:
+ return "LFS_ERR_EXIST";
+ case LFS_ERR_NOTDIR:
+ return "LFS_ERR_NOTDIR";
+ case LFS_ERR_ISDIR:
+ return "LFS_ERR_ISDIR";
+ case LFS_ERR_NOTEMPTY:
+ return "LFS_ERR_NOTEMPTY";
+ case LFS_ERR_BADF:
+ return "LFS_ERR_BADF";
+ case LFS_ERR_INVAL:
+ return "LFS_ERR_INVAL";
+ case LFS_ERR_NOSPC:
+ return "LFS_ERR_NOSPC";
+ case LFS_ERR_NOMEM:
+ return "LFS_ERR_NOMEM";
+
+ default:
+ static char errcode[10];
+ sprintf(errcode, "%ld", err);
+ return errcode;
+ }
+
+ return NULL;
+}
+
+#endif
diff --git a/src/platform/stm32wl/LittleFS.h b/src/platform/stm32wl/LittleFS.h
new file mode 100644
index 0000000000..4a0b01af2b
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS.h
@@ -0,0 +1,85 @@
+
+#ifndef LITTLEFS_H_
+#define LITTLEFS_H_
+
+#include
+
+#include "lfs.h"
+
+#include "LittleFS_File.h"
+
+#include "FreeRTOS.h" // tied to FreeRTOS for serialization
+#include "semphr.h"
+
+class LittleFS
+{
+ public:
+ LittleFS(void);
+ explicit LittleFS(struct lfs_config *cfg);
+ virtual ~LittleFS();
+
+ bool begin(struct lfs_config *cfg = NULL);
+ void end(void);
+
+ // Open the specified file/directory with the supplied mode (e.g. read or
+ // write, etc). Returns a File object for interacting with the file.
+ // Note that currently only one file can be open at a time.
+ LittleFS_Namespace::File open(char const *filename, uint8_t mode = LittleFS_Namespace::FILE_O_READ);
+
+ // Methods to determine if the requested file path exists.
+ bool exists(char const *filepath);
+
+ // Create the requested directory hierarchy--if intermediate directories
+ // do not exist they will be created.
+ bool mkdir(char const *filepath);
+
+ // Delete the file.
+ bool remove(char const *filepath);
+
+ // Rename the file.
+ bool rename(char const *oldfilepath, char const *newfilepath);
+
+ // Delete a folder (must be empty)
+ bool rmdir(char const *filepath);
+
+ // Delete a folder (recursively)
+ bool rmdir_r(char const *filepath);
+
+ // format file system
+ bool format(void);
+
+ /*------------------------------------------------------------------*/
+ /* INTERNAL USAGE ONLY
+ * Although declare as public, it is meant to be invoked by internal
+ * code. User should not call these directly
+ *------------------------------------------------------------------*/
+ lfs_t *_getFS(void) { return &_lfs; }
+ void _lockFS(void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
+ void _unlockFS(void) { xSemaphoreGive(_mutex); }
+
+ protected:
+ bool _mounted;
+ struct lfs_config *_lfs_cfg;
+ lfs_t _lfs;
+ SemaphoreHandle_t _mutex;
+
+ private:
+ StaticSemaphore_t _MutexStorageSpace;
+};
+
+#if !CFG_DEBUG
+#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
+#define PRINT_LFS_ERR(_err)
+#else
+#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_strerr_lfs)
+#define PRINT_LFS_ERR(_err) \
+ do { \
+ if (_err) { \
+ VERIFY_MESS((long int)_err, dbg_strerr_lfs); \
+ } \
+ } while (0) // LFS_ERR are of type int, VERIFY_MESS expects long_int
+
+const char *dbg_strerr_lfs(int32_t err);
+#endif
+
+#endif /* LITTLEFS_H_ */
diff --git a/src/platform/stm32wl/LittleFS_File.cpp b/src/platform/stm32wl/LittleFS_File.cpp
new file mode 100644
index 0000000000..cffb924e19
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS_File.cpp
@@ -0,0 +1,362 @@
+#include
+
+#include "LittleFS.h"
+
+#include
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+using namespace LittleFS_Namespace;
+
+File::File(LittleFS &fs)
+{
+ _fs = &fs;
+ _is_dir = false;
+ _name[0] = 0;
+ _dir_path = NULL;
+
+ _dir = NULL;
+ _file = NULL;
+}
+
+File::File(char const *filename, uint8_t mode, LittleFS &fs) : File(fs)
+{
+ // public constructor calls public API open(), which will obtain the mutex
+ this->open(filename, mode);
+}
+
+bool File::_open_file(char const *filepath, uint8_t mode)
+{
+ int flags = (mode == FILE_O_READ) ? LFS_O_RDONLY : (mode == FILE_O_WRITE) ? (LFS_O_RDWR | LFS_O_CREAT) : 0;
+
+ if (flags) {
+ _file = (lfs_file_t *)malloc(sizeof(lfs_file_t));
+ if (!_file)
+ return false;
+
+ int rc = lfs_file_open(_fs->_getFS(), _file, filepath, flags);
+
+ if (rc) {
+ // failed to open
+ PRINT_LFS_ERR(rc);
+ return false;
+ }
+
+ // move to end of file
+ if (mode == FILE_O_WRITE)
+ lfs_file_seek(_fs->_getFS(), _file, 0, LFS_SEEK_END);
+
+ _is_dir = false;
+ }
+
+ return true;
+}
+
+bool File::_open_dir(char const *filepath)
+{
+ _dir = (lfs_dir_t *)malloc(sizeof(lfs_dir_t));
+ if (!_dir)
+ return false;
+
+ int rc = lfs_dir_open(_fs->_getFS(), _dir, filepath);
+
+ if (rc) {
+ // failed to open
+ PRINT_LFS_ERR(rc);
+ return false;
+ }
+
+ _is_dir = true;
+
+ _dir_path = (char *)malloc(strlen(filepath) + 1);
+ strcpy(_dir_path, filepath);
+
+ return true;
+}
+
+bool File::open(char const *filepath, uint8_t mode)
+{
+ bool ret = false;
+ _fs->_lockFS();
+
+ ret = this->_open(filepath, mode);
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::_open(char const *filepath, uint8_t mode)
+{
+ bool ret = false;
+
+ // close if currently opened
+ if (this->isOpen())
+ _close();
+
+ struct lfs_info info;
+ int rc = lfs_stat(_fs->_getFS(), filepath, &info);
+
+ if (LFS_ERR_OK == rc) {
+ // file existed, open file or directory accordingly
+ ret = (info.type == LFS_TYPE_REG) ? _open_file(filepath, mode) : _open_dir(filepath);
+ } else if (LFS_ERR_NOENT == rc) {
+ // file not existed, only proceed with FILE_O_WRITE mode
+ if (mode == FILE_O_WRITE)
+ ret = _open_file(filepath, mode);
+ } else {
+ PRINT_LFS_ERR(rc);
+ }
+
+ // save bare file name
+ if (ret) {
+ char const *splash = strrchr(filepath, '/');
+ strncpy(_name, splash ? (splash + 1) : filepath, LFS_NAME_MAX);
+ }
+ return ret;
+}
+
+size_t File::write(uint8_t ch)
+{
+ return write(&ch, 1);
+}
+
+size_t File::write(uint8_t const *buf, size_t size)
+{
+ lfs_ssize_t wrcount = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ wrcount = lfs_file_write(_fs->_getFS(), _file, buf, size);
+ if (wrcount < 0) {
+ wrcount = 0;
+ }
+ }
+
+ _fs->_unlockFS();
+ return wrcount;
+}
+
+int File::read(void)
+{
+ // this thin wrapper relies on called function to synchronize
+ int ret = -1;
+ uint8_t ch;
+ if (read(&ch, 1) > 0) {
+ ret = static_cast(ch);
+ }
+ return ret;
+}
+
+int File::read(void *buf, uint16_t nbyte)
+{
+ int ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_read(_fs->_getFS(), _file, buf, nbyte);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+int File::peek(void)
+{
+ int ret = -1;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ uint8_t ch = 0;
+ if (lfs_file_read(_fs->_getFS(), _file, &ch, 1) > 0) {
+ ret = static_cast(ch);
+ }
+ (void)lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+int File::available(void)
+{
+ int ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ uint32_t size = lfs_file_size(_fs->_getFS(), _file);
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ ret = size - pos;
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::seek(uint32_t pos)
+{
+ bool ret = false;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET) >= 0;
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+uint32_t File::position(void)
+{
+ uint32_t ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_tell(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+uint32_t File::size(void)
+{
+ uint32_t ret = 0;
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ ret = lfs_file_size(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return ret;
+}
+
+bool File::truncate(uint32_t pos)
+{
+ int32_t ret = LFS_ERR_ISDIR;
+ _fs->_lockFS();
+ if (!this->_is_dir) {
+ ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
+ }
+ _fs->_unlockFS();
+ return (ret == 0);
+}
+
+bool File::truncate(void)
+{
+ int32_t ret = LFS_ERR_ISDIR;
+ _fs->_lockFS();
+ if (!this->_is_dir) {
+ uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
+ ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
+ }
+ _fs->_unlockFS();
+ return (ret == 0);
+}
+
+void File::flush(void)
+{
+ _fs->_lockFS();
+
+ if (!this->_is_dir) {
+ lfs_file_sync(_fs->_getFS(), _file);
+ }
+
+ _fs->_unlockFS();
+ return;
+}
+
+void File::close(void)
+{
+ _fs->_lockFS();
+ this->_close();
+ _fs->_unlockFS();
+}
+
+void File::_close(void)
+{
+ if (this->isOpen()) {
+ if (this->_is_dir) {
+ lfs_dir_close(_fs->_getFS(), _dir);
+ free(_dir);
+ _dir = NULL;
+
+ if (this->_dir_path)
+ free(_dir_path);
+ _dir_path = NULL;
+ } else {
+ lfs_file_close(this->_fs->_getFS(), _file);
+ free(_file);
+ _file = NULL;
+ }
+ }
+}
+
+File::operator bool(void)
+{
+ return isOpen();
+}
+
+bool File::isOpen(void)
+{
+ return (_file != NULL) || (_dir != NULL);
+}
+
+// WARNING -- although marked as `const`, the values pointed
+// to may change. For example, if the same File
+// object has `open()` called with a different
+// file or directory name, this same pointer will
+// suddenly (unexpectedly?) have different values.
+char const *File::name(void)
+{
+ return this->_name;
+}
+
+bool File::isDirectory(void)
+{
+ return this->_is_dir;
+}
+
+File File::openNextFile(uint8_t mode)
+{
+ _fs->_lockFS();
+
+ File ret(*_fs);
+ if (this->_is_dir) {
+ struct lfs_info info;
+ int rc;
+
+ // lfs_dir_read returns 0 when reaching end of directory, 1 if found an entry
+ // Skip the "." and ".." entries ...
+ do {
+ rc = lfs_dir_read(_fs->_getFS(), _dir, &info);
+ } while (rc == 1 && (!strcmp(".", info.name) || !strcmp("..", info.name)));
+
+ if (rc == 1) {
+ // string cat name with current folder
+ char filepath[strlen(_dir_path) + 1 + strlen(info.name) + 1]; // potential for significant stack usage
+ strcpy(filepath, _dir_path);
+ if (!(_dir_path[0] == '/' && _dir_path[1] == 0))
+ strcat(filepath, "/"); // only add '/' if cwd is not root
+ strcat(filepath, info.name);
+
+ (void)ret._open(filepath, mode); // return value is ignored ... caller is expected to check isOpened()
+ } else if (rc < 0) {
+ PRINT_LFS_ERR(rc);
+ }
+ }
+ _fs->_unlockFS();
+ return ret;
+}
+
+void File::rewindDirectory(void)
+{
+ _fs->_lockFS();
+ if (this->_is_dir) {
+ lfs_dir_rewind(_fs->_getFS(), _dir);
+ }
+ _fs->_unlockFS();
+}
diff --git a/src/platform/stm32wl/LittleFS_File.h b/src/platform/stm32wl/LittleFS_File.h
new file mode 100644
index 0000000000..e88a2790d8
--- /dev/null
+++ b/src/platform/stm32wl/LittleFS_File.h
@@ -0,0 +1,82 @@
+#ifndef LITTLEFS_FILE_H_
+#define LITTLEFS_FILE_H_
+
+// Forward declaration
+class LittleFS;
+
+namespace LittleFS_Namespace
+{
+
+// avoid conflict with other FileSystem FILE_READ/FILE_WRITE
+enum {
+ FILE_O_READ = 0,
+ FILE_O_WRITE = 1,
+};
+
+class File : public Stream
+{
+ public:
+ explicit File(LittleFS &fs);
+ File(char const *filename, uint8_t mode, LittleFS &fs);
+
+ public:
+ bool open(char const *filename, uint8_t mode);
+
+ //------------- Stream API -------------//
+ virtual size_t write(uint8_t ch);
+ virtual size_t write(uint8_t const *buf, size_t size);
+ size_t write(const char *str)
+ {
+ if (str == NULL)
+ return 0;
+ return write((const uint8_t *)str, strlen(str));
+ }
+ size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
+
+ virtual int read(void);
+ int read(void *buf, uint16_t nbyte);
+
+ virtual int peek(void);
+ virtual int available(void);
+ virtual void flush(void);
+
+ bool seek(uint32_t pos);
+ uint32_t position(void);
+ uint32_t size(void);
+
+ bool truncate(uint32_t pos);
+ bool truncate(void);
+
+ void close(void);
+
+ operator bool(void);
+
+ bool isOpen(void);
+ char const *name(void);
+
+ bool isDirectory(void);
+ File openNextFile(uint8_t mode = FILE_O_READ);
+ void rewindDirectory(void);
+
+ private:
+ LittleFS *_fs;
+
+ bool _is_dir;
+
+ union {
+ lfs_file_t *_file;
+ lfs_dir_t *_dir;
+ };
+
+ char *_dir_path;
+ char _name[LFS_NAME_MAX + 1];
+
+ bool _open(char const *filepath, uint8_t mode);
+ bool _open_file(char const *filepath, uint8_t mode);
+ bool _open_dir(char const *filepath);
+ void _close(void);
+};
+
+} // namespace LittleFS_Namespace
+
+#endif /* LITTLEFS_FILE_H_ */
diff --git a/src/platform/stm32wl/architecture.h b/src/platform/stm32wl/architecture.h
index dc7adc5ffb..1c021903a1 100644
--- a/src/platform/stm32wl/architecture.h
+++ b/src/platform/stm32wl/architecture.h
@@ -6,24 +6,19 @@
// defaults for STM32WL architecture
//
+#ifndef HAS_RADIO
+#define HAS_RADIO 1
+#endif
+
//
// set HW_VENDOR
//
#ifndef HW_VENDOR
-#define HW_VENDOR HardwareModel_PRIVATE_HW
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value);
-int stm32wl_emulate_digitalRead(long unsigned int pin);
-#ifdef __cplusplus
-}
+#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#endif
-/* virtual pins for stm32wl_emulate_digitalWrite() / stm32wl_emulate_digitalRead() to recognize */
+/* virtual pins */
#define SX126X_CS 1000
#define SX126X_DIO1 1001
#define SX126X_RESET 1003
diff --git a/src/platform/stm32wl/layer.c b/src/platform/stm32wl/layer.c
deleted file mode 100644
index d6f073200b..0000000000
--- a/src/platform/stm32wl/layer.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "architecture.h"
-#include "stm32wlxx.h"
-#include "stm32wlxx_hal.h"
-#include
-
-void HardFault_Handler(void)
-{
- asm("bkpt");
-}
-
-void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value)
-{
- switch (pin) {
- case SX126X_CS: /* active low */
- if (value)
- LL_PWR_UnselectSUBGHZSPI_NSS();
- else
- LL_PWR_SelectSUBGHZSPI_NSS();
- break;
- case SX126X_RESET: /* active low */
- if (value)
- LL_RCC_RF_DisableReset();
- else {
- LL_RCC_RF_EnableReset();
- LL_RCC_HSE_EnableTcxo();
- LL_RCC_HSE_Enable();
- while (!LL_RCC_HSE_IsReady())
- ;
- }
- break;
- default:
- asm("bkpt");
- break;
- }
-}
-
-static bool irq_happened;
-
-void SUBGHZ_Radio_IRQHandler(void)
-{
- NVIC_DisableIRQ(SUBGHZ_Radio_IRQn);
- irq_happened = true;
-}
-
-int stm32wl_emulate_digitalRead(long unsigned int pin)
-{
- int outcome = 0;
-
- switch (pin) {
- case SX126X_BUSY:
- // return ((LL_PWR_IsActiveFlag_RFBUSYMS() & LL_PWR_IsActiveFlag_RFBUSYS()) == 1UL);
- outcome = LL_PWR_IsActiveFlag_RFBUSYS();
- break;
- case SX126X_DIO1:
- default:
- NVIC_ClearPendingIRQ(SUBGHZ_Radio_IRQn);
- irq_happened = false;
- NVIC_EnableIRQ(SUBGHZ_Radio_IRQn);
- for (int i = 0; i < 64; i++)
- asm("nop");
- outcome = irq_happened;
- break;
- }
- return outcome;
-}
diff --git a/src/platform/stm32wl/main-stm32wl.cpp b/src/platform/stm32wl/main-stm32wl.cpp
index 8ebcb029e4..f57928c60b 100644
--- a/src/platform/stm32wl/main-stm32wl.cpp
+++ b/src/platform/stm32wl/main-stm32wl.cpp
@@ -11,8 +11,18 @@ void updateBatteryLevel(uint8_t level) {}
void getMacAddr(uint8_t *dmac)
{
- for (int i = 0; i < 6; i++)
- dmac[i] = i;
+ // https://flit.github.io/2020/06/06/mcu-unique-id-survey.html
+ const uint32_t uid0 = HAL_GetUIDw0(); // X/Y coordinate on wafer
+ const uint32_t uid1 = HAL_GetUIDw1(); // [31:8] Lot number (23:0), [7:0] Wafer number
+ const uint32_t uid2 = HAL_GetUIDw2(); // Lot number (55:24)
+
+ // Need to go from 96-bit to 48-bit unique ID
+ dmac[5] = (uint8_t)uid0;
+ dmac[4] = (uint8_t)(uid0 >> 16);
+ dmac[3] = (uint8_t)uid1;
+ dmac[2] = (uint8_t)(uid1 >> 8);
+ dmac[1] = (uint8_t)uid2;
+ dmac[0] = (uint8_t)(uid2 >> 8);
}
void cpuDeepSleep(uint32_t msecToWake) {}
diff --git a/src/power.h b/src/power.h
index 6b787d320d..e90e3f21bf 100644
--- a/src/power.h
+++ b/src/power.h
@@ -1,7 +1,10 @@
#pragma once
#include "PowerStatus.h"
#include "concurrency/OSThread.h"
-
+#ifdef ARCH_ESP32
+#include
+#include
+#endif
/**
* Per @spattinson
* MIN_BAT_MILLIVOLTS seems high. Typical 18650 are different chemistry to LiPo, even for LiPos that chart seems a bit off, other
@@ -14,6 +17,17 @@
#define BAT_MILLIVOLTS_FULL 4100
#define BAT_MILLIVOLTS_EMPTY 3500
+#ifdef BAT_MEASURE_ADC_UNIT
+extern RTC_NOINIT_ATTR uint64_t RTC_reg_b;
+#include "soc/sens_reg.h" // needed for adc pin reset
+#endif
+
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
+#include "modules/Telemetry/Sensor/INA219Sensor.h"
+#include "modules/Telemetry/Sensor/INA260Sensor.h"
+extern INA260Sensor ina260Sensor;
+extern INA219Sensor ina219Sensor;
+#endif
class Power : private concurrency::OSThread
{
@@ -34,7 +48,6 @@ class Power : private concurrency::OSThread
/// Setup a xpowers chip axp192/axp2101, return true if found
bool axpChipInit();
-
/// Setup a simple ADC input based battery sensor
bool analogInit();
@@ -45,4 +58,4 @@ class Power : private concurrency::OSThread
#endif
};
-extern Power *power;
+extern Power *power;
\ No newline at end of file
diff --git a/src/shutdown.h b/src/shutdown.h
index b08478a1eb..ee63422dd7 100644
--- a/src/shutdown.h
+++ b/src/shutdown.h
@@ -26,8 +26,8 @@ void powerCommandsCheck()
if (shutdownAtMsec && millis() > shutdownAtMsec) {
LOG_INFO("Shutting down from admin command\n");
- playShutdownMelody();
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
+ playShutdownMelody();
power->shutdown();
#else
LOG_WARN("FIXME implement shutdown for this platform");
diff --git a/src/sleep.cpp b/src/sleep.cpp
index e612b00320..5331eaf759 100644
--- a/src/sleep.cpp
+++ b/src/sleep.cpp
@@ -103,13 +103,13 @@ void setGPSPower(bool on)
if (pmu_found && PMU) {
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
-#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
- // t-beam v1.2 GNSS power channel
- on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3);
-#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
- // t-beam-s3-core GNSS power channel
- on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
-#endif
+ if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
+ // t-beam v1.2 GNSS power channel
+ on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3);
+ } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
+ // t-beam-s3-core GNSS power channel
+ on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
+ }
} else if (model == XPOWERS_AXP192) {
// t-beam v1.1 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3);
@@ -132,6 +132,7 @@ void initDeepSleep()
support busted boards, assume button one was pressed wakeButtons = ((uint64_t)1) << buttons.gpios[0];
*/
+#ifdef DEBUG_PORT
// If we booted because our timer ran out or the user pressed reset, send those as fake events
const char *reason = "reset"; // our best guess
RESET_REASON hwReason = rtc_get_reset_reason(0);
@@ -150,6 +151,7 @@ void initDeepSleep()
LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason);
#endif
+#endif
}
bool doPreflightSleep()
@@ -250,12 +252,12 @@ void doDeepSleep(uint32_t msecToWake)
uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) {
-#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM)
- // t-beam v1.2 radio power channel
- PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
-#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
- PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
-#endif
+ if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
+ // t-beam v1.2 radio power channel
+ PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
+ } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
+ PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
+ }
} else if (model == XPOWERS_AXP192) {
// t-beam v1.1 radio power channel
PMU->disablePowerOutput(XPOWERS_LDO2); // lora radio power channel
@@ -329,23 +331,27 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq
#endif
auto res = esp_sleep_enable_gpio_wakeup();
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_DEBUG("esp_sleep_enable_gpio_wakeup result %d\n", res);
+ }
assert(res == ESP_OK);
res = esp_sleep_enable_timer_wakeup(sleepUsec);
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_DEBUG("esp_sleep_enable_timer_wakeup result %d\n", res);
+ }
assert(res == ESP_OK);
res = esp_light_sleep_start();
- if (res != ESP_OK)
+ if (res != ESP_OK) {
LOG_DEBUG("esp_light_sleep_start result %d\n", res);
+ }
assert(res == ESP_OK);
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
#ifdef BUTTON_PIN
- if (cause == ESP_SLEEP_WAKEUP_GPIO)
+ if (cause == ESP_SLEEP_WAKEUP_GPIO) {
LOG_INFO("Exit light sleep gpio: btn=%d\n",
!digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
+ }
#endif
return cause;
diff --git a/src/xmodem.h b/src/xmodem.h
index 848e926bdb..2ba0bb39f1 100644
--- a/src/xmodem.h
+++ b/src/xmodem.h
@@ -59,7 +59,7 @@ class XModemAdapter
uint16_t packetno = 0;
-#if defined(ARCH_NRF52)
+#if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
File file = File(FSCom);
#else
File file;
diff --git a/suppressions.txt b/suppressions.txt
index 0dd5198ecf..e2af9aeefa 100644
--- a/suppressions.txt
+++ b/suppressions.txt
@@ -36,6 +36,7 @@ cstyleCast
// ignore stuff that is not ours
*:.pio/*
*:*/libdeps/*
+*:*/generated/*
noExplicitConstructor:*/mqtt/*
postfixOperator:*/mqtt/*
@@ -44,3 +45,5 @@ missingOverride
virtualCallInConstructor
passedByValue:*/RedirectablePrint.h
+
+internalAstError:*/CrossPlatformCryptoEngine.cpp
diff --git a/variants/diy/dr-dev/variant.h b/variants/diy/dr-dev/variant.h
index 122a617b65..b9c82a9c86 100644
--- a/variants/diy/dr-dev/variant.h
+++ b/variants/diy/dr-dev/variant.h
@@ -2,6 +2,8 @@
#define HAS_SCREEN 0
#define I2C_SDA 4
#define I2C_SCL 5
+#define BATTERY_PIN 34
+#define ADC_CHANNEL ADC1_GPIO34_CHANNEL
// GPS
#undef GPS_RX_PIN
@@ -67,4 +69,4 @@
#define USE_SX1262
//#define USE_SX1268
//#define USE_LLCC68
-#define SX126X_E22
+#define SX126X_E22
\ No newline at end of file
diff --git a/variants/diy/v1/variant.h b/variants/diy/v1/variant.h
index da9e415535..a1083f9bb9 100644
--- a/variants/diy/v1/variant.h
+++ b/variants/diy/v1/variant.h
@@ -9,8 +9,9 @@
#define GPS_TX_PIN 15
#define GPS_UBLOX
-#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
-#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
+#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
#define EXT_PWR_DETECT 4 // Pin to detect connected external power source for LILYGO® TTGO T-Energy T18 and other DIY boards
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
@@ -38,9 +39,8 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
-//#define SX126X_RXEN 14
-//#define SX126X_TXEN 13
-#define SX126X_POWER_EN (13)
+#define SX126X_RXEN RADIOLIB_NC // Defining the RXEN ruins RFSwitching for the E22 900M30S in RadioLib
+#define SX126X_TXEN 13
// RX/TX for RFM95/SX127x
#define RF95_RXEN 14
@@ -53,4 +53,4 @@
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
// (which is the default for the sx1262interface code)
#define SX126X_E22
-#endif
+#endif
\ No newline at end of file
diff --git a/variants/heltec_v1/variant.h b/variants/heltec_v1/variant.h
index 948f6ff1e6..d1338a28e6 100644
--- a/variants/heltec_v1/variant.h
+++ b/variants/heltec_v1/variant.h
@@ -27,3 +27,5 @@
#define ADC_MULTIPLIER 3.2
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC2_GPIO13_CHANNEL
+#define BAT_MEASURE_ADC_UNIT 2
\ No newline at end of file
diff --git a/variants/heltec_v2.1/variant.h b/variants/heltec_v2.1/variant.h
index 39a0e677f6..e7cfd5b343 100644
--- a/variants/heltec_v2.1/variant.h
+++ b/variants/heltec_v2.1/variant.h
@@ -29,5 +29,6 @@
#define ADC_MULTIPLIER 3.8
-#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
-#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
+#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO37_CHANNEL
+#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
\ No newline at end of file
diff --git a/variants/heltec_v2/variant.h b/variants/heltec_v2/variant.h
index 59e0c76e69..5c183818b8 100644
--- a/variants/heltec_v2/variant.h
+++ b/variants/heltec_v2/variant.h
@@ -27,3 +27,5 @@
// ratio of voltage divider = 3.20 (R12=100k, R10=220k)
#define ADC_MULTIPLIER 3.2
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC2_GPIO13_CHANNEL
+#define BAT_MEASURE_ADC_UNIT 2
\ No newline at end of file
diff --git a/variants/heltec_v3/variant.h b/variants/heltec_v3/variant.h
index a2e8bde8eb..d9fc0b4c20 100644
--- a/variants/heltec_v3/variant.h
+++ b/variants/heltec_v3/variant.h
@@ -8,7 +8,9 @@
#define BUTTON_PIN 0
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
-#define ADC_MULTIPLIER 5.22
+#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
+#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
+#define ADC_MULTIPLIER 4.9
#define USE_SX1262
@@ -27,4 +29,4 @@
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
-#define SX126X_E22
+#define SX126X_E22
\ No newline at end of file
diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h
index 66415741b3..0ecc5bea7e 100644
--- a/variants/heltec_wsl_v3/variant.h
+++ b/variants/heltec_wsl_v3/variant.h
@@ -9,7 +9,9 @@
#define BUTTON_PIN 0
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
-#define ADC_MULTIPLIER 5.22
+#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
+#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
+#define ADC_MULTIPLIER 4.9
#define USE_SX1262
diff --git a/variants/nano-g1-explorer/variant.h b/variants/nano-g1-explorer/variant.h
index ad8957a511..fb3fc72d13 100644
--- a/variants/nano-g1-explorer/variant.h
+++ b/variants/nano-g1-explorer/variant.h
@@ -29,8 +29,9 @@
// code)
#endif
-#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
#define ADC_MULTIPLIER 2
-#define USE_SH1107_128_64
+#define USE_SH1107_128_64
\ No newline at end of file
diff --git a/variants/rak11310/pins_arduino.h b/variants/rak11310/pins_arduino.h
new file mode 100644
index 0000000000..626bed1da8
--- /dev/null
+++ b/variants/rak11310/pins_arduino.h
@@ -0,0 +1,68 @@
+#pragma once
+
+// Pin definitions taken from:
+// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
+
+static const uint8_t WB_IO1 = 6; // SLOT_A SLOT_B
+static const uint8_t WB_IO2 = 22; // SLOT_A SLOT_B
+static const uint8_t WB_IO3 = 7; // SLOT_C
+static const uint8_t WB_IO4 = 28; // SLOT_C
+static const uint8_t WB_IO5 = 9; // SLOT_D
+static const uint8_t WB_IO6 = 8; // SLOT_D
+static const uint8_t WB_A0 = 26; // IO_SLOT
+static const uint8_t WB_A1 = 27; // IO_SLOT
+
+#define PIN_A0 (26u)
+#define PIN_A1 (27u)
+#define PIN_A2 (28u)
+#define PIN_A3 (29u)
+
+static const uint8_t A0 = PIN_A0;
+static const uint8_t A1 = PIN_A1;
+static const uint8_t A2 = PIN_A2;
+static const uint8_t A3 = PIN_A3;
+
+// LEDs
+#define PIN_LED (23u)
+#define PIN_LED1 PIN_LED
+#define PIN_LED2 (24u)
+#define LED_BUILTIN PIN_LED
+
+#define ADC_RESOLUTION 12
+
+// Serial
+#define PIN_SERIAL1_TX (0ul)
+#define PIN_SERIAL1_RX (1ul)
+
+#define PIN_SERIAL2_TX (4ul)
+#define PIN_SERIAL2_RX (5ul)
+
+// SPI
+#define PIN_SPI0_MISO (12u)
+#define PIN_SPI0_MOSI (11u)
+#define PIN_SPI0_SCK (10u)
+#define PIN_SPI0_SS (13u)
+
+#define PIN_SPI1_MISO (16u)
+#define PIN_SPI1_MOSI (19u)
+#define PIN_SPI1_SCK (18u)
+#define PIN_SPI1_SS (17u)
+
+// Wire
+#define PIN_WIRE0_SDA (2u)
+#define PIN_WIRE0_SCL (3u)
+
+#define PIN_WIRE1_SDA (20u)
+#define PIN_WIRE1_SCL (21u)
+
+#define SERIAL_HOWMANY (3u)
+#define SPI_HOWMANY (2u)
+#define WIRE_HOWMANY (2u)
+
+static const uint8_t SS = PIN_SPI0_SS;
+static const uint8_t MOSI = PIN_SPI0_MOSI;
+static const uint8_t MISO = PIN_SPI0_MISO;
+static const uint8_t SCK = PIN_SPI0_SCK;
+
+static const uint8_t SDA = PIN_WIRE0_SDA;
+static const uint8_t SCL = PIN_WIRE0_SCL;
\ No newline at end of file
diff --git a/variants/rak11310/platformio.ini b/variants/rak11310/platformio.ini
new file mode 100644
index 0000000000..a69b18c1a3
--- /dev/null
+++ b/variants/rak11310/platformio.ini
@@ -0,0 +1,13 @@
+[env:rak11310]
+extends = rp2040_base
+board = wiscore_rak11300
+upload_protocol = picotool
+
+# add our variants files to the include and src paths
+build_flags = ${rp2040_base.build_flags}
+ -DRAK11310
+ -Ivariants/rak11310
+ -DDEBUG_RP2040_PORT=Serial
+ -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
+lib_deps =
+ ${rp2040_base.lib_deps}
\ No newline at end of file
diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h
new file mode 100644
index 0000000000..a2bef07304
--- /dev/null
+++ b/variants/rak11310/variant.h
@@ -0,0 +1,53 @@
+// #define RADIOLIB_CUSTOM_ARDUINO 1
+// #define RADIOLIB_TONE_UNSUPPORTED 1
+// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
+
+#define ARDUINO_ARCH_AVR
+
+#undef CBC
+#define CBC 0
+#undef CTR
+#define CTR 1
+#undef ECB
+#define ECB 0
+
+#undef GPS_SERIAL_NUM
+
+#define LED_CONN PIN_LED2
+
+#define BUTTON_PIN 9
+#define BUTTON_NEED_PULLUP
+// #define EXT_NOTIFY_OUT 4
+
+#define BATTERY_PIN 26
+// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
+#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
+
+#define USE_SX1262
+
+#undef RF95_SCK
+#undef RF95_MISO
+#undef RF95_MOSI
+#undef RF95_NSS
+
+// RAK BSP somehow uses SPI1 instead of SPI0
+#define HW_SPI1_DEVICE
+#define RF95_SCK PIN_SPI0_SCK
+#define RF95_MOSI PIN_SPI0_MOSI
+#define RF95_MISO PIN_SPI0_MISO
+#define RF95_NSS PIN_SPI0_SS
+
+#define LORA_DIO0 RADIOLIB_NC
+#define LORA_RESET 14
+#define LORA_DIO1 29
+#define LORA_DIO2 15
+#define LORA_DIO3 RADIOLIB_NC
+
+#ifdef USE_SX1262
+#define SX126X_CS RF95_NSS
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_DIO2
+#define SX126X_RESET LORA_RESET
+#define SX126X_POWER_EN 25
+#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
+#endif
\ No newline at end of file
diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h
index 69a77a0292..fe9f062c8e 100644
--- a/variants/rak4631/variant.h
+++ b/variants/rak4631/variant.h
@@ -258,6 +258,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define PIN_ETHERNET_RESET 21
#define PIN_ETHERNET_SS PIN_EINK_CS
#define ETH_SPI_PORT SPI1
+#define AQ_SET_PIN 10
#ifdef __cplusplus
}
@@ -267,4 +268,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
-#endif
+#endif
\ No newline at end of file
diff --git a/variants/rpipico/platformio.ini b/variants/rpipico/platformio.ini
index a169e8a9d2..727a1cab66 100644
--- a/variants/rpipico/platformio.ini
+++ b/variants/rpipico/platformio.ini
@@ -1,18 +1,14 @@
[env:pico]
extends = rp2040_base
board = rpipico
-board_level = extra
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
- -DPRIVATE_HW
+ -DRPI_PICO
-Ivariants/rpipico
- -DARDUINO_AVR_NANO_EVERY
- -DDEBUG_RP2040_WIRE
- -DDEBUG_RP2040_SPI
- -DDEBUG_RP2040_CORE
-DDEBUG_RP2040_PORT=Serial
- -DUSE_TINYUSB
+ -DHW_SPI1_DEVICE
+ -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
\ No newline at end of file
diff --git a/variants/rpipico/variant.h b/variants/rpipico/variant.h
index d620a356b4..7e2660aa69 100644
--- a/variants/rpipico/variant.h
+++ b/variants/rpipico/variant.h
@@ -4,8 +4,11 @@
#define ARDUINO_ARCH_AVR
+#undef CBC
#define CBC 0
+#undef CTR
#define CTR 1
+#undef ECB
#define ECB 0
#define NO_GPS 1
@@ -18,11 +21,12 @@
#define BUTTON_PIN 17
#define EXT_NOTIFY_OUT 4
+#define LED_PIN PIN_LED
+
#define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
-#define USE_RF95
#define USE_SX1262
#undef RF95_SCK
@@ -47,6 +51,4 @@
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
-#endif
-
-#include
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/variants/rpipicow/platformio.ini b/variants/rpipicow/platformio.ini
index 6e5c32a529..3228e4c241 100644
--- a/variants/rpipicow/platformio.ini
+++ b/variants/rpipicow/platformio.ini
@@ -6,13 +6,10 @@ upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
- -DPRIVATE_HW
+ -DRPI_PICO
-Ivariants/rpipicow
- -DARDUINO_AVR_NANO_EVERY
- -DDEBUG_RP2040_WIRE
- -DDEBUG_RP2040_SPI
- -DDEBUG_RP2040_CORE
-DDEBUG_RP2040_PORT=Serial
- -DUSE_TINYUSB
+ -DHW_SPI1_DEVICE
+ -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
\ No newline at end of file
diff --git a/variants/rpipicow/variant.h b/variants/rpipicow/variant.h
index d620a356b4..4741fd130d 100644
--- a/variants/rpipicow/variant.h
+++ b/variants/rpipicow/variant.h
@@ -4,8 +4,11 @@
#define ARDUINO_ARCH_AVR
+#undef CBC
#define CBC 0
+#undef CTR
#define CTR 1
+#undef ECB
#define ECB 0
#define NO_GPS 1
@@ -22,7 +25,6 @@
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
-#define USE_RF95
#define USE_SX1262
#undef RF95_SCK
@@ -47,6 +49,4 @@
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
-#endif
-
-#include
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/variants/station-g1/variant.h b/variants/station-g1/variant.h
index 4572d47a66..3439cb1254 100644
--- a/variants/station-g1/variant.h
+++ b/variants/station-g1/variant.h
@@ -32,7 +32,8 @@
// Info:https://uniteng.com/wiki/doku.php?id=meshtastic:station#rf_design_-_lora_station_edition_g1
#endif
-#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define BATTERY_SENSE_SAMPLES 30 // Set the number of samples, It has an effect of increasing sensitivity.
#define ADC_MULTIPLIER 6.45
#define BAT_FULLVOLT 12600
@@ -41,4 +42,4 @@
#define BAT_NOBATVOLT 6690
// different screen
-#define USE_SH1106
+#define USE_SH1106
\ No newline at end of file
diff --git a/variants/tbeam_v07/variant.h b/variants/tbeam_v07/variant.h
index 2c80086889..898705ce29 100644
--- a/variants/tbeam_v07/variant.h
+++ b/variants/tbeam_v07/variant.h
@@ -6,6 +6,7 @@
#define BUTTON_PIN 39
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h
index 768a7c2daf..313b08e6d3 100644
--- a/variants/tlora_t3s3_v1/variant.h
+++ b/variants/tlora_t3s3_v1/variant.h
@@ -9,6 +9,7 @@
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
+#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define I2C_SDA 18 // I2C pins for this board
#define I2C_SCL 17
diff --git a/variants/tlora_v1_3/variant.h b/variants/tlora_v1_3/variant.h
index 7e8aec0c41..50041f2961 100644
--- a/variants/tlora_v1_3/variant.h
+++ b/variants/tlora_v1_3/variant.h
@@ -4,6 +4,7 @@
#define GPS_TX_PIN 13 // per @eugene
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
diff --git a/variants/tlora_v2/variant.h b/variants/tlora_v2/variant.h
index f18503139f..b9b521771e 100644
--- a/variants/tlora_v2/variant.h
+++ b/variants/tlora_v2/variant.h
@@ -4,6 +4,7 @@
#define GPS_TX_PIN 13 // per @eugene
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
@@ -19,4 +20,4 @@
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 14
#define LORA_DIO1 33 // Must be manually wired: https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
-#define LORA_DIO2 32 // Not really used
+#define LORA_DIO2 32 // Not really used
\ No newline at end of file
diff --git a/variants/tlora_v2_1_16/variant.h b/variants/tlora_v2_1_16/variant.h
index 11c5921ba3..adb5af898c 100644
--- a/variants/tlora_v2_1_16/variant.h
+++ b/variants/tlora_v2_1_16/variant.h
@@ -3,9 +3,12 @@
#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
#define GPS_TX_PIN 13
-#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+#define BATTERY_PIN 35
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
+#define BATTERY_SENSE_SAMPLES 30
+
// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
-#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
+#define ADC_MULTIPLIER 2
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
@@ -19,4 +22,4 @@
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33 // https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
-#define LORA_DIO2 32 // Not really used
+#define LORA_DIO2 32 // Not really used
\ No newline at end of file
diff --git a/variants/tlora_v2_1_18/variant.h b/variants/tlora_v2_1_18/variant.h
index 0262f01223..e8f0a9659d 100644
--- a/variants/tlora_v2_1_18/variant.h
+++ b/variants/tlora_v2_1_18/variant.h
@@ -4,6 +4,7 @@
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
+#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define I2C_SDA 21 // I2C pins for this board
#define I2C_SCL 22
diff --git a/variants/wio-e5/platformio.ini b/variants/wio-e5/platformio.ini
index 32436dae8a..07f6efa6df 100644
--- a/variants/wio-e5/platformio.ini
+++ b/variants/wio-e5/platformio.ini
@@ -1,5 +1,11 @@
[env:wio-e5]
extends = stm32wl5e_base
board_level = extra
-build_flags = ${stm32wl5e_base.build_flags} -Ivariants/wio-e5 -DHAL_DAC_MODULE_ONLY
- -DSERIAL_UART_INSTANCE=1 -DPIN_SERIAL_RX=PB7 -DPIN_SERIAL_TX=PB6
+build_flags =
+ ${stm32wl5e_base.build_flags}
+ -Ivariants/wio-e5
+ -DHAL_DAC_MODULE_ONLY
+ -DSERIAL_UART_INSTANCE=1
+ -DPIN_SERIAL_RX=PB7
+ -DPIN_SERIAL_TX=PB6
+upload_port = stlink
\ No newline at end of file
diff --git a/variants/wio-e5/variant.h b/variants/wio-e5/variant.h
index b1f7556b4b..86e58bcb2e 100644
--- a/variants/wio-e5/variant.h
+++ b/variants/wio-e5/variant.h
@@ -12,18 +12,6 @@ Do not expect a working Meshtastic device with this target.
#ifndef _VARIANT_WIOE5_
#define _VARIANT_WIOE5_
-// Arduino/PlatformIO support for SUBGHZSPI is not currently available
-//#define USE_SX1262
-
-#ifdef USE_SX1262
-#define HAS_RADIO 1
-
-/* module only transmits through RFO_HP */
-#define SX126X_RXEN PA5
-#define SX126X_TXEN PA4
-
-/* TCXO fed by internal LDO option behind PB0 pin */
-#define SX126X_E22
-#endif
+#define USE_STM32WLx
#endif
\ No newline at end of file
diff --git a/version.properties b/version.properties
index 0e33ac38b8..c3cd821a8d 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 1
-build = 12
+build = 16