Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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".
|
||||||
|
|||||||
@@ -150,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
|
||||||
@@ -168,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: .
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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,6 +1,6 @@
|
|||||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform = https://github.com/meshtastic/platform-native.git#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5
|
platform = https://github.com/meshtastic/platform-native.git#489ff929dca0bb768256ba2de45f95815111490f
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -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}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
[rp2040_base]
|
[rp2040_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
|
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.1
|
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
|
||||||
@@ -20,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
|
||||||
@@ -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
|
||||||
@@ -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"
|
||||||
|
|||||||
+8
-1
@@ -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
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule protobufs updated: 1a8f80d7fe...5f3daac5fa
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
+42
-1
@@ -37,12 +37,18 @@ static const adc_atten_t atten = ADC_ATTENUATION;
|
|||||||
#endif
|
#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
|
||||||
@@ -128,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
|
||||||
@@ -246,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;
|
||||||
@@ -639,7 +681,6 @@ bool Power::axpChipInit()
|
|||||||
// 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) {
|
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
|
||||||
// t-beam s3 core
|
// t-beam s3 core
|
||||||
/**
|
/**
|
||||||
|
|||||||
+12
-17
@@ -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
@@ -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>
|
||||||
|
|||||||
+16
-1
@@ -18,7 +18,7 @@
|
|||||||
* -------------------------------------------
|
* -------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name, bool isCaltopoMode)
|
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);
|
||||||
char type = isCaltopoMode ? 'P' : 'N';
|
char type = isCaltopoMode ? 'P' : 'N';
|
||||||
@@ -34,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
|
||||||
* | | | | | | | | | | | | | | |
|
* | | | | | | | | | | | | | | |
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
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_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);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#ifdef RAK4630
|
||||||
|
#include <NCP5623.h>
|
||||||
|
extern NCP5623 rgb;
|
||||||
|
|
||||||
|
#endif
|
||||||
+17
-16
@@ -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);
|
||||||
@@ -792,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);
|
||||||
|
|
||||||
@@ -835,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;
|
||||||
|
|
||||||
@@ -850,14 +851,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
bool hasNodeHeading = false;
|
bool hasNodeHeading = false;
|
||||||
|
|
||||||
if (ourNode && hasValidPosition(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 (hasValidPosition(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));
|
||||||
|
|
||||||
@@ -1239,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;
|
||||||
|
|
||||||
@@ -1258,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
|
||||||
@@ -1272,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;
|
||||||
|
|
||||||
|
|||||||
+40
-10
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -530,6 +550,18 @@ void setup()
|
|||||||
#endif
|
#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) {
|
||||||
@@ -651,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
|
||||||
@@ -677,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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,7 +238,8 @@ 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 (hasValidPosition(node)) {
|
if (hasValidPosition(node)) {
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
+151
-61
@@ -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
|
||||||
@@ -216,6 +225,15 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
moduleConfig.has_store_forward = true;
|
moduleConfig.has_store_forward = true;
|
||||||
moduleConfig.has_telemetry = true;
|
moduleConfig.has_telemetry = true;
|
||||||
moduleConfig.has_external_notification = true;
|
moduleConfig.has_external_notification = true;
|
||||||
|
#if defined(RAK4630) || defined(RAK11310)
|
||||||
|
// Default to RAK led pin 2 (blue)
|
||||||
|
moduleConfig.external_notification.enabled = true;
|
||||||
|
moduleConfig.external_notification.output = PIN_LED2;
|
||||||
|
moduleConfig.external_notification.active = true;
|
||||||
|
moduleConfig.external_notification.alert_message = true;
|
||||||
|
moduleConfig.external_notification.output_ms = 1000;
|
||||||
|
moduleConfig.external_notification.nag_timeout = 60;
|
||||||
|
#endif
|
||||||
moduleConfig.has_canned_message = true;
|
moduleConfig.has_canned_message = true;
|
||||||
|
|
||||||
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
||||||
@@ -258,6 +276,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 +293,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 +319,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 +354,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 +384,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,7 +603,7 @@ void NodeDB::saveToDisk(int saveWhat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
|
||||||
{
|
{
|
||||||
if (readIndex < *numNodes)
|
if (readIndex < *numNodes)
|
||||||
return &nodes[readIndex++];
|
return &nodes[readIndex++];
|
||||||
@@ -592,8 +611,16 @@ const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
|
||||||
|
{
|
||||||
|
if (readIndex < *numMeshNodes)
|
||||||
|
return &meshNodes[readIndex++];
|
||||||
|
else
|
||||||
|
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 +644,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 +662,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 +671,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 +691,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 +707,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 +729,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 +762,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 +779,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 +790,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 +799,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 +908,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
|
||||||
|
|||||||
+46
-21
@@ -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,9 +48,12 @@ class NodeDB
|
|||||||
meshtastic_NodeInfo *nodes;
|
meshtastic_NodeInfo *nodes;
|
||||||
pb_size_t *numNodes;
|
pb_size_t *numNodes;
|
||||||
|
|
||||||
|
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)
|
||||||
@@ -89,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);
|
||||||
|
|
||||||
@@ -102,26 +105,14 @@ class NodeDB
|
|||||||
their denial?)
|
their denial?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
|
|
||||||
const meshtastic_NodeInfo *readNextInfo(uint32_t &readIndex);
|
|
||||||
|
|
||||||
/// 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();
|
||||||
|
|
||||||
@@ -132,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,12 +232,23 @@ static inline bool hasValidPosition(const meshtastic_NodeInfo *n)
|
|||||||
{
|
{
|
||||||
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
|
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 + \
|
||||||
|
|||||||
+14
-11
@@ -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,7 +41,7 @@ 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
|
||||||
resetReadIndex();
|
resetReadIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,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;
|
||||||
@@ -371,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(readIndex);
|
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: {
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ 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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
@@ -157,7 +163,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_LocalConfig_size 461
|
#define meshtastic_LocalConfig_size 461
|
||||||
#define meshtastic_LocalModuleConfig_size 535
|
#define meshtastic_LocalModuleConfig_size 545
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -372,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...
|
||||||
@@ -578,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,
|
||||||
@@ -600,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 */
|
||||||
@@ -610,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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,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 */
|
||||||
@@ -313,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;
|
||||||
|
|
||||||
@@ -345,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
|
||||||
@@ -365,6 +377,7 @@ 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, 0}
|
#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}
|
||||||
@@ -376,6 +389,7 @@ 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, 0}
|
#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}
|
||||||
@@ -394,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
|
||||||
@@ -464,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) \
|
||||||
@@ -475,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
|
||||||
@@ -487,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) \
|
||||||
@@ -508,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) \
|
||||||
@@ -601,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;
|
||||||
@@ -614,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
|
||||||
@@ -628,6 +655,7 @@ 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 28
|
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
@@ -164,14 +167,14 @@ 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 (hasValidPosition(node2)) {
|
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.
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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,11 +57,16 @@
|
|||||||
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;
|
||||||
static Print *serialPrint = &Serial2;
|
|
||||||
|
|
||||||
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
||||||
{
|
{
|
||||||
@@ -119,8 +123,6 @@ int32_t SerialModule::runOnce()
|
|||||||
serialPrint = &Serial;
|
serialPrint = &Serial;
|
||||||
// Give it a chance to flush out 💩
|
// Give it a chance to flush out 💩
|
||||||
delay(10);
|
delay(10);
|
||||||
} else {
|
|
||||||
serialPrint = &Serial2;
|
|
||||||
}
|
}
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ int32_t SerialModule::runOnce()
|
|||||||
Serial.begin(baud);
|
Serial.begin(baud);
|
||||||
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||||
}
|
}
|
||||||
#else
|
#elif !defined(TTGO_T_ECHO)
|
||||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||||
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
||||||
Serial2.begin(baud, SERIAL_8N1);
|
Serial2.begin(baud, SERIAL_8N1);
|
||||||
@@ -140,6 +142,9 @@ int32_t SerialModule::runOnce()
|
|||||||
Serial.begin(baud, SERIAL_8N1);
|
Serial.begin(baud, SERIAL_8N1);
|
||||||
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
Serial.begin(baud, SERIAL_8N1);
|
||||||
|
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||||
#endif
|
#endif
|
||||||
serialModuleRadio = new SerialModuleRadio();
|
serialModuleRadio = new SerialModuleRadio();
|
||||||
|
|
||||||
@@ -156,26 +161,29 @@ int32_t SerialModule::runOnce()
|
|||||||
// 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);
|
||||||
serialPrint->printf("%s", outbuf);
|
serialPrint->printf("%s", outbuf);
|
||||||
}
|
}
|
||||||
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
|
} else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) {
|
||||||
if (millis() - lastNmeaTime > 10000) {
|
if (millis() - lastNmeaTime > 10000) {
|
||||||
lastNmeaTime = millis();
|
lastNmeaTime = millis();
|
||||||
uint32_t readIndex = 0;
|
uint32_t readIndex = 0;
|
||||||
const meshtastic_NodeInfo *tempNodeInfo = nodeDB.readNextInfo(readIndex);
|
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
|
||||||
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
|
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
|
||||||
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
|
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
|
||||||
serialPrint->printf("%s", outbuf);
|
serialPrint->printf("%s", outbuf);
|
||||||
tempNodeInfo = nodeDB.readNextInfo(readIndex);
|
tempNodeInfo = nodeDB.readNextMeshNode(readIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
#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 {
|
||||||
@@ -243,7 +251,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
|
|||||||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
|
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
|
||||||
serialPrint->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 : "???";
|
||||||
serialPrint->println();
|
serialPrint->println();
|
||||||
serialPrint->printf("%s: %s", sender, p.payload.bytes);
|
serialPrint->printf("%s: %s", sender, p.payload.bytes);
|
||||||
@@ -259,7 +267,7 @@ 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,
|
||||||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO);
|
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO);
|
||||||
serialPrint->printf("%s", outbuf);
|
serialPrint->printf("%s", outbuf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -83,15 +80,10 @@ 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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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_ */
|
||||||
@@ -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
|
||||||
@@ -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_ */
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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,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
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
@@ -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
@@ -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");
|
||||||
|
|||||||
+1
-1
@@ -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;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#undef GPS_SERIAL_NUM
|
#undef GPS_SERIAL_NUM
|
||||||
|
|
||||||
#define LED_CONN PIN_LED2
|
#define LED_CONN PIN_LED2
|
||||||
|
#define LED_PIN LED_BUILTIN
|
||||||
|
|
||||||
#define BUTTON_PIN 9
|
#define BUTTON_PIN 9
|
||||||
#define BUTTON_NEED_PULLUP
|
#define BUTTON_NEED_PULLUP
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
|||||||
#define PIN_ETHERNET_RESET 21
|
#define PIN_ETHERNET_RESET 21
|
||||||
#define PIN_ETHERNET_SS PIN_EINK_CS
|
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||||
#define ETH_SPI_PORT SPI1
|
#define ETH_SPI_PORT SPI1
|
||||||
|
#define AQ_SET_PIN 10
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
[env:wio-e5]
|
[env:wio-e5]
|
||||||
extends = stm32wl5e_base
|
extends = stm32wl5e_base
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags = ${stm32wl5e_base.build_flags} -Ivariants/wio-e5 -DHAL_DAC_MODULE_ONLY
|
build_flags =
|
||||||
-DSERIAL_UART_INSTANCE=1 -DPIN_SERIAL_RX=PB7 -DPIN_SERIAL_TX=PB6
|
${stm32wl5e_base.build_flags}
|
||||||
|
-Ivariants/wio-e5
|
||||||
|
-DHAL_DAC_MODULE_ONLY
|
||||||
|
-DSERIAL_UART_INSTANCE=1
|
||||||
|
-DPIN_SERIAL_RX=PB7
|
||||||
|
-DPIN_SERIAL_TX=PB6
|
||||||
|
upload_port = stlink
|
||||||
@@ -12,18 +12,6 @@ Do not expect a working Meshtastic device with this target.
|
|||||||
#ifndef _VARIANT_WIOE5_
|
#ifndef _VARIANT_WIOE5_
|
||||||
#define _VARIANT_WIOE5_
|
#define _VARIANT_WIOE5_
|
||||||
|
|
||||||
// Arduino/PlatformIO support for SUBGHZSPI is not currently available
|
#define USE_STM32WLx
|
||||||
//#define USE_SX1262
|
|
||||||
|
|
||||||
#ifdef USE_SX1262
|
|
||||||
#define HAS_RADIO 1
|
|
||||||
|
|
||||||
/* module only transmits through RFO_HP */
|
|
||||||
#define SX126X_RXEN PA5
|
|
||||||
#define SX126X_TXEN PA4
|
|
||||||
|
|
||||||
/* TCXO fed by internal LDO option behind PB0 pin */
|
|
||||||
#define SX126X_E22
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 1
|
minor = 1
|
||||||
build = 15
|
build = 17
|
||||||
|
|||||||
Reference in New Issue
Block a user