Merge branch 'meshtastic:master' into master

This commit is contained in:
Mictronics 2024-11-21 19:37:06 +01:00 committed by GitHub
commit 2793bae6bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 386 additions and 140 deletions

View File

@ -51,6 +51,7 @@ runs:
file: build.tar
target: build.tar
token: ${{ inputs.github_token }}
version: tags/v2.5.3
- name: Unpack web ui
if: inputs.include-web-ui == 'true'

View File

@ -13,8 +13,8 @@ jobs:
- name: Install libbluetooth
shell: bash
run: |
apt-get update -y --fix-missing
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
sudo apt-get update -y --fix-missing
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code
uses: actions/checkout@v4

View File

@ -203,6 +203,7 @@ jobs:
./device-*.sh
./device-*.bat
./littlefs-*.bin
./littlefswebui-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30

View File

@ -16,6 +16,7 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMAX_NUM_NODES=80
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>

View File

@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#v1.2.0-gcc12
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.0.3
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m

View File

@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets
[rp2350_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9e55f6db5c56b9867c69fe473f388beea4546672
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#a6ab6e1f95bc1428d667d55ea7173c0744acc03c ; 4.0.2+
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@ -22,4 +22,4 @@ lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto
rweather/Crypto

33
bin/base64_to_hex.py Normal file
View File

@ -0,0 +1,33 @@
import sys
import base64
def base64_to_hex_string(b64_string):
try:
# Decode the Base64 string to raw bytes
decoded_bytes = base64.b64decode(b64_string)
except Exception as e:
raise ValueError(f"Invalid Base64 input: {e}")
# Check if the decoded result is exactly 32 bytes
if len(decoded_bytes) != 32:
raise ValueError("Decoded Base64 input must be exactly 32 bytes.")
# Convert each byte to its hex representation
hex_values = [f"0x{byte:02x}" for byte in decoded_bytes]
# Join the formatted hex values with commas
formatted_output = "{ " + ", ".join(hex_values) + " };"
return formatted_output
if __name__ == "__main__":
# Check if a Base64 string was provided in command line arguments
if len(sys.argv) != 2:
print("Usage: python script.py <base64-string>")
sys.exit(1)
b64_string = sys.argv[1]
try:
formatted_hex = base64_to_hex_string(b64_string)
print(formatted_hex)
except ValueError as e:
print(e)

View File

@ -35,6 +35,11 @@ cp $SRCBIN $OUTDIR/$basename-update.bin
echo "Building Filesystem for ESP32 targets"
pio run --environment $1 -t buildfs
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$VERSION.bin
# Remove webserver files from the filesystem and rebuild
ls -l data/static # Diagnostic list of files
rm -rf data/static
pio run --environment $1 -t buildfs
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

View File

@ -1,6 +1,7 @@
@ECHO OFF
set PYTHON=python
set WEB_APP=0
:: Determine the correct esptool command to use
where esptool >nul 2>&1
@ -12,13 +13,14 @@ if %ERRORLEVEL% EQU 0 (
goto GETOPTS
:HELP
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME]
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] [--web]
echo Flash image file to device, but first erasing and writing system information
echo.
echo -h Display this help and exit
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
echo -f FILENAME The .bin file to flash. Custom to your device type and region.
echo --web Flash WEB APP.
goto EOF
:GETOPTS
@ -27,6 +29,7 @@ if /I "%1"=="--help" goto HELP
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
if /I "%1"=="--web" set WEB_APP=1 & SHIFT
SHIFT
IF NOT "__%1__"=="____" goto GETOPTS
@ -49,8 +52,14 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
) else (
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
)
for %%f in (littlefs-*.bin) do (
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
IF %WEB_APP%==1 (
for %%f in (littlefsweb-*.bin) do (
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
)
) else (
for %%f in (littlefs-*.bin) do (
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
)
)
) else (
echo "Invalid file: %FILENAME%"

View File

@ -1,6 +1,7 @@
#!/bin/sh
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
WEB_APP=false
# Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
@ -19,16 +20,26 @@ set -e
# Usage info
show_help() {
cat <<EOF
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--web]
Flash image file to device, but first erasing and writing system information"
-h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The .bin file to flash. Custom to your device type and region.
--web Flash WEB APP.
EOF
}
# Preprocess long options like --web
for arg in "$@"; do
case "$arg" in
--web)
WEB_APP=true
shift # Remove this argument from the list
;;
esac
done
while getopts ":hp:P:f:" opt; do
case "${opt}" in
@ -73,7 +84,11 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
else
$ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
fi
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
if [ "$WEB_APP" = true ]; then
$ESPTOOL_CMD write_flash 0x300000 littlefsweb-*.bin
else
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
fi
else
show_help

@ -1 +1 @@
Subproject commit af2fea10fe2eba5857fb8e27975bbcea9c10af8e
Subproject commit af7521c3a77d56eb7a64efae5637a311ac33f76d

View File

@ -1,4 +1,5 @@
#include "ButtonThread.h"
#include "../userPrefs.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h"
@ -26,12 +27,12 @@ using namespace concurrency;
ButtonThread *buttonThread; // Declared extern in header
volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE;
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
OneButton ButtonThread::userButton; // Get reference to static member
#endif
ButtonThread::ButtonThread() : OSThread("Button")
{
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
#if defined(ARCH_PORTDUINO)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
@ -39,7 +40,12 @@ ButtonThread::ButtonThread() : OSThread("Button")
LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]);
}
#elif defined(BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
#if !defined(USERPREFS_BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
#endif
#ifdef USERPREFS_BUTTON_PIN
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
#endif
#if defined(HELTEC_CAPSULE_SENSOR_V3)
this->userButton = OneButton(pin, false, false);
#elif defined(BUTTON_ACTIVE_LOW)
@ -59,7 +65,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#endif
#endif
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
userButton.attachClick(userButtonPressed);
userButton.setClickMs(BUTTON_CLICK_MS);
userButton.setPressMs(BUTTON_LONGPRESS_MS);
@ -102,7 +108,7 @@ int32_t ButtonThread::runOnce()
// If the button is pressed we suppress CPU sleep until release
canSleep = true; // Assume we should not keep the board awake
#if defined(BUTTON_PIN)
#if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
userButton.tick();
canSleep &= userButton.isIdle();
#elif defined(ARCH_PORTDUINO)
@ -130,7 +136,12 @@ int32_t ButtonThread::runOnce()
return 50;
}
#ifdef BUTTON_PIN
#if !defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
#endif
#if defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
#endif
moduleConfig.canned_message.inputbroker_pin_press) ||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
!moduleConfig.canned_message.enabled) {
@ -244,7 +255,12 @@ void ButtonThread::attachButtonInterrupts()
#elif defined(BUTTON_PIN)
// Interrupt for user button, during normal use. Improves responsiveness.
attachInterrupt(
#if !defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN,
#endif
#if defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN,
#endif
[]() {
ButtonThread::userButton.tick();
runASAP = true;
@ -273,8 +289,13 @@ void ButtonThread::detachButtonInterrupts()
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
detachInterrupt(settingsMap[user]);
#elif defined(BUTTON_PIN)
#if !defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
#endif
#if defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN);
#endif
#endif
#ifdef BUTTON_PIN_ALT
detachInterrupt(BUTTON_PIN_ALT);
@ -315,7 +336,7 @@ void ButtonThread::userButtonMultiPressed(void *callerThread)
// Non-static method, runs during callback. Grabs info while still valid
void ButtonThread::storeClickCount()
{
#ifdef BUTTON_PIN
#if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
multipressClickCount = userButton.getNumberClicks();
#endif
}

View File

@ -38,7 +38,7 @@ class ButtonThread : public concurrency::OSThread
void storeClickCount();
private:
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
static OneButton userButton; // Static - accessed from an interrupt
#endif
#ifdef BUTTON_PIN_ALT

View File

@ -788,7 +788,8 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
void GPS::writePinEN(bool on)
{
// Abort: if conflict with Canned Messages when using Wisblock(?)
if (HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))
if ((HW_VENDOR == meshtastic_HardwareModel_RAK4631 || HW_VENDOR == meshtastic_HardwareModel_WISMESH_TAP) &&
(rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))
return;
// Write and log

View File

@ -23,7 +23,7 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, c
{
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(),
uint32_t len = snprintf(buf, bufsz, "\r\n$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(), name);

View File

@ -101,9 +101,9 @@ std::vector<MeshModule *> moduleFrames;
static char ourId[5];
// vector where symbols (string) are displayed in bottom corner of display.
std::vector<std::string> functionSymbals;
// string displayed in bottom right corner of display. Created from elements in functionSymbals vector
std::string functionSymbalString = "";
std::vector<std::string> functionSymbol;
// string displayed in bottom right corner of display. Created from elements in functionSymbol vector
std::string functionSymbolString = "";
#if HAS_GPS
// GeoCoord object for the screen
@ -243,10 +243,10 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
{
// LOG_DEBUG("Draw function overlay");
if (functionSymbals.begin() != functionSymbals.end()) {
if (functionSymbol.begin() != functionSymbol.end()) {
char buf[64];
display->setFont(FONT_SMALL);
snprintf(buf, sizeof(buf), "%s", functionSymbalString.c_str());
snprintf(buf, sizeof(buf), "%s", functionSymbolString.c_str());
display->drawString(SCREEN_WIDTH - display->getStringWidth(buf), SCREEN_HEIGHT - FONT_HEIGHT_SMALL, buf);
}
}
@ -958,55 +958,65 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
display->setColor(WHITE);
#ifndef EXCLUDE_EMOJI
if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44D") == 0) {
const char *msg = reinterpret_cast<const char *>(mp.decoded.payload.bytes);
if (strcmp(msg, "\U0001F44D") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
thumbup);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44E") == 0) {
} else if (strcmp(msg, "\U0001F44E") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
thumbdown);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "") == 0) {
} else if (strcmp(msg, "\U0001F60A") == 0 || strcmp(msg, "\U0001F600") == 0 || strcmp(msg, "\U0001F642") == 0 ||
strcmp(msg, "\U0001F609") == 0 ||
strcmp(msg, "\U0001F601") == 0) { // matches 5 different common smileys, so that the phone user doesn't have to
// remember which one is compatible
display->drawXbm(x + (SCREEN_WIDTH - smiley_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - smiley_height) / 2 + 2 + 5, smiley_width, smiley_height,
smiley);
} else if (strcmp(msg, "") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height,
question);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "‼️") == 0) {
} else if (strcmp(msg, "‼️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5,
bang_width, bang_height, bang);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F4A9") == 0) {
} else if (strcmp(msg, "\U0001F4A9") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5,
poo_width, poo_height, poo);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) {
} else if (strcmp(msg, "\U0001F923") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5,
haha_width, haha_height, haha);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44B") == 0) {
} else if (strcmp(msg, "\U0001F44B") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width,
wave_icon_height, wave_icon);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F920") == 0) {
} else if (strcmp(msg, "\U0001F920") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height,
cowboy);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F42D") == 0) {
} else if (strcmp(msg, "\U0001F42D") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height,
deadmau5);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) {
} else if (strcmp(msg, "\xE2\x98\x80\xEF\xB8\x8F") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5,
sun_width, sun_height, sun);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\u2614") == 0) {
} else if (strcmp(msg, "\u2614") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10,
rain_width, rain_height, rain);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "☁️") == 0) {
} else if (strcmp(msg, "☁️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "🌫️") == 0) {
} else if (strcmp(msg, "🌫️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5,
fog_width, fog_height, fog);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) {
} else if (strcmp(msg, "\U0001F608") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "♥️") == 0) {
} else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F496") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
} else {
@ -2242,24 +2252,24 @@ void Screen::decreaseBrightness()
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/
}
void Screen::setFunctionSymbal(std::string sym)
void Screen::setFunctionSymbol(std::string sym)
{
if (std::find(functionSymbals.begin(), functionSymbals.end(), sym) == functionSymbals.end()) {
functionSymbals.push_back(sym);
functionSymbalString = "";
for (auto symbol : functionSymbals) {
functionSymbalString = symbol + " " + functionSymbalString;
if (std::find(functionSymbol.begin(), functionSymbol.end(), sym) == functionSymbol.end()) {
functionSymbol.push_back(sym);
functionSymbolString = "";
for (auto symbol : functionSymbol) {
functionSymbolString = symbol + " " + functionSymbolString;
}
setFastFramerate();
}
}
void Screen::removeFunctionSymbal(std::string sym)
void Screen::removeFunctionSymbol(std::string sym)
{
functionSymbals.erase(std::remove(functionSymbals.begin(), functionSymbals.end(), sym), functionSymbals.end());
functionSymbalString = "";
for (auto symbol : functionSymbals) {
functionSymbalString = symbol + " " + functionSymbalString;
functionSymbol.erase(std::remove(functionSymbol.begin(), functionSymbol.end(), sym), functionSymbol.end());
functionSymbolString = "";
for (auto symbol : functionSymbol) {
functionSymbolString = symbol + " " + functionSymbolString;
}
setFastFramerate();
}
@ -2747,4 +2757,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg)
} // namespace graphics
#else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
#endif // HAS_SCREEN
#endif // HAS_SCREEN

View File

@ -24,8 +24,8 @@ class Screen
void startFirmwareUpdateScreen() {}
void increaseBrightness() {}
void decreaseBrightness() {}
void setFunctionSymbal(std::string) {}
void removeFunctionSymbal(std::string) {}
void setFunctionSymbol(std::string) {}
void removeFunctionSymbol(std::string) {}
void startAlert(const char *) {}
void endAlert() {}
};
@ -282,8 +282,8 @@ class Screen : public concurrency::OSThread
void increaseBrightness();
void decreaseBrightness();
void setFunctionSymbal(std::string sym);
void removeFunctionSymbal(std::string sym);
void setFunctionSymbol(std::string sym);
void removeFunctionSymbol(std::string sym);
/// Stops showing the boot screen.
void stopBootScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BOOT_SCREEN}); }
@ -605,4 +605,4 @@ class Screen : public concurrency::OSThread
} // namespace graphics
#endif
#endif

View File

@ -56,6 +56,16 @@ static unsigned char thumbdown[] PROGMEM = {
0x80, 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00,
};
#define smiley_height 30
#define smiley_width 30
static unsigned char smiley[] PROGMEM = {
0x00, 0xfe, 0x0f, 0x00, 0x80, 0x01, 0x30, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x02,
0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x10, 0x02, 0x0e, 0x0e, 0x10, 0x02, 0x09, 0x12, 0x10,
0x01, 0x09, 0x12, 0x20, 0x01, 0x0f, 0x1e, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x81, 0x00, 0x20, 0x20,
0x82, 0x00, 0x20, 0x10, 0x02, 0x01, 0x10, 0x10, 0x04, 0x02, 0x08, 0x08, 0x04, 0xfc, 0x07, 0x08, 0x08, 0x00, 0x00, 0x04,
0x10, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x40, 0x00, 0xc0, 0x00, 0x80, 0x01, 0x30, 0x00, 0x00, 0xfe, 0x0f, 0x00};
#define question_height 25
#define question_width 25
static unsigned char question[] PROGMEM = {

View File

@ -114,7 +114,7 @@ NodeDB::NodeDB()
uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile));
int saveWhat = 0;
bool hasUniqueId = false;
// bool hasUniqueId = false;
// Get device unique id
#if defined(ARCH_ESP32) && defined(ESP_EFUSE_OPTIONAL_UNIQUE_ID)
uint32_t unique_id[4];
@ -246,6 +246,31 @@ NodeDB::NodeDB()
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
config.position.gps_enabled = 0;
}
#ifdef USERPREFS_FIXED_GPS
if (myNodeInfo.reboot_count == 1) { // Check if First boot ever or after Factory Reset.
meshtastic_Position fixedGPS = meshtastic_Position_init_default;
#ifdef USERPREFS_FIXED_GPS_LAT
fixedGPS.latitude_i = (int32_t)(USERPREFS_FIXED_GPS_LAT * 1e7);
fixedGPS.has_latitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_LON
fixedGPS.longitude_i = (int32_t)(USERPREFS_FIXED_GPS_LON * 1e7);
fixedGPS.has_longitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_ALT
fixedGPS.altitude = USERPREFS_FIXED_GPS_ALT;
fixedGPS.has_altitude = true;
#endif
#if defined(USERPREFS_FIXED_GPS_LAT) && defined(USERPREFS_FIXED_GPS_LON)
fixedGPS.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
config.has_position = true;
info->has_position = true;
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
nodeDB->setLocalPosition(fixedGPS);
config.position.fixed_position = true;
#endif
}
#endif
saveToDisk(saveWhat);
}
@ -382,9 +407,30 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
config.lora.ignore_mqtt = false;
#endif
#ifdef USERPREFS_USE_ADMIN_KEY
memcpy(config.security.admin_key[0].bytes, USERPREFS_ADMIN_KEY, 32);
config.security.admin_key[0].size = 32;
config.security.admin_key_count = 1;
// Initialize admin_key_count to zero
byte numAdminKeys = 0;
// Check if USERPREFS_ADMIN_KEY_0 is non-empty
if (sizeof(USERPREFS_ADMIN_KEY_0) > 0) {
memcpy(config.security.admin_key[numAdminKeys].bytes, USERPREFS_ADMIN_KEY_0, 32);
config.security.admin_key[numAdminKeys].size = 32;
numAdminKeys++;
}
// Check if USERPREFS_ADMIN_KEY_1 is non-empty
if (sizeof(USERPREFS_ADMIN_KEY_1) > 0) {
memcpy(config.security.admin_key[numAdminKeys].bytes, USERPREFS_ADMIN_KEY_1, 32);
config.security.admin_key[numAdminKeys].size = 32;
numAdminKeys++;
}
// Check if USERPREFS_ADMIN_KEY_2 is non-empty
if (sizeof(USERPREFS_ADMIN_KEY_2) > 0) {
memcpy(config.security.admin_key[config.security.admin_key_count].bytes, USERPREFS_ADMIN_KEY_2, 32);
config.security.admin_key[config.security.admin_key_count].size = 32;
numAdminKeys++;
}
config.security.admin_key_count = numAdminKeys;
#endif
if (shouldPreserveKey) {
config.security.private_key.size = 32;
@ -438,8 +484,13 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#else
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
#endif
#ifdef USERPREFS_FIXED_BLUETOOTH
config.bluetooth.fixed_pin = USERPREFS_FIXED_BLUETOOTH;
config.bluetooth.mode = meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#else
config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#endif
// for backward compat, default position flags are ALT+MSL
config.position.position_flags =
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL |
@ -793,8 +844,13 @@ void NodeDB::loadFromDisk()
0; // Mark the current device state as completely unusable, so that if we fail reading the entire file from
// disk we will still factoryReset to restore things.
#ifdef ARCH_ESP32
if (FSCom.exists("/static/static"))
rmDir("/static/static"); // Remove bad static web files bundle from initial 2.5.13 release
#endif
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo),
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES_FS * sizeof(meshtastic_NodeInfo),
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
// See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786
@ -813,6 +869,10 @@ void NodeDB::loadFromDisk()
meshNodes = &devicestate.node_db_lite;
numMeshNodes = devicestate.node_db_lite.size();
}
if (numMeshNodes > MAX_NUM_NODES) {
LOG_WARN("Node count %d exceeds MAX_NUM_NODES %d, truncating", numMeshNodes, MAX_NUM_NODES);
numMeshNodes = MAX_NUM_NODES;
}
meshNodes->resize(MAX_NUM_NODES);
state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,

View File

@ -601,8 +601,6 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
// LOG_DEBUG("Send queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
assert(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag); // It should have already been encoded by now
lastTxStart = millis();
radioBuffer.header.from = p->from;
radioBuffer.header.to = p->to;
radioBuffer.header.id = p->id;

View File

@ -278,7 +278,8 @@ void RadioLibInterface::onNotify(uint32_t notification)
startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again
setTransmitDelay();
} else {
// Send any outgoing packets we have ready
// Send any outgoing packets we have ready as fast as possible to keep the time between channel scan and
// actual transmission as short as possible
meshtastic_MeshPacket *txp = txQueue.dequeue();
assert(txp);
bool sent = startSend(txp);
@ -470,7 +471,8 @@ void RadioLibInterface::setStandby()
/** start an immediate transmit */
bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
{
printPacket("Start low level send", txp);
/* NOTE: Minimize the actions before startTransmit() to keep the time between
channel scan and actual transmit as low as possible to avoid collisions. */
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("Drop Tx packet because LoRa Tx disabled");
packetPool.release(txp);
@ -489,6 +491,9 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
completeSending();
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
} else {
lastTxStart = millis();
printPacket("Started Tx", txp);
}
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register

View File

@ -49,6 +49,8 @@ typedef enum _meshtastic_Language {
meshtastic_Language_DUTCH = 12,
/* Greek */
meshtastic_Language_GREEK = 13,
/* Norwegian */
meshtastic_Language_NORWEGIAN = 14,
/* Simplified Chinese (experimental) */
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
/* Traditional Chinese (experimental) */
@ -84,6 +86,7 @@ typedef struct _meshtastic_NodeHighlight {
char node_name[16];
} meshtastic_NodeHighlight;
typedef PB_BYTES_ARRAY_T(16) meshtastic_DeviceUIConfig_calibration_data_t;
typedef struct _meshtastic_DeviceUIConfig {
/* A version integer used to invalidate saved files when we make incompatible changes. */
uint32_t version;
@ -109,6 +112,8 @@ typedef struct _meshtastic_DeviceUIConfig {
/* Node list highlightening */
bool has_node_highlight;
meshtastic_NodeHighlight node_highlight;
/* 8 integers for screen calibration data */
meshtastic_DeviceUIConfig_calibration_data_t calibration_data;
} meshtastic_DeviceUIConfig;
@ -132,10 +137,10 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default}
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}}
#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""}
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero}
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}}
#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""}
@ -164,6 +169,7 @@ extern "C" {
#define meshtastic_DeviceUIConfig_language_tag 11
#define meshtastic_DeviceUIConfig_node_filter_tag 12
#define meshtastic_DeviceUIConfig_node_highlight_tag 13
#define meshtastic_DeviceUIConfig_calibration_data_tag 14
/* Struct field encoding specification for nanopb */
#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \
@ -179,7 +185,8 @@ X(a, STATIC, SINGULAR, BOOL, banner_enabled, 9) \
X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \
X(a, STATIC, SINGULAR, UENUM, language, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13)
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13) \
X(a, STATIC, SINGULAR, BYTES, calibration_data, 14)
#define meshtastic_DeviceUIConfig_CALLBACK NULL
#define meshtastic_DeviceUIConfig_DEFAULT NULL
#define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter
@ -215,7 +222,7 @@ extern const pb_msgdesc_t meshtastic_NodeHighlight_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size
#define meshtastic_DeviceUIConfig_size 99
#define meshtastic_DeviceUIConfig_size 117
#define meshtastic_NodeFilter_size 36
#define meshtastic_NodeHighlight_size 25

View File

@ -90,6 +90,8 @@ typedef struct _meshtastic_NodeInfoLite {
/* True if node is in our ignored list
Persists between NodeDB internal clean ups */
bool is_ignored;
/* Last byte of the node number of the node that should be used as the next hop to reach this node. */
uint8_t next_hop;
} meshtastic_NodeInfoLite;
/* This message is never sent over the wire, but it is used for serializing DB
@ -153,12 +155,12 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0}
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
@ -186,6 +188,7 @@ extern "C" {
#define meshtastic_NodeInfoLite_hops_away_tag 9
#define meshtastic_NodeInfoLite_is_favorite_tag 10
#define meshtastic_NodeInfoLite_is_ignored_tag 11
#define meshtastic_NodeInfoLite_next_hop_tag 12
#define meshtastic_DeviceState_my_node_tag 2
#define meshtastic_DeviceState_owner_tag 3
#define meshtastic_DeviceState_receive_queue_tag 5
@ -231,7 +234,8 @@ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11)
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \
X(a, STATIC, SINGULAR, UINT32, next_hop, 12)
#define meshtastic_NodeInfoLite_CALLBACK NULL
#define meshtastic_NodeInfoLite_DEFAULT NULL
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite
@ -284,7 +288,7 @@ extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
/* meshtastic_DeviceState_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_ChannelFile_size
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 185
#define meshtastic_NodeInfoLite_size 188
#define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96

View File

@ -212,6 +212,9 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_MS24SF1 = 82,
/* Lilygo TLora-C6 with the new ESP32-C6 MCU */
meshtastic_HardwareModel_TLORA_C6 = 83,
/* WisMesh Tap
RAK-4631 w/ TFT in injection modled case */
meshtastic_HardwareModel_WISMESH_TAP = 84,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@ -751,6 +754,12 @@ typedef struct _meshtastic_MeshPacket {
meshtastic_MeshPacket_public_key_t public_key;
/* Indicates whether the packet was en/decrypted using PKI */
bool pki_encrypted;
/* Last byte of the node number of the node that should be used as the next hop in routing.
Set by the firmware internally, clients are not supposed to set this. */
uint8_t next_hop;
/* Last byte of the node number of the node that will relay/relayed this packet.
Set by the firmware internally, clients are not supposed to set this. */
uint8_t relay_node;
} meshtastic_MeshPacket;
/* The bluetooth to device link:
@ -1159,7 +1168,7 @@ extern "C" {
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
@ -1184,7 +1193,7 @@ extern "C" {
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
@ -1280,6 +1289,8 @@ extern "C" {
#define meshtastic_MeshPacket_hop_start_tag 15
#define meshtastic_MeshPacket_public_key_tag 16
#define meshtastic_MeshPacket_pki_encrypted_tag 17
#define meshtastic_MeshPacket_next_hop_tag 18
#define meshtastic_MeshPacket_relay_node_tag 19
#define meshtastic_NodeInfo_num_tag 1
#define meshtastic_NodeInfo_user_tag 2
#define meshtastic_NodeInfo_position_tag 3
@ -1474,7 +1485,9 @@ X(a, STATIC, SINGULAR, UENUM, delayed, 13) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 14) \
X(a, STATIC, SINGULAR, UINT32, hop_start, 15) \
X(a, STATIC, SINGULAR, BYTES, public_key, 16) \
X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17)
X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17) \
X(a, STATIC, SINGULAR, UINT32, next_hop, 18) \
X(a, STATIC, SINGULAR, UINT32, relay_node, 19)
#define meshtastic_MeshPacket_CALLBACK NULL
#define meshtastic_MeshPacket_DEFAULT NULL
#define meshtastic_MeshPacket_payload_variant_decoded_MSGTYPE meshtastic_Data
@ -1724,7 +1737,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_FromRadio_size 510
#define meshtastic_Heartbeat_size 0
#define meshtastic_LogRecord_size 426
#define meshtastic_MeshPacket_size 367
#define meshtastic_MeshPacket_size 375
#define meshtastic_MqttClientProxyMessage_size 501
#define meshtastic_MyNodeInfo_size 77
#define meshtastic_NeighborInfo_size 258

View File

@ -74,6 +74,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
ResourceNode *nodeAPIv1ToRadioOptions = new ResourceNode("/api/v1/toradio", "OPTIONS", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1FromRadioOptions = new ResourceNode("/api/v1/fromradio", "OPTIONS", &handleAPIv1FromRadio);
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
// ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
@ -100,6 +101,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// Secure nodes
secureServer->registerNode(nodeAPIv1ToRadioOptions);
secureServer->registerNode(nodeAPIv1ToRadio);
secureServer->registerNode(nodeAPIv1FromRadioOptions);
secureServer->registerNode(nodeAPIv1FromRadio);
// secureServer->registerNode(nodeHotspotApple);
// secureServer->registerNode(nodeHotspotAndroid);
@ -121,6 +123,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// Insecure nodes
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
insecureServer->registerNode(nodeAPIv1ToRadio);
insecureServer->registerNode(nodeAPIv1FromRadioOptions);
insecureServer->registerNode(nodeAPIv1FromRadio);
// insecureServer->registerNode(nodeHotspotApple);
// insecureServer->registerNode(nodeHotspotAndroid);
@ -163,6 +166,12 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Methods", "GET");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
// res->print(""); @todo remove
return;
}
uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1;

View File

@ -23,6 +23,8 @@
#define MAX_NUM_NODES 100
#endif
#define MAX_NUM_NODES_FS 100
/// Max number of channels allowed
#define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0]))

View File

@ -20,6 +20,8 @@
#include <ESPmDNS.h>
#include <esp_wifi.h>
static void WiFiEvent(WiFiEvent_t event);
#elif defined(ARCH_RP2040)
#include <SimpleMDNS.h>
#endif
#ifndef DISABLE_NTP
@ -59,19 +61,21 @@ static void onNetworkConnected()
// Start web server
LOG_INFO("Start WiFi network services");
#ifdef ARCH_ESP32
// start mdns
if (!MDNS.begin("Meshtastic")) {
LOG_ERROR("Error setting up MDNS responder!");
} else {
LOG_INFO("mDNS responder started");
LOG_INFO("mDNS Host: Meshtastic.local");
#ifdef ARCH_ESP32
MDNS.addService("http", "tcp", 80);
MDNS.addService("https", "tcp", 443);
}
#else // ESP32 handles this in WiFiEvent
LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str());
#elif defined(ARCH_RP2040)
// ARCH_RP2040 does not support HTTPS, create a "meshtastic" service
MDNS.addService("meshtastic", "tcp", 4403);
// ESP32 handles this in WiFiEvent
LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str());
#endif
}
#ifndef DISABLE_NTP
LOG_INFO("Start NTP time client");
@ -129,7 +133,7 @@ static int32_t reconnectWiFi()
// Make sure we clear old connection credentials
#ifdef ARCH_ESP32
WiFi.disconnect(false, true);
#else
#elif defined(ARCH_RP2040)
WiFi.disconnect(false);
#endif
LOG_INFO("Reconnecting to WiFi access point %s", wifiName);
@ -193,7 +197,7 @@ void deinitWifi()
if (isWifiAvailable()) {
#ifdef ARCH_ESP32
WiFi.disconnect(true, false);
#else
#elif defined(ARCH_RP2040)
WiFi.disconnect(true);
#endif
WiFi.mode(WIFI_OFF);
@ -229,15 +233,15 @@ bool initWifi()
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC &&
config.network.ipv4_config.ip != 0) {
#ifndef ARCH_RP2040
#ifdef ARCH_ESP32
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
config.network.ipv4_config.dns);
#else
#elif defined(ARCH_RP2040)
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway,
config.network.ipv4_config.subnet);
#endif
}
#ifndef ARCH_RP2040
#ifdef ARCH_ESP32
WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.setSleep(false);

View File

@ -234,13 +234,13 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
screen->decreaseBrightness();
LOG_DEBUG("Decrease Screen Brightness");
break;
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbol
if (screen)
screen->setFunctionSymbal("Fn");
screen->setFunctionSymbol("Fn");
break;
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbol
if (screen)
screen->removeFunctionSymbal("Fn");
screen->removeFunctionSymbol("Fn");
break;
// mute (switch off/toggle) external notifications on fn+m
case INPUT_BROKER_MSG_MUTE_TOGGLE:
@ -249,13 +249,13 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
externalNotificationModule->setMute(false);
showTemporaryMessage("Notifications \nEnabled");
if (screen)
screen->removeFunctionSymbal("M"); // remove the mute symbol from the bottom right corner
screen->removeFunctionSymbol("M"); // remove the mute symbol from the bottom right corner
} else {
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
externalNotificationModule->setMute(true);
showTemporaryMessage("Notifications \nDisabled");
if (screen)
screen->setFunctionSymbal("M"); // add the mute symbol to the bottom right corner
screen->setFunctionSymbol("M"); // add the mute symbol to the bottom right corner
}
}
break;
@ -308,7 +308,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
break;
}
if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) {
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
screen->removeFunctionSymbol("Fn"); // remove modifier (function) symbol
}
}
@ -672,7 +672,7 @@ int32_t CannedMessageModule::runOnce()
break;
}
if (screen)
screen->removeFunctionSymbal("Fn");
screen->removeFunctionSymbol("Fn");
}
this->lastTouchMillis = millis();

View File

@ -119,12 +119,13 @@ int32_t ExternalNotificationModule::runOnce()
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
setExternalState(0, !getExternal(1));
setExternalState(1, !getExternal(1));
}
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
setExternalState(0, !getExternal(2));
LOG_DEBUG("EXTERNAL 2 %d compared to %d", externalTurnedOn[2]+moduleConfig.external_notification.output_ms, millis());
setExternalState(2, !getExternal(2));
}
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7

View File

@ -146,11 +146,20 @@ bool PositionModule::hasQualityTimesource()
#if MESHTASTIC_EXCLUDE_GPS
bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#else
bool hasGpsOrRtc = (gps && gps->isConnected()) || (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
bool hasGpsOrRtc = hasGPS() || (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#endif
return hasGpsOrRtc || setFromPhoneOrNtpToday;
}
bool PositionModule::hasGPS()
{
#if MESHTASTIC_EXCLUDE_GPS
return false;
#else
return gps && gps->isConnected();
#endif
}
meshtastic_MeshPacket *PositionModule::allocReply()
{
if (precision == 0) {
@ -194,10 +203,21 @@ meshtastic_MeshPacket *PositionModule::allocReply()
p.precision_bits = precision;
p.has_latitude_i = true;
p.has_longitude_i = true;
p.time = getValidTime(RTCQualityNTP) > 0 ? getValidTime(RTCQualityNTP) : localPosition.time;
// Always use NTP / GPS time if available
if (getValidTime(RTCQualityNTP) > 0) {
p.time = getValidTime(RTCQualityNTP);
} else if (rtc_found.address != ScanI2C::ADDRESS_NONE.address) {
LOG_INFO("Use RTC time for position");
p.time = getValidTime(RTCQualityDevice);
} else if (getRTCQuality() < RTCQualityNTP) {
LOG_INFO("Strip low RTCQuality (%d) time from position", getRTCQuality());
p.time = 0;
}
if (config.position.fixed_position) {
p.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
} else {
p.location_source = localPosition.location_source;
}
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
@ -242,20 +262,6 @@ meshtastic_MeshPacket *PositionModule::allocReply()
p.has_ground_speed = true;
}
// 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 or NTP to include the time, so that devices
// without can get time.
if (getRTCQuality() < RTCQualityNTP) {
LOG_INFO("Strip time %u from position", p.time);
p.time = 0;
} else if (rtc_found.address != ScanI2C::ADDRESS_NONE.address) {
LOG_INFO("Use RTC time %u for position", p.time);
p.time = getValidTime(RTCQualityDevice);
} else {
p.time = getValidTime(RTCQualityNTP);
LOG_INFO("Provide time to mesh %u", p.time);
}
LOG_INFO("Position reply: time=%i lat=%i lon=%i", p.time, p.latitude_i, p.longitude_i);
// TAK Tracker devices should send their position in a TAK packet over the ATAK port

View File

@ -61,6 +61,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
uint32_t precision;
void sendLostAndFoundText();
bool hasQualityTimesource();
bool hasGPS();
const uint32_t minimumTimeThreshold =
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);

View File

@ -204,9 +204,11 @@ int32_t SerialModule::runOnce()
lastNmeaTime = millis();
uint32_t readIndex = 0;
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
serialPrint->printf("%s", outbuf);
while (tempNodeInfo != NULL) {
if (tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
serialPrint->printf("%s", outbuf);
}
tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
}
}

View File

@ -47,6 +47,8 @@
#define HW_VENDOR meshtastic_HardwareModel_PPR
#elif defined(RAK2560)
#define HW_VENDOR meshtastic_HardwareModel_RAK2560
#elif defined(WISMESH_TAP)
#define HW_VENDOR meshtastic_HardwareModel_WISMESH_TAP
#elif defined(RAK4630)
#define HW_VENDOR meshtastic_HardwareModel_RAK4631
#elif defined(TTGO_T_ECHO)

View File

@ -68,10 +68,39 @@ static unsigned char icon_bits[] = {
0x98, 0x3F, 0xF0, 0x23, 0x00, 0xFC, 0x0F, 0xE0, 0x7F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xFC, 0x00, 0x00, 0x3E, 0x00, 0x70,
0x00, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x00, 0x1C, 0x00};
*/
/*
* PKI Admin keys.
* If a Admin key is set with '{};'
* then it will be ignored, a PKI key must have a size of 32.
*/
/*
#define USERPREFS_USE_ADMIN_KEY 1
static unsigned char USERPREFS_ADMIN_KEY[] = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6,
0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a,
0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c};
static unsigned char USERPREFS_ADMIN_KEY_0[] = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6,
0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a,
0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c};
static unsigned char USERPREFS_ADMIN_KEY_1[] = {};
static unsigned char USERPREFS_ADMIN_KEY_2[] = {};
*/
/*
* USERPREF_FIXED_GPS_LAT and USERPREF_FIXED_GPS_LON must be set, USERPREF_FIXED_GPS_ALT is optional
*
* Fixed GPS is Eiffel Tower, Paris, France
*/
// #define USERPREFS_FIXED_GPS
// #define USERPREFS_FIXED_GPS_LAT 48.85873920
// #define USERPREFS_FIXED_GPS_LON 2.294508368
// #define USERPREFS_FIXED_GPS_ALT 0
/*
* Set Fixed Bluetooth paring code
*/
// #define USERPREFS_FIXED_BLUETOOTH 121212
/*
* Will overwrite BUTTON_PIN if set
*/
// #define USERPREFS_BUTTON_PIN 36
#endif

View File

@ -3,6 +3,7 @@ extends = rp2040_base
board = wiscore_rak11300
upload_protocol = picotool
# keep an old SDK to use less memory.
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#v1.2.0-gcc12
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.7.2
# add our variants files to the include and src paths
@ -13,5 +14,5 @@ build_flags = ${rp2040_base.build_flags}
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
debug_build_flags = ${rp2040_base.build_flags}
debug_build_flags = ${rp2040_base.build_flags}, -g
debug_tool = cmsis-dap ; for e.g. Picotool

View File

@ -2,14 +2,13 @@
[env:rak_wismeshtap]
extends = nrf52840_base
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak_wismeshtap -D RAK_4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak_wismeshtap -DWISMESH_TAP -DRAK_4631
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_WAYPOINT=1
-DMESHTASTIC_EXCLUDE_DETECTIONSENSOR=1
-DMESHTASTIC_EXCLUDE_STOREFORWARD=1
-DMESHTASTIC_EXCLUDE_POWER_TELEMETRY=1

View File

@ -271,13 +271,8 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define HAS_RTC 1
#define HAS_ETHERNET 1
#define RAK_4631 1
#define PIN_ETHERNET_RESET 21
#define PIN_ETHERNET_SS PIN_EINK_CS
#define ETH_SPI_PORT SPI1
#define AQ_SET_PIN 10
#ifdef __cplusplus

View File

@ -12,5 +12,5 @@ build_flags = ${rp2040_base.build_flags}
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
debug_build_flags = ${rp2040_base.build_flags}
debug_build_flags = ${rp2040_base.build_flags}, -g
debug_tool = cmsis-dap ; for e.g. Picotool

View File

@ -12,5 +12,5 @@ build_flags = ${rp2040_base.build_flags}
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
lib_deps =
${rp2040_base.lib_deps}
debug_build_flags = ${rp2040_base.build_flags}
debug_build_flags = ${rp2040_base.build_flags}, -g
debug_tool = cmsis-dap ; for e.g. Picotool

View File

@ -12,5 +12,5 @@ build_flags = ${rp2350_base.build_flags}
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
lib_deps =
${rp2350_base.lib_deps}
debug_build_flags = ${rp2350_base.build_flags}
debug_build_flags = ${rp2350_base.build_flags}, -g
debug_tool = cmsis-dap ; for e.g. Picotool

View File

@ -14,5 +14,5 @@ build_src_filter = ${rp2040_base.build_src_filter} +<mesh/wifi/>
lib_deps =
${rp2040_base.lib_deps}
${networking_base.lib_deps}
debug_build_flags = ${rp2040_base.build_flags}
debug_build_flags = ${rp2040_base.build_flags}, -g
debug_tool = cmsis-dap ; for e.g. Picotool

View File

@ -36,12 +36,13 @@
#define TOUCH_I2C_PORT 0
#define TOUCH_SLAVE_ADDRESS 0x48
// Buzzer
#define PIN_BUZZER 19
// in future, we may want to add a buzzer and add all sensors to the indicator via a data protocol for now only GPS is supported
// // Buzzer
// #define PIN_BUZZER 19
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 20
#define GPS_TX_PIN 19
#define HAS_GPS 1
#define USE_SX1262
#define USE_SX1268

View File

@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 5
build = 13
build = 14