mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-24 19:50:35 +00:00
Compare commits
44 Commits
v2.5.22.d1
...
meshtastic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24fb23442b | ||
|
|
9431a75326 | ||
|
|
02ccb43092 | ||
|
|
b437f0fb54 | ||
|
|
ffe4e7b6be | ||
|
|
598cfcc081 | ||
|
|
f2e49aa4ee | ||
|
|
3a0ad9bb58 | ||
|
|
4e575872da | ||
|
|
bf958ed01d | ||
|
|
c93728eb75 | ||
|
|
01c717a41d | ||
|
|
7061fd1f16 | ||
|
|
7d8e0ede6c | ||
|
|
efca2b5849 | ||
|
|
cfcd9cc210 | ||
|
|
fe1ced7480 | ||
|
|
3787cf7803 | ||
|
|
1be28520a7 | ||
|
|
4942c7b71f | ||
|
|
4709d21df8 | ||
|
|
ec0eafedab | ||
|
|
994e22aba9 | ||
|
|
9930bba3f5 | ||
|
|
f1dc1b309a | ||
|
|
337265a07f | ||
|
|
bb73555209 | ||
|
|
93c64cb442 | ||
|
|
5da5803c4c | ||
|
|
79b3a1e60e | ||
|
|
191ca8ce12 | ||
|
|
c67aa25d19 | ||
|
|
3b0232de1b | ||
|
|
7eb77276cd | ||
|
|
7648391f91 | ||
|
|
4407d9e040 | ||
|
|
27fea5fc07 | ||
|
|
2f6cd02111 | ||
|
|
8c9947b05c | ||
|
|
50b7d6a0f7 | ||
|
|
c83ffd4911 | ||
|
|
9b46cb4ef0 | ||
|
|
01935ea35e | ||
|
|
495f69cf90 |
@@ -1,9 +1,10 @@
|
||||
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||
|
||||
USER root
|
||||
|
||||
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||
# trunk-ignore(hadolint/DL3008): Use latest version of packages
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends \
|
||||
ca-certificates \
|
||||
@@ -27,9 +28,11 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
hwdata \
|
||||
gpg \
|
||||
gnupg2 \
|
||||
libusb-1.0-0-dev \
|
||||
libi2c-dev \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pipx install platformio==6.1.15
|
||||
RUN pipx install platformio
|
||||
|
||||
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
2
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
title: "[Bug]: "
|
||||
labels: ["bug", "triage"]
|
||||
labels: [bug, triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/New Board.yml
vendored
2
.github/ISSUE_TEMPLATE/New Board.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: New Board
|
||||
description: Request us to support new hardware
|
||||
title: "[Board]: "
|
||||
labels: ["enhancement", "triage"]
|
||||
labels: [enhancement, triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Request a new feature
|
||||
title: "[Feature Request]: "
|
||||
labels: ["enhancement"]
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
5
.github/actionlint.yaml
vendored
Normal file
5
.github/actionlint.yaml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Configuration related to self-hosted runner.
|
||||
self-hosted-runner:
|
||||
# Labels of self-hosted runner in array of strings.
|
||||
labels:
|
||||
- test-runner
|
||||
2
.github/actions/build-variant/action.yml
vendored
2
.github/actions/build-variant/action.yml
vendored
@@ -34,7 +34,7 @@ inputs:
|
||||
arch:
|
||||
description: Processor arch name
|
||||
required: true
|
||||
default: "esp32"
|
||||
default: esp32
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
8
.github/actions/setup-base/action.yml
vendored
8
.github/actions/setup-base/action.yml
vendored
@@ -1,13 +1,13 @@
|
||||
name: "Setup Build Base Composite Action"
|
||||
description: "Base build actions for Meshtastic Platform IO steps"
|
||||
name: Setup Build Base Composite Action
|
||||
description: Base build actions for Meshtastic Platform IO steps
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
using: composite
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
|
||||
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
@@ -1,26 +1,27 @@
|
||||
#trunk-ignore-all(yamllint/quoted-strings): required by dependabot syntax check
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: docker
|
||||
directory: devcontainer
|
||||
directory: /.devcontainer
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
time: "05:00"
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
time: "05:00"
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: gitsubmodule
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
time: "05:00"
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: github-actions
|
||||
directory: /.github/workflows
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
time: "05:00"
|
||||
timezone: US/Pacific
|
||||
|
||||
BIN
.github/meshtastic_logo.png
vendored
Normal file
BIN
.github/meshtastic_logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
2
.github/workflows/build_nrf52.yml
vendored
2
.github/workflows/build_nrf52.yml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
build-nrf52:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.github/workflows/build_rpi2040.yml
vendored
2
.github/workflows/build_rpi2040.yml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
build-rpi2040:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.github/workflows/build_stm32.yml
vendored
2
.github/workflows/build_stm32.yml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
build-stm32:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
35
.github/workflows/generate-userprefs.yml
vendored
35
.github/workflows/generate-userprefs.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Generate UsersPrefs JSON manifest
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- userPrefs.h
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
generate-userprefs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Clang
|
||||
run: sudo apt-get install -y clang
|
||||
|
||||
- name: Install trunk
|
||||
run: curl https://get.trunk.io -fsSL | bash
|
||||
|
||||
- name: Generate userPrefs.jsom
|
||||
run: python3 ./bin/build-userprefs-json.py
|
||||
|
||||
- name: Trunk format json
|
||||
run: trunk format userPrefs.json
|
||||
|
||||
- name: Commit userPrefs.json
|
||||
run: |
|
||||
git config --global user.email "actions@github.com"
|
||||
git config --global user.name "GitHub Actions"
|
||||
git add userPrefs.json
|
||||
git commit -m "Update userPrefs.json"
|
||||
git push
|
||||
6
.github/workflows/main_matrix.yml
vendored
6
.github/workflows/main_matrix.yml
vendored
@@ -352,6 +352,12 @@ jobs:
|
||||
run: >-
|
||||
bin/bump_version.py
|
||||
|
||||
- name: Ensure debian deps are installed
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update -y --fix-missing
|
||||
sudo apt-get install -y devscripts
|
||||
|
||||
- name: Update debian changelog
|
||||
run: >-
|
||||
debian/ci_changelog.sh
|
||||
|
||||
24
.github/workflows/nightly.yml
vendored
24
.github/workflows/nightly.yml
vendored
@@ -4,16 +4,34 @@ on:
|
||||
- cron: 0 8 * * 1-5
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
trunk_check:
|
||||
name: Trunk Check Upload
|
||||
runs-on: ubuntu-latest
|
||||
name: Trunk Check and Upload
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
|
||||
uses: trunk-io/trunk-action@v1
|
||||
with:
|
||||
trunk-token: ${{ secrets.TRUNK_TOKEN }}
|
||||
|
||||
trunk_upgrade:
|
||||
# See: https://github.com/trunk-io/trunk-action/blob/v1/readme.md#automatic-upgrades
|
||||
name: Trunk Upgrade (PR)
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write # For trunk to create PRs
|
||||
pull-requests: write # For trunk to create PRs
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Trunk Upgrade
|
||||
uses: trunk-io/trunk-action/upgrade@v1
|
||||
with:
|
||||
base: master
|
||||
|
||||
41
.github/workflows/sec_sast_flawfinder.yml
vendored
41
.github/workflows/sec_sast_flawfinder.yml
vendored
@@ -1,41 +0,0 @@
|
||||
---
|
||||
name: Flawfinder Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "version.properties"
|
||||
|
||||
jobs:
|
||||
flawfinder:
|
||||
runs-on: ubuntu-latest
|
||||
name: Flawfinder
|
||||
|
||||
steps:
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# step 2
|
||||
- name: flawfinder_scan
|
||||
uses: david-a-wheeler/flawfinder@2.0.19
|
||||
with:
|
||||
arguments: "--sarif ./"
|
||||
output: "flawfinder_report.sarif"
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: flawfinder_report.sarif
|
||||
overwrite: true
|
||||
path: flawfinder_report.sarif
|
||||
|
||||
# step 4
|
||||
- name: publish code scanning alerts
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: flawfinder_report.sarif
|
||||
category: flawfinder
|
||||
6
.github/workflows/sec_sast_semgrep_cron.yml
vendored
6
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -3,10 +3,10 @@ name: Semgrep Full Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 1 * * 6"
|
||||
- cron: 0 1 * * 6
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
semgrep-full:
|
||||
|
||||
2
.github/workflows/sec_sast_semgrep_pull.yml
vendored
2
.github/workflows/sec_sast_semgrep_pull.yml
vendored
@@ -2,6 +2,8 @@
|
||||
name: Semgrep Differential Scan
|
||||
on: pull_request
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
semgrep-diff:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
2
.github/workflows/stale_bot.yml
vendored
2
.github/workflows/stale_bot.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Stale PR+Issues
|
||||
uses: actions/stale@v9.0.0
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
exempt-issue-labels: pinned,3.0
|
||||
exempt-pr-labels: pinned,3.0
|
||||
|
||||
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@@ -2,9 +2,11 @@ name: End to end tests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Run every day at midnight
|
||||
- cron: 0 0 * * * # Run every day at midnight
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
native-tests:
|
||||
uses: ./.github/workflows/test_native.yml
|
||||
|
||||
26
.github/workflows/trunk_annotate_pr.yml
vendored
Normal file
26
.github/workflows/trunk_annotate_pr.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Annotate PR with trunk issues
|
||||
# See: https://github.com/trunk-io/trunk-action/blob/v1/readme.md#getting-inline-annotations-for-fork-prs
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Pull Request] # Name from `trunk_check.yml`
|
||||
types: [completed]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
trunk_check:
|
||||
name: Trunk Code Quality Annotate
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
checks: write # For trunk to post annotations
|
||||
contents: read # For repo checkout
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@v1
|
||||
with:
|
||||
post-annotations: true
|
||||
@@ -9,7 +9,7 @@ permissions: read-all
|
||||
jobs:
|
||||
trunk_check:
|
||||
name: Trunk Check Runner
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
checks: write # For trunk to post annotations
|
||||
contents: read # For repo checkout
|
||||
@@ -20,3 +20,5 @@ jobs:
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@v1
|
||||
with:
|
||||
save-annotations: true
|
||||
6
.github/workflows/trunk_format_pr.yml
vendored
6
.github/workflows/trunk_format_pr.yml
vendored
@@ -4,11 +4,15 @@ on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
trunk-fmt:
|
||||
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
6
.github/workflows/update_protobufs.yml
vendored
6
.github/workflows/update_protobufs.yml
vendored
@@ -1,10 +1,14 @@
|
||||
name: Update protobufs and regenerate classes
|
||||
on: workflow_dispatch
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
update-protobufs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -8,3 +8,4 @@ line_length: false
|
||||
spaces: false
|
||||
url: false
|
||||
whitespace: false
|
||||
headings: false
|
||||
|
||||
10
.trunk/configs/.prettierrc
Normal file
10
.trunk/configs/.prettierrc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"overrides": [
|
||||
{
|
||||
"files": "userPrefs.jsonc",
|
||||
"options": {
|
||||
"trailingComma": "none"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,37 +1,35 @@
|
||||
version: 0.1
|
||||
cli:
|
||||
version: 1.22.8
|
||||
version: 1.22.10
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.6.6
|
||||
ref: v1.6.7
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- prettier@3.4.2
|
||||
- trufflehog@3.86.1
|
||||
- prettier@3.5.2
|
||||
- trufflehog@3.88.12
|
||||
- yamllint@1.35.1
|
||||
- bandit@1.8.0
|
||||
- checkov@3.2.334
|
||||
- bandit@1.8.3
|
||||
- checkov@3.2.373
|
||||
- terrascan@1.19.9
|
||||
- trivy@0.58.0
|
||||
#- trufflehog@3.63.2-rc0
|
||||
- trivy@0.59.1
|
||||
- taplo@0.9.3
|
||||
- ruff@0.8.3
|
||||
- isort@5.13.2
|
||||
- markdownlint@0.43.0
|
||||
- oxipng@9.1.3
|
||||
- ruff@0.9.7
|
||||
- isort@6.0.0
|
||||
- markdownlint@0.44.0
|
||||
- oxipng@9.1.4
|
||||
- svgo@3.3.2
|
||||
- actionlint@1.7.4
|
||||
- flake8@7.1.1
|
||||
- actionlint@1.7.7
|
||||
- flake8@7.1.2
|
||||
- hadolint@2.12.1-beta
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.10.0
|
||||
- black@24.10.0
|
||||
- black@25.1.0
|
||||
- git-diff-check
|
||||
- gitleaks@8.21.2
|
||||
- gitleaks@8.24.0
|
||||
- clang-format@16.0.3
|
||||
#- prettier@3.3.3
|
||||
ignore:
|
||||
- linters: [ALL]
|
||||
paths:
|
||||
|
||||
21
Dockerfile
21
Dockerfile
@@ -1,21 +1,23 @@
|
||||
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||
# trunk-ignore-all(hadolint/DL3008): Use latest version of apt packages for buildchain
|
||||
# trunk-ignore-all(trivy/DS002): We must run as root for this container
|
||||
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
|
||||
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
|
||||
FROM python:3.12-bookworm AS builder
|
||||
FROM python:3.13-bookworm AS builder
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Etc/UTC
|
||||
|
||||
# Install Dependencies
|
||||
ENV PIP_ROOT_USER_ACTION=ignore
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y wget g++ zip git ca-certificates \
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
wget g++ zip git ca-certificates \
|
||||
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
|
||||
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
||||
pip install --no-cache-dir -U platformio==6.1.16 && \
|
||||
mkdir /tmp/firmware
|
||||
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||
&& pip install --no-cache-dir -U platformio \
|
||||
&& mkdir /tmp/firmware
|
||||
|
||||
# Copy source code
|
||||
WORKDIR /tmp/firmware
|
||||
@@ -35,8 +37,9 @@ ENV TZ=Etc/UTC
|
||||
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||
USER root
|
||||
|
||||
RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||
RUN apt-get update && apt-get --no-install-recommends -y install \
|
||||
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||
&& mkdir -p /var/lib/meshtasticd \
|
||||
&& mkdir -p /etc/meshtasticd/config.d \
|
||||
&& mkdir -p /etc/meshtasticd/ssl
|
||||
|
||||
31
README.md
31
README.md
@@ -1,4 +1,7 @@
|
||||
# Meshtastic Firmware
|
||||
<div align="center" markdown="1">
|
||||
|
||||
<img src=".github/meshtastic_logo.png" alt="Meshtastic Logo" width="80"/>
|
||||
<h1>Meshtastic Firmware</h1>
|
||||
|
||||

|
||||
[](https://github.com/meshtastic/firmware/actions/workflows/ci.yml)
|
||||
@@ -6,13 +9,31 @@
|
||||
[](https://opencollective.com/meshtastic/)
|
||||
[](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
|
||||
|
||||
<a href="https://trendshift.io/repositories/5524" target="_blank"><img src="https://trendshift.io/api/badge/repositories/5524" alt="meshtastic%2Ffirmware | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://meshtastic.org">Website</a>
|
||||
-
|
||||
<a href="https://meshtastic.org/docs/">Documentation</a>
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
This repository contains the device firmware for the Meshtastic project.
|
||||
This repository contains the official device firmware for Meshtastic, an open-source LoRa mesh networking project designed for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware supports various hardware platforms, including ESP32, nRF52, RP2040/RP2350, and Linux-based devices.
|
||||
|
||||
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
||||
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||
Meshtastic enables text messaging, location sharing, and telemetry over a decentralized mesh network, making it ideal for outdoor adventures, emergency preparedness, and remote operations.
|
||||
|
||||
### Get Started
|
||||
|
||||
- 🔧 **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)** – Learn how to compile the firmware from source.
|
||||
- ⚡ **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)** – Install or update the firmware on your device.
|
||||
|
||||
Join our community and help improve Meshtastic! 🚀
|
||||
|
||||
## Stats
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
# trunk-ignore-all(trivy/DS002): We must run as root for this container
|
||||
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
|
||||
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
|
||||
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
|
||||
FROM python:3.12-alpine3.21 AS builder
|
||||
FROM python:3.13-alpine3.21 AS builder
|
||||
|
||||
ENV PIP_ROOT_USER_ACTION=ignore
|
||||
RUN apk add bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone && \
|
||||
pip install --no-cache-dir -U platformio==6.1.16 && \
|
||||
mkdir /tmp/firmware
|
||||
RUN apk --no-cache add \
|
||||
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone \
|
||||
&& rm -rf /var/cache/apk/* \
|
||||
&& pip install --no-cache-dir -U platformio \
|
||||
&& mkdir /tmp/firmware
|
||||
|
||||
WORKDIR /tmp/firmware
|
||||
COPY . /tmp/firmware
|
||||
@@ -27,7 +31,9 @@ FROM alpine:3.21
|
||||
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
|
||||
USER root
|
||||
|
||||
RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \
|
||||
RUN apk --no-cache add \
|
||||
libstdc++ libgpiod yaml-cpp libusb i2c-tools \
|
||||
&& rm -rf /var/cache/apk/* \
|
||||
&& mkdir -p /var/lib/meshtasticd \
|
||||
&& mkdir -p /etc/meshtasticd/config.d \
|
||||
&& mkdir -p /etc/meshtasticd/ssl
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
custom_esp32_kind = esp32
|
||||
platform = platformio/espressif32@6.9.0
|
||||
platform = platformio/espressif32@6.10.0
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||
@@ -45,9 +45,9 @@ lib_deps =
|
||||
${environmental_base.lib_deps}
|
||||
${radiolib_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||
h2zero/NimBLE-Arduino@^1.4.2
|
||||
h2zero/NimBLE-Arduino@^1.4.3
|
||||
https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
|
||||
lewisxhe/XPowersLib@^0.2.6
|
||||
lewisxhe/XPowersLib@^0.2.7
|
||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||
rweather/Crypto@^0.4.0
|
||||
|
||||
@@ -65,4 +65,4 @@ lib_ignore =
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
board_build.partitions = partition-table.csv
|
||||
|
||||
@@ -24,7 +24,7 @@ lib_deps =
|
||||
${networking_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
${radiolib_base.lib_deps}
|
||||
lewisxhe/XPowersLib@^0.2.6
|
||||
lewisxhe/XPowersLib@^0.2.7
|
||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||
rweather/Crypto@^0.4.0
|
||||
|
||||
@@ -38,4 +38,4 @@ lib_ignore =
|
||||
NonBlockingRTTTL
|
||||
NimBLE-Arduino
|
||||
libpax
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ platform = platformio/nordicnrf52@^10.7.0
|
||||
extends = arduino_base
|
||||
platform_packages =
|
||||
; our custom Git version until they merge our PR
|
||||
framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||
toolchain-gccarmnoneeabi@~1.90301.0
|
||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
||||
|
||||
build_type = debug
|
||||
build_flags =
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2350_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
|
||||
extends = arduino_base
|
||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.4.3
|
||||
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -10,7 +10,6 @@ build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
||||
-Isrc/platform/rp2xx0
|
||||
-D__PLAT_RP2350__
|
||||
# -D _POSIX_THREADS
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> -<platform/rp2xx0/pico_sleep> -<platform/rp2xx0/hardware_rosc>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[stm32_base]
|
||||
extends = arduino_base
|
||||
platform = ststm32
|
||||
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e
|
||||
platform = platformio/ststm32
|
||||
platform_packages = platformio/framework-arduinoststm32@^4.20900.0
|
||||
|
||||
build_type = release
|
||||
|
||||
@@ -11,9 +11,15 @@ build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-flto
|
||||
-Isrc/platform/stm32wl -g
|
||||
-DMESHTASTIC_MINIMIZE_BUILD
|
||||
-DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
-DMESHTASTIC_EXCLUDE_INPUTBROKER
|
||||
-DMESHTASTIC_EXCLUDE_I2C
|
||||
-DMESHTASTIC_EXCLUDE_POWERMON
|
||||
-DMESHTASTIC_EXCLUDE_SCREEN
|
||||
-DMESHTASTIC_EXCLUDE_MQTT
|
||||
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
-DMESHTASTIC_EXCLUDE_PKI
|
||||
-DMESHTASTIC_EXCLUDE_GPS
|
||||
-DDEBUG_MUTE
|
||||
; -DVECT_TAB_OFFSET=0x08000000
|
||||
-DconfigUSE_CMSIS_RTOS_V2=1
|
||||
; -DSPI_MODE_0=SPI_MODE0
|
||||
|
||||
@@ -24,7 +24,7 @@ mkdir -p $OUTDIR/
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio pkg update --environment native || platformioFailed
|
||||
pio pkg update --environment native || platformioFailed
|
||||
pio run --environment native || platformioFailed
|
||||
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||
cp bin/native-install.* $OUTDIR
|
||||
|
||||
52
boards/meshlink.json
Normal file
52
boards/meshlink.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DMESHLINK -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x00B3"],
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "MeshLink",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "meshlink",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "MeshLink",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["nrfutil", "jlink", "nrfjprog", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://www.loraitalia.it",
|
||||
"vendor": "LoraItalia"
|
||||
}
|
||||
1
debian/control
vendored
1
debian/control
vendored
@@ -3,6 +3,7 @@ Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Austin Lane <vidplace7@gmail.com>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
lsb-release,
|
||||
tar,
|
||||
gzip,
|
||||
platformio,
|
||||
|
||||
9
debian/rules
vendored
9
debian/rules
vendored
@@ -11,6 +11,15 @@ PIO_ENV:=\
|
||||
PLATFORMIO_LIBDEPS_DIR=pio/libdeps \
|
||||
PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||
|
||||
# Raspbian armhf builds should be compatible with armv6-hardfloat
|
||||
# https://www.valvers.com/open-software/raspberry-pi/bare-metal-programming-in-c-part-1/#rpi1-compiler-flags
|
||||
ifneq (,$(findstring Raspbian,$(shell lsb_release -is)))
|
||||
ifeq ($(DEB_BUILD_ARCH),armhf)
|
||||
PIO_ENV+=\
|
||||
PLATFORMIO_BUILD_FLAGS="-mfloat-abi=hard -mfpu=vfp -march=armv6zk"
|
||||
endif
|
||||
endif
|
||||
|
||||
override_dh_auto_build:
|
||||
# Extract tarballs within source deb
|
||||
tar -xf pio.tar
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# trunk-ignore-all(bandit/B404): subprocess is used to call addr2line
|
||||
# trunk-ignore-all(bandit/B603): subprocess is used to call addr2line
|
||||
|
||||
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -59,7 +59,7 @@ lib_deps =
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||
nanopb/Nanopb@0.4.9
|
||||
nanopb/Nanopb@0.4.91
|
||||
erriez/ErriezCRC32@1.0.1
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
|
||||
Submodule protobufs updated: 068646653e...e2790151f0
@@ -153,7 +153,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
pixels.fill(BUTTON1_COLOR, BUTTON1_COLOR_INDEX, 1);
|
||||
#endif
|
||||
#if defined(BUTTON2_COLOR) && defined(BUTTON2_COLOR_INDEX)
|
||||
pixels.fill(BUTTON2_COLOR, BUTTON1_COLOR_INDEX, 1);
|
||||
pixels.fill(BUTTON2_COLOR, BUTTON2_COLOR_INDEX, 1);
|
||||
#endif
|
||||
#endif
|
||||
pixels.show();
|
||||
|
||||
@@ -244,6 +244,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
logFoundDevice("BMP-388", (uint8_t)addr.address);
|
||||
type = BMP_3XX;
|
||||
break;
|
||||
case 0x60: // BMP-390 should be 0x60
|
||||
logFoundDevice("BMP-390", (uint8_t)addr.address);
|
||||
type = BMP_3XX;
|
||||
break;
|
||||
case 0x58: // BMP-280 should be 0x58
|
||||
default:
|
||||
logFoundDevice("BMP-280", (uint8_t)addr.address);
|
||||
@@ -521,4 +525,4 @@ void ScanI2CTwoWire::logFoundDevice(const char *device, uint8_t address)
|
||||
{
|
||||
LOG_INFO("%s found at address 0x%x", device, address);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
100
src/gps/GPS.cpp
100
src/gps/GPS.cpp
@@ -48,8 +48,6 @@ HardwareSerial *GPS::_serial_gps = nullptr;
|
||||
|
||||
GPS *gps = nullptr;
|
||||
|
||||
static const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
|
||||
|
||||
static GPSUpdateScheduling scheduling;
|
||||
|
||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||
@@ -437,6 +435,10 @@ static const int serialSpeeds[3] = {9600, 115200, 38400};
|
||||
static const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
|
||||
#endif
|
||||
|
||||
#ifndef GPS_PROBETRIES
|
||||
#define GPS_PROBETRIES 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Setup the GPS based on the model detected.
|
||||
* We detect the GPS by cycling through a set of baud rates, first common then rare.
|
||||
@@ -460,11 +462,7 @@ bool GPS::setup()
|
||||
digitalWrite(PIN_GPS_EN, HIGH);
|
||||
delay(1000);
|
||||
#endif
|
||||
#ifdef TRACKER_T1000_E
|
||||
if (probeTries < 5) {
|
||||
#else
|
||||
if (probeTries < 2) {
|
||||
#endif
|
||||
if (probeTries < GPS_PROBETRIES) {
|
||||
LOG_DEBUG("Probe for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
@@ -475,11 +473,7 @@ bool GPS::setup()
|
||||
}
|
||||
}
|
||||
// Rare Serial Speeds
|
||||
#ifdef TRACKER_T1000_E
|
||||
if (probeTries == 5) {
|
||||
#else
|
||||
if (probeTries == 2) {
|
||||
#endif
|
||||
if (probeTries == GPS_PROBETRIES) {
|
||||
LOG_DEBUG("Probe for GPS at %d", rareSerialSpeeds[speedSelect]);
|
||||
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
@@ -1043,14 +1037,6 @@ int32_t GPS::runOnce()
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
return disable();
|
||||
}
|
||||
// ONCE we will factory reset the GPS for bug #327
|
||||
if (!devicestate.did_gps_reset) {
|
||||
LOG_WARN("GPS FactoryReset requested");
|
||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
||||
devicestate.did_gps_reset = true;
|
||||
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
||||
}
|
||||
}
|
||||
GPSInitFinished = true;
|
||||
publishUpdate();
|
||||
}
|
||||
@@ -1063,24 +1049,6 @@ int32_t GPS::runOnce()
|
||||
if (whileActive()) {
|
||||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
} else {
|
||||
if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) &&
|
||||
IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9,
|
||||
GNSS_MODEL_UBLOX10)) {
|
||||
// reset the GPS on next bootup
|
||||
if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
|
||||
LOG_DEBUG("GPS is not found, try factory reset on next boot");
|
||||
devicestate.did_gps_reset = false;
|
||||
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
||||
return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
|
||||
}
|
||||
}
|
||||
}
|
||||
// At least one GPS has a bad habit of losing its mind from time to time
|
||||
if (rebootsSeen > 2) {
|
||||
rebootsSeen = 0;
|
||||
LOG_DEBUG("Would normally factoryReset()");
|
||||
// gps->factoryReset();
|
||||
}
|
||||
|
||||
// If we're due for an update, wake the GPS
|
||||
@@ -1415,62 +1383,6 @@ static int32_t toDegInt(RawDegrees d)
|
||||
return r;
|
||||
}
|
||||
|
||||
bool GPS::factoryReset()
|
||||
{
|
||||
#ifdef PIN_GPS_REINIT
|
||||
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
|
||||
pinMode(PIN_GPS_REINIT, OUTPUT);
|
||||
digitalWrite(PIN_GPS_REINIT, 0);
|
||||
delay(150); // The L76K datasheet calls for at least 100MS delay
|
||||
digitalWrite(PIN_GPS_REINIT, 1);
|
||||
#endif
|
||||
|
||||
if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
|
||||
byte _message_reset1[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
|
||||
_serial_gps->write(_message_reset1, sizeof(_message_reset1));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_DEBUG(ACK_SUCCESS_MESSAGE);
|
||||
}
|
||||
delay(100);
|
||||
byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
|
||||
_serial_gps->write(_message_reset2, sizeof(_message_reset2));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_DEBUG(ACK_SUCCESS_MESSAGE);
|
||||
}
|
||||
delay(100);
|
||||
byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
|
||||
_serial_gps->write(_message_reset3, sizeof(_message_reset3));
|
||||
if (getACK(0x05, 0x01, 10000)) {
|
||||
LOG_DEBUG(ACK_SUCCESS_MESSAGE);
|
||||
}
|
||||
} else if (gnssModel == GNSS_MODEL_MTK) {
|
||||
// send the CAS10 to perform a factory restart of the device (and other device that support PCAS statements)
|
||||
LOG_INFO("GNSS Factory Reset via PCAS10,3");
|
||||
_serial_gps->write("$PCAS10,3*1F\r\n");
|
||||
delay(100);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
LOG_INFO("Factory Reset via CAS-CFG-RST");
|
||||
uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
delay(100);
|
||||
} else {
|
||||
// fire this for good measure, if we have an L76B - won't harm other devices.
|
||||
_serial_gps->write("$PMTK104*37\r\n");
|
||||
// No PMTK_ACK for this command.
|
||||
delay(100);
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
|
||||
// UBLOX. Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset, sizeof(_message_reset));
|
||||
}
|
||||
delay(1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
||||
* Override this method to check for new locations
|
||||
|
||||
@@ -101,8 +101,6 @@ class GPS : private concurrency::OSThread
|
||||
// Empty the input buffer as quickly as possible
|
||||
void clearBuffer();
|
||||
|
||||
virtual bool factoryReset();
|
||||
|
||||
// Creates an instance of the GPS class.
|
||||
// Returns the new instance or null if the GPS is not present.
|
||||
static GPS *createGps();
|
||||
|
||||
@@ -140,6 +140,15 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
}
|
||||
#elif defined(MESHLINK)
|
||||
{
|
||||
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
||||
|
||||
adafruitDisplay = new GxEPD2_BW<EINK_DISPLAY_MODEL, EINK_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||
adafruitDisplay->init();
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
}
|
||||
#elif defined(RAK4630) || defined(MAKERPYTHON)
|
||||
{
|
||||
if (eink_found) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,7 +117,7 @@ AudioThread *audioThread = nullptr;
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
volatile static const char slipstreamTZString[] = USERPREFS_TZ_STRING;
|
||||
volatile static const char slipstreamTZString[] = {USERPREFS_TZ_STRING};
|
||||
|
||||
// We always create a screen object, but we only init it if we find the hardware
|
||||
graphics::Screen *screen = nullptr;
|
||||
@@ -931,6 +931,7 @@ void setup()
|
||||
if (!sxIf->init()) {
|
||||
LOG_WARN("No SX1262 radio");
|
||||
delete sxIf;
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("SX1262 init success");
|
||||
rIf = sxIf;
|
||||
@@ -947,6 +948,7 @@ void setup()
|
||||
if (!sxIf->init()) {
|
||||
LOG_WARN("No SX1262 radio with TCXO, Vref %fV", SX126X_DIO3_TCXO_VOLTAGE);
|
||||
delete sxIf;
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("SX1262 init success, TCXO, Vref %fV", SX126X_DIO3_TCXO_VOLTAGE);
|
||||
rIf = sxIf;
|
||||
|
||||
@@ -119,7 +119,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
channelSettings.psk.size = sizeof(defaultpsk0);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_0_NAME
|
||||
strcpy(channelSettings.name, USERPREFS_CHANNEL_0_NAME);
|
||||
strcpy(channelSettings.name, (const char *)USERPREFS_CHANNEL_0_NAME);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_0_PRECISION
|
||||
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_0_PRECISION;
|
||||
@@ -138,7 +138,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
channelSettings.psk.size = sizeof(defaultpsk1);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_1_NAME
|
||||
strcpy(channelSettings.name, USERPREFS_CHANNEL_1_NAME);
|
||||
strcpy(channelSettings.name, (const char *)USERPREFS_CHANNEL_1_NAME);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_1_PRECISION
|
||||
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_1_PRECISION;
|
||||
@@ -157,7 +157,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
channelSettings.psk.size = sizeof(defaultpsk2);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_2_NAME
|
||||
strcpy(channelSettings.name, USERPREFS_CHANNEL_2_NAME);
|
||||
strcpy(channelSettings.name, (const char *)USERPREFS_CHANNEL_2_NAME);
|
||||
#endif
|
||||
#ifdef USERPREFS_CHANNEL_2_PRECISION
|
||||
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_2_PRECISION;
|
||||
|
||||
@@ -555,7 +555,11 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
#else
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||
#endif
|
||||
#ifdef USERPREFS_CONFIG_SMART_POSITION_ENABLED
|
||||
config.position.position_broadcast_smart_enabled = USERPREFS_CONFIG_SMART_POSITION_ENABLED;
|
||||
#else
|
||||
config.position.position_broadcast_smart_enabled = true;
|
||||
#endif
|
||||
config.position.broadcast_smart_minimum_distance = 100;
|
||||
config.position.broadcast_smart_minimum_interval_secs = 30;
|
||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER)
|
||||
@@ -618,8 +622,16 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
|
||||
void NodeDB::initConfigIntervals()
|
||||
{
|
||||
#ifdef USERPREFS_CONFIG_GPS_UPDATE_INTERVAL
|
||||
config.position.gps_update_interval = USERPREFS_CONFIG_GPS_UPDATE_INTERVAL;
|
||||
#else
|
||||
config.position.gps_update_interval = default_gps_update_interval;
|
||||
#endif
|
||||
#ifdef USERPREFS_CONFIG_POSITION_BROADCAST_INTERVAL
|
||||
config.position.position_broadcast_secs = USERPREFS_CONFIG_POSITION_BROADCAST_INTERVAL;
|
||||
#else
|
||||
config.position.position_broadcast_secs = default_broadcast_interval_secs;
|
||||
#endif
|
||||
|
||||
config.power.ls_secs = default_ls_secs;
|
||||
config.power.min_wake_secs = default_min_wake_secs;
|
||||
@@ -859,12 +871,12 @@ void NodeDB::installDefaultDeviceState()
|
||||
// Set default owner name
|
||||
pickNewNodeNum(); // based on macaddr now
|
||||
#ifdef USERPREFS_CONFIG_OWNER_LONG_NAME
|
||||
snprintf(owner.long_name, sizeof(owner.long_name), USERPREFS_CONFIG_OWNER_LONG_NAME);
|
||||
snprintf(owner.long_name, sizeof(owner.long_name), (const char *)USERPREFS_CONFIG_OWNER_LONG_NAME);
|
||||
#else
|
||||
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %04x", getNodeNum() & 0x0ffff);
|
||||
#endif
|
||||
#ifdef USERPREFS_CONFIG_OWNER_SHORT_NAME
|
||||
snprintf(owner.short_name, sizeof(owner.short_name), USERPREFS_CONFIG_OWNER_SHORT_NAME);
|
||||
snprintf(owner.short_name, sizeof(owner.short_name), (const char *)USERPREFS_CONFIG_OWNER_SHORT_NAME);
|
||||
#else
|
||||
snprintf(owner.short_name, sizeof(owner.short_name), "%04x", getNodeNum() & 0x0ffff);
|
||||
#endif
|
||||
|
||||
@@ -643,6 +643,11 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
|
||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||
return false;
|
||||
} else if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && isBroadcast(p.to) && p.hop_limit > 0) {
|
||||
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Multi-hop traceroute to broadcast address is not allowed");
|
||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||
return false;
|
||||
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
||||
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
|
||||
LOG_WARN("Rate limit portnum %d", p.decoded.portnum);
|
||||
|
||||
@@ -18,6 +18,9 @@ bool STM32WLE5JCInterface::init()
|
||||
{
|
||||
RadioLibInterface::init();
|
||||
|
||||
// https://github.com/Seeed-Studio/LoRaWan-E5-Node/blob/main/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c
|
||||
setTCXOVoltage(1.7);
|
||||
|
||||
lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
|
||||
@@ -39,4 +42,4 @@ bool STM32WLE5JCInterface::init()
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif // ARCH_STM32WL
|
||||
#endif // ARCH_STM32WL
|
||||
@@ -16,9 +16,6 @@ class STM32WLE5JCInterface : public SX126xInterface<STM32WLx>
|
||||
virtual bool init() override;
|
||||
};
|
||||
|
||||
// https://github.com/Seeed-Studio/LoRaWan-E5-Node/blob/main/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c
|
||||
static const float tcxoVoltage = 1.7;
|
||||
|
||||
/* https://wiki.seeedstudio.com/LoRa-E5_STM32WLE5JC_Module/
|
||||
* Wio-E5 module ONLY transmits through RFO_HP
|
||||
* Receive: PA4=1, PA5=0
|
||||
|
||||
@@ -51,6 +51,8 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
|
||||
#else
|
||||
auto client = U::available();
|
||||
#endif
|
||||
#elif defined(ARCH_RP2040)
|
||||
auto client = U::accept();
|
||||
#else
|
||||
auto client = U::available();
|
||||
#endif
|
||||
@@ -78,4 +80,4 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
|
||||
waitTime = 100;
|
||||
#endif
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
}
|
||||
@@ -291,8 +291,8 @@ extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
@@ -310,8 +310,8 @@ extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(ch
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
@@ -344,4 +344,4 @@ extern int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AN
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "mesh/api/ethServerAPI.h"
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
#include "target_specific.h"
|
||||
#include <RAK13800_W5100S.h>
|
||||
#include <SPI.h>
|
||||
@@ -72,12 +69,6 @@ static int32_t reconnectETH()
|
||||
|
||||
ethStartupComplete = true;
|
||||
}
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||
if (mqtt && !moduleConfig.mqtt.proxy_to_client_enabled && !mqtt->isConnectedDirectly()) {
|
||||
mqtt->reconnect();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
|
||||
@@ -122,7 +122,8 @@ typedef struct _meshtastic_DeviceState {
|
||||
Indicates developer is testing and changes should never be saved to flash.
|
||||
Deprecated in 2.3.1 */
|
||||
bool no_save;
|
||||
/* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */
|
||||
/* Previously used to manage GPS factory resets.
|
||||
Deprecated in 2.5.23 */
|
||||
bool did_gps_reset;
|
||||
/* We keep the last received waypoint stored in the device flash,
|
||||
so we can show it on the screen.
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
|
||||
#include "main.h"
|
||||
#include "mesh/api/WiFiServerAPI.h"
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
#include "target_specific.h"
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
@@ -111,12 +108,6 @@ static void onNetworkConnected()
|
||||
#endif
|
||||
APStartupComplete = true;
|
||||
}
|
||||
|
||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||
#ifndef MESHTASTIC_EXCLUDE_MQTT
|
||||
if (mqtt)
|
||||
mqtt->reconnect();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t reconnectWiFi()
|
||||
|
||||
@@ -123,23 +123,23 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
* Getters
|
||||
*/
|
||||
case meshtastic_AdminMessage_get_owner_request_tag:
|
||||
LOG_INFO("Client got owner");
|
||||
LOG_DEBUG("Client got owner");
|
||||
handleGetOwner(mp);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_config_request_tag:
|
||||
LOG_INFO("Client got config");
|
||||
LOG_DEBUG("Client got config");
|
||||
handleGetConfig(mp, r->get_config_request);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_module_config_request_tag:
|
||||
LOG_INFO("Client got module config");
|
||||
LOG_DEBUG("Client got module config");
|
||||
handleGetModuleConfig(mp, r->get_module_config_request);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_channel_request_tag: {
|
||||
uint32_t i = r->get_channel_request - 1;
|
||||
LOG_INFO("Client got channel %u", i);
|
||||
LOG_DEBUG("Client got channel %u", i);
|
||||
if (i >= MAX_NUM_CHANNELS)
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
@@ -151,33 +151,35 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
* Setters
|
||||
*/
|
||||
case meshtastic_AdminMessage_set_owner_tag:
|
||||
LOG_INFO("Client set owner");
|
||||
LOG_DEBUG("Client set owner");
|
||||
handleSetOwner(r->set_owner);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_config_tag:
|
||||
LOG_INFO("Client set config");
|
||||
LOG_DEBUG("Client set config");
|
||||
handleSetConfig(r->set_config);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_module_config_tag:
|
||||
LOG_INFO("Client set module config");
|
||||
handleSetModuleConfig(r->set_module_config);
|
||||
LOG_DEBUG("Client set module config");
|
||||
if (!handleSetModuleConfig(r->set_module_config)) {
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
}
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_channel_tag:
|
||||
LOG_INFO("Client set channel %d", r->set_channel.index);
|
||||
LOG_DEBUG("Client set channel %d", r->set_channel.index);
|
||||
if (r->set_channel.index < 0 || r->set_channel.index >= (int)MAX_NUM_CHANNELS)
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
handleSetChannel(r->set_channel);
|
||||
break;
|
||||
case meshtastic_AdminMessage_set_ham_mode_tag:
|
||||
LOG_INFO("Client set ham mode");
|
||||
LOG_DEBUG("Client set ham mode");
|
||||
handleSetHamMode(r->set_ham_mode);
|
||||
break;
|
||||
case meshtastic_AdminMessage_get_ui_config_request_tag: {
|
||||
LOG_INFO("Client is getting device-ui config");
|
||||
LOG_DEBUG("Client is getting device-ui config");
|
||||
handleGetDeviceUIConfig(mp);
|
||||
handled = true;
|
||||
break;
|
||||
@@ -389,7 +391,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
LOG_DEBUG("Did not responded to a request that wanted a respond. req.variant=%d", r->which_payload_variant);
|
||||
} else if (handleResult != AdminMessageHandleResult::HANDLED) {
|
||||
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
|
||||
LOG_INFO("Ignore irrelevant admin %d", r->which_payload_variant);
|
||||
LOG_DEBUG("Ignore irrelevant admin %d", r->which_payload_variant);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -648,15 +650,23 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
||||
saveChanges(changes, requiresReboot);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
{
|
||||
if (!hasOpenEditTransaction)
|
||||
disableBluetooth();
|
||||
switch (c.which_payload_variant) {
|
||||
case meshtastic_ModuleConfig_mqtt_tag:
|
||||
#if MESHTASTIC_EXCLUDE_MQTT
|
||||
LOG_WARN("Set module config: MESHTASTIC_EXCLUDE_MQTT is defined. Not setting MQTT config");
|
||||
return false;
|
||||
#else
|
||||
LOG_INFO("Set module config: MQTT");
|
||||
if (!MQTT::isValidConfig(c.payload_variant.mqtt)) {
|
||||
return false;
|
||||
}
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.mqtt = c.payload_variant.mqtt;
|
||||
#endif
|
||||
break;
|
||||
case meshtastic_ModuleConfig_serial_tag:
|
||||
LOG_INFO("Set module config: Serial");
|
||||
@@ -724,6 +734,7 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
break;
|
||||
}
|
||||
saveChanges(SEGMENT_MODULECONFIG);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdminModule::handleSetChannel(const meshtastic_Channel &cc)
|
||||
|
||||
@@ -50,7 +50,7 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
|
||||
void handleSetOwner(const meshtastic_User &o);
|
||||
void handleSetChannel(const meshtastic_Channel &cc);
|
||||
void handleSetConfig(const meshtastic_Config &c);
|
||||
void handleSetModuleConfig(const meshtastic_ModuleConfig &c);
|
||||
bool handleSetModuleConfig(const meshtastic_ModuleConfig &c);
|
||||
void handleSetChannel();
|
||||
void handleSetHamMode(const meshtastic_HamParameters &req);
|
||||
void handleStoreDeviceUIConfig(const meshtastic_DeviceUIConfig &uicfg);
|
||||
|
||||
@@ -121,7 +121,8 @@ Will be used for broadcast.
|
||||
*/
|
||||
int32_t NeighborInfoModule::runOnce()
|
||||
{
|
||||
if (moduleConfig.neighbor_info.transmit_over_lora && !channels.isDefaultChannel(channels.getPrimaryIndex()) &&
|
||||
if (moduleConfig.neighbor_info.transmit_over_lora &&
|
||||
(!channels.isDefaultChannel(channels.getPrimaryIndex()) || !RadioInterface::uses_default_frequency_slot) &&
|
||||
airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
|
||||
sendNeighborInfo(NODENUM_BROADCAST, false);
|
||||
} else {
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
SerialModule *serialModule;
|
||||
SerialModuleRadio *serialModuleRadio;
|
||||
|
||||
#if defined(TTGO_T_ECHO) || defined(CANARYONE)
|
||||
#if defined(TTGO_T_ECHO) || defined(CANARYONE) || defined(MESHLINK)
|
||||
SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {}
|
||||
static Print *serialPrint = &Serial;
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
@@ -158,7 +158,7 @@ int32_t SerialModule::runOnce()
|
||||
Serial.begin(baud);
|
||||
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||
}
|
||||
#elif !defined(TTGO_T_ECHO) && !defined(CANARYONE)
|
||||
#elif !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK)
|
||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||
#ifdef ARCH_RP2040
|
||||
Serial2.setFIFOSize(RX_BUFFER);
|
||||
@@ -214,7 +214,7 @@ int32_t SerialModule::runOnce()
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE)
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK)
|
||||
else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) {
|
||||
processWXSerial();
|
||||
|
||||
@@ -416,7 +416,7 @@ uint32_t SerialModule::getBaudRate()
|
||||
*/
|
||||
void SerialModule::processWXSerial()
|
||||
{
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(MESHLINK)
|
||||
static unsigned int lastAveraged = 0;
|
||||
static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded.
|
||||
static double dir_sum_sin = 0;
|
||||
|
||||
@@ -31,7 +31,6 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
doDeepSleep(nightyNightMs, true, false);
|
||||
}
|
||||
|
||||
uint32_t result = UINT32_MAX;
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
@@ -46,25 +45,33 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
return disable();
|
||||
}
|
||||
|
||||
uint32_t sendToMeshIntervalMs = Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.power_update_interval, default_telemetry_broadcast_interval_secs, numOnlineNodes);
|
||||
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do some setup
|
||||
firstTime = 0;
|
||||
uint32_t result = UINT32_MAX;
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||
if (moduleConfig.telemetry.power_measurement_enabled) {
|
||||
LOG_INFO("Power Telemetry: init");
|
||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||
if (ina219Sensor.hasSensor() && !ina219Sensor.isInitialized())
|
||||
result = ina219Sensor.runOnce();
|
||||
if (ina226Sensor.hasSensor() && !ina226Sensor.isInitialized())
|
||||
result = ina226Sensor.runOnce();
|
||||
if (ina260Sensor.hasSensor() && !ina260Sensor.isInitialized())
|
||||
result = ina260Sensor.runOnce();
|
||||
if (ina3221Sensor.hasSensor() && !ina3221Sensor.isInitialized())
|
||||
result = ina3221Sensor.runOnce();
|
||||
if (max17048Sensor.hasSensor() && !max17048Sensor.isInitialized())
|
||||
result = max17048Sensor.runOnce();
|
||||
// If sensor is already initialized by EnvironmentTelemetryModule, then we don't need to initialize it again,
|
||||
// but we need to set the result to != UINT32_MAX to avoid it being disabled
|
||||
if (ina219Sensor.hasSensor())
|
||||
result = ina219Sensor.isInitialized() ? 0 : ina219Sensor.runOnce();
|
||||
if (ina226Sensor.hasSensor())
|
||||
result = ina226Sensor.isInitialized() ? 0 : ina226Sensor.runOnce();
|
||||
if (ina260Sensor.hasSensor())
|
||||
result = ina260Sensor.isInitialized() ? 0 : ina260Sensor.runOnce();
|
||||
if (ina3221Sensor.hasSensor())
|
||||
result = ina3221Sensor.isInitialized() ? 0 : ina3221Sensor.runOnce();
|
||||
if (max17048Sensor.hasSensor())
|
||||
result = max17048Sensor.isInitialized() ? 0 : max17048Sensor.runOnce();
|
||||
}
|
||||
|
||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||
return result == UINT32_MAX ? disable() : setStartDelay();
|
||||
#else
|
||||
return disable();
|
||||
@@ -74,10 +81,7 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
if (!moduleConfig.telemetry.power_measurement_enabled)
|
||||
return disable();
|
||||
|
||||
if (((lastSentToMesh == 0) ||
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.power_update_interval,
|
||||
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
|
||||
if (((lastSentToMesh == 0) || !Throttle::isWithinTimespanMs(lastSentToMesh, sendToMeshIntervalMs)) &&
|
||||
airTime->isTxAllowedAirUtil()) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = millis();
|
||||
@@ -89,8 +93,9 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
lastSentToPhone = millis();
|
||||
}
|
||||
}
|
||||
return min(sendToPhoneIntervalMs, result);
|
||||
return min(sendToPhoneIntervalMs, sendToMeshIntervalMs);
|
||||
}
|
||||
|
||||
bool PowerTelemetryModule::wantUIFrame()
|
||||
{
|
||||
return moduleConfig.telemetry.power_screen_enabled;
|
||||
|
||||
@@ -150,6 +150,12 @@ meshtastic_MeshPacket *TraceRouteModule::allocReply()
|
||||
{
|
||||
assert(currentRequest);
|
||||
|
||||
// Ignore multi-hop broadcast requests
|
||||
if (isBroadcast(currentRequest->to) && currentRequest->hop_limit < currentRequest->hop_start) {
|
||||
ignoreRequest = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Copy the payload of the current request
|
||||
auto req = *currentRequest;
|
||||
const auto &p = req.decoded;
|
||||
|
||||
@@ -144,9 +144,9 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
bearingToOther -= myHeading;
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
||||
|
||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2*PI : bearingToOther;
|
||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||
|
||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
|
||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||
|
||||
// Distance to Waypoint
|
||||
float d = GeoCoord::latLongToMeter(DegD(wp.latitude_i), DegD(wp.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
||||
@@ -161,7 +161,6 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
snprintf(distStr, sizeof(distStr), "%.1fkm %.0f°", d / 1000, bearingToOtherDegrees);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// If our node doesn't have position
|
||||
|
||||
@@ -245,6 +245,73 @@ std::pair<String, uint16_t> parseHostAndPort(String server, uint16_t port = 0)
|
||||
}
|
||||
return std::make_pair(std::move(server), port);
|
||||
}
|
||||
|
||||
bool isDefaultServer(const String &host)
|
||||
{
|
||||
return host.length() == 0 || host == default_mqtt_address;
|
||||
}
|
||||
|
||||
struct PubSubConfig {
|
||||
explicit PubSubConfig(const meshtastic_ModuleConfig_MQTTConfig &config)
|
||||
{
|
||||
if (*config.address) {
|
||||
serverAddr = config.address;
|
||||
mqttUsername = config.username;
|
||||
mqttPassword = config.password;
|
||||
}
|
||||
if (config.tls_enabled) {
|
||||
serverPort = 8883;
|
||||
}
|
||||
std::tie(serverAddr, serverPort) = parseHostAndPort(serverAddr.c_str(), serverPort);
|
||||
}
|
||||
|
||||
// Defaults
|
||||
static constexpr uint16_t defaultPort = 1883;
|
||||
uint16_t serverPort = defaultPort;
|
||||
String serverAddr = default_mqtt_address;
|
||||
const char *mqttUsername = default_mqtt_username;
|
||||
const char *mqttPassword = default_mqtt_password;
|
||||
};
|
||||
|
||||
#if HAS_NETWORKING
|
||||
bool connectPubSub(const PubSubConfig &config, PubSubClient &pubSub, Client &client)
|
||||
{
|
||||
pubSub.setBufferSize(1024);
|
||||
pubSub.setClient(client);
|
||||
pubSub.setServer(config.serverAddr.c_str(), config.serverPort);
|
||||
|
||||
LOG_INFO("Connecting directly to MQTT server %s, port: %d, username: %s, password: %s", config.serverAddr.c_str(),
|
||||
config.serverPort, config.mqttUsername, config.mqttPassword);
|
||||
|
||||
const bool connected = pubSub.connect(owner.id, config.mqttUsername, config.mqttPassword);
|
||||
if (connected) {
|
||||
LOG_INFO("MQTT connected");
|
||||
} else {
|
||||
LOG_WARN("Failed to connect to MQTT server");
|
||||
}
|
||||
return connected;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool isConnectedToNetwork()
|
||||
{
|
||||
#if HAS_WIFI
|
||||
return WiFi.isConnected();
|
||||
#elif HAS_ETHERNET
|
||||
return Ethernet.linkStatus() == LinkON;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** return true if we have a channel that wants uplink/downlink or map reporting is enabled
|
||||
*/
|
||||
bool wantsLink()
|
||||
{
|
||||
const bool hasChannelorMapReport =
|
||||
moduleConfig.mqtt.enabled && (moduleConfig.mqtt.map_reporting_enabled || channels.anyMqttEnabled());
|
||||
return hasChannelorMapReport && (moduleConfig.mqtt.proxy_to_client_enabled || isConnectedToNetwork());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
@@ -324,7 +391,7 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
|
||||
}
|
||||
|
||||
String host = parseHostAndPort(moduleConfig.mqtt.address).first;
|
||||
isConfiguredForDefaultServer = host.length() == 0 || host == default_mqtt_address;
|
||||
isConfiguredForDefaultServer = isDefaultServer(host);
|
||||
IPAddress ip;
|
||||
isMqttServerAddressPrivate = ip.fromString(host.c_str()) && isPrivateIpAddress(ip);
|
||||
|
||||
@@ -407,57 +474,22 @@ void MQTT::reconnect()
|
||||
return; // Don't try to connect directly to the server
|
||||
}
|
||||
#if HAS_NETWORKING
|
||||
// Defaults
|
||||
int serverPort = 1883;
|
||||
const char *serverAddr = default_mqtt_address;
|
||||
const char *mqttUsername = default_mqtt_username;
|
||||
const char *mqttPassword = default_mqtt_password;
|
||||
|
||||
if (*moduleConfig.mqtt.address) {
|
||||
serverAddr = moduleConfig.mqtt.address;
|
||||
mqttUsername = moduleConfig.mqtt.username;
|
||||
mqttPassword = moduleConfig.mqtt.password;
|
||||
}
|
||||
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
const PubSubConfig config(moduleConfig.mqtt);
|
||||
MQTTClient *clientConnection = mqttClient.get();
|
||||
#if MQTT_SUPPORTS_TLS
|
||||
if (moduleConfig.mqtt.tls_enabled) {
|
||||
// change default for encrypted to 8883
|
||||
try {
|
||||
serverPort = 8883;
|
||||
wifiSecureClient.setInsecure();
|
||||
|
||||
pubSub.setClient(wifiSecureClient);
|
||||
LOG_INFO("Use TLS-encrypted session");
|
||||
} catch (const std::exception &e) {
|
||||
LOG_ERROR("MQTT ERROR: %s", e.what());
|
||||
}
|
||||
mqttClientTLS.setInsecure();
|
||||
LOG_INFO("Use TLS-encrypted session");
|
||||
clientConnection = &mqttClientTLS;
|
||||
} else {
|
||||
LOG_INFO("Use non-TLS-encrypted session");
|
||||
pubSub.setClient(*mqttClient);
|
||||
}
|
||||
#else
|
||||
pubSub.setClient(*mqttClient);
|
||||
#endif
|
||||
#elif HAS_NETWORKING
|
||||
pubSub.setClient(*mqttClient);
|
||||
#endif
|
||||
|
||||
std::pair<String, uint16_t> hostAndPort = parseHostAndPort(serverAddr, serverPort);
|
||||
serverAddr = hostAndPort.first.c_str();
|
||||
serverPort = hostAndPort.second;
|
||||
pubSub.setServer(serverAddr, serverPort);
|
||||
pubSub.setBufferSize(1024);
|
||||
|
||||
LOG_INFO("Connect directly to MQTT server %s, port: %d, username: %s, password: %s", serverAddr, serverPort, mqttUsername,
|
||||
mqttPassword);
|
||||
|
||||
bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword);
|
||||
if (connected) {
|
||||
LOG_INFO("MQTT connected");
|
||||
if (connectPubSub(config, pubSub, *clientConnection)) {
|
||||
enabled = true; // Start running background process again
|
||||
runASAP = true;
|
||||
reconnectCount = 0;
|
||||
isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient->remoteIP());
|
||||
isMqttServerAddressPrivate = isPrivateIpAddress(clientConnection->remoteIP());
|
||||
|
||||
publishNodeInfo();
|
||||
sendSubscriptions();
|
||||
@@ -508,23 +540,6 @@ void MQTT::sendSubscriptions()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MQTT::wantsLink() const
|
||||
{
|
||||
bool hasChannelorMapReport =
|
||||
moduleConfig.mqtt.enabled && (moduleConfig.mqtt.map_reporting_enabled || channels.anyMqttEnabled());
|
||||
|
||||
if (hasChannelorMapReport && moduleConfig.mqtt.proxy_to_client_enabled)
|
||||
return true;
|
||||
|
||||
#if HAS_WIFI
|
||||
return hasChannelorMapReport && WiFi.isConnected();
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
return hasChannelorMapReport && Ethernet.linkStatus() == LinkON;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t MQTT::runOnce()
|
||||
{
|
||||
#if HAS_NETWORKING
|
||||
@@ -568,6 +583,47 @@ int32_t MQTT::runOnce()
|
||||
return 30000;
|
||||
}
|
||||
|
||||
bool MQTT::isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config, MQTTClient *client)
|
||||
{
|
||||
const PubSubConfig parsed(config);
|
||||
|
||||
if (config.enabled && !config.proxy_to_client_enabled) {
|
||||
#if HAS_NETWORKING
|
||||
std::unique_ptr<MQTTClient> clientConnection;
|
||||
if (config.tls_enabled) {
|
||||
#if MQTT_SUPPORTS_TLS
|
||||
MQTTClientTLS *tlsClient = new MQTTClientTLS;
|
||||
clientConnection.reset(tlsClient);
|
||||
tlsClient->setInsecure();
|
||||
#else
|
||||
LOG_ERROR("Invalid MQTT config: tls_enabled is not supported on this node");
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
clientConnection.reset(new MQTTClient);
|
||||
}
|
||||
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
|
||||
if (isConnectedToNetwork()) {
|
||||
return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection);
|
||||
}
|
||||
#else
|
||||
LOG_ERROR("Invalid MQTT config: proxy_to_client_enabled must be enabled on nodes that do not have a network");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const bool defaultServer = isDefaultServer(parsed.serverAddr);
|
||||
if (defaultServer && config.tls_enabled) {
|
||||
LOG_ERROR("Invalid MQTT config: TLS was enabled, but the default server does not support TLS");
|
||||
return false;
|
||||
}
|
||||
if (defaultServer && parsed.serverPort != PubSubConfig::defaultPort) {
|
||||
LOG_ERROR("Invalid MQTT config: Unsupported port '%d' for the default MQTT server", parsed.serverPort);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MQTT::publishNodeInfo()
|
||||
{
|
||||
// TODO: NodeInfo broadcast over MQTT only (NODENUM_BROADCAST_NO_LORA)
|
||||
|
||||
@@ -10,12 +10,10 @@
|
||||
#endif
|
||||
#if HAS_WIFI
|
||||
#include <WiFiClient.h>
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3
|
||||
#if __has_include(<WiFiClientSecure.h>)
|
||||
#include <WiFiClientSecure.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
#include <EthernetClient.h>
|
||||
#endif
|
||||
@@ -47,10 +45,6 @@ class MQTT : private concurrency::OSThread
|
||||
*/
|
||||
void onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_MeshPacket &mp_decoded, ChannelIndex chIndex);
|
||||
|
||||
/** Attempt to connect to server if necessary
|
||||
*/
|
||||
void reconnect();
|
||||
|
||||
bool isConnectedDirectly();
|
||||
|
||||
bool publish(const char *topic, const char *payload, bool retained);
|
||||
@@ -65,6 +59,9 @@ class MQTT : private concurrency::OSThread
|
||||
|
||||
bool isUsingDefaultServer() { return isConfiguredForDefaultServer; }
|
||||
|
||||
/// Validate the meshtastic_ModuleConfig_MQTTConfig.
|
||||
static bool isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config) { return isValidConfig(config, nullptr); }
|
||||
|
||||
protected:
|
||||
struct QueueEntry {
|
||||
std::string topic;
|
||||
@@ -80,22 +77,23 @@ class MQTT : private concurrency::OSThread
|
||||
#ifndef PIO_UNIT_TESTING
|
||||
private:
|
||||
#endif
|
||||
// supposedly the current version is busted:
|
||||
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
||||
#if HAS_WIFI
|
||||
using MQTTClient = WiFiClient;
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
#if (defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR < 3) || defined(RPI_PICO)
|
||||
WiFiClientSecure wifiSecureClient;
|
||||
#if __has_include(<WiFiClientSecure.h>)
|
||||
using MQTTClientTLS = WiFiClientSecure;
|
||||
#define MQTT_SUPPORTS_TLS 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
#elif HAS_ETHERNET
|
||||
using MQTTClient = EthernetClient;
|
||||
#else
|
||||
using MQTTClient = void;
|
||||
#endif
|
||||
|
||||
#if HAS_NETWORKING
|
||||
std::unique_ptr<MQTTClient> mqttClient;
|
||||
#if MQTT_SUPPORTS_TLS
|
||||
MQTTClientTLS mqttClientTLS;
|
||||
#endif
|
||||
PubSubClient pubSub;
|
||||
explicit MQTT(std::unique_ptr<MQTTClient> mqttClient);
|
||||
#endif
|
||||
@@ -111,9 +109,9 @@ class MQTT : private concurrency::OSThread
|
||||
uint32_t map_position_precision = default_map_position_precision;
|
||||
uint32_t map_publish_interval_msecs = default_map_publish_interval_secs * 1000;
|
||||
|
||||
/** return true if we have a channel that wants uplink/downlink or map reporting is enabled
|
||||
/** Attempt to connect to server if necessary
|
||||
*/
|
||||
bool wantsLink() const;
|
||||
void reconnect();
|
||||
|
||||
/** Tell the server what subscriptions we want (based on channels.downlink_enabled)
|
||||
*/
|
||||
@@ -122,6 +120,8 @@ class MQTT : private concurrency::OSThread
|
||||
/// Callback for direct mqtt subscription messages
|
||||
static void mqttCallback(char *topic, byte *payload, unsigned int length);
|
||||
|
||||
static bool isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config, MQTTClient *client);
|
||||
|
||||
/// Called when a new publish arrives from the MQTT server
|
||||
void onReceive(char *topic, byte *payload, size_t length);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class BluetoothPhoneAPI : public PhoneAPI
|
||||
{
|
||||
PhoneAPI::onNowHasData(fromRadioNum);
|
||||
|
||||
LOG_INFO("BLE notify fromNum");
|
||||
LOG_DEBUG("BLE notify fromNum");
|
||||
|
||||
uint8_t val[4];
|
||||
put_le32(val, fromRadioNum);
|
||||
@@ -51,7 +51,7 @@ class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||
{
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic)
|
||||
{
|
||||
LOG_INFO("To Radio onwrite");
|
||||
LOG_DEBUG("To Radio onwrite");
|
||||
auto val = pCharacteristic->getValue();
|
||||
|
||||
if (memcmp(lastToRadio, val.data(), val.length()) != 0) {
|
||||
@@ -298,4 +298,4 @@ void clearNVS()
|
||||
ESP.restart();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -127,4 +127,4 @@
|
||||
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
|
||||
// No serial ports on this board - ONLY use segger in memory console
|
||||
#define USE_SEGGER
|
||||
#endif
|
||||
#endif
|
||||
@@ -304,6 +304,11 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
nrf_gpio_cfg_default(WB_I2C1_SDA);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MESHLINK
|
||||
#ifdef PIN_WD_EN
|
||||
digitalWrite(PIN_WD_EN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HELTEC_MESH_NODE_T114
|
||||
nrf_gpio_cfg_default(PIN_GPS_PPS);
|
||||
|
||||
@@ -220,7 +220,11 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
||||
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_RouteDiscovery_msg,
|
||||
&scratch)) {
|
||||
decoded = &scratch;
|
||||
JSONArray route; // Route this message took
|
||||
JSONArray route; // Route this message took
|
||||
JSONArray routeBack; // Route this message took back
|
||||
JSONArray snrTowards; // Snr for forward route
|
||||
JSONArray snrBack; // Snr for reverse route
|
||||
|
||||
// Lambda function for adding a long name to the route
|
||||
auto addToRoute = [](JSONArray *route, NodeNum num) {
|
||||
char long_name[40] = "Unknown";
|
||||
@@ -236,7 +240,24 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
|
||||
}
|
||||
addToRoute(&route, mp->from); // Ended at the original destination (source of response)
|
||||
|
||||
addToRoute(&routeBack, mp->from); // Started at the original destination (source of response)
|
||||
for (uint8_t i = 0; i < decoded->route_back_count; i++) {
|
||||
addToRoute(&routeBack, decoded->route_back[i]);
|
||||
}
|
||||
addToRoute(&routeBack, mp->to); // Ended at the original transmitter (destination of response)
|
||||
|
||||
for (uint8_t i = 0; i < decoded->snr_back_count; i++) {
|
||||
snrBack.push_back(new JSONValue((float)decoded->snr_back[i] / 4));
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < decoded->snr_towards_count; i++) {
|
||||
snrTowards.push_back(new JSONValue((float)decoded->snr_towards[i] / 4));
|
||||
}
|
||||
|
||||
msgPayload["route"] = new JSONValue(route);
|
||||
msgPayload["route_back"] = new JSONValue(routeBack);
|
||||
msgPayload["snr_back"] = new JSONValue(snrBack);
|
||||
msgPayload["snr_towards"] = new JSONValue(snrTowards);
|
||||
jsonObj["payload"] = new JSONValue(msgPayload);
|
||||
} else if (shouldLog) {
|
||||
LOG_ERROR(errStr, msgType.c_str());
|
||||
|
||||
@@ -245,6 +245,9 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
|
||||
#ifdef PIN_3V3_EN
|
||||
digitalWrite(PIN_3V3_EN, LOW);
|
||||
#endif
|
||||
#ifdef PIN_WD_EN
|
||||
digitalWrite(PIN_WD_EN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
ledBlink.set(false);
|
||||
|
||||
@@ -530,4 +533,4 @@ void enableLoraInterrupt()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,3 +1,4 @@
|
||||
// trunk-ignore-all(gitleaks): These are dummy values. Not real secrets.
|
||||
#include "CryptoEngine.h"
|
||||
|
||||
#include "TestUtil.h"
|
||||
|
||||
@@ -94,6 +94,7 @@ class MockPubSubServer : public WiFiClient
|
||||
|
||||
int connect(IPAddress ip, uint16_t port) override
|
||||
{
|
||||
port_ = port;
|
||||
if (refuseConnection_)
|
||||
return 0;
|
||||
connected_ = true;
|
||||
@@ -101,6 +102,8 @@ class MockPubSubServer : public WiFiClient
|
||||
}
|
||||
int connect(const char *host, uint16_t port) override
|
||||
{
|
||||
host_ = host;
|
||||
port_ = port;
|
||||
if (refuseConnection_)
|
||||
return 0;
|
||||
connected_ = true;
|
||||
@@ -197,6 +200,8 @@ class MockPubSubServer : public WiFiClient
|
||||
bool connected_ = false;
|
||||
bool refuseConnection_ = false; // Simulate a failed connection.
|
||||
uint32_t ipAddress_ = 0x01010101; // IP address of the MQTT server.
|
||||
std::string host_; // Requested host.
|
||||
uint16_t port_; // Requested port.
|
||||
std::list<std::string> buffer_; // Buffer of messages for the pubSub client to receive.
|
||||
std::string command_; // Current command received from the pubSub client.
|
||||
std::set<std::string> subscriptions_; // Topics that the pubSub client has subscribed to.
|
||||
@@ -242,6 +247,8 @@ class MQTTUnitTest : public MQTT
|
||||
mqttClient.release();
|
||||
delete pubsub;
|
||||
}
|
||||
using MQTT::isValidConfig;
|
||||
using MQTT::reconnect;
|
||||
int queueSize() { return mqttQueue.numUsed(); }
|
||||
void reportToMap(std::optional<uint32_t> precision = std::nullopt)
|
||||
{
|
||||
@@ -488,7 +495,7 @@ void test_reconnectProxyDoesNotReconnectMqtt(void)
|
||||
moduleConfig.mqtt.proxy_to_client_enabled = true;
|
||||
MQTTUnitTest::restart();
|
||||
|
||||
mqtt->reconnect();
|
||||
unitTest->reconnect();
|
||||
|
||||
TEST_ASSERT_FALSE(pubsub->connected_);
|
||||
}
|
||||
@@ -799,6 +806,85 @@ void test_customMqttRoot(void)
|
||||
[] { return pubsub->subscriptions_.count("custom/2/e/test/+") && pubsub->subscriptions_.count("custom/2/e/PKI/+"); }));
|
||||
}
|
||||
|
||||
// Empty configuration is valid.
|
||||
void test_configEmptyIsValid(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {};
|
||||
|
||||
TEST_ASSERT_TRUE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Empty 'enabled' configuration is valid.
|
||||
void test_configEnabledEmptyIsValid(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.enabled = true};
|
||||
MockPubSubServer client;
|
||||
|
||||
TEST_ASSERT_TRUE(MQTTUnitTest::isValidConfig(config, &client));
|
||||
TEST_ASSERT_TRUE(client.connected_);
|
||||
TEST_ASSERT_EQUAL_STRING(default_mqtt_address, client.host_.c_str());
|
||||
TEST_ASSERT_EQUAL(1883, client.port_);
|
||||
}
|
||||
|
||||
// Configuration with the default server is valid.
|
||||
void test_configWithDefaultServer(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.address = default_mqtt_address};
|
||||
|
||||
TEST_ASSERT_TRUE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Configuration with the default server and port 8888 is invalid.
|
||||
void test_configWithDefaultServerAndInvalidPort(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.address = default_mqtt_address ":8888"};
|
||||
|
||||
TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Configuration with the default server and tls_enabled = true is invalid.
|
||||
void test_configWithDefaultServerAndInvalidTLSEnabled(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.tls_enabled = true};
|
||||
|
||||
TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// isValidConfig connects to a custom host and port.
|
||||
void test_configCustomHostAndPort(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.enabled = true, .address = "server:1234"};
|
||||
MockPubSubServer client;
|
||||
|
||||
TEST_ASSERT_TRUE(MQTTUnitTest::isValidConfig(config, &client));
|
||||
TEST_ASSERT_TRUE(client.connected_);
|
||||
TEST_ASSERT_EQUAL_STRING("server", client.host_.c_str());
|
||||
TEST_ASSERT_EQUAL(1234, client.port_);
|
||||
}
|
||||
|
||||
// isValidConfig returns false if a connection cannot be established.
|
||||
void test_configWithConnectionFailure(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.enabled = true, .address = "server"};
|
||||
MockPubSubServer client;
|
||||
client.refuseConnection_ = true;
|
||||
|
||||
TEST_ASSERT_FALSE(MQTTUnitTest::isValidConfig(config, &client));
|
||||
}
|
||||
|
||||
// isValidConfig returns true when tls_enabled is supported, or false otherwise.
|
||||
void test_configWithTLSEnabled(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.enabled = true, .address = "server", .tls_enabled = true};
|
||||
MockPubSubServer client;
|
||||
|
||||
#if MQTT_SUPPORTS_TLS
|
||||
TEST_ASSERT_TRUE(MQTTUnitTest::isValidConfig(config, &client));
|
||||
#else
|
||||
TEST_ASSERT_FALSE(MQTTUnitTest::isValidConfig(config, &client));
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
initializeTestEnvironment();
|
||||
@@ -842,6 +928,14 @@ void setup()
|
||||
RUN_TEST(test_enabled);
|
||||
RUN_TEST(test_disabled);
|
||||
RUN_TEST(test_customMqttRoot);
|
||||
RUN_TEST(test_configEmptyIsValid);
|
||||
RUN_TEST(test_configEnabledEmptyIsValid);
|
||||
RUN_TEST(test_configWithDefaultServer);
|
||||
RUN_TEST(test_configWithDefaultServerAndInvalidPort);
|
||||
RUN_TEST(test_configWithDefaultServerAndInvalidTLSEnabled);
|
||||
RUN_TEST(test_configCustomHostAndPort);
|
||||
RUN_TEST(test_configWithConnectionFailure);
|
||||
RUN_TEST(test_configWithTLSEnabled);
|
||||
exit(UNITY_END());
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
// "USERPREFS_FIXED_GPS_ALT": "0",
|
||||
// "USERPREFS_FIXED_GPS_LAT": "48.85873920",
|
||||
// "USERPREFS_FIXED_GPS_LON": "2.294508368",
|
||||
// "USERPREFS_CONFIG_SMART_POSITION_ENABLED": "false",
|
||||
// "USERPREFS_CONFIG_GPS_UPDATE_INTERVAL": "600",
|
||||
// "USERPREFS_CONFIG_POSITION_BROADCAST_INTERVAL": "1800",
|
||||
// "USERPREFS_LORACONFIG_CHANNEL_NUM": "31",
|
||||
// "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST",
|
||||
"USERPREFS_TZ_STRING": "tzplaceholder "
|
||||
// "USERPREFS_USE_ADMIN_KEY_0": "{ 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c }",
|
||||
// "USERPREFS_USE_ADMIN_KEY_1": "{}",
|
||||
// "USERPREFS_USE_ADMIN_KEY_2": "{}",
|
||||
@@ -37,5 +39,6 @@
|
||||
// "USERPREFS_OEM_FONT_SIZE": "0",
|
||||
// "USERPREFS_OEM_IMAGE_WIDTH": "50",
|
||||
// "USERPREFS_OEM_IMAGE_HEIGHT": "28",
|
||||
// "USERPREFS_OEM_IMAGE_DATA": "{ 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x67, 0x00, 0x00, 0x00, 0x18, 0x1F, 0xF0, 0x67, 0x00, 0x00, 0x00, 0x30, 0x1F, 0xF8, 0x33, 0x00, 0x00, 0x00, 0x30, 0x00, 0xFC, 0x31, 0x00, 0x00, 0x00, 0x60, 0x00, 0xFE, 0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x7E, 0x18, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x3F, 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x1F, 0x0C, 0x00, 0x00, 0x00, 0x80, 0x81, 0x1F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xC1, 0x0F, 0x06, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00}"
|
||||
// "USERPREFS_OEM_IMAGE_DATA": "{ 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x67, 0x00, 0x00, 0x00, 0x18, 0x1F, 0xF0, 0x67, 0x00, 0x00, 0x00, 0x30, 0x1F, 0xF8, 0x33, 0x00, 0x00, 0x00, 0x30, 0x00, 0xFC, 0x31, 0x00, 0x00, 0x00, 0x60, 0x00, 0xFE, 0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x7E, 0x18, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x3F, 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x1F, 0x0C, 0x00, 0x00, 0x00, 0x80, 0x81, 0x1F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xC1, 0x0F, 0x06, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00}",
|
||||
"USERPREFS_TZ_STRING": "tzplaceholder "
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/Dongle_nRF52840-pca10059-v
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/Dongle_nRF52840-pca10059-v1>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
debug_tool = jlink
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
debug_tool = jlink
|
||||
|
||||
@@ -13,7 +13,7 @@ board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/ME25LS01-4Y10TD_e-ink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.5.8
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
upload_protocol = nrfutil
|
||||
upload_port = /dev/ttyACM1
|
||||
upload_port = /dev/ttyACM1
|
||||
|
||||
@@ -5,13 +5,13 @@ board = nordic_pca10059
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/MakePython_nRF52840_eink -D PRIVATE_HW
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-D PIN_EINK_EN
|
||||
-DEINK_DISPLAY_MODEL=GxEPD2_290_T5D
|
||||
-DEINK_WIDTH=296
|
||||
-DEINK_HEIGHT=128
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/MakePython_nRF52840_eink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
-DEINK_DISPLAY_MODEL=GxEPD2_290_T5D
|
||||
-DEINK_WIDTH=296
|
||||
-DEINK_HEIGHT=128
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
debug_tool = jlink
|
||||
;upload_port = /dev/ttyACM4
|
||||
;upload_port = /dev/ttyACM4
|
||||
@@ -6,5 +6,5 @@ build_flags = ${nrf52840_base.build_flags} -I variants/TWC_mesh_v4 -D TWC_mesh_v
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/TWC_mesh_v4>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
debug_tool = jlink
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
debug_tool = jlink
|
||||
|
||||
@@ -70,6 +70,20 @@ lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
debug_tool = jlink
|
||||
|
||||
; Seeed XIAO nRF52840 + XIAO Wio SX1262 DIY
|
||||
[env:seeed-xiao-nrf52840-wio-sx1262]
|
||||
board = xiao_ble_sense
|
||||
extends = nrf52840_base
|
||||
board_level = extra
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/diy/seeed-xiao-nrf52840-wio-sx1262 -D PRIVATE_HW
|
||||
-Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/seeed-xiao-nrf52840-wio-sx1262>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
debug_tool = jlink
|
||||
|
||||
; NanoVHF T-Energy-S3 + E22(0)-xxxM - DIY
|
||||
[env:t-energy-s3_e22]
|
||||
extends = esp32s3_base
|
||||
@@ -86,4 +100,4 @@ build_flags =
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-I variants/diy/t-energy-s3_e22
|
||||
-I variants/diy/t-energy-s3_e22
|
||||
43
variants/diy/seeed-xiao-nrf52840-wio-sx1262/README.md
Normal file
43
variants/diy/seeed-xiao-nrf52840-wio-sx1262/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# XIAO nRF52840 + XIAO Wio SX1262
|
||||
|
||||
For a mere doubling in price you too can swap out the XIAO ESP32C3 for a XIAO nRF52840, stack the Wio SX1262 radio board either above or underneath the nRF52840, solder the pins, and achieve a massive improvement in battery life!
|
||||
|
||||
I'm not really sure why else you would want to as the ESP32C3 is perfectly cromulent, easily connects to the Wio SX1262 via the B2B connector and has an onboard IPEX connector for the included Bluetooth antenna. So you'll also lose BT range, but you will also have working ADC for the battery in Meshtastic and also have an ESP32C3 to use for something else!
|
||||
|
||||
If you're still reading you are clearly gonna do it anyway, so...mount the Wio SX1262 either on top or underneath depending on your preference. The `variant.h` will work with either configuration though it does map the Wio SX1262's button to nRF52840 Pin `D5` as it can still be used as a user button and it's nice to be able to gracefully shutdown a node by holding it down for 5 seconds.
|
||||
|
||||
If you do decide to wire up the button, orient it so looking straight-down at the Wio SX1262 the radio chip is at the bottom, button in the middle and the hole is at the top - the **left** side of the button should be soldered to `GND` (e.g. the 2nd pin down the top on the **right** row of pins) and the **right** side of the button should be soldered to `D5` (e.g. the 2nd pin up from the button on the **left** row of pins.). This mirrors the original wiring and wiring it in reverse could end up connecting GND to voltage and that's no beuno.
|
||||
|
||||
Serial Pins remain available on `D6` (TX) and `D7` (RX) should you want to use them, The same pins could be repurposed for `i2c` if you would like to have that instead of serial, in `variant.h` you would just need to change:
|
||||
|
||||
```c++
|
||||
// RX and TX pins
|
||||
#define PIN_SERIAL1_RX (6)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```c++
|
||||
// RX and TX pins
|
||||
#define PIN_SERIAL1_RX (-1)
|
||||
#define PIN_SERIAL1_TX (-1)
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```c++
|
||||
#define PIN_WIRE_SDA (-1)
|
||||
#define PIN_WIRE_SCL (-1)
|
||||
// #define PIN_WIRE_SDA (6)
|
||||
// #define PIN_WIRE_SCL (7)
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```c++
|
||||
#define PIN_WIRE_SDA (6)
|
||||
#define PIN_WIRE_SCL (7)
|
||||
```
|
||||
|
||||
If you wanted both serial and i2c you could even go so far as to use the pads for the PDM mic which is missing on the non-sense board (`P1.00` / `P0.16`)... or move up to the nRF52840 Plus which has even more pins available but hasn't been checked/confirmed if it follows the same pin mapping as the non-plus.
|
||||
55
variants/diy/seeed-xiao-nrf52840-wio-sx1262/variant.cpp
Normal file
55
variants/diy/seeed-xiao-nrf52840-wio-sx1262/variant.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// D0 .. D13
|
||||
2, // D0 is P0.02 (A0)
|
||||
3, // D1 is P0.03 (A1)
|
||||
28, // D2 is P0.28 (A2)
|
||||
29, // D3 is P0.29 (A3)
|
||||
4, // D4 is P0.04 (A4,SDA)
|
||||
5, // D5 is P0.05 (A5,SCL)
|
||||
43, // D6 is P1.11 (TX)
|
||||
44, // D7 is P1.12 (RX)
|
||||
45, // D8 is P1.13 (SCK)
|
||||
46, // D9 is P1.14 (MISO)
|
||||
47, // D10 is P1.15 (MOSI)
|
||||
|
||||
// LEDs
|
||||
26, // D11 is P0.26 (LED RED)
|
||||
6, // D12 is P0.06 (LED BLUE)
|
||||
30, // D13 is P0.30 (LED GREEN)
|
||||
14, // D14 is P0.14 (READ_BAT)
|
||||
|
||||
// LSM6DS3TR
|
||||
40, // D15 is P1.08 (6D_PWR)
|
||||
27, // D16 is P0.27 (6D_I2C_SCL)
|
||||
7, // D17 is P0.07 (6D_I2C_SDA)
|
||||
11, // D18 is P0.11 (6D_INT1)
|
||||
|
||||
// MIC
|
||||
42, // 17,//42, // D19 is P1.10 (MIC_PWR)
|
||||
32, // 26,//32, // D20 is P1.00 (PDM_CLK)
|
||||
16, // 25,//16, // D21 is P0.16 (PDM_DATA)
|
||||
|
||||
// BQ25100
|
||||
13, // D22 is P0.13 (HICHG)
|
||||
17, // D23 is P0.17 (~CHG)
|
||||
|
||||
//
|
||||
21, // D24 is P0.21 (QSPI_SCK)
|
||||
25, // D25 is P0.25 (QSPI_CSN)
|
||||
20, // D26 is P0.20 (QSPI_SIO_0 DI)
|
||||
24, // D27 is P0.24 (QSPI_SIO_1 DO)
|
||||
22, // D28 is P0.22 (QSPI_SIO_2 WP)
|
||||
23, // D29 is P0.23 (QSPI_SIO_3 HOLD)
|
||||
|
||||
// NFC
|
||||
9, // D30 is P0.09 (NFC1)
|
||||
10, // D31 is P0.10 (NFC2)
|
||||
|
||||
// VBAT
|
||||
31, // D32 is P0.10 (VBAT)
|
||||
};
|
||||
186
variants/diy/seeed-xiao-nrf52840-wio-sx1262/variant.h
Normal file
186
variants/diy/seeed-xiao-nrf52840-wio-sx1262/variant.h
Normal file
@@ -0,0 +1,186 @@
|
||||
// basically xiao_ble with pins remapped for:
|
||||
// Seeed XIAO nRF52840 : https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html
|
||||
// Seeed Wio SX1626 : https://www.seeedstudio.com/Wio-SX1262-with-XIAO-ESP32S3-p-5982.html
|
||||
|
||||
#ifndef _SEEED_XIAO_NRF52840_SENSE_H_
|
||||
#define _SEEED_XIAO_NRF52840_SENSE_H_
|
||||
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#define PINS_COUNT (33)
|
||||
#define NUM_DIGITAL_PINS (33)
|
||||
#define NUM_ANALOG_INPUTS (8) // A6 is used for battery, A7 is analog reference
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
// LEDs
|
||||
// ----
|
||||
#define LED_RED 11
|
||||
#define LED_BLUE 12
|
||||
#define LED_GREEN 13
|
||||
|
||||
#define PIN_LED1 LED_GREEN
|
||||
#define PIN_LED2 LED_BLUE
|
||||
#define PIN_LED3 LED_RED
|
||||
|
||||
#define PIN_LED PIN_LED1
|
||||
#define LED_PWR (PINS_COUNT)
|
||||
|
||||
#define LED_BUILTIN PIN_LED
|
||||
#define LED_STATE_ON 1 // State when LED is lit
|
||||
|
||||
// XIAO Wio-SX1262 Shield User button
|
||||
#define PIN_BUTTON1 5
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// Digital Pins
|
||||
// ------------
|
||||
#define D0 (0ul)
|
||||
#define D1 (1ul)
|
||||
#define D2 (2ul)
|
||||
#define D3 (3ul)
|
||||
#define D4 (4ul)
|
||||
#define D5 (5ul)
|
||||
#define D6 (6ul)
|
||||
#define D7 (7ul)
|
||||
#define D8 (8ul)
|
||||
#define D9 (9ul)
|
||||
#define D10 (10ul)
|
||||
|
||||
// Analog Pins
|
||||
// -----------
|
||||
#define PIN_A0 (0)
|
||||
#define PIN_A1 (1)
|
||||
#define PIN_A2 (2)
|
||||
#define PIN_A3 (3)
|
||||
#define PIN_A4 (4)
|
||||
#define PIN_A5 (5)
|
||||
#define PIN_VBAT (32)
|
||||
#define VBAT_ENABLE (14)
|
||||
|
||||
static const uint8_t A0 = PIN_A0;
|
||||
static const uint8_t A1 = PIN_A1;
|
||||
static const uint8_t A2 = PIN_A2;
|
||||
static const uint8_t A3 = PIN_A3;
|
||||
static const uint8_t A4 = PIN_A4;
|
||||
static const uint8_t A5 = PIN_A5;
|
||||
#define ADC_RESOLUTION 12
|
||||
|
||||
// Other Pins
|
||||
// ----------
|
||||
#define PIN_NFC1 (30)
|
||||
#define PIN_NFC2 (31)
|
||||
|
||||
// RX and TX pins
|
||||
#define PIN_SERIAL1_RX (-1)
|
||||
#define PIN_SERIAL1_TX (-1)
|
||||
// complains if not defined
|
||||
#define PIN_SERIAL2_RX (-1)
|
||||
#define PIN_SERIAL2_TX (-1)
|
||||
|
||||
// 4 is used as RF_SW and 5 for USR button so...
|
||||
#define PIN_WIRE_SDA (6)
|
||||
#define PIN_WIRE_SCL (7)
|
||||
|
||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
|
||||
// SPI SX1262
|
||||
// ----------
|
||||
#define SPI_SX1262
|
||||
#ifdef SPI_SX1262
|
||||
#define SPI_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_SPI_MISO (9)
|
||||
#define PIN_SPI_MOSI (10)
|
||||
#define PIN_SPI_SCK (8)
|
||||
|
||||
static const uint8_t SS = D3;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
// supported modules list
|
||||
#define USE_SX1262
|
||||
|
||||
// common pinouts for SX126X modules
|
||||
#define SX126X_CS D3
|
||||
#define SX126X_DIO1 D0
|
||||
#define SX126X_BUSY D1
|
||||
#define SX126X_RESET D2
|
||||
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_RXEN 38
|
||||
#define SX126X_TXEN RADIOLIB_NC
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
#endif
|
||||
|
||||
// Wire Interfaces
|
||||
// -------------------
|
||||
#define WIRE_INTERFACES_COUNT 1 // 2
|
||||
|
||||
// Sense version has IMU and PDM Mic
|
||||
// #define XIAO_SENSE
|
||||
#ifndef XIAO_SENSE
|
||||
// 6 DoF IMU
|
||||
#define PIN_LSM6DS3TR_C_POWER (15)
|
||||
#define PIN_LSM6DS3TR_C_INT1 (18)
|
||||
// PDM Interfaces
|
||||
// ---------------
|
||||
#define PIN_PDM_PWR (19)
|
||||
#define PIN_PDM_CLK (20)
|
||||
#define PIN_PDM_DIN (21)
|
||||
#endif
|
||||
|
||||
// QSPI Pins
|
||||
// ---------
|
||||
#define PIN_QSPI_SCK (24)
|
||||
#define PIN_QSPI_CS (25)
|
||||
#define PIN_QSPI_IO0 (26)
|
||||
#define PIN_QSPI_IO1 (27)
|
||||
#define PIN_QSPI_IO2 (28)
|
||||
#define PIN_QSPI_IO3 (29)
|
||||
|
||||
// On-board QSPI Flash
|
||||
// -------------------
|
||||
#define EXTERNAL_FLASH_DEVICES P25Q16H
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
// Battery
|
||||
// -------
|
||||
// P0_14 = 14 Reads battery voltage from divider on signal board.
|
||||
// PIN_VBAT is reading voltage divider on XIAO and is program pin 32 / or P0.31
|
||||
#define BAT_READ 14
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 10
|
||||
#define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED
|
||||
#define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge
|
||||
|
||||
// The battery sense is hooked to pin A0 (5)
|
||||
#define BATTERY_PIN PIN_VBAT // PIN_A0
|
||||
|
||||
// ratio of voltage divider = 3.0 (R17=1M, R18=510k)
|
||||
#define ADC_MULTIPLIER 3 // 3.0 + a bit for being optimistic
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
@@ -21,5 +21,5 @@ build_flags = ${esp32s3_base.build_flags}
|
||||
-DEINK_HEIGHT=128
|
||||
|
||||
lib_deps = ${esp32s3_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.5.3
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||
|
||||
@@ -6,7 +6,7 @@ board_check = true
|
||||
board_build.mcu = esp32s3
|
||||
upload_protocol = esptool
|
||||
upload_speed = 921600
|
||||
platform_packages = framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
|
||||
platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
|
||||
lib_deps =
|
||||
${esp32s3_base.lib_deps}
|
||||
build_unflags =
|
||||
@@ -16,4 +16,4 @@ build_flags =
|
||||
${esp32s3_base.build_flags} -D PRIVATE_HW -I variants/icarus
|
||||
-DBOARD_HAS_PSRAM
|
||||
|
||||
-DARDUINO_USB_MODE=0
|
||||
-DARDUINO_USB_MODE=0
|
||||
@@ -17,11 +17,11 @@ build_flags =
|
||||
-DM5STACK
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.5.3
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
lewisxhe/PCF8563_Library@^1.0.1
|
||||
lib_ignore =
|
||||
m5stack-coreink
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.f_cpu = 240000000L
|
||||
upload_protocol = esptool
|
||||
upload_port = /dev/ttyACM0
|
||||
upload_port = /dev/ttyACM0
|
||||
|
||||
30
variants/meshlink/platformio.ini
Normal file
30
variants/meshlink/platformio.ini
Normal file
@@ -0,0 +1,30 @@
|
||||
; MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
|
||||
; https://www.loraitalia.it
|
||||
; firmware for boards with or without oled display
|
||||
[env:meshlink]
|
||||
extends = nrf52840_base
|
||||
board = meshlink
|
||||
;board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags} -I variants/meshlink -D MESHLINK
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-D EINK_DISPLAY_MODEL=GxEPD2_213_B74
|
||||
-D EINK_WIDTH=250
|
||||
-D EINK_HEIGHT=122
|
||||
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
|
||||
-D EINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
|
||||
-D EINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
|
||||
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
|
||||
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||
-D EINK_HASQUIRK_VICIOUSFASTREFRESH ; Identify that pixels drawn by fast-refresh are harder to clear
|
||||
|
||||
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/meshlink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/GxEPD2#55f618961db45a23eff0233546430f1e5a80f63a
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
;upload_protocol = jlink
|
||||
23
variants/meshlink/variant.cpp
Normal file
23
variants/meshlink/variant.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// P0
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
|
||||
// P1
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||
|
||||
void initVariant()
|
||||
{
|
||||
pinMode(PIN_LED1, OUTPUT);
|
||||
digitalWrite(PIN_LED1, HIGH); // turn off the white led while booting
|
||||
// otherwise it will stay lit for several seconds (could be annoying)
|
||||
|
||||
#ifdef PIN_WD_EN
|
||||
pinMode(PIN_WD_EN, OUTPUT);
|
||||
digitalWrite(PIN_WD_EN, HIGH); // Enable the Watchdog at boot
|
||||
#endif
|
||||
}
|
||||
153
variants/meshlink/variant.h
Normal file
153
variants/meshlink/variant.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef _VARIANT_MESHLINK_
|
||||
#define _VARIANT_MESHLINK_
|
||||
#ifndef MESHLINK
|
||||
#define MESHLINK
|
||||
#endif
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
// #define USE_LFXO // Board uses 32khz crystal for LF
|
||||
#define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (2)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define BUTTON_PIN (-1) // If defined, this will be used for user button presses,
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (24) // Built in white led for status
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 0 // State when LED is litted
|
||||
#define LED_INVERTED 1
|
||||
|
||||
// Testing USB detection
|
||||
// #define NRF_APM
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A1 (3) // P0.03/AIN1
|
||||
#define ADC_RESOLUTION 14
|
||||
|
||||
// Other pins
|
||||
// #define PIN_AREF (2)
|
||||
// static const uint8_t AREF = PIN_AREF;
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (32 + 8)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_SPI_MISO (8)
|
||||
#define PIN_SPI_MOSI (32 + 9)
|
||||
#define PIN_SPI_SCK (11)
|
||||
|
||||
#define PIN_SPI1_MISO (23)
|
||||
#define PIN_SPI1_MOSI (21)
|
||||
#define PIN_SPI1_SCK (19)
|
||||
|
||||
static const uint8_t SS = 12;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
// #define USE_EINK
|
||||
|
||||
#define PIN_EINK_CS (15)
|
||||
#define PIN_EINK_BUSY (16)
|
||||
#define PIN_EINK_DC (14)
|
||||
#define PIN_EINK_RES (17)
|
||||
#define PIN_EINK_SCLK (19)
|
||||
#define PIN_EINK_MOSI (21) // also called SDI
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (1)
|
||||
#define PIN_WIRE_SCL (27)
|
||||
|
||||
// QSPI Pins
|
||||
#define PIN_QSPI_SCK 19
|
||||
#define PIN_QSPI_CS 22
|
||||
#define PIN_QSPI_IO0 21
|
||||
#define PIN_QSPI_IO1 23
|
||||
#define PIN_QSPI_IO2 32
|
||||
#define PIN_QSPI_IO3 20
|
||||
|
||||
// On-board QSPI Flash
|
||||
#define EXTERNAL_FLASH_DEVICES W25Q16JVUXIQ
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (12)
|
||||
#define SX126X_DIO1 (32 + 1)
|
||||
#define SX126X_BUSY (32 + 3)
|
||||
#define SX126X_RESET (6)
|
||||
// #define SX126X_RXEN (13)
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// pin 25 is used to enable or disable the watchdog. This pin has to be disabled when cpu is put to sleep
|
||||
// otherwise the timer will expire and wd will reboot the cpu
|
||||
#define PIN_WD_EN (25)
|
||||
|
||||
#define PIN_GPS_PPS (26) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_TX_PIN PIN_SERIAL1_RX // This is for bits going TOWARDS the CPU
|
||||
#define GPS_RX_PIN PIN_SERIAL1_TX // This is for bits going TOWARDS the GPS
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
#define PIN_GPS_EN (0)
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
|
||||
#define PIN_BUZZER (31) // P0.31/AIN7
|
||||
|
||||
// Battery
|
||||
// The battery sense is hooked to pin A0 (2)
|
||||
#define BATTERY_PIN (2)
|
||||
// and has 12 bit resolution
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||
#undef AREF_VOLTAGE
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.42 // fine tuning of voltage
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
#endif
|
||||
30
variants/meshlink_eink/platformio.ini
Normal file
30
variants/meshlink_eink/platformio.ini
Normal file
@@ -0,0 +1,30 @@
|
||||
; MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
|
||||
; https://www.loraitalia.it
|
||||
; firmware for boards with a 250x122 e-ink display
|
||||
[env:meshlink_eink]
|
||||
extends = nrf52840_base
|
||||
board = meshlink
|
||||
;board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags} -I variants/meshlink_eink -D MESHLINK
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-D EINK_DISPLAY_MODEL=GxEPD2_213_B74
|
||||
-D EINK_WIDTH=250
|
||||
-D EINK_HEIGHT=122
|
||||
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
|
||||
-D EINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
|
||||
-D EINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
|
||||
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
|
||||
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||
-D EINK_HASQUIRK_VICIOUSFASTREFRESH ; Identify that pixels drawn by fast-refresh are harder to clear
|
||||
|
||||
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/meshlink_eink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/GxEPD2#55f618961db45a23eff0233546430f1e5a80f63a
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
;upload_protocol = jlink
|
||||
23
variants/meshlink_eink/variant.cpp
Normal file
23
variants/meshlink_eink/variant.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// P0
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
|
||||
// P1
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||
|
||||
void initVariant()
|
||||
{
|
||||
pinMode(PIN_LED1, OUTPUT);
|
||||
digitalWrite(PIN_LED1, HIGH); // turn off the white led while booting
|
||||
// otherwise it will stay lit for several seconds (could be annoying)
|
||||
|
||||
#ifdef PIN_WD_EN
|
||||
pinMode(PIN_WD_EN, OUTPUT);
|
||||
digitalWrite(PIN_WD_EN, HIGH); // Enable the Watchdog at boot
|
||||
#endif
|
||||
}
|
||||
153
variants/meshlink_eink/variant.h
Normal file
153
variants/meshlink_eink/variant.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef _VARIANT_MESHLINK_
|
||||
#define _VARIANT_MESHLINK_
|
||||
#ifndef MESHLINK
|
||||
#define MESHLINK
|
||||
#endif
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
// #define USE_LFXO // Board uses 32khz crystal for LF
|
||||
#define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (2)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define BUTTON_PIN (-1) // If defined, this will be used for user button presses,
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (24) // Built in white led for status
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 0 // State when LED is litted
|
||||
#define LED_INVERTED 1
|
||||
|
||||
// Testing USB detection
|
||||
// #define NRF_APM
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A1 (3) // P0.03/AIN1
|
||||
#define ADC_RESOLUTION 14
|
||||
|
||||
// Other pins
|
||||
// #define PIN_AREF (2)
|
||||
// static const uint8_t AREF = PIN_AREF;
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (32 + 8)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_SPI_MISO (8)
|
||||
#define PIN_SPI_MOSI (32 + 9)
|
||||
#define PIN_SPI_SCK (11)
|
||||
|
||||
#define PIN_SPI1_MISO (23)
|
||||
#define PIN_SPI1_MOSI (21)
|
||||
#define PIN_SPI1_SCK (19)
|
||||
|
||||
static const uint8_t SS = 12;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
#define USE_EINK
|
||||
|
||||
#define PIN_EINK_CS (15)
|
||||
#define PIN_EINK_BUSY (16)
|
||||
#define PIN_EINK_DC (14)
|
||||
#define PIN_EINK_RES (17)
|
||||
#define PIN_EINK_SCLK (19)
|
||||
#define PIN_EINK_MOSI (21) // also called SDI
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (1)
|
||||
#define PIN_WIRE_SCL (27)
|
||||
|
||||
// QSPI Pins
|
||||
#define PIN_QSPI_SCK 19
|
||||
#define PIN_QSPI_CS 22
|
||||
#define PIN_QSPI_IO0 21
|
||||
#define PIN_QSPI_IO1 23
|
||||
#define PIN_QSPI_IO2 32
|
||||
#define PIN_QSPI_IO3 20
|
||||
|
||||
// On-board QSPI Flash
|
||||
#define EXTERNAL_FLASH_DEVICES W25Q16JVUXIQ
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (12)
|
||||
#define SX126X_DIO1 (32 + 1)
|
||||
#define SX126X_BUSY (32 + 3)
|
||||
#define SX126X_RESET (6)
|
||||
// #define SX126X_RXEN (13)
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// pin 25 is used to enable or disable the watchdog. This pin has to be disabled when cpu is put to sleep
|
||||
// otherwise the timer will expire and wd will reboot the cpu
|
||||
#define PIN_WD_EN (25)
|
||||
|
||||
#define PIN_GPS_PPS (26) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_TX_PIN PIN_SERIAL1_RX // This is for bits going TOWARDS the CPU
|
||||
#define GPS_RX_PIN PIN_SERIAL1_TX // This is for bits going TOWARDS the GPS
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
#define PIN_GPS_EN (0)
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
|
||||
#define PIN_BUZZER (31) // P0.31/AIN7
|
||||
|
||||
// Battery
|
||||
// The battery sense is hooked to pin A0 (2)
|
||||
#define BATTERY_PIN (2)
|
||||
// and has 12 bit resolution
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||
#undef AREF_VOLTAGE
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.42 // fine tuning of voltage
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
#endif
|
||||
@@ -9,10 +9,10 @@ upload_protocol = esptool
|
||||
;upload_port = /dev/ttyACM1
|
||||
upload_speed = 921600
|
||||
platform_packages =
|
||||
tool-esptoolpy@^1.40500.0
|
||||
platformio/tool-esptoolpy@^1.40801.0
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.5.1
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||
build_unflags =
|
||||
${esp32s3_base.build_unflags}
|
||||
|
||||
@@ -9,7 +9,7 @@ upload_protocol = esptool
|
||||
;upload_port = /dev/ttyACM0
|
||||
upload_speed = 921600
|
||||
platform_packages =
|
||||
tool-esptoolpy@^1.40500.0
|
||||
platformio/tool-esptoolpy@^1.40801.0
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||
|
||||
@@ -18,4 +18,4 @@ lib_deps =
|
||||
${networking_base.lib_deps}
|
||||
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
|
||||
debug_build_flags = ${rp2040_base.build_flags}, -g
|
||||
debug_tool = cmsis-dap ; for e.g. Picotool
|
||||
debug_tool = cmsis-dap ; for e.g. Picotool
|
||||
@@ -13,10 +13,10 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631_epaper>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||
beegee-tokyo/RAKwireless RAK12034@^1.0.0
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
;upload_protocol = jlink
|
||||
|
||||
@@ -15,11 +15,11 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631_epaper_onrxtx>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.5.1
|
||||
zinggjm/GxEPD2@^1.6.2
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||
beegee-tokyo/RAKwireless RAK12034@^1.0.0
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
;upload_port = /dev/ttyACM3
|
||||
;upload_port = /dev/ttyACM3
|
||||
|
||||
@@ -9,7 +9,7 @@ build_flags = ${rp2350_base.build_flags}
|
||||
-Ivariants/rpipico2
|
||||
-DDEBUG_RP2040_PORT=Serial
|
||||
-DHW_SPI1_DEVICE
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m33"
|
||||
lib_deps =
|
||||
${rp2350_base.lib_deps}
|
||||
debug_build_flags = ${rp2350_base.build_flags}, -g
|
||||
|
||||
30
variants/rpipico2w/platformio.ini
Normal file
30
variants/rpipico2w/platformio.ini
Normal file
@@ -0,0 +1,30 @@
|
||||
[env:pico2w]
|
||||
extends = rp2350_base
|
||||
board = rpipico2w
|
||||
upload_protocol = jlink
|
||||
# debug settings for external openocd with RP2040 support (custom build)
|
||||
debug_tool = custom
|
||||
debug_init_cmds =
|
||||
target extended-remote localhost:3333
|
||||
$INIT_BREAK
|
||||
monitor reset halt
|
||||
$LOAD_CMDS
|
||||
monitor init
|
||||
monitor reset halt
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${rp2350_base.build_flags}
|
||||
-DRPI_PICO2
|
||||
-Ivariants/rpipico2w
|
||||
# -DDEBUG_RP2040_PORT=Serial
|
||||
-DHW_SPI1_DEVICE
|
||||
-DARDUINO_RASPBERRY_PI_PICO_2W
|
||||
-DARDUINO_ARCH_RP2040
|
||||
-DHAS_WIFI=1
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m33"
|
||||
-fexceptions # for exception handling in MQTT
|
||||
build_src_filter = ${rp2350_base.build_src_filter} +<mesh/wifi/>
|
||||
lib_deps =
|
||||
${rp2350_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
debug_build_flags = ${rp2350_base.build_flags}, -g
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user