Merge branch 'master' into apollo

This commit is contained in:
Thomas Göttgens
2023-06-12 15:33:20 +02:00
committed by GitHub
139 changed files with 2758 additions and 756 deletions

View File

@@ -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

View File

@@ -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".

View File

@@ -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

1
.gitignore vendored
View File

@@ -30,3 +30,4 @@ __pycache__
venv/
release/
.vscode/extensions.json
/compile_commands.json

View File

@@ -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} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<platform/apollo3> -<mesh/eth/>

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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} -<platform/esp32/> -<platform/apollo3> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
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
https://github.com/mathertel/OneButton#2.1.0

View File

@@ -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"

View File

@@ -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"
}

View File

@@ -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,10 +21,11 @@ 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
@@ -60,7 +61,7 @@ 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/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
@@ -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

View File

@@ -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);
}

View File

@@ -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__)

View File

@@ -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))

View File

@@ -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();

View File

@@ -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;

View File

@@ -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
#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,7 +652,7 @@ 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)
if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
// Unuse power channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
PMU->disablePowerOutput(XPOWERS_DCDC3);
@@ -569,12 +681,12 @@ bool Power::axpChipInit()
// GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE)
} 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
* 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);
@@ -613,8 +725,7 @@ bool Power::axpChipInit()
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
}
// disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);

View File

@@ -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");

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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,9 +66,10 @@ 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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -12,7 +12,7 @@
#include <freertos/task.h>
#endif
#if defined(ARDUINO_NRF52_ADAFRUIT)
#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32)
#define HAS_FREE_RTOS
#include <FreeRTOS.h>

View File

@@ -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);

View File

@@ -3,5 +3,5 @@
#include "main.h"
#include <Arduino.h>
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);

View File

@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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

View File

@@ -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;
}

View File

@@ -10,6 +10,9 @@ template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>;
template class SX128xInterface<SX1280>;
#ifdef ARCH_STM32WL
template class SX126xInterface<STM32WLx>;
#endif
#if HAS_ETHERNET
#include "api/ethServerAPI.h"

View File

@@ -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()

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.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,15 +798,15 @@ 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

View File

@@ -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 + \

View File

@@ -41,8 +41,7 @@ void PhoneAPI::handleStartConfig()
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
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;
}

View File

@@ -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();

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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

View File

@@ -104,14 +104,15 @@ 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
PacketId ackId = ((c && c->error_reason == meshtastic_Routing_Error_NONE) || !c) ? p->decoded.request_id : 0;

View File

@@ -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);
}

View File

@@ -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

View File

@@ -0,0 +1,31 @@
#pragma once
#include "SX126xInterface.h"
#ifdef ARCH_STM32WL
/**
* Our adapter for STM32WLE5JC radios
*/
class STM32WLE5JCInterface : public SX126xInterface<STM32WLx>
{
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

View File

@@ -60,16 +60,19 @@ template <typename T> bool SX126xInterface<T>::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 <typename T> void SX126xInterface<T>::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);

View File

@@ -151,8 +151,9 @@ template <typename T> void SX128xInterface<T>::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);

View File

@@ -74,7 +74,7 @@ template <class T> 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

View File

@@ -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;

View File

@@ -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)

View File

@@ -6,9 +6,10 @@
#include <pb.h>
#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" */

View File

@@ -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 */
@@ -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 {
@@ -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

View File

@@ -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)

File diff suppressed because one or more lines are too long

View File

@@ -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" */

View File

@@ -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

View File

@@ -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)

View File

@@ -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 */
@@ -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" */

View File

@@ -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

View File

@@ -26,15 +26,18 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>
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
*/

View File

@@ -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 <NonBlockingRtttl.h>
#else
// Noop class for portduino.

View File

@@ -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();

View File

@@ -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;

View File

@@ -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 <Arduino.h>
#include <FSCommon.h>
/*
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");
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();
}
// 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;
}

View File

@@ -9,6 +9,7 @@
class RangeTestModule : private concurrency::OSThread
{
bool firstTime = 1;
unsigned long started = 0;
public:
RangeTestModule();

View File

@@ -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:

View File

@@ -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");

View File

@@ -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;
uint32_t baud = getBaudRate();
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;
} 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);
}
#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);
Serial2.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);
}
#else
if (moduleConfig.serial.rxd && moduleConfig.serial.txd)
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
Serial2.begin(baud, SERIAL_8N1);
Serial.begin(baud, SERIAL_8N1);
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
#endif
if (moduleConfig.serial.timeout) {
Serial2.setTimeout(moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string.
} else {
Serial2.setTimeout(TIMEOUT); // Number of MS to wait to set the timeout for the string.
}
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

View File

@@ -8,8 +8,7 @@
#include <Arduino.h>
#include <functional>
#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;

View File

@@ -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);

View File

@@ -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",

View File

@@ -7,6 +7,7 @@
#include "Router.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
@@ -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,26 +215,27 @@ 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);
valid = ina260Sensor.getMetrics(&m);
LOG_INFO(
"(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
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);
@@ -260,5 +261,6 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
LOG_INFO("Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
return true;
}
return valid;
}

View File

@@ -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;
};

View File

@@ -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);
@@ -105,3 +127,16 @@ void BME680Sensor::updateState()
LOG_ERROR("ERROR: Filesystem not implemented\n");
#endif
}
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());
}

View File

@@ -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,10 +17,7 @@ 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,
bsecSensor sensorList[9] = {BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
@@ -28,13 +25,14 @@ class BME680Sensor : virtual public TelemetrySensor
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};
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;
};

View File

@@ -12,8 +12,12 @@ int32_t INA219Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!ina219.success()) {
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
status = ina219.begin();
} else {
status = ina219.success();
}
return initI2CSensor();
}
@@ -25,3 +29,8 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
}
uint16_t INA219Sensor::getBusVoltageMv()
{
return lround(ina219.getBusVoltage_V() * 1000);
}

View File

@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
#include <Adafruit_INA219.h>
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;
};

View File

@@ -12,7 +12,10 @@ int32_t INA260Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
}
return initI2CSensor();
}
@@ -25,3 +28,8 @@ bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
}
uint16_t INA260Sensor::getBusVoltageMv()
{
return lround(ina260.readBusVoltage());
}

View File

@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
#include <Adafruit_INA260.h>
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;
};

View File

@@ -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;
};

View File

@@ -0,0 +1,7 @@
#pragma once
class VoltageSensor
{
public:
virtual uint16_t getBusVoltageMv() = 0;
};

View File

@@ -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};

View File

@@ -0,0 +1,3 @@
#include <stdint.h>
extern const uint8_t bsec_config_iaq[1974];

View File

@@ -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.

View File

@@ -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()

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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 <EEPROM.h>
//--------------------------------------------------------------------+
// 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;
}

View File

@@ -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_ */

View File

@@ -0,0 +1,258 @@
#include <Arduino.h>
#include <string.h>
#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

Some files were not shown because too many files have changed in this diff Show More