Merge branch 'master' into raspi-portduino

This commit is contained in:
Thomas Göttgens
2023-06-27 18:13:24 +02:00
committed by GitHub
co-authored by GitHub
110 changed files with 2607 additions and 734 deletions
+2
View File
@@ -40,10 +40,12 @@ body:
- T-Echo - T-Echo
- Rak4631 - Rak4631
- Rak11200 - Rak11200
- Rak11310
- Heltec v1 - Heltec v1
- Heltec v2 - Heltec v2
- Heltec v2.1 - Heltec v2.1
- Heltec V3 - Heltec V3
- Raspberry Pi Pico (W)
- Relay v1 - Relay v1
- Relay v2 - Relay v2
- DIY - DIY
+3 -2
View File
@@ -7,7 +7,8 @@
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... 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 check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on - 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, - 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 automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines. 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 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. - If your other co-developers have comments on your PR please tweak as needed.
- Please also enable "Allow edits by maintainers".
+17 -12
View File
@@ -33,6 +33,7 @@ jobs:
- board: m5stack-coreink - board: m5stack-coreink
- board: tbeam-s3-core - board: tbeam-s3-core
- board: tlora-t3s3-v1 - board: tlora-t3s3-v1
#- board: rak11310
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -103,16 +104,17 @@ jobs:
with: with:
board: ${{ matrix.board }} board: ${{ matrix.board }}
# build-rpi2040: build-rpi2040:
# strategy: strategy:
# fail-fast: false fail-fast: false
# max-parallel: 2 max-parallel: 2
# matrix: matrix:
# include: include:
# - board: pico - board: pico
# uses: ./.github/workflows/build_rpi2040.yml - board: rak11310
# with: uses: ./.github/workflows/build_rpi2040.yml
# board: ${{ matrix.board }} with:
board: ${{ matrix.board }}
build-native: build-native:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -148,12 +150,14 @@ jobs:
release/device-*.bat release/device-*.bat
- name: Docker login - name: Docker login
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:
username: meshtastic username: meshtastic
password: ${{ secrets.DOCKER_TOKEN }} password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker setup - name: Docker setup
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v2
- name: Docker build and push tagged versions - name: Docker build and push tagged versions
@@ -166,7 +170,7 @@ jobs:
tags: meshtastic/device-simulator:${{ steps.version.outputs.version }} tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
- name: Docker build and push - name: Docker build and push
if: github.ref == 'refs/heads/master' if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
@@ -186,7 +190,8 @@ jobs:
gather-artifacts: gather-artifacts:
runs-on: ubuntu-latest 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: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
+1
View File
@@ -30,3 +30,4 @@ __pycache__
venv/ venv/
release/ release/
.vscode/extensions.json .vscode/extensions.json
/compile_commands.json
+1 -1
View File
@@ -37,7 +37,7 @@ lib_deps =
${environmental_base.lib_deps} ${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.0 h2zero/NimBLE-Arduino@^1.4.0
jgromes/RadioLib@^6.0.0 jgromes/RadioLib@^6.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
+1 -2
View File
@@ -13,8 +13,7 @@ build_src_filter =
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
jgromes/RadioLib@^6.0.0 jgromes/RadioLib@^6.1.0
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
+1 -1
View File
@@ -22,7 +22,7 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
jgromes/RadioLib@^6.0.0 jgromes/RadioLib@6.1.0
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
+3 -2
View File
@@ -1,7 +1,8 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2040_base] [rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9f8c10e50b5acd18e7bfd32638199c655be73a5b platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
extends = arduino_base extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -19,5 +20,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
jgromes/RadioLib@^6.0.0 jgromes/RadioLib@^6.1.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
+12 -3
View File
@@ -1,20 +1,29 @@
[stm32wl5e_base] [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 board = generic_wl5e
framework = arduino framework = arduino
build_type = debug build_type = debug
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
-Isrc/platform/stm32wl -g -Isrc/platform/stm32wl -g
-DconfigUSE_CMSIS_RTOS_V2=1
-DVECT_TAB_OFFSET=0x08000000
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
board_upload.offset_address = 0x08000000
upload_protocol = stlink
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
jgromes/RadioLib@^6.0.0 jgromes/RadioLib@^6.1.0
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b 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 = lib_ignore =
https://github.com/mathertel/OneButton#2.1.0 https://github.com/mathertel/OneButton#2.1.0
+1 -1
View File
@@ -20,7 +20,7 @@
"maximum_ram_size": 65536, "maximum_ram_size": 65536,
"maximum_size": 262144, "maximum_size": 262144,
"protocol": "cmsis-dap", "protocol": "cmsis-dap",
"protocols": ["cmsis-dap"] "protocols": ["cmsis-dap", "stlink"]
}, },
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html", "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST" "vendor": "ST"
+40
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"
}
+9 -2
View File
@@ -2,7 +2,7 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[platformio] [platformio]
default_envs = tbeam ;default_envs = tbeam
;default_envs = pico ;default_envs = pico
;default_envs = tbeam-s3-core ;default_envs = tbeam-s3-core
;default_envs = tbeam0.7 ;default_envs = tbeam0.7
@@ -25,6 +25,7 @@ default_envs = tbeam
;default_envs = meshtastic-dr-dev ;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink ;default_envs = m5stack-coreink
;default_envs = rak4631 ;default_envs = rak4631
default_envs = wio-e5
extra_configs = extra_configs =
arch/*/*.ini arch/*/*.ini
@@ -55,6 +56,12 @@ build_flags = -Wno-missing-field-initializers
-DRADIOLIB_EXCLUDE_MORSE -DRADIOLIB_EXCLUDE_MORSE
-DRADIOLIB_EXCLUDE_RTTY -DRADIOLIB_EXCLUDE_RTTY
-DRADIOLIB_EXCLUDE_SSTV -DRADIOLIB_EXCLUDE_SSTV
-DRADIOLIB_EXCLUDE_AX25
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
-DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_PAGER
-DRADIOLIB_EXCLUDE_FSK4
-DRADIOLIB_EXCLUDE_APRS
monitor_speed = 115200 monitor_speed = 115200
@@ -102,7 +109,7 @@ lib_deps =
adafruit/Adafruit Unified Sensor@^1.1.9 adafruit/Adafruit Unified Sensor@^1.1.9
adafruit/Adafruit BMP280 Library@^2.6.6 adafruit/Adafruit BMP280 Library@^2.6.6
adafruit/Adafruit BME280 Library@^2.2.2 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 boschsensortec/BME68x Sensor Library@^1.1.40407
adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA260 Library@^1.5.0
+2 -2
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); pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif #endif
userButton.attachClick(userButtonPressed); userButton.attachClick(userButtonPressed);
userButton.setClickTicks(300); userButton.setClickMs(300);
userButton.attachDuringLongPress(userButtonPressedLong); userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed); userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed); userButton.attachMultiClick(userButtonMultiPressed);
@@ -157,7 +157,7 @@ class ButtonThread : public concurrency::OSThread
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW); digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif #endif
screen->print("Sent ad-hoc ping\n"); screen->print("Sent ad-hoc ping\n");
service.refreshMyNodeInfo(); service.refreshLocalMeshNode();
service.sendNetworkPing(NODENUM_BROADCAST, true); service.sendNetworkPing(NODENUM_BROADCAST, true);
} }
+1 -1
View File
@@ -57,7 +57,7 @@ bool renameFile(const char *pathFrom, const char *pathTo)
#endif #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 #ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) #if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
+8 -1
View File
@@ -13,6 +13,13 @@
#define FILE_O_READ "r" #define FILE_O_READ "r"
#endif #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) #if defined(ARCH_RP2040)
// RP2040 // RP2040
#include "LittleFS.h" #include "LittleFS.h"
@@ -42,6 +49,6 @@ using namespace Adafruit_LittleFS_Namespace;
void fsInit(); void fsInit();
bool copyFile(const char *from, const char *to); bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo); 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 rmDir(const char *dirname);
void setupSDCard(); void setupSDCard();
+3 -3
View File
@@ -55,7 +55,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n"); LOG_WARN("Using fixed latitude\n");
#endif #endif
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.latitude_i; return node->position.latitude_i;
} else { } else {
return p.latitude_i; return p.latitude_i;
@@ -68,7 +68,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n"); LOG_WARN("Using fixed longitude\n");
#endif #endif
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.longitude_i; return node->position.longitude_i;
} else { } else {
return p.longitude_i; return p.longitude_i;
@@ -81,7 +81,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n"); LOG_WARN("Using fixed altitude\n");
#endif #endif
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
return node->position.altitude; return node->position.altitude;
} else { } else {
return p.altitude; return p.altitude;
+116 -70
View File
@@ -6,7 +6,6 @@
#include "main.h" #include "main.h"
#include "sleep.h" #include "sleep.h"
#include "utils.h" #include "utils.h"
static const char *TAG = "ADCmod";
#ifdef DEBUG_HEAP_MQTT #ifdef DEBUG_HEAP_MQTT
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
@@ -31,16 +30,25 @@ RTC_NOINIT_ATTR uint64_t RTC_reg_b;
#endif // BAT_MEASURE_ADC_UNIT #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)); 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; 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 #endif // BATTERY_PIN && ARCH_ESP32
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
#endif
#ifdef HAS_PMU #ifdef HAS_PMU
#include "XPowersAXP192.tpp" #include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp" #include "XPowersAXP2101.tpp"
#include "XPowersLibInterface.hpp" #include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL; XPowersLibInterface *PMU = NULL;
#else #else
// Copy of the base class defined in axp20x.h. // Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency. // I'd rather not inlude axp20x.h as it brings Wire dependency.
class HasBatteryLevel class HasBatteryLevel
@@ -126,6 +134,13 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override 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 #ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2.0 #define ADC_MULTIPLIER 2.0
#endif #endif
@@ -244,6 +259,35 @@ class AnalogBatteryLevel : public HasBatteryLevel
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT; const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
float last_read_value = 0.0; float last_read_value = 0.0;
uint32_t last_read_time_ms = 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; AnalogBatteryLevel analogLevel;
@@ -292,12 +336,16 @@ bool Power::analogInit()
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs); esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
// show ADC characterization base // show ADC characterization base
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
ESP_LOGI(TAG, "ADC characterization based on Two Point values stored in eFuse"); LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse\n");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
ESP_LOGI(TAG, "ADC characterization based on reference voltage stored in eFuse"); LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse\n");
} else { } else {
ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); 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 #endif // ARCH_ESP32
#ifdef ARCH_NRF52 #ifdef ARCH_NRF52
@@ -604,82 +652,80 @@ bool Power::axpChipInit()
} else if (PMU->getChipModel() == XPOWERS_AXP2101) { } 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*/ /*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 // Unuse power channel
PMU->disablePowerOutput(XPOWERS_DCDC2); PMU->disablePowerOutput(XPOWERS_DCDC2);
PMU->disablePowerOutput(XPOWERS_DCDC3); PMU->disablePowerOutput(XPOWERS_DCDC3);
PMU->disablePowerOutput(XPOWERS_DCDC4); PMU->disablePowerOutput(XPOWERS_DCDC4);
PMU->disablePowerOutput(XPOWERS_DCDC5); PMU->disablePowerOutput(XPOWERS_DCDC5);
PMU->disablePowerOutput(XPOWERS_ALDO1); PMU->disablePowerOutput(XPOWERS_ALDO1);
PMU->disablePowerOutput(XPOWERS_ALDO4); PMU->disablePowerOutput(XPOWERS_ALDO4);
PMU->disablePowerOutput(XPOWERS_BLDO1); PMU->disablePowerOutput(XPOWERS_BLDO1);
PMU->disablePowerOutput(XPOWERS_BLDO2); PMU->disablePowerOutput(XPOWERS_BLDO2);
PMU->disablePowerOutput(XPOWERS_DLDO1); PMU->disablePowerOutput(XPOWERS_DLDO1);
PMU->disablePowerOutput(XPOWERS_DLDO2); PMU->disablePowerOutput(XPOWERS_DLDO2);
// GNSS RTC PowerVDD 3300mV // GNSS RTC PowerVDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
PMU->enablePowerOutput(XPOWERS_VBACKUP); PMU->enablePowerOutput(XPOWERS_VBACKUP);
// ESP32 VDD 3300mV // ESP32 VDD 3300mV
// ! No need to set, automatically open , Don't close it // ! No need to set, automatically open , Don't close it
// PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); // PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// PMU->setProtectedChannel(XPOWERS_DCDC1); // PMU->setProtectedChannel(XPOWERS_DCDC1);
// LoRa VDD 3300mV // LoRa VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2); PMU->enablePowerOutput(XPOWERS_ALDO2);
// GNSS VDD 3300mV // GNSS VDD 3300mV
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3); PMU->enablePowerOutput(XPOWERS_ALDO3);
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
// t-beam s3 core
/**
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during
* initialization
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO4);
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) // lora radio power channel
// t-beam s3 core PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
/** PMU->enablePowerOutput(XPOWERS_ALDO3);
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during
* initialization
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO4);
// lora radio power channel // m.2 interface
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3); PMU->enablePowerOutput(XPOWERS_DCDC3);
// m.2 interface /**
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); * ALDO2 cannot be turned off.
PMU->enablePowerOutput(XPOWERS_DCDC3); * It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
/** // 6-axis , magnetometer ,bme280 , oled screen power channel
* ALDO2 cannot be turned off. PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
* It is a necessary condition for sensor communication. PMU->enablePowerOutput(XPOWERS_ALDO1);
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
// 6-axis , magnetometer ,bme280 , oled screen power channel // sdcard power channle
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1); PMU->enablePowerOutput(XPOWERS_BLDO1);
// sdcard power channle // PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); // PMU->enablePowerOutput(XPOWERS_DCDC4);
PMU->enablePowerOutput(XPOWERS_BLDO1);
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300); // not use channel
// PMU->enablePowerOutput(XPOWERS_DCDC4); PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
// not use channel PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited PMU->disablePowerOutput(XPOWERS_VBACKUP);
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 // disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
+7 -7
View File
@@ -35,7 +35,7 @@ static bool isPowered()
static void sdsEnter() 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 // FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs)); doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs));
} }
@@ -44,7 +44,7 @@ extern Power *power;
static void shutdownEnter() static void shutdownEnter()
{ {
LOG_INFO("Enter state: SHUTDOWN\n"); LOG_DEBUG("Enter state: SHUTDOWN\n");
power->shutdown(); power->shutdown();
} }
@@ -135,7 +135,7 @@ static void lsExit()
static void nbEnter() static void nbEnter()
{ {
LOG_INFO("Enter state: NB\n"); LOG_DEBUG("Enter state: NB\n");
screen->setOn(false); screen->setOn(false);
setBluetoothEnable(false); setBluetoothEnable(false);
@@ -150,7 +150,7 @@ static void darkEnter()
static void serialEnter() static void serialEnter()
{ {
LOG_INFO("Enter state: SERIAL\n"); LOG_DEBUG("Enter state: SERIAL\n");
setBluetoothEnable(false); setBluetoothEnable(false);
screen->setOn(true); screen->setOn(true);
screen->print("Serial connected\n"); screen->print("Serial connected\n");
@@ -163,7 +163,7 @@ static void serialExit()
static void powerEnter() static void powerEnter()
{ {
LOG_INFO("Enter state: POWER\n"); LOG_DEBUG("Enter state: POWER\n");
if (!isPowered()) { if (!isPowered()) {
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things // 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"); LOG_INFO("Loss of power in Powered\n");
@@ -198,7 +198,7 @@ static void powerExit()
static void onEnter() static void onEnter()
{ {
LOG_INFO("Enter state: ON\n"); LOG_DEBUG("Enter state: ON\n");
screen->setOn(true); screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
} }
@@ -218,7 +218,7 @@ static void screenPress()
static void bootEnter() static void bootEnter()
{ {
LOG_INFO("Enter state: BOOT\n"); LOG_DEBUG("Enter state: BOOT\n");
} }
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN"); State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
+3
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, ...) 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; size_t r = 0;
if (!inDebugPrint) { if (!inDebugPrint) {
+1 -1
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 // setDestination(&noopPrint); for testing, try turning off 'all' debug output and see what leaks
Port.begin(SERIAL_BAUD); 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(); time_t timeout = millis();
while (!Port) { while (!Port) {
if ((millis() - timeout) < 5000) { if ((millis() - timeout) < 5000) {
+12 -17
View File
@@ -6,20 +6,22 @@ AirTime *airTime = NULL;
// Don't read out of this directly. Use the helper functions. // 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) void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{ {
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms); LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + 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; this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms); LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + 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) { } else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms); LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + 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[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i]; this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i]; air_period_tx[i + 1] = this->airtimes.periodTX[i];
myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i]; air_period_rx[i + 1] = this->airtimes.periodRX[i];
} }
this->airtimes.periodTX[0] = 0; this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0; this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0; this->airtimes.periodRX_ALL[0] = 0;
myNodeInfo.air_period_tx[0] = 0; air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0; air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = this->currentPeriodIndex(); this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
} }
@@ -179,18 +181,17 @@ int32_t AirTime::runOnce()
} }
// Init airtime windows to all 0 // 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.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0; this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0; this->airtimes.periodRX_ALL[i] = 0;
// myNodeInfo.air_period_tx[i] = 0; // air_period_tx[i] = 0;
// myNodeInfo.air_period_rx[i] = 0; // air_period_rx[i] = 0;
} }
firstTime = false; firstTime = false;
lastUtilPeriod = utilPeriod; lastUtilPeriod = utilPeriod;
} else { } else {
this->airtimeRotatePeriod(); this->airtimeRotatePeriod();
@@ -206,12 +207,6 @@ int32_t AirTime::runOnce()
this->utilizationTX[utilPeriodTX] = 0; 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()); LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
+1 -1
View File
@@ -291,7 +291,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
{ {
if (address.port == ScanI2C::I2CPort::WIRE1) { if (address.port == ScanI2C::I2CPort::WIRE) {
return &Wire; return &Wire;
} else { } else {
#ifdef I2C_SDA1 #ifdef I2C_SDA1
+1 -1
View File
@@ -12,7 +12,7 @@
#include <freertos/task.h> #include <freertos/task.h>
#endif #endif
#if defined(ARDUINO_NRF52_ADAFRUIT) #if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_RP2040)
#define HAS_FREE_RTOS #define HAS_FREE_RTOS
#include <FreeRTOS.h> #include <FreeRTOS.h>
+18 -2
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_PositionLite &pos, const char *name, bool isCaltopoMode)
{ {
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); 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(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(), name); geoCoord.getDMSLonCP(), name);
@@ -33,6 +34,21 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
return len; return len;
} }
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);
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);
uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i];
}
len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
return len;
}
/* ------------------------------------------- /* -------------------------------------------
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
* | | | | | | | | | | | | | | | * | | | | | | | | | | | | | | |
+2 -1
View File
@@ -3,5 +3,6 @@
#include "main.h" #include "main.h"
#include <Arduino.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 printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, const char *name, bool isCaltopoMode = false);
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos); uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
+7
View File
@@ -0,0 +1,7 @@
#include "main.h"
#ifdef RAK4630
#include <NCP5623.h>
extern NCP5623 rgb;
#endif
+21 -26
View File
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "GPS.h" #include "GPS.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "error.h"
#include "gps/GeoCoord.h" #include "gps/GeoCoord.h"
#include "gps/RTC.h" #include "gps/RTC.h"
#include "graphics/images.h" #include "graphics/images.h"
@@ -352,7 +353,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->setFont(FONT_MEDIUM); display->setFont(FONT_MEDIUM);
char tempBuf[24]; 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->drawString(0 + x, 0 + y, tempBuf);
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
@@ -372,7 +373,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
static char tempBuf[237]; static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_text_message; meshtastic_MeshPacket &mp = devicestate.rx_text_message;
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp)); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from, // LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes); // mp.decoded.variant.data.decoded.bytes);
@@ -410,7 +411,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i
static char tempBuf[237]; static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_waypoint; meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp)); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
@@ -711,13 +712,6 @@ static float estimatedHeading(double lat, double lon)
return b; 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) static uint16_t getCompassDiam(OLEDDisplay *display)
{ {
uint16_t diam = 0; uint16_t diam = 0;
@@ -799,16 +793,16 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (state->currentFrame != prevFrame) { if (state->currentFrame != prevFrame) {
prevFrame = state->currentFrame; prevFrame = state->currentFrame;
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes(); nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex); meshtastic_NodeInfoLite *n = nodeDB.getMeshNodeByIndex(nodeIndex);
if (n->num == nodeDB.getNodeNum()) { if (n->num == nodeDB.getNodeNum()) {
// Don't show our node, just skip to next // Don't show our node, just skip to next
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes(); nodeIndex = (nodeIndex + 1) % nodeDB.getNumMeshNodes();
n = nodeDB.getNodeByIndex(nodeIndex); n = nodeDB.getMeshNodeByIndex(nodeIndex);
} }
} }
meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex); meshtastic_NodeInfoLite *node = nodeDB.getMeshNodeByIndex(nodeIndex);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
@@ -842,7 +836,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
static char distStr[20]; static char distStr[20];
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL}; const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0; int16_t compassX = 0, compassY = 0;
@@ -856,15 +850,15 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
} }
bool hasNodeHeading = false; bool hasNodeHeading = false;
if (ourNode && hasPosition(ourNode)) { if (ourNode && hasValidPosition(ourNode)) {
meshtastic_Position &op = ourNode->position; meshtastic_PositionLite &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading); drawCompassNorth(display, compassX, compassY, myHeading);
if (hasPosition(node)) { if (hasValidPosition(node)) {
// display direction toward node // display direction toward node
hasNodeHeading = true; hasNodeHeading = true;
meshtastic_Position &p = node->position; meshtastic_PositionLite &p = node->position;
float d = float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i)); GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
@@ -892,7 +886,8 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (!hasNodeHeading) { if (!hasNodeHeading) {
// direction to node is unknown so display question mark // direction to node is unknown so display question mark
// Debug info for gps lock errors // 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->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
} }
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2); display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
@@ -1245,9 +1240,9 @@ void Screen::setFrames()
#endif #endif
// We don't show the node info our our node (if we have it yet - we should) // We don't show the node info our our node (if we have it yet - we should)
size_t numnodes = nodeDB.getNumNodes(); size_t numMeshNodes = nodeDB.getNumMeshNodes();
if (numnodes > 0) if (numMeshNodes > 0)
numnodes--; numMeshNodes--;
size_t numframes = 0; size_t numframes = 0;
@@ -1264,7 +1259,7 @@ void Screen::setFrames()
LOG_DEBUG("Added modules. numframes: %d\n", numframes); LOG_DEBUG("Added modules. numframes: %d\n", numframes);
// If we have a critical fault, show it first // If we have a critical fault, show it first
if (myNodeInfo.error_code) if (error_code)
normalFrames[numframes++] = drawCriticalFaultFrame; 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 // If we have a text message - show it next, unless it's a phone message and we aren't using any special modules
@@ -1278,7 +1273,7 @@ void Screen::setFrames()
// then all the nodes // then all the nodes
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens // We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
size_t numToShow = min(numnodes, 4U); size_t numToShow = min(numMeshNodes, 4U);
for (size_t i = 0; i < numToShow; i++) for (size_t i = 0; i < numToShow; i++)
normalFrames[numframes++] = drawNodeInfo; normalFrames[numframes++] = drawNodeInfo;
+59 -13
View File
@@ -19,6 +19,7 @@
#include "detect/ScanI2CTwoWire.h" #include "detect/ScanI2CTwoWire.h"
#include "detect/axpDebug.h" #include "detect/axpDebug.h"
#include "detect/einkScan.h" #include "detect/einkScan.h"
#include "graphics/RAKled.h"
#include "graphics/Screen.h" #include "graphics/Screen.h"
#include "main.h" #include "main.h"
#include "mesh/generated/meshtastic/config.pb.h" #include "mesh/generated/meshtastic/config.pb.h"
@@ -59,6 +60,9 @@ NRF52Bluetooth *nrf52Bluetooth;
#include "SX1262Interface.h" #include "SX1262Interface.h"
#include "SX1268Interface.h" #include "SX1268Interface.h"
#include "SX1280Interface.h" #include "SX1280Interface.h"
#ifdef ARCH_STM32WL
#include "STM32WLE5JCInterface.h"
#endif
#if !HAS_RADIO && defined(ARCH_PORTDUINO) #if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h" #include "platform/portduino/SimRadio.h"
#endif #endif
@@ -68,7 +72,7 @@ NRF52Bluetooth *nrf52Bluetooth;
#endif #endif
#include "PowerFSMThread.h" #include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "AccelerometerThread.h" #include "AccelerometerThread.h"
#endif #endif
@@ -260,6 +264,12 @@ void setup()
// We need to enable 3.3V periphery in order to scan it // We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT); pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH); 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 #endif
// Currently only the tbeam has a PMU // Currently only the tbeam has a PMU
@@ -347,10 +357,20 @@ void setup()
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field * nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
* "found". * "found".
*/ */
// Only one supported RGB LED currently // Only one supported RGB LED currently
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623); rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
#if !defined(ARCH_PORTDUINO) // Start the RGB LED at 50%
#ifdef RAK4630
if (rgb_found.type == ScanI2C::NCP5623) {
rgb.begin();
rgb.setCurrent(10);
rgb.setColor(128, 128, 128);
}
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
auto acc_info = i2cScanner->firstAccelerometer(); auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found; accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type); LOG_DEBUG("acc_info = %i\n", acc_info.type);
@@ -439,7 +459,7 @@ void setup()
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64 screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
#endif #endif
#if !defined(ARCH_PORTDUINO) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (acc_info.type != ScanI2C::DeviceType::NONE) { if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type); accelerometerThread = new AccelerometerThread(acc_info.type);
} }
@@ -447,7 +467,21 @@ void setup()
// Init our SPI controller (must be before screen and lora) // Init our SPI controller (must be before screen and lora)
initSPI(); 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(); SPI.begin();
#else #else
// ESP32 // ESP32
@@ -509,11 +543,25 @@ void setup()
digitalWrite(SX126X_ANT_SW, 1); digitalWrite(SX126X_ANT_SW, 1);
#endif #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); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
#endif
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init) // 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 !HAS_RADIO && defined(ARCH_PORTDUINO)
if (!rIf) { if (!rIf) {
@@ -635,12 +683,10 @@ void setup()
else { else {
router->addInterface(rIf); router->addInterface(rIf);
// Calculate and save the bit rate to myNodeInfo // Log bit rate to debug output
// TODO: This needs to be added what ever method changes the channel from the phone. LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
myNodeInfo.bitrate = (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
(float(meshtastic_Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) * 1000);
1000;
LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
} }
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values // This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
@@ -661,7 +707,7 @@ bool runASAP;
extern meshtastic_DeviceMetadata getDeviceMetadata() extern meshtastic_DeviceMetadata getDeviceMetadata()
{ {
meshtastic_DeviceMetadata deviceMetadata; 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.device_state_version = DEVICESTATE_CUR_VER;
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN; deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
deviceMetadata.hasBluetooth = HAS_BLUETOOTH; deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
-2
View File
@@ -38,8 +38,6 @@ extern bool isUSBPowered;
extern ATECCX08A atecc; extern ATECCX08A atecc;
#endif #endif
extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
extern int TCPPort; // set by Portduino extern int TCPPort; // set by Portduino
// Global Screen singleton. // Global Screen singleton.
+1
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 if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p); 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; return true;
} }
+3
View File
@@ -10,6 +10,9 @@ template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>; template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>; template class SX126xInterface<LLCC68>;
template class SX128xInterface<SX1280>; template class SX128xInterface<SX1280>;
#ifdef ARCH_STM32WL
template class SX126xInterface<STM32WLx>;
#endif
#if HAS_ETHERNET #if HAS_ETHERNET
#include "api/ethServerAPI.h" #include "api/ethServerAPI.h"
+12 -9
View File
@@ -9,6 +9,7 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h" #include "RTC.h"
#include "TypeConversions.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "modules/NodeInfoModule.h" #include "modules/NodeInfoModule.h"
@@ -76,7 +77,8 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getNode(mp->from)->has_user && nodeInfoModule) { if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getMeshNode(mp->from)->has_user &&
nodeInfoModule) {
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel); LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel); nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
} }
@@ -236,10 +238,11 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
{ {
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
assert(node); assert(node);
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { if (hasValidPosition(node)) {
if (positionModule) { if (positionModule) {
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel); LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
positionModule->sendOurPosition(dest, wantReplies, node->channel); positionModule->sendOurPosition(dest, wantReplies, node->channel);
@@ -266,9 +269,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
fromNum++; fromNum++;
} }
meshtastic_NodeInfo *MeshService::refreshMyNodeInfo() meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
{ {
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
assert(node); assert(node);
// We might not have a position yet for our local node, in that case, at least try to send the time // We might not have a position yet for our local node, in that case, at least try to send the time
@@ -277,7 +280,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
node->has_position = true; node->has_position = true;
} }
meshtastic_Position &position = node->position; meshtastic_PositionLite &position = node->position;
// Update our local node info with our time (even if we don't decide to update anyone else) // Update our local node info with our time (even if we don't decide to update anyone else)
node->last_heard = node->last_heard =
@@ -293,7 +296,7 @@ meshtastic_NodeInfo *MeshService::refreshMyNodeInfo()
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) 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) // Update our local node info with our position (even if we don't decide to update anyone else)
meshtastic_NodeInfo *node = refreshMyNodeInfo(); meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
meshtastic_Position pos = meshtastic_Position_init_default; meshtastic_Position pos = meshtastic_Position_init_default;
if (newStatus->getHasLock()) { if (newStatus->getHasLock()) {
@@ -307,12 +310,12 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
#endif #endif
if (config.position.fixed_position) { if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n"); LOG_WARN("Using fixed position\n");
pos = node->position; pos = ConvertToPosition(node->position);
} }
} }
// Finally add a fresh timestamp and battery level reading // 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 refreshLocalMeshNode() above, but these are
// inexpensive nonblocking calls and can be refactored in due course // inexpensive nonblocking calls and can be refactored in due course
pos.time = getValidTime(RTCQualityGPS); pos.time = getValidTime(RTCQualityGPS);
+1 -1
View File
@@ -98,7 +98,7 @@ class MeshService
bool cancelSending(PacketId id); bool cancelSending(PacketId id);
/// Pull the latest power and time info into my nodeinfo /// Pull the latest power and time info into my nodeinfo
meshtastic_NodeInfo *refreshMyNodeInfo(); meshtastic_NodeInfoLite *refreshLocalMeshNode();
/// Send a packet to the phone /// Send a packet to the phone
void sendToPhone(meshtastic_MeshPacket *p); void sendToPhone(meshtastic_MeshPacket *p);
+144 -63
View File
@@ -11,6 +11,7 @@
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h" #include "RTC.h"
#include "Router.h" #include "Router.h"
#include "TypeConversions.h"
#include "error.h" #include "error.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
@@ -55,10 +56,18 @@ extern void getMacAddr(uint8_t *dmac);
* we use !macaddr (no colons). * we use !macaddr (no colons).
*/ */
meshtastic_User &owner = devicestate.owner; meshtastic_User &owner = devicestate.owner;
meshtastic_Position localPosition = meshtastic_Position_init_default;
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]; static uint8_t ourMacAddr[6];
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {} NodeDB::NodeDB()
: nodes(devicestate.node_db), numNodes(&devicestate.node_db_count), meshNodes(devicestate.node_db_lite),
numMeshNodes(&devicestate.node_db_lite_count)
{
}
/** /**
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on * Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
@@ -258,6 +267,9 @@ void NodeDB::resetNodes()
{ {
devicestate.node_db_count = 0; devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db)); memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
devicestate.node_db_lite_count = 0;
memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
saveDeviceStateToDisk(); saveDeviceStateToDisk();
} }
@@ -272,17 +284,12 @@ void NodeDB::installDefaultDeviceState()
devicestate.has_my_node = true; devicestate.has_my_node = true;
devicestate.has_owner = true; devicestate.has_owner = true;
devicestate.node_db_count = 0; devicestate.node_db_count = 0;
devicestate.node_db_lite_count = 0;
devicestate.version = DEVICESTATE_CUR_VER; devicestate.version = DEVICESTATE_CUR_VER;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME 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; generatePacketId(); // FIXME - ugly way to init current_packet_id;
// Init our blank owner info to reasonable defaults
getMacAddr(ourMacAddr);
// Set default owner name // Set default owner name
pickNewNodeNum(); // based on macaddr now pickNewNodeNum(); // based on macaddr now
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]); snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
@@ -303,28 +310,34 @@ void NodeDB::init()
int saveWhat = 0; 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 // likewise - we always want the app requirements to come from the running appload
myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20 myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't // 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) // 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(); pickNewNodeNum();
// Set our board type so we can share it with others // Set our board type so we can share it with others
owner.hw_model = HW_VENDOR; owner.hw_model = HW_VENDOR;
// Include our owner in the node db under our nodenum // Include our owner in the node db under our nodenum
meshtastic_NodeInfo *info = getOrCreateNode(getNodeNum()); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
info->user = owner; info->user = owner;
info->has_user = true; info->has_user = true;
strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version)); if (*numNodes > 0) {
LOG_DEBUG("Legacy NodeDB detected... Migrating to NodeDBLite\n");
uint32_t readIndex = 0;
const meshtastic_NodeInfo *oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
while (oldNodeInfo != NULL) {
migrateToNodeInfoLite(oldNodeInfo);
oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
}
LOG_DEBUG("Migration complete! Clearing out legacy NodeDB...\n");
devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
}
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
Preferences preferences; Preferences preferences;
@@ -332,11 +345,6 @@ void NodeDB::init()
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0); myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
preferences.end(); preferences.end();
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count); 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 #endif
resetRadioConfig(); // If bogus settings got saved, then fix them resetRadioConfig(); // If bogus settings got saved, then fix them
@@ -367,17 +375,19 @@ void NodeDB::pickNewNodeNum()
{ {
NodeNum r = myNodeInfo.my_node_num; NodeNum r = myNodeInfo.my_node_num;
// If we don't have a nodenum at app - pick an initial nodenum based on the macaddr getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
if (r == 0)
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5]; // Pick an initial nodenum based on the macaddr
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
if (r == NODENUM_BROADCAST || r < NUM_RESERVED) if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
r = NUM_RESERVED; // don't pick a reserved node number r = NUM_RESERVED; // don't pick a reserved node number
meshtastic_NodeInfo *found; meshtastic_NodeInfoLite *found;
while ((found = getNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) { while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
// FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
LOG_DEBUG("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n); LOG_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
r = n; r = n;
} }
@@ -584,16 +594,24 @@ void NodeDB::saveToDisk(int saveWhat)
} }
} }
const meshtastic_NodeInfo *NodeDB::readNextInfo() const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
{ {
if (readPointer < *numNodes) if (readIndex < *numNodes)
return &nodes[readPointer++]; return &nodes[readIndex++];
else
return NULL;
}
const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
{
if (readIndex < *numMeshNodes)
return &meshNodes[readIndex++];
else else
return NULL; return NULL;
} }
/// Given a node, return how many seconds in the past (vs now) that we last heard from it /// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const meshtastic_NodeInfo *n) uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n)
{ {
uint32_t now = getTime(); uint32_t now = getTime();
@@ -617,13 +635,13 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline #define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
size_t NodeDB::getNumOnlineNodes() size_t NodeDB::getNumOnlineMeshNodes()
{ {
size_t numseen = 0; size_t numseen = 0;
// FIXME this implementation is kinda expensive // FIXME this implementation is kinda expensive
for (int i = 0; i < *numNodes; i++) for (int i = 0; i < *numMeshNodes; i++)
if (sinceLastSeen(&nodes[i]) < NUM_ONLINE_SECS) if (sinceLastSeen(&meshNodes[i]) < NUM_ONLINE_SECS)
numseen++; numseen++;
return numseen; return numseen;
@@ -635,7 +653,7 @@ size_t NodeDB::getNumOnlineNodes()
*/ */
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src) void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
{ {
meshtastic_NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info) { if (!info) {
return; return;
} }
@@ -644,7 +662,9 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
// Local packet, fully authoritative // Local packet, fully authoritative
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i, LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude); p.longitude_i, p.altitude);
info->position = p;
info->position = ConvertToPositionLite(p);
localPosition = p;
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) { } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO // FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900) // (stop-gap fix for issue #900)
@@ -662,7 +682,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
uint32_t tmp_time = info->position.time; uint32_t tmp_time = info->position.time;
// Next, update atomically // Next, update atomically
info->position = p; info->position = ConvertToPositionLite(p);
// Last, restore any fields that may have been overwritten // Last, restore any fields that may have been overwritten
if (!info->position.time) if (!info->position.time)
@@ -678,7 +698,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
*/ */
void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src) void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src)
{ {
meshtastic_NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
// Environment metrics should never go to NodeDb but we'll safegaurd anyway // Environment metrics should never go to NodeDb but we'll safegaurd anyway
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) { if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
return; return;
@@ -700,7 +720,7 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
*/ */
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p) bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p)
{ {
meshtastic_NodeInfo *info = getOrCreateNode(nodeId); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info) { if (!info) {
return false; return false;
} }
@@ -733,7 +753,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) { if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel); LOG_DEBUG("Update DB node 0x%x, rx_time=%u, channel=%d\n", mp.from, mp.rx_time, mp.channel);
meshtastic_NodeInfo *info = getOrCreateNode(getFrom(&mp)); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
if (!info) { if (!info) {
return; return;
} }
@@ -750,9 +770,9 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
} }
} }
uint8_t NodeDB::getNodeChannel(NodeNum n) uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
{ {
meshtastic_NodeInfo *info = getNode(n); meshtastic_NodeInfoLite *info = getMeshNode(n);
if (!info) { if (!info) {
return 0; // defaults to PRIMARY return 0; // defaults to PRIMARY
} }
@@ -761,7 +781,7 @@ uint8_t NodeDB::getNodeChannel(NodeNum n)
/// Find a node in our DB, return null for missing /// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR /// NOTE: This function might be called from an ISR
meshtastic_NodeInfo *NodeDB::getNode(NodeNum n) meshtastic_NodeInfo *NodeDB::getNodeInfo(NodeNum n)
{ {
for (int i = 0; i < *numNodes; i++) for (int i = 0; i < *numNodes; i++)
if (nodes[i].num == n) if (nodes[i].num == n)
@@ -770,38 +790,100 @@ meshtastic_NodeInfo *NodeDB::getNode(NodeNum n)
return NULL; return NULL;
} }
/// Find a node in our DB, create an empty NodeInfo if missing /// Find a node in our DB, return null for missing
meshtastic_NodeInfo *NodeDB::getOrCreateNode(NodeNum n) /// NOTE: This function might be called from an ISR
meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n)
{ {
meshtastic_NodeInfo *info = getNode(n); for (int i = 0; i < *numMeshNodes; i++)
if (meshNodes[i].num == n)
return &meshNodes[i];
if (!info) { return NULL;
if ((*numNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfo_size * 3)) { }
screen->print("warning: node_db full! erasing oldest entry\n");
/// Find a node in our DB, create an empty NodeInfo if missing
meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
{
meshtastic_NodeInfoLite *lite = getMeshNode(n);
if (!lite) {
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
screen->print("warning: node_db_lite full! erasing oldest entry\n");
// look for oldest node and erase it // look for oldest node and erase it
uint32_t oldest = UINT32_MAX; uint32_t oldest = UINT32_MAX;
int oldestIndex = -1; int oldestIndex = -1;
for (int i = 0; i < *numNodes; i++) { for (int i = 0; i < *numMeshNodes; i++) {
if (nodes[i].last_heard < oldest) { if (meshNodes[i].last_heard < oldest) {
oldest = nodes[i].last_heard; oldest = meshNodes[i].last_heard;
oldestIndex = i; oldestIndex = i;
} }
} }
// Shove the remaining nodes down the chain // Shove the remaining nodes down the chain
for (int i = oldestIndex; i < *numNodes - 1; i++) { for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
nodes[i] = nodes[i + 1]; meshNodes[i] = meshNodes[i + 1];
} }
(*numNodes)--; (*numMeshNodes)--;
} }
// add the node at the end // add the node at the end
info = &nodes[(*numNodes)++]; lite = &meshNodes[(*numMeshNodes)++];
// everything is missing except the nodenum // everything is missing except the nodenum
memset(info, 0, sizeof(*info)); memset(lite, 0, sizeof(*lite));
info->num = n; lite->num = n;
} }
return info; return lite;
}
void NodeDB::migrateToNodeInfoLite(const meshtastic_NodeInfo *node)
{
meshtastic_NodeInfoLite *lite = getMeshNode(node->num);
if (!lite) {
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
screen->print("warning: node_db_lite full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
for (int i = 0; i < *numMeshNodes; i++) {
if (meshNodes[i].last_heard < oldest) {
oldest = meshNodes[i].last_heard;
oldestIndex = i;
}
}
// Shove the remaining nodes down the chain
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
meshNodes[i] = meshNodes[i + 1];
}
(*numMeshNodes)--;
}
// add the node at the end
lite = &meshNodes[(*numMeshNodes)++];
// everything is missing except the nodenum
memset(lite, 0, sizeof(*lite));
lite->num = node->num;
lite->snr = node->snr;
lite->last_heard = node->last_heard;
lite->channel = node->channel;
if (node->has_position) {
lite->has_position = true;
lite->position.latitude_i = node->position.latitude_i;
lite->position.longitude_i = node->position.longitude_i;
lite->position.altitude = node->position.altitude;
lite->position.location_source = node->position.location_source;
lite->position.time = node->position.time;
}
if (node->has_user) {
lite->has_user = true;
lite->user = node->user;
}
if (node->has_device_metrics) {
lite->has_device_metrics = true;
lite->device_metrics = node->device_metrics;
}
}
} }
/// Record an error that should be reported via analytics /// Record an error that should be reported via analytics
@@ -817,9 +899,8 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
} }
// Record error to DB // Record error to DB
myNodeInfo.error_code = code; error_code = code;
myNodeInfo.error_address = address; error_address = address;
myNodeInfo.error_count++;
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend // Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
+52 -25
View File
@@ -7,6 +7,7 @@
#include "MeshTypes.h" #include "MeshTypes.h"
#include "NodeStatus.h" #include "NodeStatus.h"
#include "mesh-pb-constants.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 DeviceState versions used to be defined in the .proto file but really only this function cares. So changed to a
@@ -28,9 +29,10 @@ extern meshtastic_LocalConfig config;
extern meshtastic_LocalModuleConfig moduleConfig; extern meshtastic_LocalModuleConfig moduleConfig;
extern meshtastic_OEMStore oemStore; extern meshtastic_OEMStore oemStore;
extern meshtastic_User &owner; extern meshtastic_User &owner;
extern meshtastic_Position localPosition;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it /// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const meshtastic_NodeInfo *n); uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
/// Given a packet, return how many seconds in the past (vs now) it was received /// Given a packet, return how many seconds in the past (vs now) it was received
uint32_t sinceReceived(const meshtastic_MeshPacket *p); uint32_t sinceReceived(const meshtastic_MeshPacket *p);
@@ -46,11 +48,12 @@ class NodeDB
meshtastic_NodeInfo *nodes; meshtastic_NodeInfo *nodes;
pb_size_t *numNodes; pb_size_t *numNodes;
uint32_t readPointer = 0; meshtastic_NodeInfoLite *meshNodes;
pb_size_t *numMeshNodes;
public: public:
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled 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 meshtastic_NodeInfoLite *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
Observable<const meshtastic::NodeStatus *> newStatus; Observable<const meshtastic::NodeStatus *> newStatus;
/// don't do mesh based algoritm for node id assignment (initially) /// don't do mesh based algoritm for node id assignment (initially)
@@ -91,8 +94,6 @@ class NodeDB
/// @return our node number /// @return our node number
NodeNum getNodeNum() { return myNodeInfo.my_node_num; } NodeNum getNodeNum() { return myNodeInfo.my_node_num; }
size_t getNumNodes() { return *numNodes; }
/// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use /// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use
// bool handleWantNodeNum(NodeNum n); // bool handleWantNodeNum(NodeNum n);
@@ -104,29 +105,14 @@ class NodeDB
their denial?) 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();
/// pick a provisional nodenum we hope no one is using /// pick a provisional nodenum we hope no one is using
void pickNewNodeNum(); void pickNewNodeNum();
// get channel channel index we heard a nodeNum on, defaults to 0 if not found // get channel channel index we heard a nodeNum on, defaults to 0 if not found
uint8_t getNodeChannel(NodeNum n); uint8_t getMeshNodeChannel(NodeNum n);
/// Find a node in our DB, return null for missing
meshtastic_NodeInfo *getNode(NodeNum n);
meshtastic_NodeInfo *getNodeByIndex(size_t x)
{
assert(x < *numNodes);
return &nodes[x];
}
/// Return the number of nodes we've heard from recently (within the last 2 hrs?) /// Return the number of nodes we've heard from recently (within the last 2 hrs?)
size_t getNumOnlineNodes(); size_t getNumOnlineMeshNodes();
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(); void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
@@ -137,15 +123,38 @@ class NodeDB
void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role); void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role);
const meshtastic_NodeInfoLite *readNextMeshNode(uint32_t &readIndex);
meshtastic_NodeInfoLite *getMeshNodeByIndex(size_t x)
{
assert(x < *numMeshNodes);
return &meshNodes[x];
}
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
size_t getNumMeshNodes() { return *numMeshNodes; }
private: private:
/// Find a node in our DB, create an empty NodeInfo if missing /// Find a node in our DB, create an empty NodeInfoLite if missing
meshtastic_NodeInfo *getOrCreateNode(NodeNum n); meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
void migrateToNodeInfoLite(const meshtastic_NodeInfo *node);
/// Find a node in our DB, return null for missing
meshtastic_NodeInfo *getNodeInfo(NodeNum n);
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
const meshtastic_NodeInfo *readNextNodeInfo(uint32_t &readIndex);
size_t getNumNodes() { return *numNodes; }
meshtastic_NodeInfo *getNodeByIndex(size_t x)
{
assert(x < *numNodes);
return &nodes[x];
}
/// Notify observers of changes to the DB /// Notify observers of changes to the DB
void notifyObservers(bool forceUpdate = false) void notifyObservers(bool forceUpdate = false)
{ {
// Notify observers of the current node state // Notify observers of the current node state
const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineNodes(), getNumNodes(), forceUpdate); const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineMeshNodes(), getNumMeshNodes(), forceUpdate);
newStatus.notifyObservers(&status); newStatus.notifyObservers(&status);
} }
@@ -217,11 +226,29 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
return defaultInterval * 1000; 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);
}
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *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 /** 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. * might have changed is incremented. Allows others to detect they might now be on a new channel.
*/ */
extern uint32_t radioGeneration; 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 \ #define Module_Config_size \
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \ (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \ ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
+15 -13
View File
@@ -5,6 +5,7 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RadioInterface.h" #include "RadioInterface.h"
#include "TypeConversions.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include "xmodem.h" #include "xmodem.h"
@@ -40,9 +41,8 @@ void PhoneAPI::handleStartConfig()
state = STATE_SEND_MY_INFO; state = STATE_SEND_MY_INFO;
LOG_INFO("Starting API client config\n"); LOG_INFO("Starting API client config\n");
nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
nodeDB.resetReadPointer(); // FIXME, this read pointer should be moved out of nodeDB and into this class - because resetReadIndex();
// this will break once we have multiple instances of PhoneAPI running independently
} }
void PhoneAPI::close() void PhoneAPI::close()
@@ -144,25 +144,23 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n"); 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 // 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. // 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.which_payload_variant = meshtastic_FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo; fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO; state = STATE_SEND_NODEINFO;
service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon. service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
break; break;
case STATE_SEND_NODEINFO: { case STATE_SEND_NODEINFO: {
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n"); LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
const meshtastic_NodeInfo *info = nodeInfoForPhone;
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
if (info) { if (nodeInfoForPhone.num != 0) {
LOG_INFO("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id, LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
info->user.long_name); nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
fromRadioScratch.node_info = *info; fromRadioScratch.node_info = nodeInfoForPhone;
// Stay in current state until done sending nodeinfos // Stay in current state until done sending nodeinfos
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
} else { } else {
LOG_INFO("Done sending nodeinfos\n"); LOG_INFO("Done sending nodeinfos\n");
state = STATE_SEND_CHANNELS; state = STATE_SEND_CHANNELS;
@@ -372,8 +370,12 @@ bool PhoneAPI::available()
return true; return true;
case STATE_SEND_NODEINFO: case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone) if (nodeInfoForPhone.num == 0) {
nodeInfoForPhone = nodeDB.readNextInfo(); auto nextNode = nodeDB.readNextMeshNode(readIndex);
if (nextNode) {
nodeInfoForPhone = ConvertToNodeInfo(nextNode);
}
}
return true; // Always say we have something, because we might need to advance our state machine return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_PACKETS: { case STATE_SEND_PACKETS: {
+4 -1
View File
@@ -51,13 +51,16 @@ class PhoneAPI
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL; meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio /// We temporarily keep the nodeInfo here between the call to available and getFromRadio
const meshtastic_NodeInfo *nodeInfoForPhone = NULL; meshtastic_NodeInfo nodeInfoForPhone = meshtastic_NodeInfo_init_default;
meshtastic_ToRadio toRadioScratch = { meshtastic_ToRadio toRadioScratch = {
0}; // this is a static scratch object, any data must be copied elsewhere before returning 0}; // this is a static scratch object, any data must be copied elsewhere before returning
/// Use to ensure that clients don't get confused about old messages from the radio /// Use to ensure that clients don't get confused about old messages from the radio
uint32_t config_nonce = 0; uint32_t config_nonce = 0;
uint32_t readIndex = 0;
void resetReadIndex() { readIndex = 0; }
public: public:
PhoneAPI(); PhoneAPI();
+1 -1
View File
@@ -52,7 +52,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
*/ */
const char *getSenderShortName(const meshtastic_MeshPacket &mp) const char *getSenderShortName(const meshtastic_MeshPacket &mp)
{ {
auto node = nodeDB.getNode(getFrom(&mp)); auto node = nodeDB.getMeshNode(getFrom(&mp));
const char *sender = (node) ? node->user.short_name : "???"; const char *sender = (node) ? node->user.short_name : "???";
return sender; return sender;
} }
+2 -1
View File
@@ -232,7 +232,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
delay = random(0, 2 * CWsize) * slotTimeMsec; delay = random(0, 2 * CWsize) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay); LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else { } 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); LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d\n", delay);
} }
+17
View File
@@ -27,6 +27,19 @@ class LockingArduinoHal : public ArduinoHal
void spiEndTransaction() override; 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 class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
{ {
/// Used as our notification from the ISR /// 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. float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
#if !defined(USE_STM32WLx)
Module module; // The HW interface to the radio Module module; // The HW interface to the radio
#else
STM32WLx_ModuleWrapper module;
#endif
/** /**
* provides lowest common denominator RadioLib API * provides lowest common denominator RadioLib API
+1 -1
View File
@@ -178,7 +178,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
} }
if (!p->channel) { // don't override if a channel was requested if (!p->channel) { // don't override if a channel was requested
p->channel = nodeDB.getNodeChannel(p->to); p->channel = nodeDB.getMeshNodeChannel(p->to);
LOG_DEBUG("localSend to channel %d\n", p->channel); LOG_DEBUG("localSend to channel %d\n", p->channel);
} }
+45
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
+31
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
+54
View File
@@ -0,0 +1,54 @@
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "mesh/generated/meshtastic/mesh.pb.h"
inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
{
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
info.num = lite->num;
info.snr = lite->snr;
info.last_heard = lite->last_heard;
info.channel = lite->channel;
if (lite->has_position) {
info.has_position = true;
info.position.latitude_i = lite->position.latitude_i;
info.position.longitude_i = lite->position.longitude_i;
info.position.altitude = lite->position.altitude;
info.position.location_source = lite->position.location_source;
info.position.time = lite->position.time;
}
if (lite->has_user) {
info.has_user = true;
info.user = lite->user;
}
if (lite->has_device_metrics) {
info.has_device_metrics = true;
info.device_metrics = lite->device_metrics;
}
return info;
}
inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
{
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
lite.latitude_i = position.latitude_i;
lite.longitude_i = position.longitude_i;
lite.altitude = position.altitude;
lite.location_source = position.location_source;
lite.time = position.time;
return lite;
}
inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
{
meshtastic_Position position = meshtastic_Position_init_default;
position.latitude_i = lite.latitude_i;
position.longitude_i = lite.longitude_i;
position.altitude = lite.altitude;
position.location_source = lite.location_source;
position.time = lite.time;
return position;
}
+1 -1
View File
@@ -74,7 +74,7 @@ template <class T> class TypedQueue
concurrency::OSThread *reader = NULL; concurrency::OSThread *reader = NULL;
public: public:
TypedQueue(int maxElements) {} explicit TypedQueue(int maxElements) {}
int numFree() { return 1; } // Always claim 1 free, because we can grow to any size int numFree() { return 1; } // Always claim 1 free, because we can grow to any size
+14 -1
View File
@@ -98,6 +98,11 @@ static int32_t reconnectETH()
return 5000; // every 5 seconds 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 // Startup Ethernet
bool initEthernet() bool initEthernet()
{ {
@@ -126,7 +131,15 @@ bool initEthernet()
status = Ethernet.begin(mac); status = Ethernet.begin(mac);
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) { } else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
LOG_INFO("starting Ethernet Static\n"); 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 { } else {
LOG_INFO("Ethernet Disabled\n"); LOG_INFO("Ethernet Disabled\n");
return false; return false;
+8 -4
View File
@@ -311,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 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 */ 0 for default of 10 seconds */
uint32_t min_wake_secs; 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; } meshtastic_Config_PowerConfig;
typedef struct _meshtastic_Config_NetworkConfig_IpV4Config { typedef struct _meshtastic_Config_NetworkConfig_IpV4Config {
@@ -534,7 +536,7 @@ extern "C" {
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} #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, 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_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_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_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_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}
@@ -543,7 +545,7 @@ extern "C" {
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} #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, 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_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_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_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} #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}
@@ -579,6 +581,7 @@ extern "C" {
#define meshtastic_Config_PowerConfig_sds_secs_tag 6 #define meshtastic_Config_PowerConfig_sds_secs_tag 6
#define meshtastic_Config_PowerConfig_ls_secs_tag 7 #define meshtastic_Config_PowerConfig_ls_secs_tag 7
#define meshtastic_Config_PowerConfig_min_wake_secs_tag 8 #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_ip_tag 1
#define meshtastic_Config_NetworkConfig_IpV4Config_gateway_tag 2 #define meshtastic_Config_NetworkConfig_IpV4Config_gateway_tag 2
#define meshtastic_Config_NetworkConfig_IpV4Config_subnet_tag 3 #define meshtastic_Config_NetworkConfig_IpV4Config_subnet_tag 3
@@ -682,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, mesh_sds_timeout_secs, 5) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \ X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \ 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_CALLBACK NULL
#define meshtastic_Config_PowerConfig_DEFAULT NULL #define meshtastic_Config_PowerConfig_DEFAULT NULL
@@ -776,7 +780,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 195 #define meshtastic_Config_NetworkConfig_size 195
#define meshtastic_Config_PositionConfig_size 54 #define meshtastic_Config_PositionConfig_size 54
#define meshtastic_Config_PowerConfig_size 43 #define meshtastic_Config_PowerConfig_size 46
#define meshtastic_Config_size 198 #define meshtastic_Config_size 198
#ifdef __cplusplus #ifdef __cplusplus
@@ -9,6 +9,12 @@
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 4) 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_ChannelFile, meshtastic_ChannelFile, 2)
File diff suppressed because one or more lines are too long
+11 -5
View File
@@ -72,6 +72,9 @@ typedef struct _meshtastic_LocalModuleConfig {
/* The part of the config that is specific to the Remote Hardware module */ /* The part of the config that is specific to the Remote Hardware module */
bool has_remote_hardware; bool has_remote_hardware;
meshtastic_ModuleConfig_RemoteHardwareConfig 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; } meshtastic_LocalModuleConfig;
@@ -81,9 +84,9 @@ extern "C" {
/* Initializer values for message structs */ /* 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_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_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) */ /* Field tags (for use in manual encoding/decoding) */
#define meshtastic_LocalConfig_device_tag 1 #define meshtastic_LocalConfig_device_tag 1
@@ -104,6 +107,7 @@ extern "C" {
#define meshtastic_LocalModuleConfig_version_tag 8 #define meshtastic_LocalModuleConfig_version_tag 8
#define meshtastic_LocalModuleConfig_audio_tag 9 #define meshtastic_LocalModuleConfig_audio_tag 9
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10 #define meshtastic_LocalModuleConfig_remote_hardware_tag 10
#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_LocalConfig_FIELDLIST(X, a) \ #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, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \ X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \ 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_CALLBACK NULL
#define meshtastic_LocalModuleConfig_DEFAULT NULL #define meshtastic_LocalModuleConfig_DEFAULT NULL
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig #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_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig #define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig #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_LocalConfig_msg;
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_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 #define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 458 #define meshtastic_LocalConfig_size 461
#define meshtastic_LocalModuleConfig_size 533 #define meshtastic_LocalModuleConfig_size 545
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
+26 -11
View File
@@ -61,6 +61,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17, meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */ /* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
meshtastic_HardwareModel_STATION_G1 = 25, 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) 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, meshtastic_HardwareModel_BETAFPV_2400_TX = 45,
/* BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU */ /* BetaFPV ExpressLRS "Nano" TX Module 900MHz with ESP32 CPU */
meshtastic_HardwareModel_BETAFPV_900_NANO_TX = 46, 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. 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. /* A VERY short name, ideally two characters.
Suitable for a tiny OLED screen */ Suitable for a tiny OLED screen */
char short_name[5]; 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 */ Not populated by the phone, but added by the esp32 when broadcasting */
pb_byte_t macaddr[6]; pb_byte_t macaddr[6];
/* TBEAM, HELTEC, etc... /* TBEAM, HELTEC, etc...
@@ -574,12 +579,15 @@ typedef struct _meshtastic_MyNodeInfo {
/* Tells the phone what our node number is, default starting value is /* 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 */ lowbyte of macaddr, but it will be fixed if that is already in use */
uint32_t my_node_num; 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 */ Not the same as UserPreferences.location_sharing */
bool has_gps; 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; 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]; char firmware_version[18];
/* An error message we'd like to report back to the mothership through analytics. /* 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, 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 /* The total number of reboots this node has ever encountered
(well - since the last time we discarded preferences) */ (well - since the last time we discarded preferences) */
uint32_t reboot_count; 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; 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 caches of any messages in flight Normally quite large to handle the worst case
message delivery time, 5 minutes. message delivery time, 5 minutes.
Formerly called FLOOD_EXPIRE_TIME in the device code */ 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. /* 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 */ 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; 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; pb_size_t air_period_tx_count;
uint32_t air_period_tx[8]; 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; pb_size_t air_period_rx_count;
uint32_t air_period_rx[8]; 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; 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; 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; float air_util_tx;
} meshtastic_MyNodeInfo; } meshtastic_MyNodeInfo;
@@ -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_RemoteHardwareConfig, meshtastic_ModuleConfig_RemoteHardwareConfig, AUTO)
PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO) PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)
@@ -58,7 +58,9 @@ typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Mode {
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1, meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1,
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2, meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2,
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3, 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; } meshtastic_ModuleConfig_SerialConfig_Serial_Mode;
/* TODO: REPLACE */ /* TODO: REPLACE */
@@ -112,6 +114,15 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig {
char root[16]; char root[16];
} meshtastic_ModuleConfig_MQTTConfig; } meshtastic_ModuleConfig_MQTTConfig;
/* NeighborInfoModule Config */
typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
/* Whether the Module is enabled */
bool enabled;
/* 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 */ /* Audio Config for codec2 voice */
typedef struct _meshtastic_ModuleConfig_AudioConfig { typedef struct _meshtastic_ModuleConfig_AudioConfig {
/* Whether Audio is enabled */ /* Whether Audio is enabled */
@@ -132,21 +143,24 @@ typedef struct _meshtastic_ModuleConfig_AudioConfig {
/* Serial Config */ /* Serial Config */
typedef struct _meshtastic_ModuleConfig_SerialConfig { typedef struct _meshtastic_ModuleConfig_SerialConfig {
/* Preferences for the SerialModule /* Preferences for the SerialModule */
FIXME - Move this out of UserPreferences and into a section for module configuration. */
bool enabled; bool enabled;
/* TODO: REPLACE */ /* TODO: REPLACE */
bool echo; bool echo;
/* TODO: REPLACE */ /* RX pin (should match Arduino gpio pin number) */
uint32_t rxd; uint32_t rxd;
/* TODO: REPLACE */ /* TX pin (should match Arduino gpio pin number) */
uint32_t txd; uint32_t txd;
/* TODO: REPLACE */ /* Serial baud rate */
meshtastic_ModuleConfig_SerialConfig_Serial_Baud baud; meshtastic_ModuleConfig_SerialConfig_Serial_Baud baud;
/* TODO: REPLACE */ /* TODO: REPLACE */
uint32_t timeout; uint32_t timeout;
/* TODO: REPLACE */ /* Mode for serial module operation */
meshtastic_ModuleConfig_SerialConfig_Serial_Mode mode; 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; } meshtastic_ModuleConfig_SerialConfig;
/* External Notifications Config */ /* External Notifications Config */
@@ -308,6 +322,8 @@ typedef struct _meshtastic_ModuleConfig {
meshtastic_ModuleConfig_AudioConfig audio; meshtastic_ModuleConfig_AudioConfig audio;
/* TODO: REPLACE */ /* TODO: REPLACE */
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware; meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
/* TODO: REPLACE */
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
} payload_variant; } payload_variant;
} meshtastic_ModuleConfig; } meshtastic_ModuleConfig;
@@ -330,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_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_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_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO
#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_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_MIN meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE
#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MAX meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK #define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MAX meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK
@@ -340,6 +356,7 @@ extern "C" {
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud #define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud #define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
@@ -360,8 +377,9 @@ extern "C" {
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}} #define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""} #define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 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_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_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_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_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0} #define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
@@ -371,8 +389,9 @@ extern "C" {
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}} #define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""} #define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 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_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_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_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_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0} #define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
@@ -389,6 +408,8 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6 #define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7 #define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8 #define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
#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_codec2_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2 #define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3 #define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
@@ -403,6 +424,7 @@ extern "C" {
#define meshtastic_ModuleConfig_SerialConfig_baud_tag 5 #define meshtastic_ModuleConfig_SerialConfig_baud_tag 5
#define meshtastic_ModuleConfig_SerialConfig_timeout_tag 6 #define meshtastic_ModuleConfig_SerialConfig_timeout_tag 6
#define meshtastic_ModuleConfig_SerialConfig_mode_tag 7 #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_enabled_tag 1
#define meshtastic_ModuleConfig_ExternalNotificationConfig_output_ms_tag 2 #define meshtastic_ModuleConfig_ExternalNotificationConfig_output_ms_tag 2
#define meshtastic_ModuleConfig_ExternalNotificationConfig_output_tag 3 #define meshtastic_ModuleConfig_ExternalNotificationConfig_output_tag 3
@@ -458,6 +480,7 @@ extern "C" {
#define meshtastic_ModuleConfig_canned_message_tag 7 #define meshtastic_ModuleConfig_canned_message_tag 7
#define meshtastic_ModuleConfig_audio_tag 8 #define meshtastic_ModuleConfig_audio_tag 8
#define meshtastic_ModuleConfig_remote_hardware_tag 9 #define meshtastic_ModuleConfig_remote_hardware_tag 9
#define meshtastic_ModuleConfig_neighbor_info_tag 10
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \ #define meshtastic_ModuleConfig_FIELDLIST(X, a) \
@@ -469,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,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,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,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_CALLBACK NULL
#define meshtastic_ModuleConfig_DEFAULT NULL #define meshtastic_ModuleConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig #define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -481,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_canned_message_MSGTYPE meshtastic_ModuleConfig_CannedMessageConfig
#define meshtastic_ModuleConfig_payload_variant_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig #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_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \ #define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
@@ -502,6 +527,12 @@ X(a, STATIC, REPEATED, MESSAGE, available_pins, 3)
#define meshtastic_ModuleConfig_RemoteHardwareConfig_DEFAULT NULL #define meshtastic_ModuleConfig_RemoteHardwareConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_RemoteHardwareConfig_available_pins_MSGTYPE meshtastic_RemoteHardwarePin #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) \ #define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \ X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \ X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \
@@ -520,7 +551,8 @@ X(a, STATIC, SINGULAR, UINT32, rxd, 3) \
X(a, STATIC, SINGULAR, UINT32, txd, 4) \ X(a, STATIC, SINGULAR, UINT32, txd, 4) \
X(a, STATIC, SINGULAR, UENUM, baud, 5) \ X(a, STATIC, SINGULAR, UENUM, baud, 5) \
X(a, STATIC, SINGULAR, UINT32, timeout, 6) \ 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_CALLBACK NULL
#define meshtastic_ModuleConfig_SerialConfig_DEFAULT NULL #define meshtastic_ModuleConfig_SerialConfig_DEFAULT NULL
@@ -594,6 +626,7 @@ X(a, STATIC, SINGULAR, UENUM, type, 3)
extern const pb_msgdesc_t meshtastic_ModuleConfig_msg; extern const pb_msgdesc_t meshtastic_ModuleConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_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_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_AudioConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg; extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg; extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
@@ -607,6 +640,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_fields &meshtastic_ModuleConfig_msg #define meshtastic_ModuleConfig_fields &meshtastic_ModuleConfig_msg
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg #define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_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_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg #define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg #define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
@@ -621,9 +655,10 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49 #define meshtastic_ModuleConfig_CannedMessageConfig_size 49
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40 #define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
#define meshtastic_ModuleConfig_MQTTConfig_size 220 #define meshtastic_ModuleConfig_MQTTConfig_size 220
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
#define meshtastic_ModuleConfig_RangeTestConfig_size 10 #define meshtastic_ModuleConfig_RangeTestConfig_size 10
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96 #define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
#define meshtastic_ModuleConfig_SerialConfig_size 26 #define meshtastic_ModuleConfig_SerialConfig_size 28
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22 #define meshtastic_ModuleConfig_StoreForwardConfig_size 22
#define meshtastic_ModuleConfig_TelemetryConfig_size 26 #define meshtastic_ModuleConfig_TelemetryConfig_size 26
#define meshtastic_ModuleConfig_size 223 #define meshtastic_ModuleConfig_size 223
+16 -10
View File
@@ -521,11 +521,23 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
void AdminModule::handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req) void AdminModule::handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req)
{ {
// We create the reply here
meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
memcpy(r.get_node_remote_hardware_pins_response.node_remote_hardware_pins, devicestate.node_remote_hardware_pins,
sizeof(devicestate.node_remote_hardware_pins));
r.which_payload_variant = meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag; 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); myReply = allocDataProtobuf(r);
} }
@@ -541,9 +553,8 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
{ {
meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
meshtastic_DeviceConnectionStatus conn; meshtastic_DeviceConnectionStatus conn = meshtastic_DeviceConnectionStatus_init_zero;
conn.wifi = {0};
#if HAS_WIFI #if HAS_WIFI
conn.has_wifi = true; conn.has_wifi = true;
conn.wifi.has_status = true; conn.wifi.has_status = true;
@@ -559,11 +570,8 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
conn.wifi.status.is_mqtt_connected = mqtt && mqtt->connected(); conn.wifi.status.is_mqtt_connected = mqtt && mqtt->connected();
conn.wifi.status.is_syslog_connected = false; // FIXME wire this up conn.wifi.status.is_syslog_connected = false; // FIXME wire this up
} }
#else
conn.has_wifi = false;
#endif #endif
conn.ethernet = {0};
#if HAS_ETHERNET #if HAS_ETHERNET
conn.has_ethernet = true; conn.has_ethernet = true;
conn.ethernet.has_status = true; conn.ethernet.has_status = true;
@@ -575,8 +583,6 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
} else { } else {
conn.ethernet.status.is_connected = false; conn.ethernet.status.is_connected = false;
} }
#else
conn.has_ethernet = false;
#endif #endif
#if HAS_BLUETOOTH #if HAS_BLUETOOTH
+11 -9
View File
@@ -305,13 +305,14 @@ int32_t CannedMessageModule::runOnce()
switch (this->payload) { switch (this->payload) {
case 0xb4: // left case 0xb4: // left
if (this->destSelect) { if (this->destSelect) {
size_t numNodes = nodeDB.getNumNodes(); size_t numMeshNodes = nodeDB.getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) { if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum(); this->dest = nodeDB.getNodeNum();
} }
for (unsigned int i = 0; i < numNodes; i++) { for (unsigned int i = 0; i < numMeshNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) { if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i - 1)->num : nodeDB.getNodeByIndex(numNodes - 1)->num; this->dest =
(i > 0) ? nodeDB.getMeshNodeByIndex(i - 1)->num : nodeDB.getMeshNodeByIndex(numMeshNodes - 1)->num;
break; break;
} }
} }
@@ -326,13 +327,14 @@ int32_t CannedMessageModule::runOnce()
break; break;
case 0xb7: // right case 0xb7: // right
if (this->destSelect) { if (this->destSelect) {
size_t numNodes = nodeDB.getNumNodes(); size_t numMeshNodes = nodeDB.getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) { if (this->dest == NODENUM_BROADCAST) {
this->dest = nodeDB.getNodeNum(); this->dest = nodeDB.getNodeNum();
} }
for (unsigned int i = 0; i < numNodes; i++) { for (unsigned int i = 0; i < numMeshNodes; i++) {
if (nodeDB.getNodeByIndex(i)->num == this->dest) { if (nodeDB.getMeshNodeByIndex(i)->num == this->dest) {
this->dest = (i < numNodes - 1) ? nodeDB.getNodeByIndex(i + 1)->num : nodeDB.getNodeByIndex(0)->num; this->dest =
(i < numMeshNodes - 1) ? nodeDB.getMeshNodeByIndex(i + 1)->num : nodeDB.getMeshNodeByIndex(0)->num;
break; break;
} }
} }
@@ -409,7 +411,7 @@ const char *CannedMessageModule::getNodeName(NodeNum node)
if (node == NODENUM_BROADCAST) { if (node == NODENUM_BROADCAST) {
return "Broadcast"; return "Broadcast";
} else { } else {
meshtastic_NodeInfo *info = nodeDB.getNode(node); meshtastic_NodeInfoLite *info = nodeDB.getMeshNode(node);
if (info != NULL) { if (info != NULL) {
return info->user.long_name; return info->user.long_name;
} else { } else {
+1 -1
View File
@@ -11,7 +11,7 @@
#include "main.h" #include "main.h"
#ifdef RAK4630 #ifdef RAK4630
#include <NCP5623.h> #include <graphics/RAKled.h>
NCP5623 rgb; NCP5623 rgb;
uint8_t red = 0; uint8_t red = 0;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "SinglePortModule.h" #include "SinglePortModule.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "configuration.h" #include "configuration.h"
#ifndef ARCH_PORTDUINO #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include <NonBlockingRtttl.h> #include <NonBlockingRtttl.h>
#else #else
// Noop class for portduino. // Noop class for portduino.
+6 -8
View File
@@ -22,12 +22,12 @@
#endif #endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "modules/esp32/AudioModule.h" #include "modules/esp32/AudioModule.h"
#include "modules/esp32/RangeTestModule.h"
#include "modules/esp32/StoreForwardModule.h" #include "modules/esp32/StoreForwardModule.h"
#endif #endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) #if defined(ARCH_ESP32) || defined(ARCH_NRF52)
#include "modules/ExternalNotificationModule.h" #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" #include "modules/SerialModule.h"
#endif #endif
#endif #endif
@@ -72,20 +72,18 @@ void setupModules()
new AirQualityTelemetryModule(); new AirQualityTelemetryModule();
} }
#endif #endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
!defined(CONFIG_IDF_TARGET_ESP32C3)
new SerialModule(); new SerialModule();
#endif #endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only run on an esp32 based device. // Only run on an esp32 based device.
audioModule = new AudioModule(); audioModule = new AudioModule();
externalNotificationModule = new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule(); storeForwardModule = new StoreForwardModule();
#endif
new RangeTestModule(); #if defined(ARCH_ESP32) || defined(ARCH_NRF52)
#elif defined(ARCH_NRF52)
externalNotificationModule = new ExternalNotificationModule(); externalNotificationModule = new ExternalNotificationModule();
new RangeTestModule();
#endif #endif
} else { } else {
adminModule = new AdminModule(); adminModule = new AdminModule();
+26 -23
View File
@@ -3,6 +3,7 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "RTC.h"
#include "Router.h" #include "Router.h"
#include "TypeConversions.h"
#include "airtime.h" #include "airtime.h"
#include "configuration.h" #include "configuration.h"
#include "gps/GeoCoord.h" #include "gps/GeoCoord.h"
@@ -56,55 +57,57 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
meshtastic_MeshPacket *PositionModule::allocReply() meshtastic_MeshPacket *PositionModule::allocReply()
{ {
meshtastic_NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
assert(node->has_position); assert(node->has_position);
node->position.seq_number++;
// configuration of POSITION packet // configuration of POSITION packet
// consider making this a function argument? // consider making this a function argument?
uint32_t pos_flags = config.position.position_flags; uint32_t pos_flags = config.position.position_flags;
// Populate a Position struct with ONLY the requested fields // Populate a Position struct with ONLY the requested fields
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
localPosition = ConvertToPosition(node->position);
}
localPosition.seq_number++;
// lat/lon are unconditionally included - IF AVAILABLE! // lat/lon are unconditionally included - IF AVAILABLE!
p.latitude_i = node->position.latitude_i; p.latitude_i = localPosition.latitude_i;
p.longitude_i = node->position.longitude_i; p.longitude_i = localPosition.longitude_i;
p.time = node->position.time; p.time = localPosition.time;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) { if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL)
p.altitude = node->position.altitude; p.altitude = localPosition.altitude;
else else
p.altitude_hae = node->position.altitude_hae; p.altitude_hae = localPosition.altitude_hae;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION)
p.altitude_geoidal_separation = node->position.altitude_geoidal_separation; p.altitude_geoidal_separation = localPosition.altitude_geoidal_separation;
} }
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_DOP) { if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_DOP) {
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HVDOP) { if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HVDOP) {
p.HDOP = node->position.HDOP; p.HDOP = localPosition.HDOP;
p.VDOP = node->position.VDOP; p.VDOP = localPosition.VDOP;
} else } else
p.PDOP = node->position.PDOP; p.PDOP = localPosition.PDOP;
} }
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SATINVIEW) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SATINVIEW)
p.sats_in_view = node->position.sats_in_view; p.sats_in_view = localPosition.sats_in_view;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_TIMESTAMP) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_TIMESTAMP)
p.timestamp = node->position.timestamp; p.timestamp = localPosition.timestamp;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SEQ_NO) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SEQ_NO)
p.seq_number = node->position.seq_number; p.seq_number = localPosition.seq_number;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HEADING) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_HEADING)
p.ground_track = node->position.ground_track; p.ground_track = localPosition.ground_track;
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SPEED) if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_SPEED)
p.ground_speed = node->position.ground_speed; p.ground_speed = localPosition.ground_speed;
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless
@@ -144,7 +147,7 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
int32_t PositionModule::runOnce() int32_t PositionModule::runOnce()
{ {
meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
// We limit our GPS broadcasts to a max rate // We limit our GPS broadcasts to a max rate
uint32_t now = millis(); uint32_t now = millis();
@@ -154,7 +157,7 @@ int32_t PositionModule::runOnce()
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) { if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
// Only send packets if the channel is less than 40% utilized. // Only send packets if the channel is less than 40% utilized.
if (airTime->isTxAllowedChannelUtil()) { if (airTime->isTxAllowedChannelUtil()) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { if (hasValidPosition(node)) {
lastGpsSend = now; lastGpsSend = now;
lastGpsLatitude = node->position.latitude_i; lastGpsLatitude = node->position.latitude_i;
@@ -164,16 +167,16 @@ int32_t PositionModule::runOnce()
bool requestReplies = currentGeneration != radioGeneration; bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration; currentGeneration = radioGeneration;
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies); LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
sendOurPosition(NODENUM_BROADCAST, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies);
} }
} }
} else if (config.position.position_broadcast_smart_enabled) { } else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized or we're a tracker. // 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)) { if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // 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. // The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelThreshold = const uint32_t distanceTravelThreshold =
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
@@ -193,7 +196,7 @@ int32_t PositionModule::runOnce()
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, " LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n", "minTimeInterval=%ims)\n",
node2->position.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
msSinceLastSend, minimumTimeThreshold); msSinceLastSend, minimumTimeThreshold);
sendOurPosition(NODENUM_BROADCAST, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies);
@@ -1,4 +1,5 @@
#include "RangeTestModule.h" #include "RangeTestModule.h"
#include "FSCommon.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
@@ -8,7 +9,6 @@
#include "configuration.h" #include "configuration.h"
#include "gps/GeoCoord.h" #include "gps/GeoCoord.h"
#include <Arduino.h> #include <Arduino.h>
#include <FSCommon.h>
/* /*
As a sender, I can send packets every n seconds. These packets include an incremented PacketID. 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() 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 Uncomment the preferences below if you want to use the module
@@ -60,7 +60,6 @@ int32_t RangeTestModule::runOnce()
return disable(); return disable();
// This thread does not need to run as a receiver // This thread does not need to run as a receiver
} }
} else { } else {
if (moduleConfig.range_test.sender) { if (moduleConfig.range_test.sender) {
@@ -122,7 +121,7 @@ void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp) ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp)
{ {
#ifdef ARCH_ESP32 #if defined(ARCH_ESP32) || defined(ARCH_NRF52)
if (moduleConfig.range_test.enabled) { if (moduleConfig.range_test.enabled) {
@@ -139,7 +138,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
} }
/* /*
NodeInfo *n = nodeDB.getNode(getFrom(&mp)); NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
LOG_DEBUG("-----------------------------------------\n"); LOG_DEBUG("-----------------------------------------\n");
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes); LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
@@ -153,7 +152,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n"); 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.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_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->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i); LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i); LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -165,7 +163,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_DEBUG("-----------------------------------------\n"); LOG_DEBUG("-----------------------------------------\n");
*/ */
} }
} else { } else {
LOG_INFO("Range Test Module Disabled\n"); LOG_INFO("Range Test Module Disabled\n");
} }
@@ -177,9 +174,10 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp) bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
{ {
#ifdef ARCH_ESP32
auto &p = mp.decoded; auto &p = mp.decoded;
meshtastic_NodeInfo *n = nodeDB.getNode(getFrom(&mp)); meshtastic_NodeInfoLite *n = nodeDB.getMeshNode(getFrom(&mp));
/* /*
LOG_DEBUG("-----------------------------------------\n"); LOG_DEBUG("-----------------------------------------\n");
LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes); LOG_DEBUG("p.payload.bytes \"%s\"\n", p.payload.bytes);
@@ -193,7 +191,6 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
LOG_DEBUG("---- Node Information of Received Packet (mp.from):\n"); 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.long_name %s\n", n->user.long_name);
LOG_DEBUG("n->user.short_name %s\n", n->user.short_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->has_position %d\n", n->has_position);
LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i); LOG_DEBUG("n->position.latitude_i %d\n", n->position.latitude_i);
LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i); LOG_DEBUG("n->position.longitude_i %d\n", n->position.longitude_i);
@@ -284,6 +281,7 @@ bool RangeTestModuleRadio::appendFile(const meshtastic_MeshPacket &mp)
fileToAppend.printf("\"%s\"\n", p.payload.bytes); fileToAppend.printf("\"%s\"\n", p.payload.bytes);
fileToAppend.flush(); fileToAppend.flush();
fileToAppend.close(); fileToAppend.close();
#endif
return 1; return 1;
} }
+101 -85
View File
@@ -39,13 +39,12 @@
KNOWN PROBLEMS KNOWN PROBLEMS
* Until the module is initilized by the startup sequence, the TX pin is in a floating * 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". 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) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
!defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 128 #define RX_BUFFER 128
#define TIMEOUT 250 #define TIMEOUT 250
@@ -58,19 +57,25 @@
SerialModule *serialModule; SerialModule *serialModule;
SerialModuleRadio *serialModuleRadio; 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") {} SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {}
static Print *serialPrint = &Serial2;
#endif
char serialBytes[meshtastic_Constants_DATA_PAYLOAD_LEN]; char serialBytes[meshtastic_Constants_DATA_PAYLOAD_LEN];
size_t serialPayloadSize; size_t serialPayloadSize;
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
{ {
switch (moduleConfig.serial.mode) { switch (moduleConfig.serial.mode) {
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG: case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
ourPortNum = meshtastic_PortNum_TEXT_MESSAGE_APP; ourPortNum = meshtastic_PortNum_TEXT_MESSAGE_APP;
break; break;
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA: case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA:
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO:
ourPortNum = meshtastic_PortNum_POSITION_APP; ourPortNum = meshtastic_PortNum_POSITION_APP;
break; break;
default: default:
@@ -95,89 +100,52 @@ int32_t SerialModule::runOnce()
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
*/ */
// moduleConfig.serial.enabled = 1; // moduleConfig.serial.enabled = true;
// moduleConfig.serial.rxd = 35; // moduleConfig.serial.rxd = 35;
// moduleConfig.serial.txd = 15; // 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.timeout = 1000;
// moduleConfig.serial.echo = 1; // 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) { if (firstTime) {
// Interface with the serial peripheral from in here. // Interface with the serial peripheral from in here.
LOG_INFO("Initializing serial peripheral interface\n"); 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) { if (moduleConfig.serial.override_console_serial_port) {
baud = 38400; Serial.flush();
serialPrint = &Serial;
} else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) { // Give it a chance to flush out 💩
baud = 110; delay(10);
} 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;
} }
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
Serial2.setRxBufferSize(RX_BUFFER);
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
Serial2.setRxBufferSize(RX_BUFFER);
Serial2.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); 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 #else
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) Serial.begin(baud, SERIAL_8N1);
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd); Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
Serial2.begin(baud, SERIAL_8N1);
#endif #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(); serialModuleRadio = new SerialModuleRadio();
firstTime = 0; firstTime = 0;
@@ -186,26 +154,37 @@ int32_t SerialModule::runOnce()
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) { if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
emitRebooted(); emitRebooted();
} }
} else { } else {
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) { if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
return runOncePart(); return runOncePart();
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) { } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
// in NMEA mode send out GGA every 2 seconds, Don't read from Port // in NMEA mode send out GGA every 2 seconds, Don't read from Port
if (millis() - lastNmeaTime > 2000) { if (millis() - lastNmeaTime > 2000) {
lastNmeaTime = millis(); lastNmeaTime = millis();
printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position); printGGA(outbuf, sizeof(outbuf), localPosition);
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_NodeInfoLite *tempNodeInfo = nodeDB.readNextMeshNode(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.readNextMeshNode(readIndex);
}
}
}
#ifndef TTGO_T_ECHO
else {
while (Serial2.available()) { while (Serial2.available()) {
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
serialModuleRadio->sendPayload(); serialModuleRadio->sendPayload();
} }
} }
#endif
} }
return (10); return (10);
} else { } else {
return disable(); return disable();
@@ -262,23 +241,23 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
if (lastRxID != mp.id) { if (lastRxID != mp.id) {
lastRxID = mp.id; lastRxID = mp.id;
// LOG_DEBUG("* * Message came this device\n"); // LOG_DEBUG("* * Message came this device\n");
// Serial2.println("* * Message came this device"); // serialPrint->println("* * Message came this device");
Serial2.printf("%s", p.payload.bytes); serialPrint->printf("%s", p.payload.bytes);
} }
} }
} else { } else {
if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT || if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT ||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) { 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) { } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) {
meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp)); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
String sender = (node && node->has_user) ? node->user.short_name : "???"; String sender = (node && node->has_user) ? node->user.short_name : "???";
Serial2.println(); serialPrint->println();
Serial2.printf("%s: %s", sender, p.payload.bytes); serialPrint->printf("%s: %s", sender, p.payload.bytes);
Serial2.println(); serialPrint->println();
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) { } 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 // Decode the Payload some more
meshtastic_Position scratch; meshtastic_Position scratch;
meshtastic_Position *decoded = NULL; meshtastic_Position *decoded = NULL;
@@ -288,12 +267,49 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
decoded = &scratch; decoded = &scratch;
} }
// send position packet as WPL to the serial port // send position packet as WPL to the serial port
printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name); printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getMeshNode(getFrom(&mp))->user.long_name,
Serial2.printf("%s", outbuf); 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 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 #endif
+4 -2
View File
@@ -8,8 +8,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <functional> #include <functional>
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
!defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread 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 /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override; virtual bool checkIsConnected() override;
private:
uint32_t getBaudRate();
}; };
extern SerialModule *serialModule; extern SerialModule *serialModule;
+2 -2
View File
@@ -50,14 +50,14 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
t.time = getTime(); t.time = getTime();
t.which_variant = meshtastic_Telemetry_device_metrics_tag; 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()) { if (powerStatus->getIsCharging()) {
t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL; t.variant.device_metrics.battery_level = MAGIC_USB_BATTERY_LEVEL;
} else { } else {
t.variant.device_metrics.battery_level = powerStatus->getBatteryChargePercent(); 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; 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", LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
+49 -48
View File
@@ -7,6 +7,7 @@
#include "Router.h" #include "Router.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#include "power.h"
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
@@ -14,8 +15,6 @@
#include "Sensor/BME280Sensor.h" #include "Sensor/BME280Sensor.h"
#include "Sensor/BME680Sensor.h" #include "Sensor/BME680Sensor.h"
#include "Sensor/BMP280Sensor.h" #include "Sensor/BMP280Sensor.h"
#include "Sensor/INA219Sensor.h"
#include "Sensor/INA260Sensor.h"
#include "Sensor/LPS22HBSensor.h" #include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h" #include "Sensor/MCP9808Sensor.h"
#include "Sensor/SHT31Sensor.h" #include "Sensor/SHT31Sensor.h"
@@ -25,8 +24,6 @@ BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor; BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor; BME680Sensor bme680Sensor;
MCP9808Sensor mcp9808Sensor; MCP9808Sensor mcp9808Sensor;
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
SHTC3Sensor shtc3Sensor; SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor; LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor; SHT31Sensor sht31Sensor;
@@ -52,7 +49,7 @@ SHT31Sensor sht31Sensor;
int32_t EnvironmentTelemetryModule::runOnce() 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 Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
@@ -83,23 +80,22 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = bme680Sensor.runOnce(); result = bme680Sensor.runOnce();
if (mcp9808Sensor.hasSensor()) if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce(); result = mcp9808Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
if (shtc3Sensor.hasSensor()) if (shtc3Sensor.hasSensor())
result = shtc3Sensor.runOnce(); result = shtc3Sensor.runOnce();
if (lps22hbSensor.hasSensor()) { if (lps22hbSensor.hasSensor())
result = lps22hbSensor.runOnce(); result = lps22hbSensor.runOnce();
}
if (sht31Sensor.hasSensor()) if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce(); result = sht31Sensor.runOnce();
} }
return result; return result;
} else { } else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever // if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.environment_measurement_enabled) if (!moduleConfig.telemetry.environment_measurement_enabled) {
return result; return disable();
} else {
if (bme680Sensor.hasSensor())
result = bme680Sensor.runTrigger();
}
uint32_t now = millis(); uint32_t now = millis();
if (((lastSentToMesh == 0) || if (((lastSentToMesh == 0) ||
@@ -107,13 +103,15 @@ int32_t EnvironmentTelemetryModule::runOnce()
airTime->isTxAllowedAirUtil()) { airTime->isTxAllowedAirUtil()) {
sendTelemetry(); sendTelemetry();
lastSentToMesh = now; 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 // Just send to phone when it's not our time to send to mesh yet
// Only send while queue is empty (phone assumed connected) // Only send while queue is empty (phone assumed connected)
sendTelemetry(NODENUM_BROADCAST, true); sendTelemetry(NODENUM_BROADCAST, true);
lastSentToPhone = now;
} }
} }
return sendToPhoneIntervalMs; return min(sendToPhoneIntervalMs, result);
} }
bool EnvironmentTelemetryModule::wantUIFrame() bool EnvironmentTelemetryModule::wantUIFrame()
@@ -205,6 +203,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{ {
meshtastic_Telemetry m; meshtastic_Telemetry m;
bool valid = false;
m.time = getTime(); m.time = getTime();
m.which_variant = meshtastic_Telemetry_environment_metrics_tag; m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
@@ -216,50 +215,52 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
m.variant.environment_metrics.voltage = 0; m.variant.environment_metrics.voltage = 0;
if (sht31Sensor.hasSensor()) if (sht31Sensor.hasSensor())
sht31Sensor.getMetrics(&m); valid = sht31Sensor.getMetrics(&m);
if (lps22hbSensor.hasSensor()) if (lps22hbSensor.hasSensor())
lps22hbSensor.getMetrics(&m); valid = lps22hbSensor.getMetrics(&m);
if (shtc3Sensor.hasSensor()) if (shtc3Sensor.hasSensor())
shtc3Sensor.getMetrics(&m); valid = shtc3Sensor.getMetrics(&m);
if (bmp280Sensor.hasSensor()) if (bmp280Sensor.hasSensor())
bmp280Sensor.getMetrics(&m); valid = bmp280Sensor.getMetrics(&m);
if (bme280Sensor.hasSensor()) if (bme280Sensor.hasSensor())
bme280Sensor.getMetrics(&m); valid = bme280Sensor.getMetrics(&m);
if (bme680Sensor.hasSensor()) if (bme680Sensor.hasSensor())
bme680Sensor.getMetrics(&m); valid = bme680Sensor.getMetrics(&m);
if (mcp9808Sensor.hasSensor()) if (mcp9808Sensor.hasSensor())
mcp9808Sensor.getMetrics(&m); valid = mcp9808Sensor.getMetrics(&m);
if (ina219Sensor.hasSensor()) if (ina219Sensor.hasSensor())
ina219Sensor.getMetrics(&m); valid = ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor()) if (ina260Sensor.hasSensor())
ina260Sensor.getMetrics(&m); valid = ina260Sensor.getMetrics(&m);
LOG_INFO( if (valid) {
"(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n", LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, "
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current, "voltage=%f\n",
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity, m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage); m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
sensor_read_error_count = 0; sensor_read_error_count = 0;
meshtastic_MeshPacket *p = allocDataProtobuf(m); meshtastic_MeshPacket *p = allocDataProtobuf(m);
p->to = dest; p->to = dest;
p->decoded.want_response = false; p->decoded.want_response = false;
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)
p->priority = meshtastic_MeshPacket_Priority_RELIABLE; p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
else else
p->priority = meshtastic_MeshPacket_Priority_MIN; p->priority = meshtastic_MeshPacket_Priority_MIN;
// release previous packet before occupying a new spot // release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr) if (lastMeasurementPacket != nullptr)
packetPool.release(lastMeasurementPacket); packetPool.release(lastMeasurementPacket);
lastMeasurementPacket = packetPool.allocCopy(*p); lastMeasurementPacket = packetPool.allocCopy(*p);
if (phoneOnly) { if (phoneOnly) {
LOG_INFO("Sending packet to phone\n"); LOG_INFO("Sending packet to phone\n");
service.sendToPhone(p); service.sendToPhone(p);
} else { } else {
LOG_INFO("Sending packet to mesh\n"); LOG_INFO("Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true); service.sendToMesh(p, RX_SRC_LOCAL, true);
}
} }
return true; return valid;
} }
@@ -39,5 +39,6 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
meshtastic_MeshPacket *lastMeasurementPacket; meshtastic_MeshPacket *lastMeasurementPacket;
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0; uint32_t lastSentToMesh = 0;
uint32_t lastSentToPhone = 0;
uint32_t sensor_read_error_count = 0; uint32_t sensor_read_error_count = 0;
}; };
+40 -7
View File
@@ -6,21 +6,41 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {} BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
int32_t BME680Sensor::runTrigger()
{
if (!bme680.run()) {
checkStatus("runTrigger");
}
return 35;
}
int32_t BME680Sensor::runOnce() int32_t BME680Sensor::runOnce()
{ {
LOG_INFO("Init sensor: %s with the BSEC Library\n", sensorName);
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; 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) { if (bme680.status == BSEC_OK) {
bme680.setConfig(Default_H2S_NonH2S_config);
loadState();
bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
status = 1; 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 { } else {
status = 0; status = 0;
} }
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d\n", bme680.status);
return initI2CSensor(); return initI2CSensor();
} }
@@ -29,8 +49,8 @@ void BME680Sensor::setup() {}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) 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.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal;
measurement->variant.environment_metrics.relative_humidity = measurement->variant.environment_metrics.relative_humidity =
bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal; bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal;
@@ -107,3 +127,16 @@ void BME680Sensor::updateState()
LOG_ERROR("ERROR: Filesystem not implemented\n"); LOG_ERROR("ERROR: Filesystem not implemented\n");
#endif #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());
}
+12 -14
View File
@@ -4,7 +4,7 @@
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis() #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 class BME680Sensor : virtual public TelemetrySensor
{ {
@@ -17,24 +17,22 @@ class BME680Sensor : virtual public TelemetrySensor
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0; uint8_t accuracy = 0;
uint16_t stateUpdateCounter = 0; uint16_t stateUpdateCounter = 0;
bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ, bsecSensor sensorList[9] = {BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY};
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_GAS_PERCENTAGE};
void loadState(); void loadState();
void updateState(); void updateState();
void checkStatus(String functionName);
public: public:
BME680Sensor(); BME680Sensor();
int32_t runTrigger();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
}; };
+11 -2
View File
@@ -12,8 +12,12 @@ int32_t INA219Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]); if (!ina219.success()) {
status = ina219.begin(); ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
status = ina219.begin();
} else {
status = ina219.success();
}
return initI2CSensor(); return initI2CSensor();
} }
@@ -25,3 +29,8 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.current = ina219.getCurrent_mA(); measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true; return true;
} }
uint16_t INA219Sensor::getBusVoltageMv()
{
return lround(ina219.getBusVoltage_V() * 1000);
}
+3 -1
View File
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h" #include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include "VoltageSensor.h"
#include <Adafruit_INA219.h> #include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor class INA219Sensor : virtual public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA219 ina219; Adafruit_INA219 ina219;
@@ -14,4 +15,5 @@ class INA219Sensor : virtual public TelemetrySensor
INA219Sensor(); INA219Sensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
}; };
@@ -12,7 +12,10 @@ int32_t INA260Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
}
return initI2CSensor(); return initI2CSensor();
} }
@@ -25,3 +28,8 @@ bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.current = ina260.readCurrent(); measurement->variant.environment_metrics.current = ina260.readCurrent();
return true; return true;
} }
uint16_t INA260Sensor::getBusVoltageMv()
{
return lround(ina260.readBusVoltage());
}
+3 -1
View File
@@ -1,8 +1,9 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h" #include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include "VoltageSensor.h"
#include <Adafruit_INA260.h> #include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor class INA260Sensor : virtual public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA260 ina260 = Adafruit_INA260(); Adafruit_INA260 ina260 = Adafruit_INA260();
@@ -14,4 +15,5 @@ class INA260Sensor : virtual public TelemetrySensor
INA260Sensor(); INA260Sensor();
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
}; };
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h" #include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "main.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor class TelemetrySensor
{ {
@@ -18,6 +18,7 @@ class TelemetrySensor
const char *sensorName; const char *sensorName;
meshtastic_TelemetrySensorType sensorType; meshtastic_TelemetrySensorType sensorType;
unsigned status; unsigned status;
bool initialized = false;
int32_t initI2CSensor() int32_t initI2CSensor()
{ {
@@ -28,6 +29,7 @@ class TelemetrySensor
LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName); LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName);
setup(); setup();
} }
initialized = true;
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
virtual void setup(); virtual void setup();
@@ -36,5 +38,8 @@ class TelemetrySensor
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; } bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; }
virtual int32_t runOnce() = 0; virtual int32_t runOnce() = 0;
virtual bool isInitialized() { return initialized; }
virtual bool isRunning() { return status > 0; }
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0; virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
}; };
@@ -0,0 +1,7 @@
#pragma once
class VoltageSensor
{
public:
virtual uint16_t getBusVoltageMv() = 0;
};
@@ -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};
@@ -0,0 +1,3 @@
#include <stdint.h>
extern const uint8_t bsec_config_iaq[1974];
-3
View File
@@ -36,8 +36,6 @@ int32_t StoreForwardModule::runOnce()
this->packetHistoryTXQueue_index++; this->packetHistoryTXQueue_index++;
} }
} }
LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) { } else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
lastHeartbeat = millis(); lastHeartbeat = millis();
LOG_INFO("*** Sending heartbeat\n"); LOG_INFO("*** Sending heartbeat\n");
@@ -266,7 +264,6 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
storeForwardModule->historyAdd(mp); storeForwardModule->historyAdd(mp);
LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent); LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryCurrent);
} }
} else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) { } else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
auto &p = mp.decoded; auto &p = mp.decoded;
meshtastic_StoreAndForward scratch; meshtastic_StoreAndForward scratch;
+4
View File
@@ -172,6 +172,10 @@ void cpuDeepSleep(uint32_t msecToWake)
setBluetoothEnable(false); setBluetoothEnable(false);
#ifdef RAK4630 #ifdef RAK4630
digitalWrite(PIN_3V3_EN, LOW); digitalWrite(PIN_3V3_EN, LOW);
#ifndef USE_EINK
// RAK-12039 set pin for Air quality sensor
digitalWrite(AQ_SET_PIN, LOW);
#endif
#endif #endif
// FIXME, use system off mode with ram retention for key state? // FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per // FIXME, use non-init RAM per
+14 -2
View File
@@ -2,6 +2,18 @@
#define ARCH_RP2040 #define ARCH_RP2040
#if defined(PRIVATE_HW) #ifndef HAS_TELEMETRY
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW #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 #endif
+6 -6
View File
@@ -21,10 +21,10 @@ void getMacAddr(uint8_t *dmac)
{ {
pico_unique_board_id_t src; pico_unique_board_id_t src;
pico_get_unique_board_id(&src); pico_get_unique_board_id(&src);
dmac[5] = src.id[0]; dmac[5] = src.id[7];
dmac[4] = src.id[1]; dmac[4] = src.id[6];
dmac[3] = src.id[2]; dmac[3] = src.id[5];
dmac[2] = src.id[3]; dmac[2] = src.id[4];
dmac[1] = src.id[4]; dmac[1] = src.id[3];
dmac[0] = src.id[5]; dmac[0] = src.id[2];
} }
+141
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;
}
+54
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_ */
+258
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
+85
View File
@@ -0,0 +1,85 @@
#ifndef LITTLEFS_H_
#define LITTLEFS_H_
#include <Stream.h>
#include "lfs.h"
#include "LittleFS_File.h"
#include "FreeRTOS.h" // tied to FreeRTOS for serialization
#include "semphr.h"
class LittleFS
{
public:
LittleFS(void);
explicit LittleFS(struct lfs_config *cfg);
virtual ~LittleFS();
bool begin(struct lfs_config *cfg = NULL);
void end(void);
// Open the specified file/directory with the supplied mode (e.g. read or
// write, etc). Returns a File object for interacting with the file.
// Note that currently only one file can be open at a time.
LittleFS_Namespace::File open(char const *filename, uint8_t mode = LittleFS_Namespace::FILE_O_READ);
// Methods to determine if the requested file path exists.
bool exists(char const *filepath);
// Create the requested directory hierarchy--if intermediate directories
// do not exist they will be created.
bool mkdir(char const *filepath);
// Delete the file.
bool remove(char const *filepath);
// Rename the file.
bool rename(char const *oldfilepath, char const *newfilepath);
// Delete a folder (must be empty)
bool rmdir(char const *filepath);
// Delete a folder (recursively)
bool rmdir_r(char const *filepath);
// format file system
bool format(void);
/*------------------------------------------------------------------*/
/* INTERNAL USAGE ONLY
* Although declare as public, it is meant to be invoked by internal
* code. User should not call these directly
*------------------------------------------------------------------*/
lfs_t *_getFS(void) { return &_lfs; }
void _lockFS(void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
void _unlockFS(void) { xSemaphoreGive(_mutex); }
protected:
bool _mounted;
struct lfs_config *_lfs_cfg;
lfs_t _lfs;
SemaphoreHandle_t _mutex;
private:
StaticSemaphore_t _MutexStorageSpace;
};
#if !CFG_DEBUG
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
#define PRINT_LFS_ERR(_err)
#else
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_strerr_lfs)
#define PRINT_LFS_ERR(_err) \
do { \
if (_err) { \
VERIFY_MESS((long int)_err, dbg_strerr_lfs); \
} \
} while (0) // LFS_ERR are of type int, VERIFY_MESS expects long_int
const char *dbg_strerr_lfs(int32_t err);
#endif
#endif /* LITTLEFS_H_ */
+362
View File
@@ -0,0 +1,362 @@
#include <Arduino.h>
#include "LittleFS.h"
#include <lfs.h>
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
using namespace LittleFS_Namespace;
File::File(LittleFS &fs)
{
_fs = &fs;
_is_dir = false;
_name[0] = 0;
_dir_path = NULL;
_dir = NULL;
_file = NULL;
}
File::File(char const *filename, uint8_t mode, LittleFS &fs) : File(fs)
{
// public constructor calls public API open(), which will obtain the mutex
this->open(filename, mode);
}
bool File::_open_file(char const *filepath, uint8_t mode)
{
int flags = (mode == FILE_O_READ) ? LFS_O_RDONLY : (mode == FILE_O_WRITE) ? (LFS_O_RDWR | LFS_O_CREAT) : 0;
if (flags) {
_file = (lfs_file_t *)malloc(sizeof(lfs_file_t));
if (!_file)
return false;
int rc = lfs_file_open(_fs->_getFS(), _file, filepath, flags);
if (rc) {
// failed to open
PRINT_LFS_ERR(rc);
return false;
}
// move to end of file
if (mode == FILE_O_WRITE)
lfs_file_seek(_fs->_getFS(), _file, 0, LFS_SEEK_END);
_is_dir = false;
}
return true;
}
bool File::_open_dir(char const *filepath)
{
_dir = (lfs_dir_t *)malloc(sizeof(lfs_dir_t));
if (!_dir)
return false;
int rc = lfs_dir_open(_fs->_getFS(), _dir, filepath);
if (rc) {
// failed to open
PRINT_LFS_ERR(rc);
return false;
}
_is_dir = true;
_dir_path = (char *)malloc(strlen(filepath) + 1);
strcpy(_dir_path, filepath);
return true;
}
bool File::open(char const *filepath, uint8_t mode)
{
bool ret = false;
_fs->_lockFS();
ret = this->_open(filepath, mode);
_fs->_unlockFS();
return ret;
}
bool File::_open(char const *filepath, uint8_t mode)
{
bool ret = false;
// close if currently opened
if (this->isOpen())
_close();
struct lfs_info info;
int rc = lfs_stat(_fs->_getFS(), filepath, &info);
if (LFS_ERR_OK == rc) {
// file existed, open file or directory accordingly
ret = (info.type == LFS_TYPE_REG) ? _open_file(filepath, mode) : _open_dir(filepath);
} else if (LFS_ERR_NOENT == rc) {
// file not existed, only proceed with FILE_O_WRITE mode
if (mode == FILE_O_WRITE)
ret = _open_file(filepath, mode);
} else {
PRINT_LFS_ERR(rc);
}
// save bare file name
if (ret) {
char const *splash = strrchr(filepath, '/');
strncpy(_name, splash ? (splash + 1) : filepath, LFS_NAME_MAX);
}
return ret;
}
size_t File::write(uint8_t ch)
{
return write(&ch, 1);
}
size_t File::write(uint8_t const *buf, size_t size)
{
lfs_ssize_t wrcount = 0;
_fs->_lockFS();
if (!this->_is_dir) {
wrcount = lfs_file_write(_fs->_getFS(), _file, buf, size);
if (wrcount < 0) {
wrcount = 0;
}
}
_fs->_unlockFS();
return wrcount;
}
int File::read(void)
{
// this thin wrapper relies on called function to synchronize
int ret = -1;
uint8_t ch;
if (read(&ch, 1) > 0) {
ret = static_cast<int>(ch);
}
return ret;
}
int File::read(void *buf, uint16_t nbyte)
{
int ret = 0;
_fs->_lockFS();
if (!this->_is_dir) {
ret = lfs_file_read(_fs->_getFS(), _file, buf, nbyte);
}
_fs->_unlockFS();
return ret;
}
int File::peek(void)
{
int ret = -1;
_fs->_lockFS();
if (!this->_is_dir) {
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
uint8_t ch = 0;
if (lfs_file_read(_fs->_getFS(), _file, &ch, 1) > 0) {
ret = static_cast<int>(ch);
}
(void)lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET);
}
_fs->_unlockFS();
return ret;
}
int File::available(void)
{
int ret = 0;
_fs->_lockFS();
if (!this->_is_dir) {
uint32_t size = lfs_file_size(_fs->_getFS(), _file);
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
ret = size - pos;
}
_fs->_unlockFS();
return ret;
}
bool File::seek(uint32_t pos)
{
bool ret = false;
_fs->_lockFS();
if (!this->_is_dir) {
ret = lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET) >= 0;
}
_fs->_unlockFS();
return ret;
}
uint32_t File::position(void)
{
uint32_t ret = 0;
_fs->_lockFS();
if (!this->_is_dir) {
ret = lfs_file_tell(_fs->_getFS(), _file);
}
_fs->_unlockFS();
return ret;
}
uint32_t File::size(void)
{
uint32_t ret = 0;
_fs->_lockFS();
if (!this->_is_dir) {
ret = lfs_file_size(_fs->_getFS(), _file);
}
_fs->_unlockFS();
return ret;
}
bool File::truncate(uint32_t pos)
{
int32_t ret = LFS_ERR_ISDIR;
_fs->_lockFS();
if (!this->_is_dir) {
ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
}
_fs->_unlockFS();
return (ret == 0);
}
bool File::truncate(void)
{
int32_t ret = LFS_ERR_ISDIR;
_fs->_lockFS();
if (!this->_is_dir) {
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
}
_fs->_unlockFS();
return (ret == 0);
}
void File::flush(void)
{
_fs->_lockFS();
if (!this->_is_dir) {
lfs_file_sync(_fs->_getFS(), _file);
}
_fs->_unlockFS();
return;
}
void File::close(void)
{
_fs->_lockFS();
this->_close();
_fs->_unlockFS();
}
void File::_close(void)
{
if (this->isOpen()) {
if (this->_is_dir) {
lfs_dir_close(_fs->_getFS(), _dir);
free(_dir);
_dir = NULL;
if (this->_dir_path)
free(_dir_path);
_dir_path = NULL;
} else {
lfs_file_close(this->_fs->_getFS(), _file);
free(_file);
_file = NULL;
}
}
}
File::operator bool(void)
{
return isOpen();
}
bool File::isOpen(void)
{
return (_file != NULL) || (_dir != NULL);
}
// WARNING -- although marked as `const`, the values pointed
// to may change. For example, if the same File
// object has `open()` called with a different
// file or directory name, this same pointer will
// suddenly (unexpectedly?) have different values.
char const *File::name(void)
{
return this->_name;
}
bool File::isDirectory(void)
{
return this->_is_dir;
}
File File::openNextFile(uint8_t mode)
{
_fs->_lockFS();
File ret(*_fs);
if (this->_is_dir) {
struct lfs_info info;
int rc;
// lfs_dir_read returns 0 when reaching end of directory, 1 if found an entry
// Skip the "." and ".." entries ...
do {
rc = lfs_dir_read(_fs->_getFS(), _dir, &info);
} while (rc == 1 && (!strcmp(".", info.name) || !strcmp("..", info.name)));
if (rc == 1) {
// string cat name with current folder
char filepath[strlen(_dir_path) + 1 + strlen(info.name) + 1]; // potential for significant stack usage
strcpy(filepath, _dir_path);
if (!(_dir_path[0] == '/' && _dir_path[1] == 0))
strcat(filepath, "/"); // only add '/' if cwd is not root
strcat(filepath, info.name);
(void)ret._open(filepath, mode); // return value is ignored ... caller is expected to check isOpened()
} else if (rc < 0) {
PRINT_LFS_ERR(rc);
}
}
_fs->_unlockFS();
return ret;
}
void File::rewindDirectory(void)
{
_fs->_lockFS();
if (this->_is_dir) {
lfs_dir_rewind(_fs->_getFS(), _dir);
}
_fs->_unlockFS();
}
+82
View File
@@ -0,0 +1,82 @@
#ifndef LITTLEFS_FILE_H_
#define LITTLEFS_FILE_H_
// Forward declaration
class LittleFS;
namespace LittleFS_Namespace
{
// avoid conflict with other FileSystem FILE_READ/FILE_WRITE
enum {
FILE_O_READ = 0,
FILE_O_WRITE = 1,
};
class File : public Stream
{
public:
explicit File(LittleFS &fs);
File(char const *filename, uint8_t mode, LittleFS &fs);
public:
bool open(char const *filename, uint8_t mode);
//------------- Stream API -------------//
virtual size_t write(uint8_t ch);
virtual size_t write(uint8_t const *buf, size_t size);
size_t write(const char *str)
{
if (str == NULL)
return 0;
return write((const uint8_t *)str, strlen(str));
}
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
virtual int read(void);
int read(void *buf, uint16_t nbyte);
virtual int peek(void);
virtual int available(void);
virtual void flush(void);
bool seek(uint32_t pos);
uint32_t position(void);
uint32_t size(void);
bool truncate(uint32_t pos);
bool truncate(void);
void close(void);
operator bool(void);
bool isOpen(void);
char const *name(void);
bool isDirectory(void);
File openNextFile(uint8_t mode = FILE_O_READ);
void rewindDirectory(void);
private:
LittleFS *_fs;
bool _is_dir;
union {
lfs_file_t *_file;
lfs_dir_t *_dir;
};
char *_dir_path;
char _name[LFS_NAME_MAX + 1];
bool _open(char const *filepath, uint8_t mode);
bool _open_file(char const *filepath, uint8_t mode);
bool _open_dir(char const *filepath);
void _close(void);
};
} // namespace LittleFS_Namespace
#endif /* LITTLEFS_FILE_H_ */
+6 -11
View File
@@ -6,24 +6,19 @@
// defaults for STM32WL architecture // defaults for STM32WL architecture
// //
#ifndef HAS_RADIO
#define HAS_RADIO 1
#endif
// //
// set HW_VENDOR // set HW_VENDOR
// //
#ifndef HW_VENDOR #ifndef HW_VENDOR
#define HW_VENDOR HardwareModel_PRIVATE_HW #define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#endif #endif
#ifdef __cplusplus /* virtual pins */
extern "C" {
#endif
void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value);
int stm32wl_emulate_digitalRead(long unsigned int pin);
#ifdef __cplusplus
}
#endif
/* virtual pins for stm32wl_emulate_digitalWrite() / stm32wl_emulate_digitalRead() to recognize */
#define SX126X_CS 1000 #define SX126X_CS 1000
#define SX126X_DIO1 1001 #define SX126X_DIO1 1001
#define SX126X_RESET 1003 #define SX126X_RESET 1003
-65
View File
@@ -1,65 +0,0 @@
#include "architecture.h"
#include "stm32wlxx.h"
#include "stm32wlxx_hal.h"
#include <stdbool.h>
void HardFault_Handler(void)
{
asm("bkpt");
}
void stm32wl_emulate_digitalWrite(long unsigned int pin, long unsigned int value)
{
switch (pin) {
case SX126X_CS: /* active low */
if (value)
LL_PWR_UnselectSUBGHZSPI_NSS();
else
LL_PWR_SelectSUBGHZSPI_NSS();
break;
case SX126X_RESET: /* active low */
if (value)
LL_RCC_RF_DisableReset();
else {
LL_RCC_RF_EnableReset();
LL_RCC_HSE_EnableTcxo();
LL_RCC_HSE_Enable();
while (!LL_RCC_HSE_IsReady())
;
}
break;
default:
asm("bkpt");
break;
}
}
static bool irq_happened;
void SUBGHZ_Radio_IRQHandler(void)
{
NVIC_DisableIRQ(SUBGHZ_Radio_IRQn);
irq_happened = true;
}
int stm32wl_emulate_digitalRead(long unsigned int pin)
{
int outcome = 0;
switch (pin) {
case SX126X_BUSY:
// return ((LL_PWR_IsActiveFlag_RFBUSYMS() & LL_PWR_IsActiveFlag_RFBUSYS()) == 1UL);
outcome = LL_PWR_IsActiveFlag_RFBUSYS();
break;
case SX126X_DIO1:
default:
NVIC_ClearPendingIRQ(SUBGHZ_Radio_IRQn);
irq_happened = false;
NVIC_EnableIRQ(SUBGHZ_Radio_IRQn);
for (int i = 0; i < 64; i++)
asm("nop");
outcome = irq_happened;
break;
}
return outcome;
}
+12 -2
View File
@@ -11,8 +11,18 @@ void updateBatteryLevel(uint8_t level) {}
void getMacAddr(uint8_t *dmac) void getMacAddr(uint8_t *dmac)
{ {
for (int i = 0; i < 6; i++) // https://flit.github.io/2020/06/06/mcu-unique-id-survey.html
dmac[i] = i; const uint32_t uid0 = HAL_GetUIDw0(); // X/Y coordinate on wafer
const uint32_t uid1 = HAL_GetUIDw1(); // [31:8] Lot number (23:0), [7:0] Wafer number
const uint32_t uid2 = HAL_GetUIDw2(); // Lot number (55:24)
// Need to go from 96-bit to 48-bit unique ID
dmac[5] = (uint8_t)uid0;
dmac[4] = (uint8_t)(uid0 >> 16);
dmac[3] = (uint8_t)uid1;
dmac[2] = (uint8_t)(uid1 >> 8);
dmac[1] = (uint8_t)uid2;
dmac[0] = (uint8_t)(uid2 >> 8);
} }
void cpuDeepSleep(uint32_t msecToWake) {} void cpuDeepSleep(uint32_t msecToWake) {}
+7 -1
View File
@@ -22,6 +22,13 @@ extern RTC_NOINIT_ATTR uint64_t RTC_reg_b;
#include "soc/sens_reg.h" // needed for adc pin reset #include "soc/sens_reg.h" // needed for adc pin reset
#endif #endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
#include "modules/Telemetry/Sensor/INA219Sensor.h"
#include "modules/Telemetry/Sensor/INA260Sensor.h"
extern INA260Sensor ina260Sensor;
extern INA219Sensor ina219Sensor;
#endif
class Power : private concurrency::OSThread class Power : private concurrency::OSThread
{ {
@@ -41,7 +48,6 @@ class Power : private concurrency::OSThread
/// Setup a xpowers chip axp192/axp2101, return true if found /// Setup a xpowers chip axp192/axp2101, return true if found
bool axpChipInit(); bool axpChipInit();
/// Setup a simple ADC input based battery sensor /// Setup a simple ADC input based battery sensor
bool analogInit(); bool analogInit();
+1 -1
View File
@@ -26,8 +26,8 @@ void powerCommandsCheck()
if (shutdownAtMsec && millis() > shutdownAtMsec) { if (shutdownAtMsec && millis() > shutdownAtMsec) {
LOG_INFO("Shutting down from admin command\n"); LOG_INFO("Shutting down from admin command\n");
playShutdownMelody();
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) #if defined(ARCH_NRF52) || defined(ARCH_ESP32)
playShutdownMelody();
power->shutdown(); power->shutdown();
#else #else
LOG_WARN("FIXME implement shutdown for this platform"); LOG_WARN("FIXME implement shutdown for this platform");
+13 -13
View File
@@ -103,13 +103,13 @@ void setGPSPower(bool on)
if (pmu_found && PMU) { if (pmu_found && PMU) {
uint8_t model = PMU->getChipModel(); uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) { if (model == XPOWERS_AXP2101) {
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
// t-beam v1.2 GNSS power channel // t-beam v1.2 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(XPOWERS_ALDO3); on ? PMU->enablePowerOutput(XPOWERS_ALDO3) : PMU->disablePowerOutput(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 power channel // t-beam-s3-core GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4); on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
#endif }
} else if (model == XPOWERS_AXP192) { } else if (model == XPOWERS_AXP192) {
// t-beam v1.1 GNSS power channel // t-beam v1.1 GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3); on ? PMU->enablePowerOutput(XPOWERS_LDO3) : PMU->disablePowerOutput(XPOWERS_LDO3);
@@ -252,12 +252,12 @@ void doDeepSleep(uint32_t msecToWake)
uint8_t model = PMU->getChipModel(); uint8_t model = PMU->getChipModel();
if (model == XPOWERS_AXP2101) { if (model == XPOWERS_AXP2101) {
#if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
// t-beam v1.2 radio power channel // t-beam v1.2 radio power channel
PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
#elif (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
#endif }
} else if (model == XPOWERS_AXP192) { } else if (model == XPOWERS_AXP192) {
// t-beam v1.1 radio power channel // t-beam v1.1 radio power channel
PMU->disablePowerOutput(XPOWERS_LDO2); // lora radio power channel PMU->disablePowerOutput(XPOWERS_LDO2); // lora radio power channel
+1 -1
View File
@@ -59,7 +59,7 @@ class XModemAdapter
uint16_t packetno = 0; uint16_t packetno = 0;
#if defined(ARCH_NRF52) #if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
File file = File(FSCom); File file = File(FSCom);
#else #else
File file; File file;
+3
View File
@@ -36,6 +36,7 @@ cstyleCast
// ignore stuff that is not ours // ignore stuff that is not ours
*:.pio/* *:.pio/*
*:*/libdeps/* *:*/libdeps/*
*:*/generated/*
noExplicitConstructor:*/mqtt/* noExplicitConstructor:*/mqtt/*
postfixOperator:*/mqtt/* postfixOperator:*/mqtt/*
@@ -44,3 +45,5 @@ missingOverride
virtualCallInConstructor virtualCallInConstructor
passedByValue:*/RedirectablePrint.h passedByValue:*/RedirectablePrint.h
internalAstError:*/CrossPlatformCryptoEngine.cpp
+1
View File
@@ -9,6 +9,7 @@
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
#define ADC_MULTIPLIER 4.9 #define ADC_MULTIPLIER 4.9
#define USE_SX1262 #define USE_SX1262
+1
View File
@@ -10,6 +10,7 @@
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_CHANNEL ADC1_GPIO1_CHANNEL
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
#define ADC_MULTIPLIER 4.9 #define ADC_MULTIPLIER 4.9
#define USE_SX1262 #define USE_SX1262
+68
View File
@@ -0,0 +1,68 @@
#pragma once
// Pin definitions taken from:
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
static const uint8_t WB_IO1 = 6; // SLOT_A SLOT_B
static const uint8_t WB_IO2 = 22; // SLOT_A SLOT_B
static const uint8_t WB_IO3 = 7; // SLOT_C
static const uint8_t WB_IO4 = 28; // SLOT_C
static const uint8_t WB_IO5 = 9; // SLOT_D
static const uint8_t WB_IO6 = 8; // SLOT_D
static const uint8_t WB_A0 = 26; // IO_SLOT
static const uint8_t WB_A1 = 27; // IO_SLOT
#define PIN_A0 (26u)
#define PIN_A1 (27u)
#define PIN_A2 (28u)
#define PIN_A3 (29u)
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
// LEDs
#define PIN_LED (23u)
#define PIN_LED1 PIN_LED
#define PIN_LED2 (24u)
#define LED_BUILTIN PIN_LED
#define ADC_RESOLUTION 12
// Serial
#define PIN_SERIAL1_TX (0ul)
#define PIN_SERIAL1_RX (1ul)
#define PIN_SERIAL2_TX (4ul)
#define PIN_SERIAL2_RX (5ul)
// SPI
#define PIN_SPI0_MISO (12u)
#define PIN_SPI0_MOSI (11u)
#define PIN_SPI0_SCK (10u)
#define PIN_SPI0_SS (13u)
#define PIN_SPI1_MISO (16u)
#define PIN_SPI1_MOSI (19u)
#define PIN_SPI1_SCK (18u)
#define PIN_SPI1_SS (17u)
// Wire
#define PIN_WIRE0_SDA (2u)
#define PIN_WIRE0_SCL (3u)
#define PIN_WIRE1_SDA (20u)
#define PIN_WIRE1_SCL (21u)
#define SERIAL_HOWMANY (3u)
#define SPI_HOWMANY (2u)
#define WIRE_HOWMANY (2u)
static const uint8_t SS = PIN_SPI0_SS;
static const uint8_t MOSI = PIN_SPI0_MOSI;
static const uint8_t MISO = PIN_SPI0_MISO;
static const uint8_t SCK = PIN_SPI0_SCK;
static const uint8_t SDA = PIN_WIRE0_SDA;
static const uint8_t SCL = PIN_WIRE0_SCL;
+13
View File
@@ -0,0 +1,13 @@
[env:rak11310]
extends = rp2040_base
board = wiscore_rak11300
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
-DRAK11310
-Ivariants/rak11310
-DDEBUG_RP2040_PORT=Serial
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
+54
View File
@@ -0,0 +1,54 @@
// #define RADIOLIB_CUSTOM_ARDUINO 1
// #define RADIOLIB_TONE_UNSUPPORTED 1
// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
#define ARDUINO_ARCH_AVR
#undef CBC
#define CBC 0
#undef CTR
#define CTR 1
#undef ECB
#define ECB 0
#undef GPS_SERIAL_NUM
#define LED_CONN PIN_LED2
#define LED_PIN LED_BUILTIN
#define BUTTON_PIN 9
#define BUTTON_NEED_PULLUP
// #define EXT_NOTIFY_OUT 4
#define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
#define USE_SX1262
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
// RAK BSP somehow uses SPI1 instead of SPI0
#define HW_SPI1_DEVICE
#define RF95_SCK PIN_SPI0_SCK
#define RF95_MOSI PIN_SPI0_MOSI
#define RF95_MISO PIN_SPI0_MISO
#define RF95_NSS PIN_SPI0_SS
#define LORA_DIO0 RADIOLIB_NC
#define LORA_RESET 14
#define LORA_DIO1 29
#define LORA_DIO2 15
#define LORA_DIO3 RADIOLIB_NC
#ifdef USE_SX1262
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_POWER_EN 25
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#endif

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