mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-12 04:47:23 +00:00
Compare commits
6 Commits
adaptive-c
...
kill-led-b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
965ded88e1 | ||
|
|
e0a720d667 | ||
|
|
a14505cafa | ||
|
|
2ae409ff8b | ||
|
|
e500ae6415 | ||
|
|
8fb0365833 |
47
.github/workflows/first_time_contributor.yml
vendored
47
.github/workflows/first_time_contributor.yml
vendored
@@ -1,47 +0,0 @@
|
||||
name: Welcome First-Time Contributor
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: opened
|
||||
pull_request_target:
|
||||
types: opened
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
welcome:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write # Required to post comments and labels on issues
|
||||
pull-requests: write # Required to post comments and labels on PRs
|
||||
steps:
|
||||
- uses: plbstl/first-contribution@v4
|
||||
with:
|
||||
labels: first-contribution
|
||||
issue-opened-msg: |
|
||||
### @{fc-author}, Welcome to Meshtastic! :wave:
|
||||
|
||||
Thanks for opening your first issue. If it's helpful, an easy way
|
||||
to get logs is the "Open Serial Monitor" button on the [Web Flasher](https://flasher.meshtastic.org).
|
||||
|
||||
If you have ideas for features, note that we often debate big ideas
|
||||
in the [discussions tab](https://github.com/meshtastic/firmware/discussions/categories/ideas)
|
||||
first. This tracker tends to be for ideas that have community
|
||||
consensus and a clear implementation.
|
||||
|
||||
We're very active [on discord](https://discord.com/invite/meshtastic),
|
||||
especially the \#firmware and \#alphanauts-testing channels. If you'll
|
||||
be around for a while, we'd love to see you there!
|
||||
|
||||
Welcome to the community! :heart:
|
||||
|
||||
pr-opened-msg: |
|
||||
### @{fc-author}, Welcome to Meshtastic!
|
||||
|
||||
Thanks for opening your first pull request. We really appreciate it.
|
||||
|
||||
We discuss work as a team in discord, please join us in the [#firmware channel](https://discord.com/invite/meshtastic).
|
||||
There's a big backlog of patches at the moment. If you have time,
|
||||
please help us with some code review and testing of [other PRs](https://github.com/meshtastic/firmware/pulls)!
|
||||
|
||||
Welcome to the team :smile:
|
||||
28
.github/workflows/main_matrix.yml
vendored
28
.github/workflows/main_matrix.yml
vendored
@@ -8,9 +8,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- pioarduino # Remove when merged // use `feature/` in the future.
|
||||
- event/*
|
||||
- feature/*
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- version.properties
|
||||
@@ -20,9 +18,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- pioarduino # Remove when merged // use `feature/` in the future.
|
||||
- event/*
|
||||
- feature/*
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
#- "**.yml"
|
||||
@@ -244,7 +240,6 @@ jobs:
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
if: github.event_name == 'pull_request_target'
|
||||
with:
|
||||
filter: blob:none # means we download all the git history but none of the commit (except ones with checkout like the head)
|
||||
fetch-depth: 0
|
||||
@@ -258,26 +253,19 @@ jobs:
|
||||
uses: actions/upload-artifact@v6
|
||||
id: upload-manifest
|
||||
with:
|
||||
name: manifests-${{ github.sha }}
|
||||
name: manifests-all
|
||||
overwrite: true
|
||||
path: manifests-new/*.mt.json
|
||||
path: |
|
||||
manifests-new/*.mt.json
|
||||
- name: Find the merge base
|
||||
if: github.event_name == 'pull_request_target'
|
||||
run: echo "MERGE_BASE=$(git merge-base "origin/$base" "$head")" >> $GITHUB_ENV
|
||||
env:
|
||||
base: ${{ github.base_ref }}
|
||||
head: ${{ github.sha }}
|
||||
# Currently broken (for-loop through EVERY artifact -- rate limiting)
|
||||
# - name: Download the old manifests
|
||||
# if: github.event_name == 'pull_request_target'
|
||||
# run: gh run download -R "$repo" --name "manifests-$merge_base" --dir manifest-old/
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# merge_base: ${{ env.MERGE_BASE }}
|
||||
# repo: ${{ github.repository }}
|
||||
# - name: Do scan and post comment
|
||||
# if: github.event_name == 'pull_request_target'
|
||||
# run: python3 bin/shame.py ${{ github.event.pull_request.number }} manifests-old/ manifests-new/
|
||||
head: ${{ github.head_ref }}
|
||||
- name: Download the old manifests
|
||||
run: gh run download -R ${{ github.repository }} --commit ${{ env.MERGE_BASE }} --name manifests-all --dir manifest-old/
|
||||
- name: Do scan and post comment
|
||||
run: python3 bin/shame.py ${{ github.event.pull_request.number }} manifests-old/ manifests-new/
|
||||
|
||||
release-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.github/workflows/test_native.yml
vendored
2
.github/workflows/test_native.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Test Report
|
||||
uses: dorny/test-reporter@v2.4.0
|
||||
uses: dorny/test-reporter@v2.3.0
|
||||
with:
|
||||
name: PlatformIO Tests
|
||||
path: testreport.xml
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -41,12 +41,3 @@ src/mesh/raspihttp/private_key.pem
|
||||
|
||||
# Ignore logo (set at build time with platformio-custom.py)
|
||||
data/boot/logo.*
|
||||
|
||||
# pioarduino platform
|
||||
managed_components/*
|
||||
arduino-lib-builder*
|
||||
dependencies.lock
|
||||
idf_component.yml
|
||||
CMakeLists.txt
|
||||
sdkconfig.*
|
||||
.dummy/*
|
||||
|
||||
@@ -8,10 +8,10 @@ plugins:
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.496
|
||||
- renovate@42.66.14
|
||||
- checkov@3.2.495
|
||||
- renovate@42.64.1
|
||||
- prettier@3.7.4
|
||||
- trufflehog@3.92.4
|
||||
- trufflehog@3.92.3
|
||||
- yamllint@1.37.1
|
||||
- bandit@1.9.2
|
||||
- trivy@0.68.2
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Minimal container to run PlatformIO native/portduino tests
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip \
|
||||
git \
|
||||
build-essential \
|
||||
cmake \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
libncurses5 \
|
||||
libsdl2-dev \
|
||||
libx11-dev \
|
||||
libxext-dev \
|
||||
libusb-1.0-0-dev \
|
||||
libyaml-cpp-dev \
|
||||
libuv1-dev \
|
||||
libgpiod-dev \
|
||||
libbluetooth-dev \
|
||||
libulfius-dev \
|
||||
liborcania-dev \
|
||||
libmicrohttpd-dev \
|
||||
libjansson-dev \
|
||||
libgnutls28-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
libi2c-dev \
|
||||
openssl \
|
||||
lsb-release \
|
||||
cppcheck \
|
||||
uuid-dev \
|
||||
zlib1g-dev \
|
||||
libbsd-dev \
|
||||
gdb \
|
||||
&& pip3 install --no-cache-dir platformio \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
CMD ["bash"]
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
| Firmware Version | Supported |
|
||||
| ---------------- | ------------------ |
|
||||
| 2.7.x | :white_check_mark: |
|
||||
| <= 2.6.x | :x: |
|
||||
| 2.6.x | :white_check_mark: |
|
||||
| <= 2.5.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
||||
@@ -21,14 +21,13 @@ rm -f $BUILDDIR/firmware*
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
basename=firmware-$1-$VERSION
|
||||
ota_basename=${basename}-ota
|
||||
|
||||
pio run --environment $1 -t mtjson # -v
|
||||
|
||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||
|
||||
echo "Copying NRF52 dfu (OTA) file"
|
||||
cp $BUILDDIR/$basename.zip $OUTDIR/$ota_basename.zip
|
||||
cp $BUILDDIR/$basename.zip $OUTDIR/$basename.zip
|
||||
|
||||
echo "Copying NRF52 UF2 file"
|
||||
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<release version="2.7.18" date="2026-01-02">
|
||||
<release version="2.7.18" date="2025-12-20">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.18</url>
|
||||
</release>
|
||||
<release version="2.7.17" date="2025-11-28">
|
||||
|
||||
@@ -17,8 +17,6 @@ lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
|
||||
|
||||
def manifest_gather(source, target, env):
|
||||
out = []
|
||||
board_platform = env.BoardConfig().get("platform")
|
||||
needs_ota_suffix = board_platform == "nordicnrf52"
|
||||
check_paths = [
|
||||
progname,
|
||||
f"{progname}.elf",
|
||||
@@ -34,11 +32,8 @@ def manifest_gather(source, target, env):
|
||||
for p in check_paths:
|
||||
f = env.File(env.subst(f"$BUILD_DIR/{p}"))
|
||||
if f.exists():
|
||||
manifest_name = p
|
||||
if needs_ota_suffix and p == f"{progname}.zip":
|
||||
manifest_name = f"{progname}-ota.zip"
|
||||
d = {
|
||||
"name": manifest_name,
|
||||
"name": p,
|
||||
"md5": f.get_content_hash(), # Returns MD5 hash
|
||||
"bytes": f.get_size() # Returns file size in bytes
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DLILYGO_TBEAM_1W",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"psram_type": "opi",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "t-beam-1w"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"lora"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "LilyGo TBeam-1W",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "http://www.lilygo.cn/",
|
||||
"vendor": "LilyGo"
|
||||
}
|
||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@@ -2,7 +2,7 @@ meshtasticd (2.7.18.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.18
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Fri, 02 Jan 2026 12:45:36 +0000
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Sat, 20 Dec 2025 15:47:25 +0000
|
||||
|
||||
meshtasticd (2.7.17.0) unstable; urgency=medium
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ build_flags = -Wno-missing-field-initializers
|
||||
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
|
||||
-DMESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE=1
|
||||
-D MAX_THREADS=40 ; As we've split modules, we have more threads to manage
|
||||
-DLED_BUILTIN=-1
|
||||
#-DBUILD_EPOCH=$UNIX_TIME ; set in platformio-custom.py now
|
||||
#-D OLED_PL=1
|
||||
#-D DEBUG_HEAP=1 ; uncomment to add free heap space / memory leak debugging logs
|
||||
@@ -64,7 +65,7 @@ monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/b34c6817c25d6faabb3a8a162b5d14fb75395433.zip
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/2887bf4a19f64d92c984dcc8fd5ca7429e425e4a.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
|
||||
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
|
||||
@@ -119,7 +120,7 @@ lib_deps =
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/a8e2f947f7abaf0c5ac8e6dd189a22156335beaa.zip
|
||||
https://github.com/meshtastic/device-ui/archive/862ed040c4ab44f0dfbbe492691f144886102588.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
|
||||
Submodule protobufs updated: f78b3f0dcc...c474fd3f49
@@ -24,9 +24,6 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
|
||||
switch (event->inputEvent) {
|
||||
case INPUT_BROKER_USER_PRESS:
|
||||
case INPUT_BROKER_ALT_PRESS:
|
||||
playClick(); // Low delay feedback
|
||||
break;
|
||||
|
||||
case INPUT_BROKER_SELECT:
|
||||
case INPUT_BROKER_SELECT_LONG:
|
||||
playBeep(); // Confirmation feedback
|
||||
@@ -61,4 +58,4 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
|
||||
return 0; // Allow other handlers to process the event
|
||||
}
|
||||
}
|
||||
@@ -113,14 +113,7 @@ void playShutdownMelody()
|
||||
void playChirp()
|
||||
{
|
||||
// A short, friendly "chirp" sound for key presses
|
||||
ToneDuration melody[] = {{NOTE_AS3, 20}}; // Short AS3 note
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
void playClick()
|
||||
{
|
||||
// A very short "click" sound with minimum delay; ideal for rotary encoder events
|
||||
ToneDuration melody[] = {{NOTE_AS3, 1}}; // Very Short AS3
|
||||
ToneDuration melody[] = {{NOTE_AS3, 20}}; // Very short AS3 note
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ void playGPSDisableBeep();
|
||||
void playComboTune();
|
||||
void playBoop();
|
||||
void playChirp();
|
||||
void playClick();
|
||||
void playLongPressLeadUp();
|
||||
bool playNextLeadUpNote(); // Play the next note in the lead-up sequence
|
||||
void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning
|
||||
@@ -444,18 +444,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BME680 BSEC2 support detection
|
||||
#if !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
|
||||
#if defined(RAK_4631) || defined(TBEAM_V10)
|
||||
|
||||
#define MESHTASTIC_BME680_BSEC2_SUPPORTED 1
|
||||
#define MESHTASTIC_BME680_HEADER <bsec2.h>
|
||||
#else
|
||||
#define MESHTASTIC_BME680_BSEC2_SUPPORTED 0
|
||||
#define MESHTASTIC_BME680_HEADER <Adafruit_BME680.h>
|
||||
#endif // defined(RAK_4631)
|
||||
#endif // !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global switches to turn off features for a minimized build
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "graphics/draw/UIRenderer.h"
|
||||
#include "main.h"
|
||||
#include "meshtastic/config.pb.h"
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "power.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <graphics/images.h>
|
||||
@@ -57,6 +56,7 @@ void decomposeTime(uint32_t rtc_sec, int &hour, int &minute, int &second)
|
||||
|
||||
// === Shared External State ===
|
||||
bool hasUnreadMessage = false;
|
||||
bool isMuted = false;
|
||||
ScreenResolution currentResolution = ScreenResolution::Low;
|
||||
|
||||
// === Internal State ===
|
||||
@@ -306,7 +306,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
|
||||
}
|
||||
display->drawXbm(iconX, iconY, mail_width, mail_height, mail);
|
||||
}
|
||||
} else if (externalNotificationModule->getMute()) {
|
||||
} else if (isMuted) {
|
||||
if (currentResolution == ScreenResolution::High) {
|
||||
int iconX = iconRightEdge - mute_symbol_big_width;
|
||||
int iconY = textY + (FONT_HEIGHT_SMALL - mute_symbol_big_height) / 2;
|
||||
@@ -325,7 +325,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
|
||||
int iconX = iconRightEdge - mute_symbol_width;
|
||||
int iconY = textY + (FONT_HEIGHT_SMALL - mail_height) / 2;
|
||||
|
||||
if (isInverted && !force_no_invert) {
|
||||
if (isInverted) {
|
||||
display->setColor(WHITE);
|
||||
display->fillRect(iconX - 1, iconY - 1, mute_symbol_width + 2, mute_symbol_height + 2);
|
||||
display->setColor(BLACK);
|
||||
@@ -383,7 +383,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
|
||||
int iconY = textY + (FONT_HEIGHT_SMALL - mail_height) / 2;
|
||||
display->drawXbm(iconX, iconY, mail_width, mail_height, mail);
|
||||
}
|
||||
} else if (externalNotificationModule->getMute()) {
|
||||
} else if (isMuted) {
|
||||
if (currentResolution == ScreenResolution::High) {
|
||||
int iconX = iconRightEdge - mute_symbol_big_width;
|
||||
int iconY = textY + (FONT_HEIGHT_SMALL - mute_symbol_big_height) / 2;
|
||||
@@ -470,49 +470,18 @@ bool isAllowedPunctuation(char c)
|
||||
return allowed.find(c) != std::string::npos;
|
||||
}
|
||||
|
||||
static void replaceAll(std::string &s, const std::string &from, const std::string &to)
|
||||
{
|
||||
if (from.empty())
|
||||
return;
|
||||
size_t pos = 0;
|
||||
while ((pos = s.find(from, pos)) != std::string::npos) {
|
||||
s.replace(pos, from.size(), to);
|
||||
pos += to.size();
|
||||
}
|
||||
}
|
||||
|
||||
std::string sanitizeString(const std::string &input)
|
||||
{
|
||||
std::string output;
|
||||
bool inReplacement = false;
|
||||
|
||||
// Make a mutable copy so we can normalize UTF-8 “smart punctuation” into ASCII first.
|
||||
std::string s = input;
|
||||
|
||||
// Curly single quotes: ‘ ’
|
||||
replaceAll(s, "\xE2\x80\x98", "'"); // U+2018
|
||||
replaceAll(s, "\xE2\x80\x99", "'"); // U+2019
|
||||
|
||||
// Curly double quotes: “ ”
|
||||
replaceAll(s, "\xE2\x80\x9C", "\""); // U+201C
|
||||
replaceAll(s, "\xE2\x80\x9D", "\""); // U+201D
|
||||
|
||||
// En dash / Em dash: – —
|
||||
replaceAll(s, "\xE2\x80\x93", "-"); // U+2013
|
||||
replaceAll(s, "\xE2\x80\x94", "-"); // U+2014
|
||||
|
||||
// Non-breaking space
|
||||
replaceAll(s, "\xC2\xA0", " "); // U+00A0
|
||||
|
||||
// Now do your original sanitize pass over the normalized string.
|
||||
for (unsigned char uc : s) {
|
||||
char c = static_cast<char>(uc);
|
||||
if (std::isalnum(uc) || isAllowedPunctuation(c)) {
|
||||
for (char c : input) {
|
||||
if (std::isalnum(static_cast<unsigned char>(c)) || isAllowedPunctuation(c)) {
|
||||
output += c;
|
||||
inReplacement = false;
|
||||
} else {
|
||||
if (!inReplacement) {
|
||||
output += static_cast<char>(0xBF); // ISO-8859-1 for inverted question mark
|
||||
output += 0xbf; // ISO-8859-1 for inverted question mark
|
||||
inReplacement = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace graphics
|
||||
|
||||
// Shared state (declare inside namespace)
|
||||
extern bool hasUnreadMessage;
|
||||
extern bool isMuted;
|
||||
enum class ScreenResolution : uint8_t { UltraLow = 0, Low = 1, High = 2 };
|
||||
extern ScreenResolution currentResolution;
|
||||
ScreenResolution determineScreenResolution(int16_t screenheight, int16_t screenwidth);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,9 +22,6 @@ class menuHandler
|
||||
node_base_menu,
|
||||
gps_toggle_menu,
|
||||
gps_format_menu,
|
||||
gps_smart_position_menu,
|
||||
gps_update_interval_menu,
|
||||
gps_position_broadcast_menu,
|
||||
compass_point_north_menu,
|
||||
reset_node_db_menu,
|
||||
buzzermodemenupicker,
|
||||
@@ -39,6 +36,7 @@ class menuHandler
|
||||
number_test,
|
||||
wifi_toggle_menu,
|
||||
bluetooth_toggle_menu,
|
||||
notifications_menu,
|
||||
screen_options_menu,
|
||||
power_menu,
|
||||
system_base_menu,
|
||||
@@ -79,9 +77,6 @@ class menuHandler
|
||||
static void compassNorthMenu();
|
||||
static void GPSToggleMenu();
|
||||
static void GPSFormatMenu();
|
||||
static void GPSSmartPositionMenu();
|
||||
static void GPSUpdateIntervalMenu();
|
||||
static void GPSPositionBroadcastMenu();
|
||||
static void BuzzerModeMenu();
|
||||
static void switchToMUIMenu();
|
||||
static void TFTColorPickerMenu(OLEDDisplay *display);
|
||||
@@ -97,6 +92,7 @@ class menuHandler
|
||||
static void numberTest();
|
||||
static void wifiBaseMenu();
|
||||
static void wifiToggleMenu();
|
||||
static void notificationsMenu();
|
||||
static void screenOptionsMenu();
|
||||
static void powerMenu();
|
||||
static void nodeNameLengthMenu();
|
||||
@@ -128,28 +124,7 @@ template <typename T> struct MenuOption {
|
||||
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
|
||||
};
|
||||
|
||||
struct ScreenColor {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
bool useVariant;
|
||||
|
||||
ScreenColor(uint8_t rIn = 0, uint8_t gIn = 0, uint8_t bIn = 0, bool variantIn = false)
|
||||
: r(rIn), g(gIn), b(bIn), useVariant(variantIn)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
|
||||
using LoraRegionOption = MenuOption<meshtastic_Config_LoRaConfig_RegionCode>;
|
||||
using TimezoneOption = MenuOption<const char *>;
|
||||
using CompassOption = MenuOption<meshtastic_CompassMode>;
|
||||
using ScreenColorOption = MenuOption<ScreenColor>;
|
||||
using GPSToggleOption = MenuOption<meshtastic_Config_PositionConfig_GpsMode>;
|
||||
using GPSFormatOption = MenuOption<meshtastic_DeviceUIConfig_GpsCoordinateFormat>;
|
||||
using NodeNameOption = MenuOption<bool>;
|
||||
using PositionMenuOption = MenuOption<int>;
|
||||
using ClockFaceOption = MenuOption<bool>;
|
||||
|
||||
} // namespace graphics
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
||||
|
||||
#include "./PositionsApplet.h"
|
||||
#include "NodeDB.h"
|
||||
|
||||
using namespace NicheGraphics;
|
||||
|
||||
@@ -50,8 +49,8 @@ ProcessMessage InkHUD::PositionsApplet::handleReceived(const meshtastic_MeshPack
|
||||
if (!hasPosition)
|
||||
return ProcessMessage::CONTINUE;
|
||||
|
||||
const int8_t hopsAway = getHopsAway(mp);
|
||||
const bool hasHopsAway = hopsAway >= 0;
|
||||
bool hasHopsAway = (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start); // From NodeDB::updateFrom
|
||||
uint8_t hopsAway = mp.hop_start - mp.hop_limit;
|
||||
|
||||
// Determine if the position packet would change anything on-screen
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
@@ -1186,6 +1186,11 @@ void setup()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PIN_PWR_DELAY_MS
|
||||
// This may be required to give the peripherals time to power up.
|
||||
delay(PIN_PWR_DELAY_MS);
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
// as one can't use a function pointer to the class constructor:
|
||||
auto loraModuleInterface = [](LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
||||
|
||||
@@ -195,7 +195,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
||||
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
|
||||
// bad.
|
||||
routingModule->sendAckNak(meshtastic_Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel,
|
||||
routingModule->getHopLimitForResponse(mp));
|
||||
routingModule->getHopLimitForResponse(mp.hop_start, mp.hop_limit));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to)
|
||||
assert(p->which_payload_variant == meshtastic_MeshPacket_decoded_tag); // Should already be set by now
|
||||
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
|
||||
p->channel = to.channel; // Use the same channel that the request came in on
|
||||
p->hop_limit = routingModule->getHopLimitForResponse(to);
|
||||
p->hop_limit = routingModule->getHopLimitForResponse(to.hop_start, to.hop_limit);
|
||||
|
||||
// No need for an ack if we are just delivering locally (it just generates an ignored ack)
|
||||
p->want_ack = (to.from != 0) ? to.want_ack : false;
|
||||
|
||||
@@ -95,8 +95,11 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
|
||||
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
|
||||
nodeInfoModule && !isPreferredRebroadcaster && !nodeDB->isFull()) {
|
||||
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||
const int8_t hopsUsed = getHopsAway(*mp, config.lora.hop_limit);
|
||||
if (hopsUsed > (int32_t)(config.lora.hop_limit + 2)) {
|
||||
// Hops used by the request. If somebody in between running modified firmware modified it, ignore it
|
||||
auto hopStart = mp->hop_start;
|
||||
auto hopLimit = mp->hop_limit;
|
||||
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
|
||||
if (hopsUsed > config.lora.hop_limit + 2) {
|
||||
LOG_DEBUG("Skip send NodeInfo: %d hops away is too far away", hopsUsed);
|
||||
} else {
|
||||
LOG_INFO("Heard new node on ch. %d, send NodeInfo and ask for response", mp->channel);
|
||||
@@ -192,13 +195,15 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
|
||||
|
||||
p.rx_time = getValidTime(RTCQualityFromNet); // Record the time the packet arrived from the phone
|
||||
|
||||
IF_SCREEN(if (p.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP && p.decoded.payload.size > 0 &&
|
||||
p.to != NODENUM_BROADCAST && p.to != 0) // DM only
|
||||
{
|
||||
perhapsDecode(&p);
|
||||
const StoredMessage &sm = messageStore.addFromPacket(p);
|
||||
graphics::MessageRenderer::handleNewMessage(nullptr, sm, p); // notify UI
|
||||
})
|
||||
#if HAS_SCREEN
|
||||
if (p.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP && p.decoded.payload.size > 0 && p.to != NODENUM_BROADCAST &&
|
||||
p.to != 0) // DM only
|
||||
{
|
||||
perhapsDecode(&p);
|
||||
const StoredMessage &sm = messageStore.addFromPacket(p);
|
||||
graphics::MessageRenderer::handleNewMessage(nullptr, sm, p); // notify UI
|
||||
}
|
||||
#endif
|
||||
// Send the packet into the mesh
|
||||
DEBUG_HEAP_BEFORE;
|
||||
auto a = packetPool.allocCopy(p);
|
||||
|
||||
@@ -64,7 +64,7 @@ bool NextHopRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
||||
perhapsRebroadcast(p);
|
||||
}
|
||||
} else {
|
||||
bool isRepeated = getHopsAway(*p) == 0;
|
||||
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
|
||||
// If repeated and not in Tx queue anymore, try relaying again, or if we are the destination, send the ACK again
|
||||
if (isRepeated) {
|
||||
if (!findInTxQueue(p->from, p->id)) {
|
||||
@@ -101,7 +101,8 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
|
||||
bool wasAlreadyRelayer = wasRelayer(p->relay_node, p->decoded.request_id, p->to);
|
||||
bool weWereSoleRelayer = false;
|
||||
bool weWereRelayer = wasRelayer(ourRelayID, p->decoded.request_id, p->to, &weWereSoleRelayer);
|
||||
if ((weWereRelayer && wasAlreadyRelayer) || (getHopsAway(*p) == 0 && weWereSoleRelayer)) {
|
||||
if ((weWereRelayer && wasAlreadyRelayer) ||
|
||||
(p->hop_start != 0 && p->hop_start == p->hop_limit && weWereSoleRelayer)) {
|
||||
if (origTx->next_hop != p->relay_node) { // Not already set
|
||||
LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply (was relayer %d we were sole %d)", p->from,
|
||||
p->relay_node, wasAlreadyRelayer, weWereSoleRelayer);
|
||||
@@ -238,12 +239,6 @@ bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
||||
// call to startRetransmission.
|
||||
packetPool.release(p);
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
if (iface) {
|
||||
iface->clearAdaptiveCodingRateState(getFrom(p), p->id);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
||||
@@ -805,8 +805,7 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.external_notification.output_ms = 500;
|
||||
moduleConfig.external_notification.nag_timeout = 2;
|
||||
#endif
|
||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3) || \
|
||||
defined(ELECROW_ThinkNode_M6)
|
||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3)
|
||||
// Default to PIN_LED2 for external notification output (LED color depends on device variant)
|
||||
moduleConfig.external_notification.enabled = true;
|
||||
moduleConfig.external_notification.output = PIN_LED2;
|
||||
@@ -1549,23 +1548,6 @@ uint32_t sinceReceived(const meshtastic_MeshPacket *p)
|
||||
return delta;
|
||||
}
|
||||
|
||||
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown)
|
||||
{
|
||||
// Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a
|
||||
// bitfield that is always present. Use the presence of the bitfield to determine if the origin's firmware
|
||||
// version is guaranteed to have hop_start populated. Note that this can only be done for decoded packets as
|
||||
// the bitfield is encrypted under the channel encryption key. For encrypted packets, this returns
|
||||
// defaultIfUnknown when hop_start is 0.
|
||||
if (p.hop_start == 0 && !(p.which_payload_variant == meshtastic_MeshPacket_decoded_tag && p.decoded.has_bitfield))
|
||||
return defaultIfUnknown; // Cannot reliably determine the number of hops.
|
||||
|
||||
// Guard against invalid values.
|
||||
if (p.hop_start < p.hop_limit)
|
||||
return defaultIfUnknown;
|
||||
|
||||
return p.hop_start - p.hop_limit;
|
||||
}
|
||||
|
||||
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
|
||||
|
||||
size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
|
||||
@@ -1818,10 +1800,9 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||
info->via_mqtt = mp.via_mqtt; // Store if we received this packet via MQTT
|
||||
|
||||
// If hopStart was set and there wasn't someone messing with the limit in the middle, add hopsAway
|
||||
const int8_t hopsAway = getHopsAway(mp);
|
||||
if (hopsAway >= 0) {
|
||||
if (mp.hop_start != 0 && mp.hop_limit <= mp.hop_start) {
|
||||
info->has_hops_away = true;
|
||||
info->hops_away = hopsAway;
|
||||
info->hops_away = mp.hop_start - mp.hop_limit;
|
||||
}
|
||||
sortMeshDB();
|
||||
}
|
||||
|
||||
@@ -110,10 +110,6 @@ uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
|
||||
/// Given a packet, return how many seconds in the past (vs now) it was received
|
||||
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
||||
|
||||
/// Given a packet, return the number of hops used to reach this node.
|
||||
/// Returns defaultIfUnknown if the number of hops couldn't be determined.
|
||||
int8_t getHopsAway(const meshtastic_MeshPacket &p, int8_t defaultIfUnknown = -1);
|
||||
|
||||
enum LoadFileResult {
|
||||
// Successfully opened the file
|
||||
LOAD_SUCCESS = 1,
|
||||
|
||||
@@ -171,8 +171,7 @@ const RegionInfo regions[] = {
|
||||
863 - 868 MHz <25 mW EIRP, 500kHz channels allowed, must not be used at airfields
|
||||
https://github.com/meshtastic/firmware/issues/7204
|
||||
*/
|
||||
RDEF(KZ_433, 433.075f, 434.775f, 100, 0, 10, true, false, false),
|
||||
RDEF(KZ_863, 863.0f, 868.0f, 100, 0, 30, true, false, false),
|
||||
RDEF(KZ_433, 433.075f, 434.775f, 100, 0, 10, true, false, false), RDEF(KZ_863, 863.0f, 868.0f, 100, 0, 30, true, false, true),
|
||||
|
||||
/*
|
||||
Nepal
|
||||
@@ -520,10 +519,6 @@ void RadioInterface::applyModemConfig()
|
||||
sf = 12;
|
||||
break;
|
||||
}
|
||||
if (loraConfig.coding_rate >= 5 && loraConfig.coding_rate <= 8 && loraConfig.coding_rate != cr) {
|
||||
cr = loraConfig.coding_rate;
|
||||
LOG_INFO("Using custom Coding Rate %u", cr);
|
||||
}
|
||||
} else {
|
||||
sf = loraConfig.spread_factor;
|
||||
cr = loraConfig.coding_rate;
|
||||
@@ -618,13 +613,6 @@ void RadioInterface::applyModemConfig()
|
||||
slotTimeMsec = computeSlotTimeMsec();
|
||||
preambleTimeMsec = preambleLength * (pow_of_2(sf) / bw);
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
if (adaptiveCrOverride >= 5 && adaptiveCrOverride <= 8 && cr != adaptiveCrOverride) {
|
||||
cr = adaptiveCrOverride;
|
||||
LOG_DEBUG("Adaptive coding rate override set to %u", cr);
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f", freq, loraConfig.frequency_offset);
|
||||
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d", myRegion->name, channelName, loraConfig.modem_preset,
|
||||
channel_num, power);
|
||||
@@ -737,70 +725,3 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
|
||||
sendingPacket = p;
|
||||
return p->encrypted.size + sizeof(PacketHeader);
|
||||
}
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
uint8_t RadioInterface::computeAdaptiveCodingRate(uint8_t attempt) const
|
||||
{
|
||||
if (attempt <= 1) {
|
||||
return 5; // Attempt 1: 4/5
|
||||
}
|
||||
if (attempt == 2) {
|
||||
return 7; // Attempt 2: 4/7
|
||||
}
|
||||
return 8; // Attempt 3+: 4/8
|
||||
}
|
||||
|
||||
uint64_t RadioInterface::adaptiveKey(NodeNum from, PacketId id) const
|
||||
{
|
||||
return (static_cast<uint64_t>(from) << 32) | id;
|
||||
}
|
||||
|
||||
void RadioInterface::pruneAdaptiveAttempts(uint32_t now)
|
||||
{
|
||||
const uint32_t expiryMsec = 5 * 60 * 1000UL; // drop state after 5 minutes
|
||||
for (auto it = adaptiveAttempts.begin(); it != adaptiveAttempts.end();) {
|
||||
if (now - it->second.lastUseMsec > expiryMsec) {
|
||||
it = adaptiveAttempts.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RadioInterface::recordAdaptiveAttempt(const meshtastic_MeshPacket *p)
|
||||
{
|
||||
const uint32_t now = millis();
|
||||
pruneAdaptiveAttempts(now);
|
||||
|
||||
const uint64_t key = adaptiveKey(getFrom(p), p->id);
|
||||
auto &state = adaptiveAttempts[key];
|
||||
if (state.attempts < UINT8_MAX) {
|
||||
state.attempts++;
|
||||
}
|
||||
state.lastUseMsec = now;
|
||||
return state.attempts;
|
||||
}
|
||||
|
||||
bool RadioInterface::applyAdaptiveCodingRate(const meshtastic_MeshPacket *p)
|
||||
{
|
||||
const uint8_t attempt = recordAdaptiveAttempt(p);
|
||||
const uint8_t desiredCr = computeAdaptiveCodingRate(attempt);
|
||||
if (desiredCr < 5 || desiredCr > 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
adaptiveCrOverride = desiredCr;
|
||||
if (cr != desiredCr) {
|
||||
cr = desiredCr;
|
||||
reconfigure();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RadioInterface::clearAdaptiveCodingRateState(NodeNum from, PacketId id)
|
||||
{
|
||||
adaptiveAttempts.erase(adaptiveKey(from, id));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#include "PointerQueue.h"
|
||||
#include "airtime.h"
|
||||
#include "error.h"
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
|
||||
|
||||
@@ -223,11 +220,6 @@ class RadioInterface
|
||||
// Whether we use the default frequency slot given our LoRa config (region and modem preset)
|
||||
static bool uses_default_frequency_slot;
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
/** Clear adaptive coding rate tracking for a completed packet id */
|
||||
void clearAdaptiveCodingRateState(NodeNum from, PacketId id);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
int8_t power = 17; // Set by applyModemConfig()
|
||||
|
||||
@@ -258,20 +250,6 @@ class RadioInterface
|
||||
*/
|
||||
virtual void saveChannelNum(uint32_t savedChannelNum);
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
bool applyAdaptiveCodingRate(const meshtastic_MeshPacket *p);
|
||||
struct AdaptiveAttemptState {
|
||||
uint8_t attempts = 0;
|
||||
uint32_t lastUseMsec = 0;
|
||||
};
|
||||
std::unordered_map<uint64_t, AdaptiveAttemptState> adaptiveAttempts;
|
||||
uint8_t adaptiveCrOverride = 0;
|
||||
uint8_t recordAdaptiveAttempt(const meshtastic_MeshPacket *p);
|
||||
uint8_t computeAdaptiveCodingRate(uint8_t attempt) const;
|
||||
void pruneAdaptiveAttempts(uint32_t now);
|
||||
uint64_t adaptiveKey(NodeNum from, PacketId id) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
* Convert our modemConfig enum into wf, sf, etc...
|
||||
|
||||
@@ -540,9 +540,6 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
|
||||
packetPool.release(txp);
|
||||
return false;
|
||||
} else {
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
applyAdaptiveCodingRate(txp);
|
||||
#endif
|
||||
configHardwareForSend(); // must be after setStandby
|
||||
|
||||
size_t numbytes = beginSending(txp);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "ReliableRouter.h"
|
||||
#include "Default.h"
|
||||
#include "MeshTypes.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "memGet.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
@@ -109,12 +108,12 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
||||
// If this packet should always be ACKed reliably with want_ack back to the original sender, make sure we
|
||||
// do that unconditionally.
|
||||
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
||||
routingModule->getHopLimitForResponse(*p), true);
|
||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit), true);
|
||||
} else if (!p->decoded.request_id && !p->decoded.reply_id) {
|
||||
// If it's not an ACK or a reply, send an ACK.
|
||||
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel,
|
||||
routingModule->getHopLimitForResponse(*p));
|
||||
} else if ((getHopsAway(*p) == 0) || p->next_hop != NO_NEXT_HOP_PREFERENCE) {
|
||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
||||
} else if ((p->hop_start > 0 && p->hop_start == p->hop_limit) || p->next_hop != NO_NEXT_HOP_PREFERENCE) {
|
||||
// If we received the packet directly from the original sender, send a 0-hop ACK since the original sender
|
||||
// won't overhear any implicit ACKs. If we received the packet via NextHopRouter, also send a 0-hop ACK to
|
||||
// stop the immediate relayer's retransmissions.
|
||||
@@ -124,11 +123,11 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
||||
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
|
||||
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY");
|
||||
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
|
||||
routingModule->getHopLimitForResponse(*p));
|
||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
||||
} else {
|
||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||
sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex(),
|
||||
routingModule->getHopLimitForResponse(*p));
|
||||
routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit));
|
||||
}
|
||||
} else if (p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum()) && p->hop_limit > 0) {
|
||||
// No wantAck, but we need to ACK with hop limit of 0 if we were the next hop to stop their retransmissions
|
||||
|
||||
@@ -81,7 +81,8 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
|
||||
bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
||||
{
|
||||
// First hop MUST always decrement to prevent retry issues
|
||||
if (getHopsAway(*p) == 0) {
|
||||
bool isFirstHop = (p->hop_start != 0 && p->hop_start == p->hop_limit);
|
||||
if (isFirstHop) {
|
||||
return true; // Always decrement on first hop
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
||||
|
||||
// Check 3: role check (moderate cost - multiple comparisons)
|
||||
if (!IS_ONE_OF(node->user.role, meshtastic_Config_DeviceConfig_Role_ROUTER,
|
||||
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE)) {
|
||||
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -729,8 +730,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
meshtastic_PortNum_POSITION_APP, meshtastic_PortNum_NODEINFO_APP, meshtastic_PortNum_ROUTING_APP,
|
||||
meshtastic_PortNum_TELEMETRY_APP, meshtastic_PortNum_ADMIN_APP, meshtastic_PortNum_ALERT_APP,
|
||||
meshtastic_PortNum_KEY_VERIFICATION_APP, meshtastic_PortNum_WAYPOINT_APP,
|
||||
meshtastic_PortNum_STORE_FORWARD_APP, meshtastic_PortNum_TRACEROUTE_APP,
|
||||
meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP)) {
|
||||
meshtastic_PortNum_STORE_FORWARD_APP, meshtastic_PortNum_TRACEROUTE_APP)) {
|
||||
LOG_DEBUG("Ignore packet on non-standard portnum for CORE_PORTNUMS_ONLY");
|
||||
cancelSending(p->from, p->id);
|
||||
skipHandle = true;
|
||||
@@ -745,19 +745,15 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
MeshModule::callModules(*p, src);
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
if (p_encrypted == nullptr) {
|
||||
LOG_WARN("p_encrypted is null, skipping MQTT publish");
|
||||
} else {
|
||||
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not
|
||||
// to us (because we would be able to decrypt it)
|
||||
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
||||
!isBroadcast(p->to) && !isToUs(p))
|
||||
p_encrypted->pki_encrypted = true;
|
||||
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
||||
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
||||
!isFromUs(p) && mqtt)
|
||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||
}
|
||||
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
|
||||
// us (because we would be able to decrypt it)
|
||||
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
||||
!isBroadcast(p->to) && !isToUs(p))
|
||||
p_encrypted->pki_encrypted = true;
|
||||
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
||||
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
||||
!isFromUs(p) && mqtt)
|
||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -62,11 +62,6 @@ template <typename T> bool SX126xInterface<T>::init()
|
||||
digitalWrite(LORA_PA_TX_EN, LOW);
|
||||
#endif
|
||||
|
||||
#ifdef RF95_FAN_EN
|
||||
digitalWrite(RF95_FAN_EN, HIGH);
|
||||
pinMode(RF95_FAN_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000;
|
||||
if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) {
|
||||
@@ -90,13 +85,6 @@ template <typename T> bool SX126xInterface<T>::init()
|
||||
power = -9;
|
||||
|
||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
|
||||
|
||||
#ifdef SX126X_PA_RAMP_US
|
||||
// Set custom PA ramp time for boards requiring longer stabilization (e.g., T-Beam 1W needs >800us)
|
||||
if (res == RADIOLIB_ERR_NONE) {
|
||||
lora.setPaRampTime(SX126X_PA_RAMP_US);
|
||||
}
|
||||
#endif
|
||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||
LOG_INFO("SX126x init result %d", res);
|
||||
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED)
|
||||
|
||||
@@ -822,8 +822,6 @@ typedef struct _meshtastic_StoreForwardPlusPlus {
|
||||
uint32_t encapsulated_from;
|
||||
/* The receive time of the message in question */
|
||||
uint32_t encapsulated_rxtime;
|
||||
/* Used in a LINK_REQUEST to specify the message X spots back from head */
|
||||
uint32_t chain_count;
|
||||
} meshtastic_StoreForwardPlusPlus;
|
||||
|
||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||
@@ -1430,7 +1428,7 @@ extern "C" {
|
||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 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, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||
@@ -1462,7 +1460,7 @@ extern "C" {
|
||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 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, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||
@@ -1550,7 +1548,6 @@ extern "C" {
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8
|
||||
#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9
|
||||
#define meshtastic_StoreForwardPlusPlus_chain_count_tag 10
|
||||
#define meshtastic_Waypoint_id_tag 1
|
||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||
@@ -1776,8 +1773,7 @@ X(a, STATIC, SINGULAR, BYTES, message, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, chain_count, 10)
|
||||
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9)
|
||||
#define meshtastic_StoreForwardPlusPlus_CALLBACK NULL
|
||||
#define meshtastic_StoreForwardPlusPlus_DEFAULT NULL
|
||||
|
||||
@@ -2147,7 +2143,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
#define meshtastic_QueueStatus_size 23
|
||||
#define meshtastic_RouteDiscovery_size 256
|
||||
#define meshtastic_Routing_size 259
|
||||
#define meshtastic_StoreForwardPlusPlus_size 377
|
||||
#define meshtastic_StoreForwardPlusPlus_size 371
|
||||
#define meshtastic_ToRadio_size 504
|
||||
#define meshtastic_User_size 115
|
||||
#define meshtastic_Waypoint_size 165
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace graphics
|
||||
extern int bannerSignalBars;
|
||||
}
|
||||
extern ScanI2C::DeviceAddress cardkb_found;
|
||||
extern bool graphics::isMuted;
|
||||
extern bool osk_found;
|
||||
|
||||
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
|
||||
|
||||
@@ -170,7 +170,7 @@ bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
|
||||
} else {
|
||||
LOG_DEBUG(" Ignoring dummy neighbor info packet (single neighbor with nodeId 0, snr 0)");
|
||||
}
|
||||
} else if (getHopsAway(mp) == 0) {
|
||||
} else if (mp.hop_start != 0 && mp.hop_start == mp.hop_limit) {
|
||||
LOG_DEBUG("Get or create neighbor: %u with snr %f", mp.from, mp.rx_snr);
|
||||
// If the hopLimit is the same as hopStart, then it is a neighbor
|
||||
getOrCreateNeighbor(mp.from, mp.from, 0,
|
||||
|
||||
@@ -429,9 +429,7 @@ int32_t PositionModule::runOnce()
|
||||
|
||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||
if (waitingForFreshPosition) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("Skip initial position send; no fresh position since boot");
|
||||
#endif
|
||||
} else if (nodeDB->hasValidPosition(node)) {
|
||||
lastGpsSend = now;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
|
||||
// In event mode we want to prevent excessive position broadcasts
|
||||
// we set the minimum interval to 5m
|
||||
const uint32_t minimumTimeThreshold =
|
||||
max(uint32_t(300000), Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30));
|
||||
max(300000, Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30));
|
||||
#else
|
||||
const uint32_t minimumTimeThreshold =
|
||||
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
|
||||
|
||||
@@ -58,11 +58,12 @@ void RoutingModule::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketI
|
||||
router->sendLocal(p); // we sometimes send directly to the local node
|
||||
}
|
||||
|
||||
uint8_t RoutingModule::getHopLimitForResponse(const meshtastic_MeshPacket &mp)
|
||||
uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit)
|
||||
{
|
||||
const int8_t hopsUsed = getHopsAway(mp);
|
||||
if (hopsUsed >= 0) {
|
||||
if (hopsUsed > (int32_t)(config.lora.hop_limit)) {
|
||||
if (hopStart != 0) {
|
||||
// Hops used by the request. If somebody in between running modified firmware modified it, ignore it
|
||||
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
|
||||
if (hopsUsed > config.lora.hop_limit) {
|
||||
// In event mode, we never want to send packets with more than our default 3 hops.
|
||||
#if !(EVENTMODE) // This falls through to the default.
|
||||
return hopsUsed; // If the request used more hops than the limit, use the same amount of hops
|
||||
|
||||
@@ -20,7 +20,7 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
|
||||
uint8_t hopLimit = 0);
|
||||
|
||||
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
||||
uint8_t getHopLimitForResponse(const meshtastic_MeshPacket &mp);
|
||||
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
||||
|
||||
protected:
|
||||
friend class Router;
|
||||
|
||||
@@ -20,7 +20,7 @@ int StatusLEDModule::handleStatusUpdate(const meshtastic::Status *arg)
|
||||
switch (arg->getStatusType()) {
|
||||
case STATUS_TYPE_POWER: {
|
||||
meshtastic::PowerStatus *powerStatus = (meshtastic::PowerStatus *)arg;
|
||||
if (powerStatus->getHasUSB() || powerStatus->getIsCharging()) {
|
||||
if (powerStatus->getHasUSB()) {
|
||||
power_state = charging;
|
||||
if (powerStatus->getBatteryChargePercent() >= 100) {
|
||||
power_state = charged;
|
||||
|
||||
@@ -45,9 +45,10 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
|
||||
// Mute
|
||||
case INPUT_BROKER_MSG_MUTE_TOGGLE:
|
||||
if (moduleConfig.external_notification.enabled && externalNotificationModule) {
|
||||
externalNotificationModule->setMute(externalNotificationModule->getMute());
|
||||
IF_SCREEN(if (!externalNotificationModule->getMute()) externalNotificationModule->stopNow(); screen->showSimpleBanner(
|
||||
externalNotificationModule->getMute() ? "Notifications\nEnabled" : "Notifications\nDisabled", 3000);)
|
||||
bool isMuted = externalNotificationModule->getMute();
|
||||
externalNotificationModule->setMute(!isMuted);
|
||||
IF_SCREEN(graphics::isMuted = !isMuted; if (!isMuted) externalNotificationModule->stopNow();
|
||||
screen->showSimpleBanner(isMuted ? "Notifications\nEnabled" : "Notifications\nDisabled", 3000);)
|
||||
}
|
||||
return 0;
|
||||
// Bluetooth
|
||||
|
||||
@@ -53,7 +53,7 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
|
||||
#include "Sensor/LTR390UVSensor.h"
|
||||
#endif
|
||||
|
||||
#if __has_include(MESHTASTIC_BME680_HEADER)
|
||||
#if __has_include(<bsec2.h>)
|
||||
#include "Sensor/BME680Sensor.h"
|
||||
#endif
|
||||
|
||||
@@ -214,7 +214,7 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
||||
#if __has_include(<Adafruit_LTR390.h>)
|
||||
addSensor<LTR390UVSensor>(i2cScanner, ScanI2C::DeviceType::LTR390UV);
|
||||
#endif
|
||||
#if __has_include(MESHTASTIC_BME680_HEADER)
|
||||
#if __has_include(<bsec2.h>)
|
||||
addSensor<BME680Sensor>(i2cScanner, ScanI2C::DeviceType::BME_680);
|
||||
#endif
|
||||
#if __has_include(<Adafruit_BMP280.h>)
|
||||
|
||||
@@ -136,12 +136,12 @@ void HealthTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *
|
||||
display->drawString(x, y += _fontHeight(FONT_SMALL), tempStr);
|
||||
if (lastMeasurement.variant.health_metrics.has_heart_bpm) {
|
||||
char heartStr[32];
|
||||
snprintf(heartStr, sizeof(heartStr), "Heart Rate: %u bpm", lastMeasurement.variant.health_metrics.heart_bpm);
|
||||
snprintf(heartStr, sizeof(heartStr), "Heart Rate: %.0f bpm", lastMeasurement.variant.health_metrics.heart_bpm);
|
||||
display->drawString(x, y += _fontHeight(FONT_SMALL), heartStr);
|
||||
}
|
||||
if (lastMeasurement.variant.health_metrics.has_spO2) {
|
||||
char spo2Str[32];
|
||||
snprintf(spo2Str, sizeof(spo2Str), "spO2: %u %%", lastMeasurement.variant.health_metrics.spO2);
|
||||
snprintf(spo2Str, sizeof(spo2Str), "spO2: %.0f %%", lastMeasurement.variant.health_metrics.spO2);
|
||||
display->drawString(x, y += _fontHeight(FONT_SMALL), spo2Str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<bsec2.h>)
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "BME680Sensor.h"
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
|
||||
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
int32_t BME680Sensor::runOnce()
|
||||
{
|
||||
if (!bme680.run()) {
|
||||
@@ -18,13 +17,10 @@ int32_t BME680Sensor::runOnce()
|
||||
}
|
||||
return 35;
|
||||
}
|
||||
#endif // defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
|
||||
|
||||
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
{
|
||||
status = 0;
|
||||
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
if (!bme680.begin(dev->address.address, *bus))
|
||||
checkStatus("begin");
|
||||
|
||||
@@ -46,25 +42,12 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
if (status == 0)
|
||||
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
|
||||
|
||||
#else
|
||||
bme680 = makeBME680(bus);
|
||||
|
||||
if (!bme680->begin(dev->address.address)) {
|
||||
LOG_ERROR("Init sensor: %s failed at begin()", sensorName);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = 1;
|
||||
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
initI2CSensor();
|
||||
return status;
|
||||
}
|
||||
|
||||
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
|
||||
return false;
|
||||
|
||||
@@ -82,27 +65,9 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
|
||||
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
|
||||
updateState();
|
||||
#else
|
||||
if (!bme680->performReading()) {
|
||||
LOG_ERROR("BME680Sensor::getMetrics: performReading failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
measurement->variant.environment_metrics.has_temperature = true;
|
||||
measurement->variant.environment_metrics.has_relative_humidity = true;
|
||||
measurement->variant.environment_metrics.has_barometric_pressure = true;
|
||||
measurement->variant.environment_metrics.has_gas_resistance = true;
|
||||
|
||||
measurement->variant.environment_metrics.temperature = bme680->readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = bme680->readHumidity();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme680->readPressure() / 100.0F;
|
||||
measurement->variant.environment_metrics.gas_resistance = bme680->readGas() / 1000.0;
|
||||
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
return true;
|
||||
}
|
||||
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
void BME680Sensor::loadState()
|
||||
{
|
||||
#ifdef FSCom
|
||||
@@ -179,6 +144,5 @@ void BME680Sensor::checkStatus(const char *functionName)
|
||||
else if (bme680.sensor.status > BME68X_OK)
|
||||
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
|
||||
}
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,40 +1,23 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<bsec2.h>)
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
#include <bme68xLibrary.h>
|
||||
#include <bsec2.h>
|
||||
#else
|
||||
#include <Adafruit_BME680.h>
|
||||
#include <memory>
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
|
||||
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
const uint8_t bsec_config[] = {
|
||||
#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt"
|
||||
};
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
class BME680Sensor : public TelemetrySensor
|
||||
{
|
||||
private:
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
Bsec2 bme680;
|
||||
#else
|
||||
using BME680Ptr = std::unique_ptr<Adafruit_BME680>;
|
||||
|
||||
static BME680Ptr makeBME680(TwoWire *bus) { return std::make_unique<Adafruit_BME680>(bus); }
|
||||
|
||||
BME680Ptr bme680;
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
protected:
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
const char *bsecConfigFileName = "/prefs/bsec.dat";
|
||||
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
|
||||
uint8_t accuracy = 0;
|
||||
@@ -51,13 +34,10 @@ class BME680Sensor : public TelemetrySensor
|
||||
void loadState();
|
||||
void updateState();
|
||||
void checkStatus(const char *functionName);
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
|
||||
public:
|
||||
BME680Sensor();
|
||||
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
|
||||
virtual int32_t runOnce() override;
|
||||
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
|
||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
|
||||
};
|
||||
|
||||
@@ -21,17 +21,18 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
|
||||
// We only store/display messages destined for us.
|
||||
devicestate.rx_text_message = mp;
|
||||
devicestate.has_rx_text_message = true;
|
||||
IF_SCREEN(
|
||||
// Guard against running in MeshtasticUI or with no screen
|
||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
||||
// Store in the central message history
|
||||
const StoredMessage &sm = messageStore.addFromPacket(mp);
|
||||
#if HAS_SCREEN
|
||||
// Guard against running in MeshtasticUI
|
||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
||||
// Store in the central message history
|
||||
const StoredMessage &sm = messageStore.addFromPacket(mp);
|
||||
|
||||
// Pass message to renderer (banner + thread switching + scroll reset)
|
||||
// Use the global Screen singleton to retrieve the current OLED display
|
||||
auto *display = screen ? screen->getDisplayDevice() : nullptr;
|
||||
graphics::MessageRenderer::handleNewMessage(display, sm, mp);
|
||||
})
|
||||
// Pass message to renderer (banner + thread switching + scroll reset)
|
||||
// Use the global Screen singleton to retrieve the current OLED display
|
||||
auto *display = screen ? screen->getDisplayDevice() : nullptr;
|
||||
graphics::MessageRenderer::handleNewMessage(display, sm, mp);
|
||||
}
|
||||
#endif
|
||||
// Only trigger screen wake if configuration allows it
|
||||
if (shouldWakeOnReceivedMessage()) {
|
||||
powerFSM.trigger(EVENT_RECEIVED_MSG);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "TraceRouteModule.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "graphics/ScreenFonts.h"
|
||||
#include "graphics/SharedUIDisplay.h"
|
||||
@@ -360,10 +359,10 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
|
||||
}
|
||||
|
||||
// Only insert unknown hops if hop_start is valid
|
||||
const int8_t hopsTaken = getHopsAway(p);
|
||||
if (hopsTaken >= 0) {
|
||||
if (p.hop_start != 0 && p.hop_limit <= p.hop_start) {
|
||||
uint8_t hopsTaken = p.hop_start - p.hop_limit;
|
||||
int8_t diff = hopsTaken - *route_count;
|
||||
for (int8_t i = 0; i < diff; i++) {
|
||||
for (uint8_t i = 0; i < diff; i++) {
|
||||
if (*route_count < ROUTE_SIZE) {
|
||||
route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop
|
||||
*route_count += 1;
|
||||
@@ -371,7 +370,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
|
||||
}
|
||||
// Add unknown SNR values if necessary
|
||||
diff = *route_count - *snr_count;
|
||||
for (int8_t i = 0; i < diff; i++) {
|
||||
for (uint8_t i = 0; i < diff; i++) {
|
||||
if (*snr_count < ROUTE_SIZE) {
|
||||
snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR
|
||||
*snr_count += 1;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
#include "NimBLEAdvertising.h"
|
||||
#ifdef CONFIG_BT_NIMBLE_EXT_ADV
|
||||
#include "NimBLEExtAdvertising.h"
|
||||
#include "PowerStatus.h"
|
||||
#endif
|
||||
#include "PowerStatus.h"
|
||||
|
||||
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||
#include "host/ble_gap.h"
|
||||
@@ -26,15 +26,12 @@
|
||||
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr uint16_t kPreferredBleMtu = 517;
|
||||
constexpr uint16_t kPreferredBleTxOctets = 251;
|
||||
constexpr uint16_t kPreferredBleTxTimeUs = (kPreferredBleTxOctets + 14) * 8;
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
// Debugging options: careful, they slow things down quite a bit!
|
||||
// #define DEBUG_NIMBLE_ON_READ_TIMING // uncomment to time onRead duration
|
||||
@@ -313,11 +310,9 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
||||
{
|
||||
PhoneAPI::onNowHasData(fromRadioNum);
|
||||
|
||||
int currentNotifyCount = notifyCount.fetch_add(1);
|
||||
|
||||
uint8_t cc = bleServer->getConnectedCount();
|
||||
|
||||
#ifdef DEBUG_NIMBLE_NOTIFY
|
||||
int currentNotifyCount = notifyCount.fetch_add(1);
|
||||
uint8_t cc = bleServer->getConnectedCount();
|
||||
// This logging slows things down when there are lots of packets going to the phone, like initial connection:
|
||||
LOG_DEBUG("BLE notify(%d) fromNum: %d connections: %d", currentNotifyCount, fromRadioNum, cc);
|
||||
#endif
|
||||
@@ -326,13 +321,7 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
||||
put_le32(val, fromRadioNum);
|
||||
|
||||
fromNumCharacteristic->setValue(val, sizeof(val));
|
||||
#ifdef NIMBLE_TWO
|
||||
// NOTE: I don't have any NIMBLE_TWO devices, but this line makes me suspicious, and I suspect it needs to just be
|
||||
// notify().
|
||||
fromNumCharacteristic->notify(val, sizeof(val), BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
fromNumCharacteristic->notify();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
@@ -397,12 +386,7 @@ static uint8_t lastToRadio[MAX_TO_FROM_RADIO_SIZE];
|
||||
|
||||
class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic)
|
||||
|
||||
#endif
|
||||
void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &) override
|
||||
{
|
||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||
// Assumption: onWrite is serialized by NimBLE, so we don't need to lock here against multiple concurrent onWrite calls.
|
||||
@@ -449,11 +433,7 @@ class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||
|
||||
class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onRead(NimBLECharacteristic *pCharacteristic)
|
||||
#endif
|
||||
void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &) override
|
||||
{
|
||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||
|
||||
@@ -561,32 +541,27 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
||||
|
||||
class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
public:
|
||||
NimbleBluetoothServerCallback(NimbleBluetooth *ble) { this->ble = ble; }
|
||||
explicit NimbleBluetoothServerCallback(NimbleBluetooth *ble) : ble(ble) {}
|
||||
|
||||
private:
|
||||
NimbleBluetooth *ble;
|
||||
|
||||
virtual uint32_t onPassKeyDisplay()
|
||||
#else
|
||||
virtual uint32_t onPassKeyRequest()
|
||||
#endif
|
||||
uint32_t onPassKeyDisplay() override
|
||||
{
|
||||
uint32_t passkey = config.bluetooth.fixed_pin;
|
||||
|
||||
if (config.bluetooth.mode == meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
|
||||
LOG_INFO("Use random passkey");
|
||||
// This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
||||
passkey = random(100000, 999999);
|
||||
}
|
||||
LOG_INFO("*** Enter passkey %d on the peer side ***", passkey);
|
||||
LOG_INFO("*** Enter passkey %06u on the peer side ***", passkey);
|
||||
|
||||
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
||||
meshtastic::BluetoothStatus newStatus(std::to_string(passkey));
|
||||
bluetoothStatus->updateStatus(&newStatus);
|
||||
|
||||
#if HAS_SCREEN // Todo: migrate this display code back into Screen class, and observe bluetoothStatus
|
||||
#if HAS_SCREEN
|
||||
if (screen) {
|
||||
screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||
char btPIN[16] = "888888";
|
||||
@@ -615,39 +590,29 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
});
|
||||
}
|
||||
#endif
|
||||
passkeyShowing = true;
|
||||
|
||||
passkeyShowing = true;
|
||||
return passkey;
|
||||
}
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onAuthenticationComplete(NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onAuthenticationComplete(ble_gap_conn_desc *desc)
|
||||
#endif
|
||||
void onAuthenticationComplete(NimBLEConnInfo &connInfo) override
|
||||
{
|
||||
LOG_INFO("BLE authentication complete");
|
||||
|
||||
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::CONNECTED);
|
||||
bluetoothStatus->updateStatus(&newStatus);
|
||||
|
||||
// Todo: migrate this display code back into Screen class, and observe bluetoothStatus
|
||||
if (passkeyShowing) {
|
||||
passkeyShowing = false;
|
||||
if (screen)
|
||||
if (screen) {
|
||||
screen->endAlert();
|
||||
}
|
||||
}
|
||||
|
||||
// Store the connection handle for future use
|
||||
#ifdef NIMBLE_TWO
|
||||
nimbleBluetoothConnHandle = connInfo.getConnHandle();
|
||||
#else
|
||||
nimbleBluetoothConnHandle = desc->conn_handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo)
|
||||
void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override
|
||||
{
|
||||
LOG_INFO("BLE incoming connection %s", connInfo.getAddress().toString().c_str());
|
||||
|
||||
@@ -672,21 +637,12 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
LOG_INFO("BLE conn %u initial MTU %u (target %u)", connHandle, connInfo.getMTU(), kPreferredBleMtu);
|
||||
pServer->updateConnParams(connHandle, 6, 12, 0, 200);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason)
|
||||
void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override
|
||||
{
|
||||
LOG_INFO("BLE disconnect reason: %d", reason);
|
||||
#else
|
||||
virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
|
||||
{
|
||||
LOG_INFO("BLE disconnect");
|
||||
#endif
|
||||
#ifdef NIMBLE_TWO
|
||||
if (ble->isDeInit)
|
||||
return;
|
||||
#endif
|
||||
|
||||
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::DISCONNECTED);
|
||||
bluetoothStatus->updateStatus(&newStatus);
|
||||
@@ -710,35 +666,69 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
bluetoothPhoneAPI->writeCount = 0;
|
||||
}
|
||||
|
||||
// Clear the last ToRadio packet buffer to avoid rejecting first packet from new connection
|
||||
memset(lastToRadio, 0, sizeof(lastToRadio));
|
||||
|
||||
nimbleBluetoothConnHandle = BLE_HS_CONN_HANDLE_NONE; // BLE_HS_CONN_HANDLE_NONE means "no connection"
|
||||
nimbleBluetoothConnHandle = BLE_HS_CONN_HANDLE_NONE;
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
// Restart Advertising
|
||||
ble->startAdvertising();
|
||||
#else
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
if (!pAdvertising->start(0)) {
|
||||
if (pAdvertising->isAdvertising()) {
|
||||
LOG_DEBUG("BLE advertising already running");
|
||||
} else {
|
||||
LOG_ERROR("BLE failed to restart advertising");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
static NimbleBluetoothToRadioCallback *toRadioCallbacks;
|
||||
static NimbleBluetoothFromRadioCallback *fromRadioCallbacks;
|
||||
|
||||
void NimbleBluetooth::startAdvertising()
|
||||
{
|
||||
#if defined(CONFIG_BT_NIMBLE_EXT_ADV)
|
||||
NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
NimBLEExtAdvertisement legacyAdvertising;
|
||||
|
||||
legacyAdvertising.setLegacyAdvertising(true);
|
||||
legacyAdvertising.setScannable(true);
|
||||
legacyAdvertising.setConnectable(true);
|
||||
legacyAdvertising.setFlags(BLE_HS_ADV_F_DISC_GEN);
|
||||
if (powerStatus->getHasBattery() == 1) {
|
||||
legacyAdvertising.setCompleteServices(NimBLEUUID((uint16_t)0x180f));
|
||||
}
|
||||
legacyAdvertising.setCompleteServices(NimBLEUUID(MESH_SERVICE_UUID));
|
||||
legacyAdvertising.setMinInterval(500);
|
||||
legacyAdvertising.setMaxInterval(1000);
|
||||
|
||||
NimBLEExtAdvertisement legacyScanResponse;
|
||||
legacyScanResponse.setLegacyAdvertising(true);
|
||||
legacyScanResponse.setConnectable(true);
|
||||
legacyScanResponse.setName(getDeviceName());
|
||||
|
||||
if (!pAdvertising->setInstanceData(0, legacyAdvertising)) {
|
||||
LOG_ERROR("BLE failed to set legacyAdvertising");
|
||||
} else if (!pAdvertising->setScanResponseData(0, legacyScanResponse)) {
|
||||
LOG_ERROR("BLE failed to set legacyScanResponse");
|
||||
} else if (!pAdvertising->start(0, 0, 0)) {
|
||||
LOG_ERROR("BLE failed to start legacyAdvertising");
|
||||
}
|
||||
#else
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
pAdvertising->reset();
|
||||
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
||||
if (powerStatus->getHasBattery() == 1) {
|
||||
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f));
|
||||
}
|
||||
|
||||
NimBLEAdvertisementData scan;
|
||||
scan.setName(getDeviceName());
|
||||
pAdvertising->setScanResponseData(scan);
|
||||
pAdvertising->enableScanResponse(true);
|
||||
|
||||
if (!pAdvertising->start(0)) {
|
||||
LOG_ERROR("BLE failed to start advertising");
|
||||
}
|
||||
#endif
|
||||
LOG_DEBUG("BLE Advertising started");
|
||||
}
|
||||
|
||||
void NimbleBluetooth::shutdown()
|
||||
{
|
||||
// No measurable power saving for ESP32 during light-sleep(?)
|
||||
#ifndef ARCH_ESP32
|
||||
// Shutdown bluetooth for minimum power draw
|
||||
LOG_INFO("Disable bluetooth");
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
pAdvertising->reset();
|
||||
@@ -746,7 +736,6 @@ void NimbleBluetooth::shutdown()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Proper shutdown for ESP32. Needs reboot to reverse.
|
||||
void NimbleBluetooth::deinit()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@@ -760,21 +749,17 @@ void NimbleBluetooth::deinit()
|
||||
digitalWrite(BLE_LED, LOW);
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NIMBLE_TWO
|
||||
NimBLEDevice::deinit();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Has initial setup been completed
|
||||
bool NimbleBluetooth::isActive()
|
||||
{
|
||||
return bleServer;
|
||||
return bleServer != nullptr;
|
||||
}
|
||||
|
||||
bool NimbleBluetooth::isConnected()
|
||||
{
|
||||
return bleServer->getConnectedCount() > 0;
|
||||
return bleServer && bleServer->getConnectedCount() > 0;
|
||||
}
|
||||
|
||||
int NimbleBluetooth::getRssi()
|
||||
@@ -818,7 +803,7 @@ void NimbleBluetooth::setup()
|
||||
LOG_INFO("Init the NimBLE bluetooth module");
|
||||
|
||||
NimBLEDevice::init(getDeviceName());
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
||||
NimBLEDevice::setPower(9);
|
||||
|
||||
#if NIMBLE_ENABLE_2M_PHY && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6))
|
||||
int mtuResult = NimBLEDevice::setMTU(kPreferredBleMtu);
|
||||
@@ -851,11 +836,7 @@ void NimbleBluetooth::setup()
|
||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||
}
|
||||
bleServer = NimBLEDevice::createServer();
|
||||
#ifdef NIMBLE_TWO
|
||||
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback(this);
|
||||
#else
|
||||
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback();
|
||||
#endif
|
||||
auto *serverCallbacks = new NimbleBluetoothServerCallback(this);
|
||||
bleServer->setCallbacks(serverCallbacks, true);
|
||||
setupService();
|
||||
startAdvertising();
|
||||
@@ -900,11 +881,7 @@ void NimbleBluetooth::setupService()
|
||||
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
||||
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
|
||||
#ifdef NIMBLE_TWO
|
||||
NimBLE2904 *batteryLevelDescriptor = BatteryCharacteristic->create2904();
|
||||
#else
|
||||
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
|
||||
#endif
|
||||
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
||||
batteryLevelDescriptor->setNamespace(1);
|
||||
batteryLevelDescriptor->setUnit(0x27ad);
|
||||
@@ -912,54 +889,12 @@ void NimbleBluetooth::setupService()
|
||||
batteryService->start();
|
||||
}
|
||||
|
||||
void NimbleBluetooth::startAdvertising()
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
NimBLEExtAdvertisement legacyAdvertising;
|
||||
|
||||
legacyAdvertising.setLegacyAdvertising(true);
|
||||
legacyAdvertising.setScannable(true);
|
||||
legacyAdvertising.setConnectable(true);
|
||||
legacyAdvertising.setFlags(BLE_HS_ADV_F_DISC_GEN);
|
||||
if (powerStatus->getHasBattery() == 1) {
|
||||
legacyAdvertising.setCompleteServices(NimBLEUUID((uint16_t)0x180f));
|
||||
}
|
||||
legacyAdvertising.setCompleteServices(NimBLEUUID(MESH_SERVICE_UUID));
|
||||
legacyAdvertising.setMinInterval(500);
|
||||
legacyAdvertising.setMaxInterval(1000);
|
||||
|
||||
NimBLEExtAdvertisement legacyScanResponse;
|
||||
legacyScanResponse.setLegacyAdvertising(true);
|
||||
legacyScanResponse.setConnectable(true);
|
||||
legacyScanResponse.setName(getDeviceName());
|
||||
|
||||
if (!pAdvertising->setInstanceData(0, legacyAdvertising)) {
|
||||
LOG_ERROR("BLE failed to set legacyAdvertising");
|
||||
} else if (!pAdvertising->setScanResponseData(0, legacyScanResponse)) {
|
||||
LOG_ERROR("BLE failed to set legacyScanResponse");
|
||||
} else if (!pAdvertising->start(0, 0, 0)) {
|
||||
LOG_ERROR("BLE failed to start legacyAdvertising");
|
||||
}
|
||||
#else
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
pAdvertising->reset();
|
||||
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
||||
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||
pAdvertising->start(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Given a level between 0-100, update the BLE attribute
|
||||
void updateBatteryLevel(uint8_t level)
|
||||
{
|
||||
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
|
||||
BatteryCharacteristic->setValue(&level, 1);
|
||||
#ifdef NIMBLE_TWO
|
||||
BatteryCharacteristic->notify(&level, 1, BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
BatteryCharacteristic->notify();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,11 +909,7 @@ void NimbleBluetooth::sendLog(const uint8_t *logMessage, size_t length)
|
||||
if (!bleServer || !isConnected() || length > 512) {
|
||||
return;
|
||||
}
|
||||
#ifdef NIMBLE_TWO
|
||||
logRadioCharacteristic->notify(logMessage, length, BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
logRadioCharacteristic->notify(logMessage, length, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clearNVS()
|
||||
|
||||
@@ -12,16 +12,11 @@ class NimbleBluetooth : BluetoothApi
|
||||
bool isConnected();
|
||||
int getRssi();
|
||||
void sendLog(const uint8_t *logMessage, size_t length);
|
||||
#if defined(NIMBLE_TWO)
|
||||
void startAdvertising();
|
||||
#endif
|
||||
bool isDeInit = false;
|
||||
|
||||
private:
|
||||
void setupService();
|
||||
#if !defined(NIMBLE_TWO)
|
||||
void startAdvertising();
|
||||
#endif
|
||||
};
|
||||
|
||||
void setBluetoothEnable(bool enable);
|
||||
|
||||
@@ -279,7 +279,7 @@ void portduinoSetup()
|
||||
// RAK6421-13300-S1:aabbcc123456:5ba85807d92138b7519cfb60460573af:3061e8d8
|
||||
// <model string>:mac address :<16 random unique bytes in hexidecimal> : crc32
|
||||
// crc32 is calculated on the eeprom string up to but not including the final colon
|
||||
if (strlen(autoconf_product) < 6 && portduino_config.i2cdev != "") {
|
||||
if (strlen(autoconf_product) < 6) {
|
||||
try {
|
||||
char *mac_start = nullptr;
|
||||
char *devID_start = nullptr;
|
||||
@@ -869,4 +869,4 @@ void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault
|
||||
destPin.line = destPin.pin;
|
||||
destPin.gpiochip = portduino_config.lora_default_gpiochip;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -418,9 +418,8 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
||||
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
||||
if (mp->rx_snr != 0)
|
||||
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
||||
const int8_t hopsAway = getHopsAway(*mp);
|
||||
if (hopsAway >= 0) {
|
||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(hopsAway));
|
||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit));
|
||||
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
||||
}
|
||||
|
||||
@@ -451,9 +450,8 @@ std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPa
|
||||
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
|
||||
if (mp->rx_snr != 0)
|
||||
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
|
||||
const int8_t hopsAway = getHopsAway(*mp);
|
||||
if (hopsAway >= 0) {
|
||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(hopsAway));
|
||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
||||
jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit));
|
||||
jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start));
|
||||
}
|
||||
jsonObj["size"] = new JSONValue((unsigned int)mp->encrypted.size);
|
||||
|
||||
@@ -358,9 +358,8 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
||||
jsonObj["rssi"] = (int)mp->rx_rssi;
|
||||
if (mp->rx_snr != 0)
|
||||
jsonObj["snr"] = (float)mp->rx_snr;
|
||||
const int8_t hopsAway = getHopsAway(*mp);
|
||||
if (hopsAway >= 0) {
|
||||
jsonObj["hops_away"] = (unsigned int)(hopsAway);
|
||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
||||
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
|
||||
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
||||
}
|
||||
|
||||
@@ -394,9 +393,8 @@ std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPa
|
||||
jsonObj["rssi"] = (int)mp->rx_rssi;
|
||||
if (mp->rx_snr != 0)
|
||||
jsonObj["snr"] = (float)mp->rx_snr;
|
||||
const int8_t hopsAway = getHopsAway(*mp);
|
||||
if (hopsAway >= 0) {
|
||||
jsonObj["hops_away"] = (unsigned int)(hopsAway);
|
||||
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
|
||||
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
|
||||
jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
|
||||
}
|
||||
jsonObj["size"] = (unsigned int)mp->encrypted.size;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "SerialConsole.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "gps/RTC.h"
|
||||
#include "mesh/MeshRadio.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
|
||||
#include "TestUtil.h"
|
||||
|
||||
@@ -16,19 +14,5 @@ void initializeTestEnvironment()
|
||||
tv.tv_usec = 0;
|
||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||
#endif
|
||||
concurrency::OSThread::setup();
|
||||
}
|
||||
|
||||
void initializeTestEnvironmentMinimal()
|
||||
{
|
||||
// Only satisfy OSThread assertions; skip SerialConsole and platform-specific setup
|
||||
concurrency::hasBeenSetup = true;
|
||||
|
||||
// Ensure region/config globals are sane before any RadioInterface instances compute slot timing
|
||||
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||
config.lora.use_preset = true;
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
initRegion();
|
||||
|
||||
concurrency::OSThread::setup();
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
// Initialize testing environment.
|
||||
void initializeTestEnvironment();
|
||||
|
||||
// Minimal init without creating SerialConsole or portduino peripherals (useful for lightweight logic tests)
|
||||
void initializeTestEnvironmentMinimal();
|
||||
void initializeTestEnvironment();
|
||||
@@ -1,164 +0,0 @@
|
||||
#include <Arduino.h>
|
||||
#include <unity.h>
|
||||
|
||||
#include "TestUtil.h"
|
||||
// Ensure adaptive coding rate logic is available during tests
|
||||
#ifndef USE_ADAPTIVE_CODING_RATE
|
||||
#define USE_ADAPTIVE_CODING_RATE 1
|
||||
#endif
|
||||
#include "mesh/RadioInterface.h"
|
||||
|
||||
class TestRadio : public RadioInterface
|
||||
{
|
||||
public:
|
||||
bool applyForTest(const meshtastic_MeshPacket *p) { return applyAdaptiveCodingRate(p); }
|
||||
|
||||
uint8_t getAttempts(NodeNum from, PacketId id)
|
||||
{
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
auto it = adaptiveAttempts.find(adaptiveKey(from, id));
|
||||
return (it == adaptiveAttempts.end()) ? 0 : it->second.attempts;
|
||||
#else
|
||||
(void)from;
|
||||
(void)id;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
void setAdaptiveState(NodeNum from, PacketId id, uint8_t attempts, uint32_t lastUse)
|
||||
{
|
||||
adaptiveAttempts[adaptiveKey(from, id)] = {attempts, lastUse};
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t currentCr() const { return cr; }
|
||||
void setCrForTest(uint8_t value) { cr = value; }
|
||||
|
||||
ErrorCode send(meshtastic_MeshPacket *p) override
|
||||
{
|
||||
packetPool.release(p);
|
||||
return ERRNO_OK;
|
||||
}
|
||||
|
||||
uint32_t getPacketTime(uint32_t /*totalPacketLen*/, bool /*received*/ = false) override { return 0; }
|
||||
|
||||
bool reconfigure() override
|
||||
{
|
||||
reconfigureCount++;
|
||||
lastCr = cr;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t reconfigureCount = 0;
|
||||
uint8_t lastCr = 0;
|
||||
};
|
||||
|
||||
void test_attempt_progression()
|
||||
{
|
||||
TestRadio radio;
|
||||
meshtastic_MeshPacket packet = {};
|
||||
packet.from = 0xABCDEF01;
|
||||
packet.id = 0x1;
|
||||
|
||||
TEST_ASSERT_FALSE(radio.applyForTest(&packet));
|
||||
TEST_ASSERT_EQUAL_UINT8(1, radio.getAttempts(packet.from, packet.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(5, radio.currentCr());
|
||||
TEST_ASSERT_EQUAL_UINT32(0, radio.reconfigureCount);
|
||||
|
||||
TEST_ASSERT_TRUE(radio.applyForTest(&packet));
|
||||
TEST_ASSERT_EQUAL_UINT8(2, radio.getAttempts(packet.from, packet.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(7, radio.currentCr());
|
||||
TEST_ASSERT_EQUAL_UINT32(1, radio.reconfigureCount);
|
||||
TEST_ASSERT_EQUAL_UINT8(7, radio.lastCr);
|
||||
|
||||
TEST_ASSERT_TRUE(radio.applyForTest(&packet));
|
||||
TEST_ASSERT_EQUAL_UINT8(3, radio.getAttempts(packet.from, packet.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(8, radio.currentCr());
|
||||
TEST_ASSERT_EQUAL_UINT32(2, radio.reconfigureCount);
|
||||
TEST_ASSERT_EQUAL_UINT8(8, radio.lastCr);
|
||||
}
|
||||
|
||||
void test_attempts_are_per_packet()
|
||||
{
|
||||
TestRadio radio;
|
||||
meshtastic_MeshPacket first = {};
|
||||
first.from = 0x1001;
|
||||
first.id = 0xA;
|
||||
|
||||
meshtastic_MeshPacket second = {};
|
||||
second.from = 0x1001;
|
||||
second.id = 0xB;
|
||||
|
||||
radio.applyForTest(&first);
|
||||
radio.applyForTest(&second);
|
||||
radio.applyForTest(&first);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(2, radio.getAttempts(first.from, first.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(1, radio.getAttempts(second.from, second.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(7, radio.currentCr());
|
||||
}
|
||||
|
||||
void test_clear_resets_attempts_and_rate()
|
||||
{
|
||||
TestRadio radio;
|
||||
meshtastic_MeshPacket packet = {};
|
||||
packet.from = 0xCAFE;
|
||||
packet.id = 0x55;
|
||||
|
||||
radio.applyForTest(&packet);
|
||||
radio.applyForTest(&packet);
|
||||
radio.applyForTest(&packet);
|
||||
|
||||
radio.reconfigureCount = 0;
|
||||
radio.setCrForTest(8);
|
||||
radio.clearAdaptiveCodingRateState(packet.from, packet.id);
|
||||
|
||||
TEST_ASSERT_TRUE(radio.applyForTest(&packet));
|
||||
TEST_ASSERT_EQUAL_UINT8(1, radio.getAttempts(packet.from, packet.id));
|
||||
TEST_ASSERT_EQUAL_UINT8(5, radio.currentCr());
|
||||
TEST_ASSERT_EQUAL_UINT32(1, radio.reconfigureCount);
|
||||
}
|
||||
|
||||
void test_prunes_expired_state()
|
||||
{
|
||||
TestRadio radio;
|
||||
meshtastic_MeshPacket packet = {};
|
||||
packet.from = 0xBEEF;
|
||||
packet.id = 0x99;
|
||||
|
||||
radio.applyForTest(&packet);
|
||||
#ifdef USE_ADAPTIVE_CODING_RATE
|
||||
const uint32_t now = millis();
|
||||
radio.setAdaptiveState(packet.from, packet.id, 3, now - (5 * 60 * 1000UL + 50));
|
||||
#endif
|
||||
radio.reconfigureCount = 0;
|
||||
radio.setCrForTest(5);
|
||||
|
||||
TEST_ASSERT_FALSE(radio.applyForTest(&packet));
|
||||
TEST_ASSERT_EQUAL_UINT8(1, radio.getAttempts(packet.from, packet.id));
|
||||
TEST_ASSERT_EQUAL_UINT32(0, radio.reconfigureCount);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
printf("AdaptiveCodingRate test setup start\n");
|
||||
fflush(stdout);
|
||||
// Use minimal init to avoid pulling in SerialConsole/portduino peripherals for these logic-only tests
|
||||
initializeTestEnvironmentMinimal();
|
||||
|
||||
printf("AdaptiveCodingRate test init done\n");
|
||||
fflush(stdout);
|
||||
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_attempt_progression);
|
||||
RUN_TEST(test_attempts_are_per_packet);
|
||||
RUN_TEST(test_clear_resets_attempts_and_rate);
|
||||
RUN_TEST(test_prunes_expired_state);
|
||||
UNITY_END();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
}
|
||||
@@ -38,6 +38,7 @@ build_flags =
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
|
||||
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
|
||||
@@ -60,11 +61,11 @@ lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
||||
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||
h2zero/NimBLE-Arduino@^1.4.3
|
||||
h2zero/NimBLE-Arduino@2.3.7
|
||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
||||
https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip
|
||||
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
|
||||
lewisxhe/XPowersLib@0.3.2
|
||||
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||
|
||||
@@ -5,4 +5,4 @@ extends = esp32_common
|
||||
custom_esp32_kind = esp32
|
||||
|
||||
build_flags =
|
||||
${esp32_common.build_flags}
|
||||
${esp32_common.build_flags}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#define LED_GREEN 12
|
||||
#define LED_BLUE 2
|
||||
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#define LED_GREEN 12
|
||||
#define LED_BLUE 2
|
||||
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
[env:tbeam]
|
||||
extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
|
||||
board_level = extra
|
||||
board_check = true
|
||||
build_flags = ${esp32_base.build_flags}
|
||||
-D TBEAM_V10
|
||||
-I variants/esp32/tbeam
|
||||
-DBOARD_HAS_PSRAM
|
||||
-mfix-esp32-psram-cache-issue
|
||||
-ULED_BUILTIN
|
||||
upload_speed = 921600
|
||||
|
||||
[env:tbeam-displayshield]
|
||||
extends = env:tbeam
|
||||
board_level = extra
|
||||
|
||||
build_flags =
|
||||
${env:tbeam.build_flags}
|
||||
-D USE_ST7796
|
||||
|
||||
@@ -4,3 +4,8 @@ custom_esp32_kind = esp32c3
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_c3_exception_decoder
|
||||
|
||||
build_flags =
|
||||
${esp32_common.build_flags}
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
|
||||
@@ -26,7 +26,6 @@ build_flags =
|
||||
-D HAS_BLUETOOTH=1
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
-D NIMBLE_TWO
|
||||
monitor_speed=115200
|
||||
lib_ignore =
|
||||
NonBlockingRTTTL
|
||||
|
||||
@@ -8,3 +8,4 @@ build_flags =
|
||||
-I variants/esp32c6/tlora_c6
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
-DARDUINO_USB_MODE=1
|
||||
-ULED_BUILTIN
|
||||
|
||||
@@ -3,3 +3,8 @@ extends = esp32_common
|
||||
custom_esp32_kind = esp32s3
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
build_flags =
|
||||
${esp32_common.build_flags}
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
|
||||
@@ -8,3 +8,4 @@ build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-D HELTEC_V3
|
||||
-I variants/esp32s3/heltec_v3
|
||||
-ULED_BUILTIN
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 35;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t LED_BUILTIN = 45; // LED is not populated on earliest board variant
|
||||
#define BUILTIN_LED LED_BUILTIN // Backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t LED_BUILTIN = 45; // LED is not populated on earliest board variant
|
||||
#define BUILTIN_LED LED_BUILTIN // Backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t LED_BUILTIN = 35;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t KEY_BUILTIN = 0;
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
// Some boards have too low voltage on this pin (board design bug)
|
||||
// Use different pin with 3V and connect with 48
|
||||
// and change this setup for the chosen pin (for example 38)
|
||||
static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + 48;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
#define RGB_BUILTIN LED_BUILTIN
|
||||
#define RGB_BUILTIN SOC_GPIO_PIN_COUNT + 48
|
||||
#define RGB_BRIGHTNESS 64
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
|
||||
@@ -49,10 +49,6 @@ static const uint8_t T14 = 14;
|
||||
static const uint8_t VBAT_SENSE = 2;
|
||||
static const uint8_t VBUS_SENSE = 34;
|
||||
|
||||
// User LED
|
||||
#define LED_BUILTIN 13
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t RGB_DATA = 40;
|
||||
// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API neopixelWrite()
|
||||
#define RGB_BUILTIN (RGB_DATA + SOC_GPIO_PIN_COUNT)
|
||||
|
||||
@@ -55,6 +55,5 @@
|
||||
#define SX126X_RESET 14
|
||||
#define SX126X_RXEN 47
|
||||
#define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,61 +17,9 @@ static const uint8_t MOSI = 11;
|
||||
static const uint8_t MISO = 10;
|
||||
static const uint8_t SCK = 13;
|
||||
|
||||
#define SPI_INTERFACES_COUNT 1
|
||||
|
||||
#define SPI_MOSI (11)
|
||||
#define SPI_SCK (13)
|
||||
#define SPI_MISO (10)
|
||||
#define SPI_CS (12)
|
||||
|
||||
// LEDs
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
|
||||
#ifdef _VARIANT_RAK3112_
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
// TXD1 RXD1 on Base Board
|
||||
#define PIN_SERIAL1_RX (44)
|
||||
#define PIN_SERIAL1_TX (43)
|
||||
|
||||
/*
|
||||
* Internal SPI to LoRa transceiver
|
||||
*/
|
||||
#define LORA_SX126X_SCK 5
|
||||
#define LORA_SX126X_MISO 3
|
||||
#define LORA_SX126X_MOSI 6
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A0 (21)
|
||||
#define PIN_A1 (14)
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_WIRE1_SDA (17)
|
||||
#define PIN_WIRE1_SCL (18)
|
||||
|
||||
/*
|
||||
* GPIO's
|
||||
*/
|
||||
#define WB_IO1 21
|
||||
#define WB_IO2 2
|
||||
// #define WB_IO2 14
|
||||
#define WB_IO3 41
|
||||
#define WB_IO4 42
|
||||
#define WB_IO5 38
|
||||
#define WB_IO6 39
|
||||
// #define WB_SW1 35 NC
|
||||
#define WB_A0 1
|
||||
#define WB_A1 2
|
||||
#define WB_CS 12
|
||||
#define WB_LED1 46
|
||||
#define WB_LED2 45
|
||||
#endif
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
||||
@@ -9,15 +9,3 @@ build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-D RAK3312
|
||||
-I variants/esp32s3/rak3312
|
||||
|
||||
[env:rak3112]
|
||||
extends = esp32s3_base
|
||||
board = wiscore_rak3312
|
||||
board_level = extra
|
||||
upload_protocol = esptool
|
||||
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-D RAK3312
|
||||
-D _VARIANT_RAK3112_
|
||||
-I variants/esp32s3/rak3312
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
#endif
|
||||
|
||||
#define SX126X_POWER_EN (4)
|
||||
|
||||
#define PIN_POWER_EN PIN_3V3_EN
|
||||
#define PIN_3V3_EN (14)
|
||||
|
||||
#define LED_GREEN 46
|
||||
#define LED_BLUE 45
|
||||
|
||||
@@ -30,30 +35,10 @@
|
||||
|
||||
#define LED_STATE_ON 1 // State when LED is litted
|
||||
|
||||
#define BATTERY_PIN 1
|
||||
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
|
||||
|
||||
#ifdef _VARIANT_RAK3112_ // Modular variant (stamp)
|
||||
#define ADC_MULTIPLIER 2.11
|
||||
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_CS SPI_CS
|
||||
|
||||
#define I2C_SDA1 PIN_WIRE1_SDA
|
||||
#define I2C_SCL1 PIN_WIRE1_SCL
|
||||
#else // Generic 3312 variant (40-pin standard connector)
|
||||
#define ADC_MULTIPLIER 1.667
|
||||
|
||||
#define SX126X_POWER_EN (4)
|
||||
|
||||
#define PIN_POWER_EN PIN_3V3_EN
|
||||
#define PIN_3V3_EN (14)
|
||||
|
||||
#define HAS_GPS 1
|
||||
#define GPS_TX_PIN 43
|
||||
#define GPS_RX_PIN 44
|
||||
|
||||
#endif
|
||||
#define BATTERY_PIN 1
|
||||
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
|
||||
#define ADC_MULTIPLIER 1.667
|
||||
@@ -22,7 +22,4 @@ static const uint8_t SCK = 13;
|
||||
#define SPI_MISO (10)
|
||||
#define SPI_CS (12)
|
||||
|
||||
// LEDs
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// static const uint8_t LED_BUILTIN = -1;
|
||||
|
||||
// static const uint8_t TX = 43;
|
||||
// static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
// I2C for OLED and sensors
|
||||
static const uint8_t SDA = 8;
|
||||
static const uint8_t SCL = 9;
|
||||
|
||||
// Default SPI mapped to Radio/SD
|
||||
static const uint8_t SS = 15; // LoRa CS
|
||||
static const uint8_t MOSI = 11;
|
||||
static const uint8_t MISO = 12;
|
||||
static const uint8_t SCK = 13;
|
||||
|
||||
// SD Card CS
|
||||
#define SDCARD_CS 10
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
@@ -1,14 +0,0 @@
|
||||
; LilyGo T-Beam-1W (1 Watt LoRa with external PA)
|
||||
[env:t-beam-1w]
|
||||
extends = esp32s3_base
|
||||
board = t-beam-1w
|
||||
board_build.partitions = default_8MB.csv
|
||||
board_check = true
|
||||
|
||||
lib_deps =
|
||||
${esp32s3_base.lib_deps}
|
||||
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-I variants/esp32s3/t-beam-1w
|
||||
-D T_BEAM_1W
|
||||
@@ -1,97 +0,0 @@
|
||||
// LilyGo T-Beam-1W variant.h
|
||||
// Configuration based on LilyGO utilities.h and RF documentation
|
||||
|
||||
// I2C for OLED display (SH1106 at 0x3C)
|
||||
#define I2C_SDA 8
|
||||
#define I2C_SCL 9
|
||||
|
||||
// GPS - Quectel L76K
|
||||
#define GPS_RX_PIN 5
|
||||
#define GPS_TX_PIN 6
|
||||
#define GPS_1PPS_PIN 7
|
||||
#define GPS_WAKEUP_PIN 16 // GPS_EN_PIN in LilyGO code
|
||||
#define HAS_GPS 1
|
||||
#define GPS_BAUDRATE 9600
|
||||
|
||||
// Buttons
|
||||
#define BUTTON_PIN 0 // BUTTON 1
|
||||
#define BUTTON_PIN_ALT 17 // BUTTON 2
|
||||
|
||||
// SPI (shared by LoRa and SD)
|
||||
#define SPI_MOSI 11
|
||||
#define SPI_SCK 13
|
||||
#define SPI_MISO 12
|
||||
#define SPI_CS 10
|
||||
|
||||
// SD Card
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_CS SPI_CS
|
||||
|
||||
// LoRa Radio - SX1262 with 1W PA
|
||||
#define USE_SX1262
|
||||
|
||||
#define LORA_SCK SPI_SCK
|
||||
#define LORA_MISO SPI_MISO
|
||||
#define LORA_MOSI SPI_MOSI
|
||||
#define LORA_CS 15
|
||||
#define LORA_RESET 3
|
||||
#define LORA_DIO1 1
|
||||
#define LORA_BUSY 38
|
||||
|
||||
// CRITICAL: Radio power enable - MUST be HIGH before lora.begin()!
|
||||
// GPIO 40 powers the SX1262 + PA module via LDO
|
||||
#define SX126X_POWER_EN 40
|
||||
|
||||
// TX power offset for external PA (0 = no offset, full SX1262 power)
|
||||
#define TX_GAIN_LORA 10
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX126X_CS LORA_CS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_BUSY
|
||||
#define SX126X_RESET LORA_RESET
|
||||
|
||||
// RF switching configuration for 1W PA module
|
||||
// DIO2 controls PA (via SX126X_DIO2_AS_RF_SWITCH)
|
||||
// CTRL PIN (GPIO 21) controls LNA - must be HIGH during RX
|
||||
// Truth table: DIO2=1,CTRL=0 → TX (PA on, LNA off)
|
||||
// DIO2=0,CTRL=1 → RX (PA off, LNA on)
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_RXEN 21 // LNA enable - HIGH during RX
|
||||
|
||||
// TCXO voltage - required for radio init
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
#define SX126X_MAX_POWER 22
|
||||
#endif
|
||||
|
||||
// LED
|
||||
#define LED_PIN 18
|
||||
#define LED_STATE_ON 1 // HIGH = ON
|
||||
|
||||
// Battery ADC
|
||||
#define BATTERY_PIN 4
|
||||
#define ADC_CHANNEL ADC1_GPIO4_CHANNEL
|
||||
#define BATTERY_SENSE_SAMPLES 30
|
||||
#define ADC_MULTIPLIER 2.9333
|
||||
|
||||
// NTC temperature sensor
|
||||
#define NTC_PIN 14
|
||||
|
||||
// Fan control
|
||||
#define FAN_CTRL_PIN 41
|
||||
// Meshtastic standard fan control pin macro
|
||||
#define RF95_FAN_EN FAN_CTRL_PIN
|
||||
|
||||
// PA Ramp Time - T-Beam 1W requires >800us stabilization (default is 200us)
|
||||
// Value 0x05 = RADIOLIB_SX126X_PA_RAMP_800U
|
||||
#define SX126X_PA_RAMP_US 0x05
|
||||
|
||||
// Display - SH1106 OLED (128x64)
|
||||
#define USE_SH1106
|
||||
#define OLED_WIDTH 128
|
||||
#define OLED_HEIGHT 64
|
||||
|
||||
// 32768 Hz crystal present
|
||||
#define HAS_32768HZ 1
|
||||
@@ -6,8 +6,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
// static const uint8_t LED_BUILTIN = -1;
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// static const uint8_t LED_BUILTIN = -1;
|
||||
|
||||
// static const uint8_t TX = 43;
|
||||
// static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t LED_BUILTIN = 18;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
#define LED_BUILTIN LED_BUILTIN
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#define USB_VID 0x16D0
|
||||
#define USB_PID 0x1178
|
||||
|
||||
#define LED_BUILTIN 13
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ lib_deps =
|
||||
adafruit/Adafruit seesaw Library@1.7.9
|
||||
# renovate: datasource=git-refs depName=RAK12034-BMX160 packageName=https://github.com/RAKWireless/RAK12034-BMX160 gitBranch=main
|
||||
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
|
||||
# renovate: datasource=custom.pio depName=adafruit/Adafruit BME680 Library packageName=adafruit/library/Adafruit BME680
|
||||
adafruit/Adafruit BME680 Library@^2.0.5
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
extends = portduino_base
|
||||
build_flags = ${portduino_base.build_flags} -I variants/native/portduino
|
||||
-I /usr/include
|
||||
-I /opt/homebrew/include
|
||||
-L /opt/homebrew/lib -largp
|
||||
-DUSE_ADAPTIVE_CODING_RATE
|
||||
board = cross_platform
|
||||
board_level = extra
|
||||
lib_deps =
|
||||
@@ -12,11 +9,6 @@ lib_deps =
|
||||
# renovate: datasource=custom.pio depName=Melopero RV3028 packageName=melopero/library/Melopero RV3028
|
||||
melopero/Melopero RV3028@1.2.0
|
||||
|
||||
; Disable LovyanGFX for native test builds to avoid missing macOS system headers
|
||||
lib_ignore =
|
||||
${portduino_base.lib_ignore}
|
||||
LovyanGFX
|
||||
|
||||
build_src_filter = ${portduino_base.build_src_filter}
|
||||
|
||||
[env:native]
|
||||
|
||||
@@ -50,7 +50,6 @@ extern "C" {
|
||||
#define RGBLED_BLUE (0 + 12) // Blue of RGB P0.12
|
||||
#define RGBLED_CA // comment out this line if you have a common cathode type, as defined use common anode logic
|
||||
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
#define LED_CONN PIN_LED2
|
||||
|
||||
#define LED_GREEN PIN_LED1
|
||||
|
||||
@@ -55,7 +55,6 @@ extern "C" {
|
||||
#define LED_RED PIN_LED3
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_GREEN PIN_LED2
|
||||
#define LED_BUILTIN LED_BLUE
|
||||
#define LED_CONN PIN_GREEN
|
||||
#define LED_STATE_ON 0 // State when LED is lit // LED灯亮时的状态
|
||||
#define PIN_BUZZER (0 + 6)
|
||||
|
||||
@@ -7,7 +7,6 @@ build_flags =
|
||||
${nrf52840_base.build_flags}
|
||||
-Ivariants/nrf52840/ELECROW-ThinkNode-M3
|
||||
-DELECROW_ThinkNode_M3
|
||||
-DUSE_ADAPTIVE_CODING_RATE
|
||||
-DGPS_POWER_TOGGLE
|
||||
-D CONFIG_NFCT_PINS_AS_GPIOS=1
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
@@ -16,5 +15,5 @@ lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=nRF52_PWM packageName=khoih-prog/library/nRF52_PWM
|
||||
khoih-prog/nRF52_PWM@1.0.1
|
||||
; # renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
|
||||
; lewisxhe/SensorLib@0.3.3
|
||||
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
|
||||
lewisxhe/PCF8563_Library@1.0.1
|
||||
|
||||
@@ -58,7 +58,6 @@ extern "C" {
|
||||
#define LED_BLUE 37
|
||||
#define LED_PAIRING LED_BLUE // Signals the Status LED Module to handle this LED
|
||||
|
||||
#define LED_BUILTIN -1
|
||||
#define LED_STATE_ON LOW
|
||||
#define LED_STATE_OFF HIGH
|
||||
|
||||
@@ -114,8 +113,7 @@ extern "C" {
|
||||
#define LR11X0_DIO_AS_RF_SWITCH
|
||||
|
||||
// PCF8563 RTC Module
|
||||
// REVISIT https://github.com/meshtastic/firmware/pull/9084
|
||||
// #define PCF8563_RTC 0x51
|
||||
#define PCF8563_RTC 0x51
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user