Compare commits

..

4 Commits

Author SHA1 Message Date
vidplace7
e8e6b39bc9 Add libuv to GitHub Actions 2025-03-18 15:12:29 -04:00
Jorropo
bf7afd657a replace symlink to point to my fork
Allows anyone to test the PR
2025-03-18 20:03:38 +01:00
vidplace7
ca951caa38 Add libuv to Linux packaging 2025-03-18 20:03:38 +01:00
Jorropo
16a1c9f148 Add UDP multicast support on linux.
We tested it an it works.

This is really hacky to say the least.
2025-03-18 20:03:38 +01:00
500 changed files with 4667 additions and 24846 deletions

View File

@@ -72,15 +72,6 @@ body:
validations: validations:
required: true required: true
- type: checkboxes
id: mui
attributes:
label: Is this bug report about any UI component firmware like InkHUD or Meshtatic UI (MUI)?
options:
- label: Meshtastic UI aka MUI colorTFT
- label: InkHUD ePaper
- label: OLED slide UI on any display
- type: input - type: input
id: version id: version
attributes: attributes:

View File

@@ -43,13 +43,6 @@ runs:
id: base id: base
uses: ./.github/actions/setup-base uses: ./.github/actions/setup-base
- name: Get web ui version
if: inputs.include-web-ui == 'true'
id: webver
shell: bash
run: |
echo "ver=$(cat bin/web.version)" >> $GITHUB_OUTPUT
- name: Pull web ui - name: Pull web ui
if: inputs.include-web-ui == 'true' if: inputs.include-web-ui == 'true'
uses: dsaltares/fetch-gh-release-asset@master uses: dsaltares/fetch-gh-release-asset@master
@@ -58,7 +51,7 @@ runs:
file: build.tar file: build.tar
target: build.tar target: build.tar
token: ${{ inputs.github_token }} token: ${{ inputs.github_token }}
version: tags/v${{ steps.webver.outputs.ver }} version: tags/v2.5.3
- name: Unpack web ui - name: Unpack web ui
if: inputs.include-web-ui == 'true' if: inputs.include-web-ui == 'true'

View File

@@ -20,7 +20,7 @@ runs:
shell: bash shell: bash
run: | run: |
sudo apt-get -y update --fix-missing sudo apt-get -y update --fix-missing
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev libuv1-dev lsb-release
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5

29
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
#trunk-ignore-all(yamllint/quoted-strings): required by dependabot syntax check
version: 2
updates:
- package-ecosystem: docker
directory: /.devcontainer
schedule:
interval: daily
time: "05:00"
timezone: US/Pacific
- package-ecosystem: docker
directory: /
schedule:
interval: daily
time: "05:00"
timezone: US/Pacific
- package-ecosystem: gitsubmodule
directory: /
schedule:
interval: daily
time: "05:00"
timezone: US/Pacific
ignore:
- dependency-name: protobufs
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: daily
time: "05:00"
timezone: US/Pacific

View File

@@ -1,6 +1,7 @@
## 🙏 Thank you for sending in a pull request, here's some tips to get started!
### ❌ (Please delete all these tips and replace them with your text) ❌ ### ❌ (Please delete all these tips and replace them with your text) ❌
## Thank you for sending in a pull request, here's some tips to get started!
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first - Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
@@ -11,17 +12,4 @@
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed. - If your other co-developers have comments on your PR please tweak as needed.
- Please also enable "Allow edits by maintainers". - Please also enable "Allow edits by maintainers".
- Please do not submit untested code.
- If you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and commnunity members can help test your changes.
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord - If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
## 🤝 Attestations
- [ ] I have tested that my proposed changes behave as described.
- [ ] I have tested that my proposed changes do not cause any obvious regressions on the following devices:
- [ ] Heltec (Lora32) V3
- [ ] LilyGo T-Deck
- [ ] LilyGo T-Beam
- [ ] RAK WisBlock 4631
- [ ] Seeed Studio T-1000E tracker card
- [ ] Other (please specify below)

View File

@@ -26,11 +26,6 @@ on:
required: false required: false
type: boolean type: boolean
default: false default: false
pio_env:
description: PlatformIO environment to build
required: false
type: string
default: native
outputs: outputs:
digest: digest:
description: Digest of built image description: Digest of built image
@@ -95,5 +90,3 @@ jobs:
push: ${{ inputs.push }} push: ${{ inputs.push }}
tags: ${{ steps.meta.outputs.tags }} # Tag is only meant to be consumed by the "manifest" job tags: ${{ steps.meta.outputs.tags }} # Tag is only meant to be consumed by the "manifest" job
platforms: ${{ inputs.platform }} platforms: ${{ inputs.platform }}
build-args: |
PIO_ENV=${{ inputs.pio_env }}

View File

@@ -5,20 +5,14 @@ concurrency:
on: on:
# # Triggers the workflow on push but only for the master branch # # Triggers the workflow on push but only for the master branch
push: push:
branches: branches: [master, develop]
- master
- develop
- event/*
paths-ignore: paths-ignore:
- "**.md" - "**.md"
- version.properties - version.properties
# Note: This is different from "pull_request". Need to specify ref when doing checkouts. # Note: This is different from "pull_request". Need to specify ref when doing checkouts.
pull_request_target: pull_request_target:
branches: branches: [master, develop]
- master
- develop
- event/*
paths-ignore: paths-ignore:
- "**.md" - "**.md"
#- "**.yml" #- "**.yml"
@@ -38,12 +32,12 @@ jobs:
name: Checkout base name: Checkout base
- id: jsonStep - id: jsonStep
run: | run: |
if [[ "$GITHUB_HEAD_REF" == "" ]]; then if [[ "${{ github.head_ref }}" == "" ]]; then
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
else else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick) TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
fi fi
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF Targets: $TARGETS" echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} } Ref: ${{ github.ref }} Targets: $TARGETS"
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
outputs: outputs:
esp32: ${{ steps.jsonStep.outputs.esp32 }} esp32: ${{ steps.jsonStep.outputs.esp32 }}
@@ -149,10 +143,9 @@ jobs:
secrets: inherit secrets: inherit
test-native: test-native:
if: ${{ !contains(github.ref_name, 'event/') }}
uses: ./.github/workflows/test_native.yml uses: ./.github/workflows/test_native.yml
docker-deb-amd64: docker-debian-amd64:
uses: ./.github/workflows/docker_build.yml uses: ./.github/workflows/docker_build.yml
with: with:
distro: debian distro: debian
@@ -160,16 +153,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
push: false push: false
docker-deb-amd64-tft: docker-alpine-amd64:
uses: ./.github/workflows/docker_build.yml
with:
distro: debian
platform: linux/amd64
runs-on: ubuntu-24.04
push: false
pio_env: native-tft
docker-alp-amd64:
uses: ./.github/workflows/docker_build.yml uses: ./.github/workflows/docker_build.yml
with: with:
distro: alpine distro: alpine
@@ -177,16 +161,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
push: false push: false
docker-alp-amd64-tft: docker-debian-arm64:
uses: ./.github/workflows/docker_build.yml
with:
distro: alpine
platform: linux/amd64
runs-on: ubuntu-24.04
push: false
pio_env: native-tft
docker-deb-arm64:
uses: ./.github/workflows/docker_build.yml uses: ./.github/workflows/docker_build.yml
with: with:
distro: debian distro: debian
@@ -194,7 +169,7 @@ jobs:
runs-on: ubuntu-24.04-arm runs-on: ubuntu-24.04-arm
push: false push: false
docker-deb-armv7: docker-debian-armv7:
uses: ./.github/workflows/docker_build.yml uses: ./.github/workflows/docker_build.yml
with: with:
distro: debian distro: debian
@@ -202,6 +177,17 @@ jobs:
runs-on: ubuntu-24.04-arm runs-on: ubuntu-24.04-arm
push: false push: false
after-checks:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
needs: [check]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
gather-artifacts: gather-artifacts:
permissions: permissions:
contents: write contents: write
@@ -346,7 +332,7 @@ jobs:
merge-multiple: true merge-multiple: true
path: ./output/pio-deps-native-tft path: ./output/pio-deps-native-tft
- name: Zip Linux sources - name: Zip linux sources
working-directory: output working-directory: output
run: | run: |
zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
@@ -356,9 +342,7 @@ jobs:
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -lR run: ls -lR
- name: Add Linux sources to GtiHub Release - name: Add linux sources to release
# Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }}
run: | run: |
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip
@@ -416,53 +400,9 @@ jobs:
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -lR run: ls -lR
- name: Add bins and debug elfs to GitHub Release - name: Add bins and debug elfs to release
# Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }}
run: | run: |
gh release upload v${{ steps.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip gh release upload v${{ steps.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
gh release upload v${{ steps.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip gh release upload v${{ steps.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-firmware:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-firmware]
env:
targets: esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,stm32
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Get release version string
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with:
pattern: firmware-{${{ env.targets }}}-${{ steps.version.outputs.long }}
merge-multiple: true
path: ./publish
- name: Publish firmware to meshtastic.github.io
uses: peaceiris/actions-gh-pages@v4
env:
# On event/* branches, use the event name as the destination prefix
DEST_PREFIX: ${{ contains(github.ref_name, 'event/') && format('{0}/', github.ref_name) || '' }}
with:
deploy_key: ${{ secrets.DIST_PAGES_DEPLOY_KEY }}
external_repository: meshtastic/meshtastic.github.io
publish_branch: master
publish_dir: ./publish
destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ steps.version.outputs.long }}
keep_files: true
user_name: github-actions[bot]
user_email: github-actions[bot]@users.noreply.github.com
commit_message: ${{ steps.version.outputs.long }}
enable_jekyll: true

View File

@@ -46,14 +46,11 @@ jobs:
# Create a PR to bump version when a release is Published # Create a PR to bump version when a release is Published
bump-version: bump-version:
if: github.event.action == 'published' if: ${{ github.event.release.published }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write
contents: write contents: write
defaults:
run:
shell: bash
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -63,44 +60,32 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- name: Bump version.properties - name: Get release version string
run: | run: |
# Bump version.properties echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
chmod +x ./bin/bump_version.py echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
./bin/bump_version.py id: version
env:
BUILD_LOCATION: local
- name: Get new release version string - name: Bump version.properties
run: | run: >-
echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT bin/bump_version.py
id: new_version
- name: Ensure debian deps are installed - name: Ensure debian deps are installed
shell: bash
run: | run: |
sudo apt-get update -y --fix-missing sudo apt-get update -y --fix-missing
sudo apt-get install -y devscripts sudo apt-get install -y devscripts
- name: Update debian changelog - name: Update debian changelog
run: | run: >-
# Update debian changelog debian/ci_changelog.sh
chmod +x ./debian/ci_changelog.sh
./debian/ci_changelog.sh
- name: Bump org.meshtastic.meshtasticd.metainfo.xml - name: Create version.properties pull request
run: |
# Bump org.meshtastic.meshtasticd.metainfo.xml
pip install -r bin/bump_metainfo/requirements.txt -q
chmod +x ./bin/bump_metainfo/bump_metainfo.py
./bin/bump_metainfo/bump_metainfo.py --file bin/org.meshtastic.meshtasticd.metainfo.xml "${{ steps.new_version.outputs.short }}"
env:
PIP_DISABLE_PIP_VERSION_CHECK: 1
- name: Create Bumps pull request
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v7
with: with:
base: ${{ github.event.repository.default_branch }} title: Bump version.properties
title: Bump release version
commit-message: automated bumps
add-paths: | add-paths: |
version.properties version.properties
debian/changelog debian/changelog
bin/org.meshtastic.meshtasticd.metainfo.xml

View File

@@ -13,7 +13,7 @@ permissions:
jobs: jobs:
semgrep-full: semgrep-full:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
container: container:
image: semgrep/semgrep image: semgrep/semgrep

View File

@@ -6,7 +6,7 @@ permissions: read-all
jobs: jobs:
semgrep-diff: semgrep-diff:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
container: container:
image: semgrep/semgrep image: semgrep/semgrep

View File

@@ -143,7 +143,7 @@ jobs:
merge-multiple: true merge-multiple: true
- name: Test Report - name: Test Report
uses: dorny/test-reporter@v2.1.0 uses: dorny/test-reporter@v2.0.0
with: with:
name: PlatformIO Tests name: PlatformIO Tests
path: testreport.xml path: testreport.xml

View File

@@ -5,10 +5,7 @@ on:
- cron: 0 0 * * * # Run every day at midnight - cron: 0 0 * * * # Run every day at midnight
workflow_dispatch: {} workflow_dispatch: {}
permissions: permissions: read-all
contents: read
actions: read
checks: write
jobs: jobs:
native-tests: native-tests:
@@ -47,7 +44,7 @@ jobs:
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 18
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4

View File

@@ -1 +0,0 @@
renovate.json

View File

@@ -1,34 +1,34 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.24.0 version: 1.22.11
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.7.0 ref: v1.6.7
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- checkov@3.2.435
- renovate@40.34.4
- prettier@3.5.3 - prettier@3.5.3
- trufflehog@3.88.34 - trufflehog@3.88.17
- yamllint@1.37.1 - yamllint@1.36.0
- bandit@1.8.3 - bandit@1.8.3
- trivy@0.62.1 - checkov@3.2.386
- terrascan@1.19.9
- trivy@0.60.0
- taplo@0.9.3 - taplo@0.9.3
- ruff@0.11.11 - ruff@0.10.0
- isort@6.0.1 - isort@6.0.1
- markdownlint@0.45.0 - markdownlint@0.44.0
- oxipng@9.1.5 - oxipng@9.1.4
- svgo@3.3.2 - svgo@3.3.2
- actionlint@1.7.7 - actionlint@1.7.7
- flake8@7.2.0 - flake8@7.1.2
- hadolint@2.12.1-beta - hadolint@2.12.1-beta
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.10.0 - shellcheck@0.10.0
- black@25.1.0 - black@25.1.0
- git-diff-check - git-diff-check
- gitleaks@8.26.0 - gitleaks@8.24.0
- clang-format@16.0.3 - clang-format@16.0.3
ignore: ignore:
- linters: [ALL] - linters: [ALL]
@@ -38,7 +38,7 @@ runtimes:
enabled: enabled:
- python@3.10.8 - python@3.10.8
- go@1.21.0 - go@1.21.0
- node@22.16.0 - node@18.20.5
actions: actions:
disabled: disabled:
- trunk-announce - trunk-announce

54
.vscode/settings.json vendored
View File

@@ -10,59 +10,5 @@
}, },
"[powershell]": { "[powershell]": {
"editor.defaultFormatter": "ms-vscode.powershell" "editor.defaultFormatter": "ms-vscode.powershell"
},
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"*.xbm": "cpp"
} }
} }

View File

@@ -1,20 +1,20 @@
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
# trunk-ignore-all(trivy/DS002): We must run as root for this container # 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/DL3002): We must run as root for this container
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM python:3.13-bookworm AS builder FROM python:3.13-bookworm AS builder
ARG PIO_ENV=native
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC ENV TZ=Etc/UTC
# Install Dependencies # Install Dependencies
ENV PIP_ROOT_USER_ACTION=ignore ENV PIP_ROOT_USER_ACTION=ignore
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
curl wget g++ zip git ca-certificates pkg-config \ wget g++ zip git ca-certificates \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \ libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev \ libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
libx11-dev libinput-dev libxkbcommon-x11-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \ && apt-get clean && rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir -U platformio \ && pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware && mkdir /tmp/firmware
@@ -24,26 +24,13 @@ WORKDIR /tmp/firmware
COPY . /tmp/firmware COPY . /tmp/firmware
# Build # Build
RUN bash ./bin/build-native.sh "$PIO_ENV" && \ RUN bash ./bin/build-native.sh && \
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd" cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
# Fetch web assets
RUN curl -L "https://github.com/meshtastic/web/releases/download/v$(cat /tmp/firmware/bin/web.version)/build.tar" -o /tmp/web.tar \
&& mkdir -p /tmp/web \
&& tar -xf /tmp/web.tar -C /tmp/web/ \
&& gzip -dr /tmp/web \
&& rm /tmp/web.tar
##### PRODUCTION BUILD ############# ##### PRODUCTION BUILD #############
FROM debian:bookworm-slim FROM debian:bookworm-slim
LABEL org.opencontainers.image.title="Meshtastic" \
org.opencontainers.image.description="Debian Meshtastic daemon and web interface" \
org.opencontainers.image.url="https://meshtastic.org" \
org.opencontainers.image.documentation="https://meshtastic.org/docs/" \
org.opencontainers.image.authors="Meshtastic" \
org.opencontainers.image.licenses="GPL-3.0-or-later" \
org.opencontainers.image.source="https://github.com/meshtastic/firmware/"
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC ENV TZ=Etc/UTC
@@ -51,17 +38,14 @@ ENV TZ=Etc/UTC
USER root USER root
RUN apt-get update && apt-get --no-install-recommends -y install \ RUN apt-get update && apt-get --no-install-recommends -y install \
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev \ libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev liborcania2.3 libulfius2.7 libssl3 \
liborcania2.3 libulfius2.7 libssl3 \
libx11-6 libinput10 libxkbcommon-x11-0 \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \ && apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/meshtasticd \ && mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \ && mkdir -p /etc/meshtasticd/config.d \
&& mkdir -p /etc/meshtasticd/ssl && mkdir -p /etc/meshtasticd/ssl
# Fetch compiled binary from the builder # Fetch compiled binary from the builder
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/ COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
COPY --from=builder /tmp/web /usr/share/meshtasticd/
# Copy config templates # Copy config templates
COPY ./bin/config.d /etc/meshtasticd/available.d COPY ./bin/config.d /etc/meshtasticd/available.d
@@ -70,9 +54,7 @@ VOLUME /var/lib/meshtasticd
# Expose Meshtastic TCP API port from the host # Expose Meshtastic TCP API port from the host
EXPOSE 4403 EXPOSE 4403
# Expose Meshtastic Web UI port from the host
EXPOSE 9443
CMD [ "sh", "-cx", "meshtasticd --fsdir=/var/lib/meshtasticd" ] CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ]
HEALTHCHECK NONE HEALTHCHECK NONE

View File

@@ -4,8 +4,8 @@
| Firmware Version | Supported | | Firmware Version | Supported |
| ---------------- | ------------------ | | ---------------- | ------------------ |
| 2.6.x | :white_check_mark: | | 2.5.x | :white_check_mark: |
| <= 2.5.x | :x: | | <= 2.4.x | :x: |
## Reporting a Vulnerability ## Reporting a Vulnerability

View File

@@ -1,16 +1,15 @@
# trunk-ignore-all(trivy/DS002): We must run as root for this container # 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/DL3002): We must run as root for this container
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions # trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM python:3.13-alpine3.21 AS builder FROM python:3.13-alpine3.21 AS builder
ARG PIO_ENV=native
ENV PIP_ROOT_USER_ACTION=ignore
ENV PIP_ROOT_USER_ACTION=ignore
RUN apk --no-cache add \ RUN apk --no-cache add \
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \ bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \ libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
libx11-dev libinput-dev libxkbcommon-dev \
&& rm -rf /var/cache/apk/* \ && rm -rf /var/cache/apk/* \
&& pip install --no-cache-dir -U platformio \ && pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware && mkdir /tmp/firmware
@@ -22,35 +21,23 @@ COPY . /tmp/firmware
# Add `argp` for musl # Add `argp` for musl
ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp" ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp"
RUN bash ./bin/build-native.sh "$PIO_ENV" && \ RUN bash ./bin/build-native.sh && \
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd" cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
# ##### PRODUCTION BUILD ############# # ##### PRODUCTION BUILD #############
FROM alpine:3.21 FROM alpine:3.21
LABEL org.opencontainers.image.title="Meshtastic" \
org.opencontainers.image.description="Alpine Meshtastic daemon" \
org.opencontainers.image.url="https://meshtastic.org" \
org.opencontainers.image.documentation="https://meshtastic.org/docs/" \
org.opencontainers.image.authors="Meshtastic" \
org.opencontainers.image.licenses="GPL-3.0-or-later" \
org.opencontainers.image.source="https://github.com/meshtastic/firmware/"
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root # nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
USER root USER root
RUN apk --no-cache add \ RUN apk --no-cache add \
shadow libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \ libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
libx11 libinput libxkbcommon \
&& rm -rf /var/cache/apk/* \ && rm -rf /var/cache/apk/* \
&& mkdir -p /var/lib/meshtasticd \ && mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \ && mkdir -p /etc/meshtasticd/config.d \
&& mkdir -p /etc/meshtasticd/ssl && mkdir -p /etc/meshtasticd/ssl
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
# Fetch compiled binary from the builder
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/
# Copy config templates
COPY ./bin/config.d /etc/meshtasticd/available.d
WORKDIR /var/lib/meshtasticd WORKDIR /var/lib/meshtasticd
VOLUME /var/lib/meshtasticd VOLUME /var/lib/meshtasticd

View File

@@ -2,9 +2,7 @@
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base
custom_esp32_kind = esp32 custom_esp32_kind = esp32
platform = platform = platformio/espressif32@6.10.0
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
platformio/espressif32@6.10.0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
@@ -46,20 +44,13 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
https://github.com/meshtastic/esp32_https_server/archive/896f1771ceb5979987a0b41028bf1b4e7aad419b.zip
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
h2zero/NimBLE-Arduino@^1.4.3 h2zero/NimBLE-Arduino@^1.4.3
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
lewisxhe/XPowersLib@^0.2.7 lewisxhe/XPowersLib@^0.2.7
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip rweather/Crypto@^0.4.0
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
rweather/Crypto@0.4.0
lib_ignore = lib_ignore =
segger_rtt segger_rtt

View File

@@ -1,8 +1,6 @@
[esp32c6_base] [esp32c6_base]
extends = esp32_base extends = esp32_base
platform = platform = https://github.com/Jason2866/platform-espressif32.git#22faa566df8c789000f8136cd8d0aca49617af55
# Do not renovate until we have switched to pioarduino tagged builds
https://github.com/Jason2866/platform-espressif32/archive/22faa566df8c789000f8136cd8d0aca49617af55.zip
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
-Wall -Wall
@@ -25,14 +23,10 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
lewisxhe/XPowersLib@^0.2.7 lewisxhe/XPowersLib@^0.2.7
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip rweather/Crypto@^0.4.0
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
rweather/Crypto@0.4.0
build_src_filter = build_src_filter =
${esp32_base.build_src_filter} -<mesh/http> ${esp32_base.build_src_filter} -<mesh/http>

View File

@@ -16,4 +16,4 @@ build_flags =
lib_ignore = lib_ignore =
${esp32_base.lib_ignore} ${esp32_base.lib_ignore}
NimBLE-Arduino NimBLE-Arduino
libpax libpax

View File

@@ -3,3 +3,4 @@ extends = esp32_base
custom_esp32_kind = esp32s3 custom_esp32_kind = esp32s3
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -1,14 +1,10 @@
[nrf52_base] [nrf52_base]
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files ; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
platform = platform = platformio/nordicnrf52@^10.7.0
# renovate: datasource=custom.pio depName=platformio/nordicnrf52 packageName=platformio/platform/nordicnrf52
platformio/nordicnrf52@^10.8.0
extends = arduino_base extends = arduino_base
platform_packages = platform_packages =
; our custom Git version until they merge our PR ; our custom Git version until they merge our PR
# TODO renovate platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#e13f5820002a4fb2a5e6754b42ace185277e5adf
; Don't renovate toolchain-gccarmnoneeabi
platformio/toolchain-gccarmnoneeabi@~1.90301.0 platformio/toolchain-gccarmnoneeabi@~1.90301.0
build_type = debug build_type = debug
@@ -21,6 +17,7 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1 -DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1 -DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMAX_NUM_NODES=80
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
@@ -28,9 +25,8 @@ build_src_filter =
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto rweather/Crypto@^0.4.0
rweather/Crypto@0.4.0
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lvgl lvgl

View File

@@ -6,9 +6,7 @@ build_flags = ${nrf52_base.build_flags}
lib_deps = lib_deps =
${nrf52_base.lib_deps} ${nrf52_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps} https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
# renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/5f838d2709461a2c981f642917aa50254a25c14c.zip
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board. ; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.

View File

@@ -1,8 +1,6 @@
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated). ; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
[portduino_base] [portduino_base]
platform = platform = https://github.com/Jorropo/platform-native.git#17fa89daec4402af491512f75278a7fec8a5818c
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
https://github.com/meshtastic/platform-native/archive/622341c6de8a239704318b10c3dbb00c21a3eab3.zip
framework = arduino framework = arduino
build_src_filter = build_src_filter =
@@ -17,19 +15,18 @@ build_src_filter =
+<mesh/raspihttp/> +<mesh/raspihttp/>
-<mesh/eth/> -<mesh/eth/>
-<modules/esp32> -<modules/esp32>
-<modules/Telemetry/EnvironmentTelemetry.cpp>
-<modules/Telemetry/AirQualityTelemetry.cpp>
-<modules/Telemetry/Sensor>
+<../variants/portduino> +<../variants/portduino>
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
${environmental_base.lib_deps} rweather/Crypto@^0.4.0
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
rweather/Crypto@0.4.0
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@^1.2.0
# renovate: datasource=git-refs depName=libch341-spi-userspace packageName=https://github.com/pine64/libch341-spi-userspace gitBranch=main https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
@@ -45,7 +42,4 @@ build_flags =
-lyaml-cpp -lyaml-cpp
-li2c -li2c
-luv -luv
-std=gnu17
-std=c++17 -std=c++17
lib_ignore = Adafruit NeoPixel

View File

@@ -1,13 +1,8 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2040_base] [rp2040_base]
platform = platform = https://github.com/maxgerhardt/platform-raspberrypi.git#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
# TODO renovate
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
; For arduino-pico >= 4.4.3
extends = arduino_base extends = arduino_base
platform_packages = platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.4.3
# TODO renovate
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -28,7 +23,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto rweather/Crypto
rweather/Crypto@0.4.0

View File

@@ -1,13 +1,8 @@
; Common settings for rp2350 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2350_base] [rp2350_base]
platform = platform = https://github.com/maxgerhardt/platform-raspberrypi.git#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
# TODO renovate
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
; For arduino-pico >= 4.4.3
extends = arduino_base extends = arduino_base
platform_packages = platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.4.3
# TODO renovate
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -25,7 +20,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto rweather/Crypto
rweather/Crypto@0.4.0

View File

@@ -1,18 +1,13 @@
[stm32_base] [stm32_base]
extends = arduino_base extends = arduino_base
platform = platform = platformio/ststm32
# renovate: datasource=custom.pio depName=platformio/ststm32 packageName=platformio/platform/ststm32 platform_packages = platformio/framework-arduinoststm32@^4.20900.0
platformio/ststm32@19.1.0
platform_packages =
# TODO renovate
platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip
extra_scripts =
${env.extra_scripts}
post:extra_scripts/extra_stm32.py
build_type = release build_type = release
build_flags = ;board_build.flash_offset = 0x08000000
build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
-flto -flto
-Isrc/platform/stm32wl -g -Isrc/platform/stm32wl -g
@@ -23,25 +18,27 @@ build_flags =
-DMESHTASTIC_EXCLUDE_SCREEN -DMESHTASTIC_EXCLUDE_SCREEN
-DMESHTASTIC_EXCLUDE_MQTT -DMESHTASTIC_EXCLUDE_MQTT
-DMESHTASTIC_EXCLUDE_BLUETOOTH -DMESHTASTIC_EXCLUDE_BLUETOOTH
-DMESHTASTIC_EXCLUDE_PKI
-DMESHTASTIC_EXCLUDE_GPS -DMESHTASTIC_EXCLUDE_GPS
;-DDEBUG_MUTE ; -DVECT_TAB_OFFSET=0x08000000
-DconfigUSE_CMSIS_RTOS_V2=1
; -DSPI_MODE_0=SPI_MODE0
-fmerge-all-constants -fmerge-all-constants
-ffunction-sections -ffunction-sections
-fdata-sections -fdata-sections
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
board_upload.offset_address = 0x08000000 board_upload.offset_address = 0x08000000
upload_protocol = stlink upload_protocol = stlink
debug_tool = stlink
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
${radiolib_base.lib_deps} charlesbaynham/OSFS@^1.2.3
# renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main jgromes/RadioLib@7.0.2
https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
lib_ignore = lib_ignore =
mathertel/OneButton@2.6.1 mathertel/OneButton@2.6.1
Wire Wire

View File

@@ -1,7 +0,0 @@
# Set spidev ownership to 'spi' group
SUBSYSTEM=="spidev", KERNEL=="spidev*", GROUP="spi", MODE="0660"
# Allow access to USB CH341 devices
SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512", MODE="0666"
# Set gpio ownership to 'gpio' group
SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"

View File

@@ -15,7 +15,6 @@ platformioFailed() {
VERSION=$(bin/buildinfo.py long) VERSION=$(bin/buildinfo.py long)
SHORT_VERSION=$(bin/buildinfo.py short) SHORT_VERSION=$(bin/buildinfo.py short)
PIO_ENV=${1:-native}
OUTDIR=release/ OUTDIR=release/
@@ -25,7 +24,7 @@ mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale # Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
pio pkg update --environment "$PIO_ENV" || platformioFailed pio pkg update --environment native || platformioFailed
pio run --environment "$PIO_ENV" || platformioFailed pio run --environment native || platformioFailed
cp ".pio/build/$PIO_ENV/program" "$OUTDIR/meshtasticd_linux_$(uname -m)" cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
cp bin/native-install.* $OUTDIR cp bin/native-install.* $OUTDIR

View File

@@ -1,72 +0,0 @@
#!/usr/bin/env python3
import argparse
import xml.etree.ElementTree as ET
from defusedxml.ElementTree import parse
from datetime import datetime, timezone
# Indent by 2 spaces to align with xml formatting.
def indent(elem, level=0):
i = "\n" + level * " "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
for child in elem:
indent(child, level + 1)
if not child.tail or not child.tail.strip():
child.tail = i
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
def main():
parser = argparse.ArgumentParser(
description="Prepend new release entry to metainfo.xml file.")
parser.add_argument("--file", help="Path to the metainfo.xml file",
default="org.meshtastic.meshtasticd.metainfo.xml")
parser.add_argument("version", help="Version string (e.g. 2.6.4)")
parser.add_argument("--date", help="Release date (YYYY-MM-DD), defaults to today",
default=datetime.now(timezone.utc).date().isoformat())
args = parser.parse_args()
tree = parse(args.file)
root = tree.getroot()
releases = root.find('releases')
if releases is None:
raise RuntimeError("<releases> element not found in XML.")
existing_versions = {
release.get('version'): release
for release in releases.findall('release')
}
existing_release = existing_versions.get(args.version)
if existing_release is not None:
if not existing_release.get('date'):
print(f"Version {args.version} found without date. Adding date...")
existing_release.set('date', args.date)
else:
print(
f"Version {args.version} is already present with date, skipping insertion.")
else:
new_release = ET.Element('release', {
'version': args.version,
'date': args.date
})
url = ET.SubElement(new_release, 'url', {'type': 'details'})
url.text = f"https://github.com/meshtastic/firmware/releases?q=tag%3Av{args.version}"
releases.insert(0, new_release)
indent(releases, level=1)
releases.tail = "\n"
print(f"Inserted new release: {args.version}")
tree.write(args.file, encoding='UTF-8', xml_declaration=True)
if __name__ == "__main__":
main()

View File

@@ -1 +0,0 @@
defusedxml==0.7.1

View File

@@ -6,12 +6,6 @@
### Including the "Module:" line! ### Including the "Module:" line!
--- ---
Lora: Lora:
# Default to auto-detecting the module type
# This will be overridden by configs from config.d
Module: auto
# # Uncomment to enable Simulation mode, or use --sim
# Module: sim
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME! # Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
# CS: 7 # CS: 7
@@ -188,22 +182,14 @@ Logging:
# AsciiLogs: true # default if not specified is !isatty() on stdout # AsciiLogs: true # default if not specified is !isatty() on stdout
Webserver: Webserver:
# Port: 9443 # Port for Webserver & Webservices # Port: 443 # Port for Webserver & Webservices
# RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer # RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer
# SSLKey: /etc/meshtasticd/ssl/private_key.pem # Path to SSL Key, generated if not present # SSLKey: /etc/meshtasticd/ssl/private_key.pem # Path to SSL Key, generated if not present
# SSLCert: /etc/meshtasticd/ssl/certificate.pem # Path to SSL Certificate, generated if not present # SSLCert: /etc/meshtasticd/ssl/certificate.pem # Path to SSL Certificate, generated if not present
HostMetrics:
# ReportInterval: 30 # Interval in minutes between HostMetrics report packets, or 0 for disabled
# Channel: 0 # channel to send Host Metrics over. Defaults to the primary channel.
# UserStringCommand: cat /sys/firmware/devicetree/base/serial-number # Command to execute, to send the results as the userString
General: General:
MaxNodes: 200 MaxNodes: 200
MaxMessageQueue: 100 MaxMessageQueue: 100
ConfigDirectory: /etc/meshtasticd/config.d/ ConfigDirectory: /etc/meshtasticd/config.d/
AvailableDirectory: /etc/meshtasticd/available.d/
# MACAddress: AA:BB:CC:DD:EE:FF # MACAddress: AA:BB:CC:DD:EE:FF
# MACAddressSource: eth0 # MACAddressSource: eth0

View File

@@ -0,0 +1,5 @@
# Module: RF95 # Adafruit RFM9x
# Reset: 25
# CS: 7
# IRQ: 22
# Busy: 23

View File

@@ -1,6 +0,0 @@
Lora:
Module: RF95 # Adafruit RFM9x
Reset: 25
CS: 7
IRQ: 22
# Busy: 23

View File

@@ -1,5 +1,3 @@
# MeshAdv-Pi E22-900M30S
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 21 CS: 21
@@ -11,4 +9,4 @@ Lora:
DIO3_TCXO_VOLTAGE: true DIO3_TCXO_VOLTAGE: true
# Only for E22-900M33S: # Only for E22-900M33S:
# Limit the output power to 8 dBm # Limit the output power to 8 dBm
# SX126X_MAX_POWER: 8 # SX126X_MAX_POWER: 8

View File

@@ -1,11 +0,0 @@
# MeshAdv Mini E22-900M22S
# https://github.com/chrismyers2000/MeshAdv-Mini
Lora:
Module: sx1262 # Ebyte E22-900M22S
CS: 8
IRQ: 16
Busy: 20
Reset: 24
TXen: 13
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true

View File

@@ -1,11 +0,0 @@
Lora:
Module: lr1121
CS: 0
IRQ: 6
Reset: 2
Busy: 4
spidev: ch341
DIO3_TCXO_VOLTAGE: 1.8
# USB_Serialnum: 12345678
USB_PID: 0x5512
USB_VID: 0x1A86

View File

@@ -1,17 +0,0 @@
Lora:
Module: sx1262
CS: 0
IRQ: 6
Reset: 2
Busy: 4
RXen: 1
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: ch341
USB_PID: 0x5512
USB_VID: 0x1A86
# Optional: Reduce power to 10 dBm to
# avoid over-drawing the USB port
# SX126X_MAX_POWER: 10
# Optional: Set the serial number for multi-radio support
# USB_Serialnum: 13374201

View File

@@ -7,19 +7,12 @@ SET "DEBUG=0"
SET "PYTHON=" SET "PYTHON="
SET "WEB_APP=0" SET "WEB_APP=0"
SET "TFT_BUILD=0" SET "TFT_BUILD=0"
SET "BIGDB8=0" SET "TFT8=0"
SET "BIGDB16=0" SET "TFT16=0"
SET "ESPTOOL_BAUD=115200" SET "ESPTOOL_BAUD=115200"
SET "ESPTOOL_CMD=" SET "ESPTOOL_CMD="
SET "LOGCOUNTER=0" SET "LOGCOUNTER=0"
@REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
SET "C3=esp32c3"
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
SET "BIGDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger"
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite t-watch-s3"
GOTO getopts GOTO getopts
:help :help
ECHO Flash image file to device, but first erasing and writing system information. ECHO Flash image file to device, but first erasing and writing system information.
@@ -41,7 +34,7 @@ ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.bin -p COM11 --web
GOTO eof GOTO eof
:version :version
ECHO %SCRIPT_NAME% [Version 2.6.1] ECHO %SCRIPT_NAME% [Version 2.6.0]
ECHO Meshtastic ECHO Meshtastic
GOTO eof GOTO eof
@@ -113,7 +106,7 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..." CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1 !ESPTOOL_CMD! >nul 2>&1
IF %ERRORLEVEL% GEQ 2 ( IF %ERRORLEVEL% GTR 2 (
@REM esptool exits with code 1 if help is displayed. @REM esptool exits with code 1 if help is displayed.
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!" CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1 EXIT /B 1
@@ -128,7 +121,6 @@ CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
IF "__!ESPTOOL_PORT!__" == "____" ( IF "__!ESPTOOL_PORT!__" == "____" (
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET." CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
) ELSE ( ) ELSE (
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!." CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
) )
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!." CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
@@ -141,36 +133,44 @@ IF NOT "!FILENAME:-tft-=!"=="!FILENAME!" (
CALL :LOG_MESSAGE ERROR "Cannot enable WebUI (--web) and MUI." & GOTO eof CALL :LOG_MESSAGE ERROR "Cannot enable WebUI (--web) and MUI." & GOTO eof
) )
SET "TFT_BUILD=1" SET "TFT_BUILD=1"
GOTO tft
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!" CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!"
GOTO no_tft
) )
FOR %%a IN (%BIGDB_8MB%) DO ( :tft
SET "TFT8MB=picomputer-s3 unphone seeed-sensecap-indicator"
FOR %%a IN (%TFT8MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" ( IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %BIGDB_8MB%. @REM We are working with any of %TFT8MB%.
SET "BIGDB8=1" SET "TFT8=1"
GOTO end_loop_bigdb_8mb GOTO end_loop_tft8mb
) )
) )
:end_loop_bigdb_8mb :end_loop_tft8mb
FOR %%a IN (%BIGDB_16MB%) DO ( SET "TFT16MB=t-deck"
FOR %%a IN (%TFT16MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" ( IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %BIGDB_16MB%. @REM We are working with any of %TFT16MB%.
SET "BIGDB16=1" SET "TFT16=1"
GOTO end_loop_bigdb_16mb GOTO end_loop_tft16mb
) )
) )
:end_loop_bigdb_16mb :end_loop_tft16mb
IF %BIGDB8% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 8mb partition selected." IF %TFT8% EQU 1 CALL :LOG_MESSAGE INFO "tft and MUI 8mb selected."
IF %BIGDB16% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 16mb partition selected." IF %TFT16% EQU 1 CALL :LOG_MESSAGE INFO "tft and MUI 16mb selected."
:no_tft
@REM Extract BASENAME from %FILENAME% for later use. @REM Extract BASENAME from %FILENAME% for later use.
SET "BASENAME=!FILENAME:firmware-=!" SET "BASENAME=!FILENAME:firmware-=!"
CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!" CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!"
@REM Account for S3 and C3 board's different OTA partition. @REM Account for S3 and C3 board's different OTA partition.
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
FOR %%a IN (%S3%) DO ( FOR %%a IN (%S3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" ( IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %S3%. @REM We are working with any of %S3%.
@@ -179,6 +179,7 @@ FOR %%a IN (%S3%) DO (
) )
) )
SET "C3=esp32c3"
FOR %%a IN (%C3%) DO ( FOR %%a IN (%C3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" ( IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %C3%. @REM We are working with any of %C3%.
@@ -207,14 +208,14 @@ CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
SET "OTA_OFFSET=0x260000" SET "OTA_OFFSET=0x260000"
SET "SPIFFS_OFFSET=0x300000" SET "SPIFFS_OFFSET=0x300000"
@REM Offsets for BigDB 8mb. @REM Offsets for MUI 8mb.
IF %BIGDB8% EQU 1 ( IF %TFT8% EQU 1 IF %TFT_BUILD% EQU 1 (
SET "OTA_OFFSET=0x340000" SET "OTA_OFFSET=0x340000"
SET "SPIFFS_OFFSET=0x670000" SET "SPIFFS_OFFSET=0x670000"
) )
@REM Offsets for BigDB 16mb. @REM Offsets for MUI 16mb.
IF %BIGDB16% EQU 1 ( IF %TFT16% EQU 1 IF %TFT_BUILD% EQU 1 (
SET "OTA_OFFSET=0x650000" SET "OTA_OFFSET=0x650000"
SET "SPIFFS_OFFSET=0xc90000" SET "SPIFFS_OFFSET=0xc90000"
) )

View File

@@ -2,58 +2,9 @@
PYTHON=${PYTHON:-$(which python3 python | head -n 1)} PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
WEB_APP=false WEB_APP=false
TFT8=false
TFT16=false
TFT_BUILD=false TFT_BUILD=false
MCU=""
# Variant groups
BIGDB_8MB=(
"picomputer-s3"
"unphone"
"seeed-sensecap-indicator"
"crowpanel-esp32s3"
"heltec_capsule_sensor_v3"
"heltec-v3"
"heltec-vision-master-e213"
"heltec-vision-master-e290"
"heltec-vision-master-t190"
"heltec-wireless-paper"
"heltec-wireless-tracker"
"heltec-wsl-v3"
"icarus"
"seeed-xiao-s3"
"tbeam-s3-core"
"tracksenger"
)
BIGDB_16MB=(
"t-deck"
"mesh-tab"
"t-energy-s3"
"dreamcatcher"
"ESP32-S3-Pico"
"m5stack-cores3"
"station-g2"
"t-eth-elite"
"t-watch-s3"
)
S3_VARIANTS=(
"s3"
"-v3"
"t-deck"
"wireless-paper"
"wireless-tracker"
"station-g2"
"unphone"
"t-eth-elite"
"mesh-tab"
"dreamcatcher"
"ESP32-S3-Pico"
"seeed-sensecap-indicator"
"heltec_capsule_sensor_v3"
"vision-master"
"icarus"
"tracksenger"
"elecrow-adv"
)
# Determine the correct esptool command to use # Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then if "$PYTHON" -m esptool version >/dev/null 2>&1; then
@@ -91,8 +42,8 @@ while [ $# -gt 0 ]; do
exit 0 exit 0
;; ;;
-p) -p)
ESPTOOL_CMD="$ESPTOOL_CMD --port $2" ESPTOOL_PORT="$2"
shift shift # Shift past the option argument
;; ;;
-P) -P)
PYTHON="$2" PYTHON="$2"
@@ -127,13 +78,21 @@ if [[ $FILENAME != firmware-* ]]; then
exit 1 exit 1
fi fi
# Check if FILENAME contains "-tft-" and prevent web/mui comingling. # Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
if [[ ${FILENAME//-tft-/} != "$FILENAME" ]]; then if [[ ${FILENAME//-tft-/} != "$FILENAME" ]]; then
TFT_BUILD=true TFT_BUILD=true
if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then
echo "Cannot enable WebUI (--web) and MUI." echo "Cannot enable WebUI (--web) and MUI."
exit 1 exit 1
fi fi
if [[ $FILENAME == *"picomputer-s3"* || $FILENAME == *"unphone"* || $FILENAME == *"seeed-sensecap-indicator"* ]]; then
TFT8=true
fi
if [[ $FILENAME == *"t-deck"* ]]; then
TFT16=true
fi
fi fi
# Extract BASENAME from %FILENAME% for later use. # Extract BASENAME from %FILENAME% for later use.
@@ -146,31 +105,20 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
# Default OTA Offset # Default OTA Offset
OTA_OFFSET=0x260000 OTA_OFFSET=0x260000
# littlefs* offset for BigDB 8mb and OTA OFFSET. # littlefs* offset for MUI 8mb and OTA OFFSET.
for variant in "${BIGDB_8MB[@]}"; do if [ "$TFT8" = true ] && [ "$TFT_BUILD" = true ]; then
if [ -z "${FILENAME##*"$variant"*}" ]; then OFFSET=0x670000
OFFSET=0x670000 OTA_OFFSET=0x340000
OTA_OFFSET=0x340000 fi
fi
done
# littlefs* offset for BigDB 16mb and OTA OFFSET. # littlefs* offset for MUI 16mb and OTA OFFSET.
for variant in "${BIGDB_16MB[@]}"; do if [ "$TFT16" = true ] && [ "$TFT_BUILD" = true ]; then
if [ -z "${FILENAME##*"$variant"*}" ]; then OFFSET=0xc90000
OFFSET=0xc90000 OTA_OFFSET=0x650000
OTA_OFFSET=0x650000 fi
fi
done
# Account for S3 board's different OTA partition # Account for S3 board's different OTA partition
# FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
for variant in "${S3_VARIANTS[@]}"; do
if [ -z "${FILENAME##*"$variant"*}" ]; then
MCU="esp32s3"
fi
done
if [ "$MCU" != "esp32s3" ]; then
if [ -n "${FILENAME##*"esp32c3"*}" ]; then if [ -n "${FILENAME##*"esp32c3"*}" ]; then
OTAFILE=bleota.bin OTAFILE=bleota.bin
else else

View File

@@ -16,7 +16,7 @@ ECHO.
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python]
ECHO. ECHO.
ECHO Options: ECHO Options:
ECHO -f filename The update .bin file to flash. Custom to your device type and region. (required) ECHO -f filename The .bin file to flash. Custom to your device type and region. (required)
ECHO The file must be located in this current directory. ECHO The file must be located in this current directory.
ECHO -p PORT Set the environment variable for ESPTOOL_PORT. ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
ECHO If not set, ESPTOOL iterates all ports (Dangerous). ECHO If not set, ESPTOOL iterates all ports (Dangerous).
@@ -28,7 +28,7 @@ ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4-update.bin -p C
GOTO eof GOTO eof
:version :version
ECHO %SCRIPT_NAME% [Version 2.6.1] ECHO %SCRIPT_NAME% [Version 2.6.0]
ECHO Meshtastic ECHO Meshtastic
GOTO eof GOTO eof
@@ -53,7 +53,6 @@ IF "__!FILENAME!__"=="____" (
CALL :LOG_MESSAGE DEBUG "Missing -f filename input." CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
GOTO help GOTO help
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" ( IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported." CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
GOTO help GOTO help
@@ -63,6 +62,7 @@ IF "__!FILENAME!__"=="____" (
SET "FILENAME=!FILENAME:./=!" SET "FILENAME=!FILENAME:./=!"
) )
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..." CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
IF NOT EXIST !FILENAME! ( IF NOT EXIST !FILENAME! (
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating." CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
@@ -71,7 +71,7 @@ IF NOT EXIST !FILENAME! (
IF "!FILENAME:update=!"=="!FILENAME!" ( IF "!FILENAME:update=!"=="!FILENAME!" (
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!" CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!." CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash update !FILENAME!."
GOTO eof GOTO eof
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!" CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
@@ -95,7 +95,7 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..." CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1 !ESPTOOL_CMD! >nul 2>&1
IF %ERRORLEVEL% GEQ 2 ( IF %ERRORLEVEL% GTR 2 (
@REM esptool exits with code 1 if help is displayed. @REM esptool exits with code 1 if help is displayed.
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!" CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1 EXIT /B 1
@@ -110,7 +110,6 @@ CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
IF "__!ESPTOOL_PORT!__" == "____" ( IF "__!ESPTOOL_PORT!__" == "____" (
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET." CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
) ELSE ( ) ELSE (
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!." CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
) )
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!." CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."

View File

@@ -35,8 +35,8 @@ while getopts ":hp:P:f:" opt; do
show_help show_help
exit 0 exit 0
;; ;;
p) ESPTOOL_CMD="$ESPTOOL_CMD --port ${OPTARG}" p) export ESPTOOL_PORT=${OPTARG}
;; ;;
P) PYTHON=${OPTARG} P) PYTHON=${OPTARG}
;; ;;
f) FILENAME=${OPTARG} f) FILENAME=${OPTARG}

View File

@@ -5,11 +5,10 @@ StartLimitInterval=200
StartLimitBurst=5 StartLimitBurst=5
[Service] [Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE User=root
User=meshtasticd Group=root
Group=meshtasticd
Type=simple Type=simple
ExecStart=/usr/bin/meshtasticd ExecStart=/usr/sbin/meshtasticd
Restart=always Restart=always
RestartSec=3 RestartSec=3

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cp "release/meshtasticd_linux_$(uname -m)" /usr/bin/meshtasticd cp "release/meshtasticd_linux_$(uname -m)" /usr/sbin/meshtasticd
mkdir -p /etc/meshtasticd mkdir -p /etc/meshtasticd
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml

View File

@@ -1,8 +0,0 @@
[Desktop Entry]
Name=Meshtastic
Comment=Meshtastic App
Exec=meshtasticd
Icon=org.meshtastic.meshtasticd
Terminal=true
Type=Application
Categories=Network;Chat;HamRadio;

View File

@@ -1,112 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<component type="desktop-application">
<id>org.meshtastic.meshtasticd</id>
<name>Meshtastic</name>
<summary>Decentralized mesh communication</summary>
<metadata_license>CC-BY-4.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<developer id="org.meshtastic">
<name>Meshtastic</name>
</developer>
<description>
<p>
Meshtastic is an open source project for creating off-grid, affordable, and resilient communication with LoRa mesh networks.
</p>
</description>
<launchable type="desktop-id">org.meshtastic.meshtasticd.desktop</launchable>
<categories>
<category>Network</category>
<category>Chat</category>
<category>HamRadio</category>
</categories>
<keywords>
<keyword>mesh</keyword>
<keyword>LoRa</keyword>
</keywords>
<recommends>
<control>keyboard</control>
<control>pointing</control>
<control>touch</control>
</recommends>
<requires>
<display_length compare="ge">360</display_length>
</requires>
<branding>
<color type="primary" scheme_preference="light">#97be89</color>
<color type="primary" scheme_preference="dark">#206538</color>
</branding>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-location">intense</content_attribute>
</content_rating>
<url type="bugtracker">https://github.com/meshtastic/firmware/issues</url>
<url type="homepage">https://meshtastic.org/</url>
<url type="donation">https://opencollective.com/meshtastic</url>
<url type="faq">https://meshtastic.org/docs/software/linux/usage/</url>
<url type="vcs-browser">https://github.com/meshtastic/firmware/</url>
<screenshots>
<screenshot type="default">
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_home_dashboard_dark.webp</image>
<caption>Home Dashboard</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_initial_boot.webp</image>
<caption>Setup</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_node_list_dark.webp</image>
<caption>Nodes List</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_chat_list_dark.webp</image>
<caption>Chats List</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_chat_message_dark.webp</image>
<caption>Messages</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_map_dark.webp</image>
<caption>Map</caption>
</screenshot>
<screenshot>
<image>https://meshtastic.org/img/software/meshtastic-ui/mui_settings_dark.webp</image>
<caption>Settings</caption>
</screenshot>
</screenshots>
<releases>
<release version="2.6.10" date="2025-05-25">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.10</url>
</release>
<release version="2.6.9" date="2025-05-15">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.9</url>
</release>
<release version="2.6.8" date="2025-05-05">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.8</url>
</release>
<release version="2.6.7" date="2025-04-28">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.7</url>
</release>
<release version="2.6.6" date="2025-04-15">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.6</url>
</release>
<release version="2.6.5" date="2025-03-30">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.5</url>
</release>
<release version="2.6.4" date="2025-03-28">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.6.4</url>
</release>
</releases>
</component>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="512" height="512" viewBox="0 0 512 512" xml:space="preserve">
<desc>Created with Fabric.js 4.6.0</desc>
<defs>
</defs>
<g transform="matrix(1 0 0 1 256 256)" id="xYQ9Gk9Jwpgj_HMOXB3F_" >
<path style="stroke: rgb(213,130,139); stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(103,234,148); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-256, -256)" d="M 0 0 L 512 0 L 512 512 L 0 512 z" stroke-linecap="round" />
</g>
<g transform="matrix(1.79 0 0 1.79 313.74 258.36)" id="1xBsk2n9FZp60Rz1O-ceJ" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: round; stroke-miterlimit: 2; fill: rgb(44,45,60); fill-rule: evenodd; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-250.97, -362.41)" d="M 250.908 330.267 L 193.126 415.005 L 180.938 406.694 L 244.802 313.037 C 246.174 311.024 248.453 309.819 250.889 309.816 C 253.326 309.814 255.606 311.015 256.982 313.026 L 320.994 406.536 L 308.821 414.869 L 250.908 330.267 Z" stroke-linecap="round" />
</g>
<g transform="matrix(1.81 0 0 1.81 145 256.15)" id="KxN7E9YpbyPgz0S4z4Cl6" >
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: round; stroke-miterlimit: 2; fill: rgb(44,45,60); fill-rule: evenodd; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-115.14, -528.06)" d="M 87.642 581.398 L 154.757 482.977 L 142.638 474.713 L 75.523 573.134 L 87.642 581.398 Z" stroke-linecap="round" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -83,7 +83,7 @@ if platform.name == "espressif32":
if platform.name == "nordicnrf52": if platform.name == "nordicnrf52":
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex", env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2", env.VerboseAction(f"{sys.executable} ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
"Generating UF2 file")) "Generating UF2 file"))
Import("projenv") Import("projenv")

View File

@@ -2,10 +2,6 @@ function meshtastic_version {
meshtastic_version=$(python3 bin/buildinfo.py short) meshtastic_version=$(python3 bin/buildinfo.py short)
echo -n "$meshtastic_version" echo -n "$meshtastic_version"
} }
function web_version {
web_version=$(cat bin/web.version)
echo -n "$web_version"
}
function git_commits_num { function git_commits_num {
total_commits=$(git rev-list --all --count) total_commits=$(git rev-list --all --count)
echo -n "$total_commits" echo -n "$total_commits"

View File

@@ -1 +0,0 @@
2.5.3

View File

@@ -1,53 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"]
],
"usb_product": "elecrow_eink",
"mcu": "nrf52840",
"variant": "ELECROW-ThinkNode-M1",
"variants_dir": "variants",
"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",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "elecrow eink",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "FIXME",
"vendor": "ELECROW"
}

View File

@@ -1,43 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=0",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "ESP32-S3-WROOM-1-N16R8"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "ESP32-S3-WROOM-1-N16R8 (16 MB Flash, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 524288,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"monitor": {
"speed": 115200
},
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf",
"vendor": "Espressif"
}

View File

@@ -1,53 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"]
],
"usb_product": "HT-n5262",
"mcu": "nrf52840",
"variant": "heltec_mesh_pocket",
"variants_dir": "variants",
"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",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "Heltec nrf (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://heltec.org/project/meshpocket/",
"vendor": "Heltec"
}

View File

@@ -2,8 +2,7 @@
"build": { "build": {
"arduino": { "arduino": {
"ldscript": "esp32s3_out.ld", "ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv", "partitions": "default_8MB.csv"
"memory_type": "qio_opi"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": [ "extra_flags": [
@@ -16,7 +15,6 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [ "hwids": [
["0x303A", "0x1001"], ["0x303A", "0x1001"],
["0x303A", "0x0002"] ["0x303A", "0x0002"]

View File

@@ -2,8 +2,7 @@
"build": { "build": {
"arduino": { "arduino": {
"ldscript": "esp32s3_out.ld", "ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv", "partitions": "default_8MB.csv"
"memory_type": "qio_opi"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": [ "extra_flags": [
@@ -16,7 +15,6 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [ "hwids": [
["0x303A", "0x1001"], ["0x303A", "0x1001"],
["0x303A", "0x0002"] ["0x303A", "0x0002"]

View File

@@ -2,8 +2,7 @@
"build": { "build": {
"arduino": { "arduino": {
"ldscript": "esp32s3_out.ld", "ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv", "partitions": "default_8MB.csv"
"memory_type": "qio_opi"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": [ "extra_flags": [
@@ -16,7 +15,6 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [ "hwids": [
["0x303A", "0x1001"], ["0x303A", "0x1001"],
["0x303A", "0x0002"] ["0x303A", "0x0002"]

View File

@@ -18,7 +18,6 @@
"f_boot": "120000000L", "f_boot": "120000000L",
"boot": "qio", "boot": "qio",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [["0x1A86", "0x7523"]], "hwids": [["0x1A86", "0x7523"]],
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "esp32s3" "variant": "esp32s3"

View File

@@ -15,7 +15,6 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [["0x2886", "0x0059"]], "hwids": [["0x2886", "0x0059"]],
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "seeed-xiao-s3" "variant": "seeed-xiao-s3"

View File

@@ -1,54 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x2886", "0x0059"]],
"usb_product": "XIAO-BOOT",
"mcu": "nrf52840",
"variant": "seeed_solar_node",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "7.3.0",
"sd_fwid": "0x0123"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "seeed_solar_node",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink",
"cmsis-dap",
"blackmagic"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.seeedstudio.com/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html",
"vendor": "Seeed Studio"
}

View File

@@ -1,54 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x2886", "0x1668"]],
"usb_product": "TRACKER L1",
"mcu": "nrf52840",
"variant": "seeed_wio_tracker_L1",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "7.3.0",
"sd_fwid": "0x0123"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "seeed_wio_tracker_L1",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink",
"cmsis-dap",
"blackmagic"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.seeedstudio.com/Wio-Tracker-L1-p-6477.html",
"vendor": "Seeed Studio"
}

View File

@@ -16,7 +16,6 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "qio", "flash_mode": "qio",
"psram_type": "opi",
"hwids": [ "hwids": [
["0x303A", "0x1001"], ["0x303A", "0x1001"],
["0x303A", "0x0002"] ["0x303A", "0x0002"]
@@ -24,16 +23,16 @@
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "t-watch-s3" "variant": "t-watch-s3"
}, },
"connectivity": ["wifi", "bluetooth", "lora"], "connectivity": ["wifi"],
"debug": { "debug": {
"openocd_target": "esp32s3.cfg" "openocd_target": "esp32s3.cfg"
}, },
"frameworks": ["arduino"], "frameworks": ["arduino"],
"name": "LilyGo T-Watch 2020 V3", "name": "LilyGo T-Watch 2020 V3",
"upload": { "upload": {
"flash_size": "16MB", "flash_size": "8MB",
"maximum_ram_size": 327680, "maximum_ram_size": 327680,
"maximum_size": 16777216, "maximum_size": 8388608,
"require_upload_port": true, "require_upload_port": true,
"use_1200bps_touch": true, "use_1200bps_touch": true,
"wait_for_upload_port": true, "wait_for_upload_port": true,

14
debian/changelog vendored
View File

@@ -1,19 +1,9 @@
meshtasticd (2.6.10.0) UNRELEASED; urgency=medium meshtasticd (2.5.22.0) UNRELEASED; urgency=medium
[ Austin Lane ]
* Initial packaging * Initial packaging
* GitHub Actions Automatic version bump * GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump * GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump * GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump * GitHub Actions Automatic version bump
[ ] -- Austin Lane <github-actions[bot]@users.noreply.github.com> Wed, 05 Feb 2025 01:10:33 +0000
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
-- <github-actions[bot]@users.noreply.github.com> Sun, 25 May 2025 20:46:49 +0000

View File

@@ -5,14 +5,13 @@ export PLATFORMIO_PACKAGES_DIR=pio/packages
export PLATFORMIO_CORE_DIR=pio/core export PLATFORMIO_CORE_DIR=pio/core
# Download libraries to `pio` # Download libraries to `pio`
platformio pkg install -e native-tft platformio pkg install -e native
platformio pkg install -e native-tft -t platformio/tool-scons@4.40502.0 platformio pkg install -e native -t platformio/tool-scons@4.40502.0
# Compress `pio` directory to prevent dh_clean from sanitizing it # Compress `pio` directory to prevent dh_clean from sanitizing it
tar -cf pio.tar pio/ tar -cf pio.tar pio/
rm -rf pio rm -rf pio
# Download the meshtastic/web release build.tar to `web.tar` # Download the latest meshtastic/web release build.tar to `web.tar`
web_ver=$(cat bin/web.version) curl -L https://github.com/meshtastic/web/releases/latest/download/build.tar -o web.tar
curl -L "https://github.com/meshtastic/web/releases/download/v$web_ver/build.tar" -o web.tar
package=$(dpkg-parsechangelog --show-field Source) package=$(dpkg-parsechangelog --show-field Source)

11
debian/control vendored
View File

@@ -21,19 +21,14 @@ Build-Depends: debhelper-compat (= 13),
openssl, openssl,
libssl-dev, libssl-dev,
libulfius-dev, libulfius-dev,
liborcania-dev, liborcania-dev
libx11-dev,
libinput-dev,
libxkbcommon-x11-dev
Standards-Version: 4.6.2 Standards-Version: 4.6.2
Homepage: https://github.com/meshtastic/firmware Homepage: https://github.com/meshtastic/firmware
Rules-Requires-Root: no Rules-Requires-Root: no
Package: meshtasticd Package: meshtasticd
Architecture: any Architecture: any
Depends: adduser, Depends: ${misc:Depends}, ${shlibs:Depends}
${misc:Depends},
${shlibs:Depends}
Description: Meshtastic daemon for communicating with Meshtastic devices Description: Meshtastic daemon for communicating with Meshtastic devices
Meshtastic is an off-grid text communication platform that uses inexpensive Meshtastic is an off-grid text communication platform that uses inexpensive
LoRa radios. LoRa radios.

View File

@@ -1,6 +1,5 @@
var/lib/meshtasticd
etc/meshtasticd etc/meshtasticd
etc/meshtasticd/config.d etc/meshtasticd/config.d
etc/meshtasticd/available.d etc/meshtasticd/available.d
usr/share/meshtasticd/web usr/share/meshtasticd/web
etc/meshtasticd/ssl etc/meshtasticd/ssl

View File

@@ -1,8 +1,8 @@
.pio/build/native-tft/meshtasticd usr/bin .pio/build/native/meshtasticd usr/sbin
bin/config.yaml etc/meshtasticd bin/config.yaml etc/meshtasticd
bin/config.d/* etc/meshtasticd/available.d bin/config.d/* etc/meshtasticd/available.d
bin/meshtasticd.service lib/systemd/system bin/meshtasticd.service lib/systemd/system
web/* usr/share/meshtasticd/web web/* usr/share/meshtasticd/web

View File

@@ -1,80 +0,0 @@
#!/bin/sh
# postinst script for meshtasticd
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure|reconfigure)
# create spi, gpio groups (for udev rules)
# these groups already exist on Raspberry Pi OS
getent group spi >/dev/null 2>/dev/null || addgroup --system spi
getent group gpio >/dev/null 2>/dev/null || addgroup --system gpio
# create a meshtasticd group and user
getent passwd meshtasticd >/dev/null 2>/dev/null || adduser --system --home /var/lib/meshtasticd --no-create-home meshtasticd
getent group meshtasticd >/dev/null 2>/dev/null || addgroup --system meshtasticd
adduser meshtasticd meshtasticd >/dev/null 2>/dev/null
adduser meshtasticd spi >/dev/null 2>/dev/null
adduser meshtasticd gpio >/dev/null 2>/dev/null
# add meshtasticd user to appropriate groups (if they exist)
getent group plugdev >/dev/null 2>/dev/null && adduser meshtasticd plugdev >/dev/null 2>/dev/null
getent group dialout >/dev/null 2>/dev/null && adduser meshtasticd dialout >/dev/null 2>/dev/null
getent group i2c >/dev/null 2>/dev/null && adduser meshtasticd i2c >/dev/null 2>/dev/null
getent group video >/dev/null 2>/dev/null && adduser meshtasticd video >/dev/null 2>/dev/null
getent group audio >/dev/null 2>/dev/null && adduser meshtasticd audio >/dev/null 2>/dev/null
getent group input >/dev/null 2>/dev/null && adduser meshtasticd input >/dev/null 2>/dev/null
# migrate /root/.portduino to /var/lib/meshtasticd/.portduino
# should only run once, upon upgrade from < 2.6.9
if [ -n "$2" ] && dpkg --compare-versions "$2" lt 2.6.9; then
if [ -d /root/.portduino ] && [ ! -e /var/lib/meshtasticd/.portduino ]; then
cp -r /root/.portduino /var/lib/meshtasticd/.portduino
echo "Migrated meshtasticd VFS from /root/.portduino to /var/lib/meshtasticd/.portduino"
echo "meshtasticd now runs as the 'meshtasticd' user, not 'root'."
echo "See https://github.com/meshtastic/firmware/pull/6718 for details"
fi
fi
if [ -d /var/lib/meshtasticd ]; then
chown -R meshtasticd:meshtasticd /var/lib/meshtasticd
fi
if [ -d /etc/meshtasticd ]; then
chown -R meshtasticd:meshtasticd /etc/meshtasticd
fi
if [ -d /usr/share/meshtasticd ]; then
chown -R meshtasticd:meshtasticd /usr/share/meshtasticd
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

View File

@@ -1,41 +0,0 @@
#!/bin/sh
# postrm script for meshtasticd
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <overwriter>
# <overwriter-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
# Only remove /var/lib/meshtasticd on purge
if [ "${1}" = "purge" ] ; then
rm -rf /var/lib/meshtasticd
fi
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

View File

@@ -1,7 +0,0 @@
# Set spidev ownership to 'spi' group
SUBSYSTEM=="spidev", KERNEL=="spidev*", GROUP="spi", MODE="0660"
# Allow access to USB CH341 devices
SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512", MODE="0666"
# Set gpio ownership to 'gpio' group
SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"

4
debian/rules vendored
View File

@@ -26,7 +26,7 @@ override_dh_auto_build:
mkdir -p web && tar -xf web.tar -C web mkdir -p web && tar -xf web.tar -C web
gunzip web/ -r gunzip web/ -r
# Build with platformio # Build with platformio
$(PIO_ENV) platformio run -e native-tft $(PIO_ENV) platformio run -e native
# Move the binary and default config to the correct name # Move the binary and default config to the correct name
mv .pio/build/native-tft/program .pio/build/native-tft/meshtasticd mv .pio/build/native/program .pio/build/native/meshtasticd
cp bin/config-dist.yaml bin/config.yaml cp bin/config-dist.yaml bin/config.yaml

View File

@@ -1,22 +0,0 @@
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
Import("env")
# Custom HEX from ELF
env.AddPostAction(
"$BUILD_DIR/${PROGNAME}.elf",
env.VerboseAction(
" ".join(
[
"$OBJCOPY",
"-O",
"ihex",
"-R",
".eeprom",
"$BUILD_DIR/${PROGNAME}.elf",
"$BUILD_DIR/${PROGNAME}.hex",
]
),
"Building $BUILD_DIR/${PROGNAME}.hex",
),
)

View File

@@ -10,8 +10,6 @@
# - https://docs.pagure.org/rpkg-util/v3/index.html # - https://docs.pagure.org/rpkg-util/v3/index.html
# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/ # - https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/
%global meshtasticd_user meshtasticd
Name: meshtasticd Name: meshtasticd
# Version Ex: 2.5.19 # Version Ex: 2.5.19
Version: {{{ meshtastic_version }}} Version: {{{ meshtastic_version }}}
@@ -23,7 +21,7 @@ Summary: Meshtastic daemon for communicating with Meshtastic devices
License: GPL-3.0 License: GPL-3.0
URL: https://github.com/meshtastic/firmware URL: https://github.com/meshtastic/firmware
Source0: {{{ git_dir_pack }}} Source0: {{{ git_dir_pack }}}
Source1: https://github.com/meshtastic/web/releases/download/v{{{ web_version }}}/build.tar Source1: https://github.com/meshtastic/web/releases/latest/download/build.tar
BuildRequires: systemd-rpm-macros BuildRequires: systemd-rpm-macros
BuildRequires: python3-devel BuildRequires: python3-devel
@@ -44,12 +42,6 @@ BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(liborcania) BuildRequires: pkgconfig(liborcania)
BuildRequires: pkgconfig(libyder) BuildRequires: pkgconfig(libyder)
BuildRequires: pkgconfig(libulfius) BuildRequires: pkgconfig(libulfius)
# TFT components:
BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(libinput)
BuildRequires: pkgconfig(xkbcommon-x11)
Requires: systemd-udev
%description %description
Meshtastic daemon for controlling Meshtastic devices. Meshtastic is an off-grid Meshtastic daemon for controlling Meshtastic devices. Meshtastic is an off-grid
@@ -63,29 +55,19 @@ tar -xf %{SOURCE1} -C web
gzip -dr web gzip -dr web
%build %build
# Use the “native-tft” environment from platformio to build a Linux binary # Use the “native” environment from platformio to build a Linux binary
platformio run -e native-tft platformio run -e native
%install %install
# Install meshtasticd binary mkdir -p %{buildroot}%{_sbindir}
mkdir -p %{buildroot}%{_bindir} install -m 0755 .pio/build/native/program %{buildroot}%{_sbindir}/meshtasticd
install -m 0755 .pio/build/native-tft/program %{buildroot}%{_bindir}/meshtasticd
# Install portduino VFS dir
install -p -d -m 0770 %{buildroot}%{_localstatedir}/lib/meshtasticd
# Install udev rules
mkdir -p %{buildroot}%{_udevrulesdir}
install -m 0644 bin/99-meshtasticd-udev.rules %{buildroot}%{_udevrulesdir}/99-meshtasticd-udev.rules
# Install config dirs
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd
install -m 0644 bin/config-dist.yaml %{buildroot}%{_sysconfdir}/meshtasticd/config.yaml install -m 0644 bin/config-dist.yaml %{buildroot}%{_sysconfdir}/meshtasticd/config.yaml
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/config.d mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/config.d
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/available.d mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/available.d
cp -r bin/config.d/* %{buildroot}%{_sysconfdir}/meshtasticd/available.d cp -r bin/config.d/* %{buildroot}%{_sysconfdir}/meshtasticd/available.d
# Install systemd service
install -D -m 0644 bin/meshtasticd.service %{buildroot}%{_unitdir}/meshtasticd.service install -D -m 0644 bin/meshtasticd.service %{buildroot}%{_unitdir}/meshtasticd.service
# Install the web files under /usr/share/meshtasticd/web # Install the web files under /usr/share/meshtasticd/web
@@ -94,54 +76,10 @@ cp -r web/* %{buildroot}%{_datadir}/meshtasticd/web
# Install default SSL storage directory (for web) # Install default SSL storage directory (for web)
mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/ssl mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/ssl
%pre
# create spi group (for udev rules)
getent group spi > /dev/null || groupadd -r spi
# create a meshtasticd group and user
getent group %{meshtasticd_user} > /dev/null || groupadd -r %{meshtasticd_user}
getent passwd %{meshtasticd_user} > /dev/null || \
useradd -r -d %{_localstatedir}/lib/meshtasticd -g %{meshtasticd_user} -G spi \
-s /sbin/nologin -c "Meshtastic Daemon" %{meshtasticd_user}
# add meshtasticd user to appropriate groups (if they exist)
getent group gpio > /dev/null && usermod -a -G gpio %{meshtasticd_user} > /dev/null
getent group plugdev > /dev/null && usermod -a -G plugdev %{meshtasticd_user} > /dev/null
getent group dialout > /dev/null && usermod -a -G dialout %{meshtasticd_user} > /dev/null
getent group i2c > /dev/null && usermod -a -G i2c %{meshtasticd_user} > /dev/null
getent group video > /dev/null && usermod -a -G video %{meshtasticd_user} > /dev/null
getent group audio > /dev/null && usermod -a -G audio %{meshtasticd_user} > /dev/null
getent group input > /dev/null && usermod -a -G input %{meshtasticd_user} > /dev/null
exit 0
%triggerin -- meshtasticd < 2.6.9
# migrate .portduino (if it exists and hasnt already been copied)
if [ -d /root/.portduino ] && [ ! -e /var/lib/meshtasticd/.portduino ]; then
mkdir -p /var/lib/meshtasticd
cp -r /root/.portduino /var/lib/meshtasticd/.portduino
chown -R %{meshtasticd_user}:%{meshtasticd_user} \
%{_localstatedir}/lib/meshtasticd || :
# Fix SELinux labels if present (no-op on non-SELinux systems)
restorecon -R /var/lib/meshtasticd/.portduino 2>/dev/null || :
echo "Migrated meshtasticd VFS from /root/.portduino to /var/lib/meshtasticd/.portduino"
echo "meshtasticd now runs as the 'meshtasticd' user, not 'root'."
echo "See https://github.com/meshtastic/firmware/pull/6718 for details"
fi
%post
%systemd_post meshtasticd.service
%preun
%systemd_preun meshtasticd.service
%postun
%systemd_postun_with_restart meshtasticd.service
%files %files
%defattr(-,%{meshtasticd_user},%{meshtasticd_user})
%license LICENSE %license LICENSE
%doc README.md %doc README.md
%{_bindir}/meshtasticd %{_sbindir}/meshtasticd
%dir %{_localstatedir}/lib/meshtasticd
%{_udevrulesdir}/99-meshtasticd-udev.rules
%dir %{_sysconfdir}/meshtasticd %dir %{_sysconfdir}/meshtasticd
%dir %{_sysconfdir}/meshtasticd/config.d %dir %{_sysconfdir}/meshtasticd/config.d
%dir %{_sysconfdir}/meshtasticd/available.d %dir %{_sysconfdir}/meshtasticd/available.d
@@ -154,4 +92,4 @@ fi
%dir %{_sysconfdir}/meshtasticd/ssl %dir %{_sysconfdir}/meshtasticd/ssl
%changelog %changelog
%autochangelog %autochangelog

View File

@@ -50,26 +50,18 @@ build_flags = -Wno-missing-field-initializers
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1 -DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
-DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1 -DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1
-DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware -DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
-DMESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE=1
#-DBUILD_EPOCH=$UNIX_TIME #-DBUILD_EPOCH=$UNIX_TIME
#-D OLED_PL=1 #-D OLED_PL=1
monitor_speed = 115200 monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/0119501e9983bd894830b02f545c377ee08d66fe.zip
# renovate: datasource=custom.pio depName=OneButton packageName=mathertel/library/OneButton
mathertel/OneButton@2.6.1 mathertel/OneButton@2.6.1
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/arduino-fsm/archive/7db3702bf0cfe97b783d6c72595e3f38e0b19159.zip https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
# renovate: datasource=git-refs depName=meshtastic-TinyGPSPlus packageName=https://github.com/meshtastic/TinyGPSPlus gitBranch=master https://github.com/meshtastic/ArduinoThread.git#7c3ee9e1951551b949763b1f5280f8db1fa4068d
https://github.com/meshtastic/TinyGPSPlus/archive/71a82db35f3b973440044c476d4bcdc673b104f4.zip
# renovate: datasource=git-refs depName=meshtastic-ArduinoThread packageName=https://github.com/meshtastic/ArduinoThread gitBranch=master
https://github.com/meshtastic/ArduinoThread/archive/7c3ee9e1951551b949763b1f5280f8db1fa4068d.zip
# renovate: datasource=custom.pio depName=Nanopb packageName=nanopb/library/Nanopb
nanopb/Nanopb@0.4.91 nanopb/Nanopb@0.4.91
# renovate: datasource=custom.pio depName=ErriezCRC32 packageName=erriez/library/ErriezCRC32
erriez/ErriezCRC32@1.0.1 erriez/ErriezCRC32@1.0.1
; Used for the code analysis in PIO Home / Inspect ; Used for the code analysis in PIO Home / Inspect
@@ -85,7 +77,6 @@ check_flags =
framework = arduino framework = arduino
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL
end2endzone/NonBlockingRTTTL@1.3.0 end2endzone/NonBlockingRTTTL@1.3.0
build_flags = ${env.build_flags} -Os build_flags = ${env.build_flags} -Os
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/> build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
@@ -93,103 +84,57 @@ build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/nic
; Common libs for communicating over TCP/IP networks such as MQTT ; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base] [networking_base]
lib_deps = lib_deps =
# renovate: datasource=custom.pio depName=TBPubSubClient packageName=thingsboard/library/TBPubSubClient knolleary/PubSubClient@2.8
thingsboard/TBPubSubClient@2.12.1 arduino-libraries/NTPClient@3.1.0
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
arduino-libraries/NTPClient@3.2.1
# renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog
arcao/Syslog@2.0.0 arcao/Syslog@2.0.0
[radiolib_base] [radiolib_base]
lib_deps = lib_deps =
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
jgromes/RadioLib@7.1.2 jgromes/RadioLib@7.1.2
[device-ui_base] [device-ui_base]
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master https://github.com/meshtastic/device-ui.git#74e739ed4532ca10393df9fc89ae5a22f0bab2b1
https://github.com/meshtastic/device-ui/archive/37e2fb84a8d1b7d8cc1e2ed00d34cfb1f284bd59.zip
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
; (not included in native / portduino)
[environmental_base] [environmental_base]
lib_deps = lib_deps =
# renovate: datasource=custom.pio depName=Adafruit BusIO packageName=adafruit/library/Adafruit BusIO adafruit/Adafruit BusIO@1.16.2
adafruit/Adafruit BusIO@1.17.1 adafruit/Adafruit Unified Sensor@1.1.14
# renovate: datasource=custom.pio depName=Adafruit Unified Sensor packageName=adafruit/library/Adafruit Unified Sensor
adafruit/Adafruit Unified Sensor@1.1.15
# renovate: datasource=custom.pio depName=Adafruit BMP280 packageName=adafruit/library/Adafruit BMP280 Library
adafruit/Adafruit BMP280 Library@2.6.8 adafruit/Adafruit BMP280 Library@2.6.8
# renovate: datasource=custom.pio depName=Adafruit BMP085 packageName=adafruit/library/Adafruit BMP085 Library
adafruit/Adafruit BMP085 Library@1.2.4 adafruit/Adafruit BMP085 Library@1.2.4
# renovate: datasource=custom.pio depName=Adafruit BME280 packageName=adafruit/library/Adafruit BME280 Library adafruit/Adafruit BME280 Library@2.2.4
adafruit/Adafruit BME280 Library@2.3.0 adafruit/Adafruit BMP3XX Library@2.1.5
# renovate: datasource=custom.pio depName=Adafruit DPS310 packageName=adafruit/library/Adafruit DPS310
adafruit/Adafruit DPS310@1.1.5 adafruit/Adafruit DPS310@1.1.5
# renovate: datasource=custom.pio depName=Adafruit MCP9808 packageName=adafruit/library/Adafruit MCP9808 Library
adafruit/Adafruit MCP9808 Library@2.0.2 adafruit/Adafruit MCP9808 Library@2.0.2
# renovate: datasource=custom.pio depName=Adafruit INA260 packageName=adafruit/library/Adafruit INA260 Library
adafruit/Adafruit INA260 Library@1.5.2 adafruit/Adafruit INA260 Library@1.5.2
# renovate: datasource=custom.pio depName=Adafruit INA219 packageName=adafruit/library/Adafruit INA219
adafruit/Adafruit INA219@1.2.3 adafruit/Adafruit INA219@1.2.3
# renovate: datasource=custom.pio depName=Adafruit PM25 AQI Sensor packageName=adafruit/library/Adafruit PM25 AQI Sensor
adafruit/Adafruit PM25 AQI Sensor@2.0.0
# renovate: datasource=custom.pio depName=Adafruit MPU6050 packageName=adafruit/library/Adafruit MPU6050
adafruit/Adafruit MPU6050@2.2.6
# renovate: datasource=custom.pio depName=Adafruit LIS3DH packageName=adafruit/library/Adafruit LIS3DH
adafruit/Adafruit LIS3DH@1.3.0
# renovate: datasource=custom.pio depName=Adafruit AHTX0 packageName=adafruit/library/Adafruit AHTX0
adafruit/Adafruit AHTX0@2.0.5
# renovate: datasource=custom.pio depName=Adafruit LSM6DS packageName=adafruit/library/Adafruit LSM6DS
adafruit/Adafruit LSM6DS@4.7.4
# renovate: datasource=custom.pio depName=Adafruit TSL2591 packageName=adafruit/library/Adafruit TSL2591 Library
adafruit/Adafruit TSL2591 Library@1.4.5
# renovate: datasource=custom.pio depName=EmotiBit MLX90632 packageName=emotibit/library/EmotiBit MLX90632
emotibit/EmotiBit MLX90632@1.0.8
# renovate: datasource=custom.pio depName=Adafruit MLX90614 packageName=adafruit/library/Adafruit MLX90614 Library
adafruit/Adafruit MLX90614 Library@2.1.5
# renovate: datasource=github-tags depName=INA3221 packageName=KodinLanewave/INA3221
https://github.com/KodinLanewave/INA3221/archive/1.0.1.zip
# renovate: datasource=custom.pio depName=QMC5883L Compass packageName=mprograms/library/QMC5883LCompass
mprograms/QMC5883LCompass@1.2.3
# renovate: datasource=custom.pio depName=DFRobot_RTU packageName=dfrobot/library/DFRobot_RTU
dfrobot/DFRobot_RTU@1.0.3
# renovate: datasource=git-refs depName=DFRobot_RainfallSensor packageName=https://github.com/DFRobot/DFRobot_RainfallSensor gitBranch=master
https://github.com/DFRobot/DFRobot_RainfallSensor/archive/38fea5e02b40a5430be6dab39a99a6f6347d667e.zip
# renovate: datasource=custom.pio depName=INA226 packageName=robtillaart/library/INA226
robtillaart/INA226@0.6.4
# renovate: datasource=custom.pio depName=SparkFun MAX3010x packageName=sparkfun/library/SparkFun MAX3010x Pulse and Proximity Sensor Library
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
# renovate: datasource=custom.pio depName=SparkFun 9DoF IMU Breakout ICM 20948 packageName=sparkfun/library/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.3.2
# renovate: datasource=custom.pio depName=Adafruit LTR390 Library packageName=adafruit/library/Adafruit LTR390 Library
adafruit/Adafruit LTR390 Library@1.1.2
# renovate: datasource=custom.pio depName=Adafruit PCT2075 packageName=adafruit/library/Adafruit PCT2075
adafruit/Adafruit PCT2075@1.0.5
; (not included in native / portduino)
[environmental_extra]
lib_deps =
# renovate: datasource=custom.pio depName=Adafruit BMP3XX packageName=adafruit/library/Adafruit BMP3XX Library
adafruit/Adafruit BMP3XX Library@2.1.6
# renovate: datasource=custom.pio depName=Adafruit MAX1704X packageName=adafruit/library/Adafruit MAX1704X
adafruit/Adafruit MAX1704X@1.0.3 adafruit/Adafruit MAX1704X@1.0.3
# renovate: datasource=custom.pio depName=Adafruit SHTC3 packageName=adafruit/library/Adafruit SHTC3 Library
adafruit/Adafruit SHTC3 Library@1.0.1 adafruit/Adafruit SHTC3 Library@1.0.1
# renovate: datasource=custom.pio depName=Adafruit LPS2X packageName=adafruit/library/Adafruit LPS2X
adafruit/Adafruit LPS2X@2.0.6 adafruit/Adafruit LPS2X@2.0.6
# renovate: datasource=custom.pio depName=Adafruit SHT31 packageName=adafruit/library/Adafruit SHT31 Library
adafruit/Adafruit SHT31 Library@2.2.2 adafruit/Adafruit SHT31 Library@2.2.2
# renovate: datasource=custom.pio depName=Adafruit VEML7700 packageName=adafruit/library/Adafruit VEML7700 Library adafruit/Adafruit PM25 AQI Sensor@1.1.1
adafruit/Adafruit MPU6050@2.2.6
adafruit/Adafruit LIS3DH@1.3.0
adafruit/Adafruit AHTX0@2.0.5
adafruit/Adafruit LSM6DS@4.7.3
adafruit/Adafruit VEML7700 Library@2.1.6 adafruit/Adafruit VEML7700 Library@2.1.6
# renovate: datasource=custom.pio depName=Adafruit SHT4x packageName=adafruit/library/Adafruit SHT4x Library
adafruit/Adafruit SHT4x Library@1.0.5 adafruit/Adafruit SHT4x Library@1.0.5
# renovate: datasource=custom.pio depName=SparkFun Qwiic Scale NAU7802 packageName=sparkfun/library/SparkFun Qwiic Scale NAU7802 Arduino Library adafruit/Adafruit TSL2591 Library@1.4.5
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6 sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6
# renovate: datasource=custom.pio depName=ClosedCube OPT3001 packageName=closedcube/library/ClosedCube OPT3001 sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
ClosedCube OPT3001@1.1.2 ClosedCube OPT3001@1.1.2
# renovate: datasource=custom.pio depName=Bosch BSEC2 packageName=boschsensortec/library/bsec2 emotibit/EmotiBit MLX90632@1.0.8
boschsensortec/bsec2@1.10.2610 adafruit/Adafruit MLX90614 Library@2.1.5
# renovate: datasource=custom.pio depName=Bosch BME68x packageName=boschsensortec/library/BME68x Sensor Library https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@1.3.40408 boschsensortec/BME68x Sensor Library@1.1.40407
# renovate: datasource=git-refs depName=meshtastic-DFRobot_LarkWeatherStation packageName=https://github.com/meshtastic/DFRobot_LarkWeatherStation gitBranch=master https://github.com/KodinLanewave/INA3221@1.0.1
https://github.com/meshtastic/DFRobot_LarkWeatherStation/archive/4de3a9cadef0f6a5220a8a906cf9775b02b0040d.zip mprograms/QMC5883LCompass@1.2.3
dfrobot/DFRobot_RTU@1.0.3
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
https://github.com/DFRobot/DFRobot_RainfallSensor#38fea5e02b40a5430be6dab39a99a6f6347d667e
robtillaart/INA226@0.6.0
; Health Sensor Libraries
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2

View File

@@ -1,99 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
":dependencyDashboard",
":semanticCommitTypeAll(chore)",
":ignoreModulesAndTests",
"group:recommended",
"replacements:all",
"workarounds:all"
],
"forkProcessing": "enabled",
"ignoreDeps": [
"protobufs"
],
"git-submodules": {
"enabled": true
},
"pip_requirements": {
"managerFilePatterns": [
"/bin/bump_metainfo/requirements.txt/"
]
},
"commitMessageTopic": "{{depName}}",
"labels": [
"dependencies"
],
"customDatasources": {
"pio": {
"description": "PlatformIO Registry",
"defaultRegistryUrlTemplate": "https://api.registry.platformio.org/v3/packages/{{packageName}}",
"format": "json",
"transformTemplates": [
"{\"releases\": [$map($.versions, function($v) { { \"version\": $v.name, \"releaseTimestamp\": $v.released_at } })], \"homepage\": $encodeUrl($join([\"https://registry.platformio.org/\",$.type,\"/\",$.owner.username,\"/\",$.name])) }"
]
}
},
"customManagers": [
{
"customType": "regex",
"description": "Match meshtastic/web version",
"managerFilePatterns": [
"/bin/web.version/"
],
"matchStrings": [
"(?<currentValue>.+)$"
],
"datasourceTemplate": "github-releases",
"depNameTemplate": "meshtastic/web",
"versioningTemplate": "semver-coerced"
},
{
"customType": "regex",
"description": "Match normal PIO dependencies",
"managerFilePatterns": [
"/.*\\.ini$/"
],
"matchStrings": [
"# renovate: datasource=(?<datasource>.*?)(?: depName=(?<depName>.+?))? packageName=(?<packageName>.+?)(?: versioning=(?<versioning>[a-z-]+?))?\\s+?.+?@(?<currentValue>.+?)\\s"
],
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver-coerced{{/if}}"
},
{
"customType": "regex",
"description": "Match PIO zipped dependencies with github tag ref",
"managerFilePatterns": [
"/.*\\.ini$/"
],
"matchStrings": [
"# renovate: datasource=github-tags(?: depName=(?<depName>.+?))? packageName=(?<packageName>.+?)(?: versioning=(?<versioning>[a-z-]+?))?\\s+?https://.+?archive/(?<currentValue>.+?).zip\\s"
],
"datasourceTemplate": "github-tags",
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver-coerced{{/if}}"
},
{
"customType": "regex",
"description": "Match PIO zipped dependencies with git commit ref",
"managerFilePatterns": [
"/.*\\.ini$/"
],
"matchStrings": [
"# renovate: datasource=git-refs(?: depName=(?<depName>.+?))? packageName=(?<packageName>.+?)(?: versioning=(?<versioning>[a-z-]+?))?\\sgitBranch=(?<gitBranch>.+?)\\s+?https://.+?archive/(?<currentDigest>.+?).zip\\s"
],
"datasourceTemplate": "git-refs",
"currentValueTemplate": "{{{gitBranch}}}",
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}git{{/if}}"
}
],
"packageRules": [
{
"matchDepNames": [
"meshtastic/device-ui"
],
"reviewers": [
"mverch67"
],
"changelogUrl": "https://github.com/meshtastic/device-ui/compare/{{currentDigest}}...{{newDigest}}"
}
]
}

View File

@@ -6,11 +6,6 @@
NCP5623 rgb; NCP5623 rgb;
#endif #endif
#ifdef HAS_LP5562
#include <graphics/NomadStarLED.h>
LP5562 rgbw;
#endif
#ifdef HAS_NEOPIXEL #ifdef HAS_NEOPIXEL
#include <graphics/NeoPixel.h> #include <graphics/NeoPixel.h>
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE); Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
@@ -31,7 +26,7 @@ class AmbientLightingThread : public concurrency::OSThread
notifyDeepSleepObserver.observe(&notifyDeepSleep); // Let us know when shutdown() is issued. notifyDeepSleepObserver.observe(&notifyDeepSleep); // Let us know when shutdown() is issued.
// Enables Ambient Lighting by default if conditions are meet. // Enables Ambient Lighting by default if conditions are meet.
#ifdef HAS_RGB_LED #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#ifdef ENABLE_AMBIENTLIGHTING #ifdef ENABLE_AMBIENTLIGHTING
moduleConfig.ambient_lighting.led_state = true; moduleConfig.ambient_lighting.led_state = true;
#endif #endif
@@ -44,7 +39,7 @@ class AmbientLightingThread : public concurrency::OSThread
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8; // moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF; // moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
#if defined(HAS_NCP5623) || defined(HAS_LP5562) #ifdef HAS_NCP5623
_type = type; _type = type;
if (_type == ScanI2C::DeviceType::NONE) { if (_type == ScanI2C::DeviceType::NONE) {
LOG_DEBUG("AmbientLighting Disable due to no RGB leds found on I2C bus"); LOG_DEBUG("AmbientLighting Disable due to no RGB leds found on I2C bus");
@@ -52,21 +47,17 @@ class AmbientLightingThread : public concurrency::OSThread
return; return;
} }
#endif #endif
#ifdef HAS_RGB_LED #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
if (!moduleConfig.ambient_lighting.led_state) { if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLighting Disable due to moduleConfig.ambient_lighting.led_state OFF"); LOG_DEBUG("AmbientLighting Disable due to moduleConfig.ambient_lighting.led_state OFF");
disable(); disable();
return; return;
} }
LOG_DEBUG("AmbientLighting init"); LOG_DEBUG("AmbientLighting init");
#if defined(HAS_NCP5623) || defined(HAS_LP5562) #ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623) { if (_type == ScanI2C::NCP5623) {
rgb.begin(); rgb.begin();
#endif #endif
#ifdef HAS_LP5562
} else if (_type == ScanI2C::LP5562) {
rgbw.begin();
#endif
#ifdef RGBLED_RED #ifdef RGBLED_RED
pinMode(RGBLED_RED, OUTPUT); pinMode(RGBLED_RED, OUTPUT);
pinMode(RGBLED_GREEN, OUTPUT); pinMode(RGBLED_GREEN, OUTPUT);
@@ -79,7 +70,7 @@ class AmbientLightingThread : public concurrency::OSThread
#endif #endif
setLighting(); setLighting();
#endif #endif
#if defined(HAS_NCP5623) || defined(HAS_LP5562) #ifdef HAS_NCP5623
} }
#endif #endif
} }
@@ -87,13 +78,13 @@ class AmbientLightingThread : public concurrency::OSThread
protected: protected:
int32_t runOnce() override int32_t runOnce() override
{ {
#ifdef HAS_RGB_LED #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#if defined(HAS_NCP5623) || defined(HAS_LP5562) #ifdef HAS_NCP5623
if ((_type == ScanI2C::NCP5623 || _type == ScanI2C::LP5562) && moduleConfig.ambient_lighting.led_state) { if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
#endif #endif
setLighting(); setLighting();
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
#if defined(HAS_NCP5623) || defined(HAS_LP5562) #ifdef HAS_NCP5623
} }
#endif #endif
#endif #endif
@@ -117,14 +108,6 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setBlue(0); rgb.setBlue(0);
LOG_INFO("OFF: NCP5623 Ambient lighting"); LOG_INFO("OFF: NCP5623 Ambient lighting");
#endif #endif
#ifdef HAS_LP5562
rgbw.setCurrent(0);
rgbw.setRed(0);
rgbw.setGreen(0);
rgbw.setBlue(0);
rgbw.setWhite(0);
LOG_INFO("OFF: LP5562 Ambient lighting");
#endif
#ifdef HAS_NEOPIXEL #ifdef HAS_NEOPIXEL
pixels.clear(); pixels.clear();
pixels.show(); pixels.show();
@@ -158,14 +141,6 @@ class AmbientLightingThread : public concurrency::OSThread
LOG_DEBUG("Init NCP5623 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current, LOG_DEBUG("Init NCP5623 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current,
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif #endif
#ifdef HAS_LP5562
rgbw.setCurrent(moduleConfig.ambient_lighting.current);
rgbw.setRed(moduleConfig.ambient_lighting.red);
rgbw.setGreen(moduleConfig.ambient_lighting.green);
rgbw.setBlue(moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Init LP5562 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current,
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
#ifdef HAS_NEOPIXEL #ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue), moduleConfig.ambient_lighting.blue),

View File

@@ -41,8 +41,10 @@ class AudioThread : public concurrency::OSThread
delete i2sRtttl; delete i2sRtttl;
i2sRtttl = nullptr; i2sRtttl = nullptr;
} }
delete rtttlFile; if (rtttlFile != nullptr) {
rtttlFile = nullptr; delete rtttlFile;
rtttlFile = nullptr;
}
setCPUFast(false); setCPUFast(false);
} }

View File

@@ -9,7 +9,6 @@
#include "RadioLibInterface.h" #include "RadioLibInterface.h"
#include "buzz.h" #include "buzz.h"
#include "main.h" #include "main.h"
#include "modules/CannedMessageModule.h"
#include "modules/ExternalNotificationModule.h" #include "modules/ExternalNotificationModule.h"
#include "power.h" #include "power.h"
#include "sleep.h" #include "sleep.h"
@@ -27,7 +26,6 @@
using namespace concurrency; using namespace concurrency;
ButtonThread *buttonThread; // Declared extern in header ButtonThread *buttonThread; // Declared extern in header
extern CannedMessageModule *cannedMessageModule;
volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE; volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE;
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
@@ -49,7 +47,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#ifdef USERPREFS_BUTTON_PIN #ifdef USERPREFS_BUTTON_PIN
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
#endif #endif
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB) #if defined(HELTEC_CAPSULE_SENSOR_V3)
this->userButton = OneButton(pin, false, false); this->userButton = OneButton(pin, false, false);
#elif defined(BUTTON_ACTIVE_LOW) #elif defined(BUTTON_ACTIVE_LOW)
this->userButton = OneButton(pin, BUTTON_ACTIVE_LOW, BUTTON_ACTIVE_PULLUP); this->userButton = OneButton(pin, BUTTON_ACTIVE_LOW, BUTTON_ACTIVE_PULLUP);
@@ -75,28 +73,23 @@ ButtonThread::ButtonThread() : OSThread("Button")
userButton.setDebounceMs(1); userButton.setDebounceMs(1);
userButton.attachDoubleClick(userButtonDoublePressed); userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
#if !defined(T_DECK) && \ #ifndef T_DECK // T-Deck immediately wakes up after shutdown, so disable this function
!defined( \
ELECROW_ThinkNode_M2) // T-Deck immediately wakes up after shutdown, Thinknode M2 has this on the smaller ALT button
userButton.attachLongPressStart(userButtonPressedLongStart); userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop); userButton.attachLongPressStop(userButtonPressedLongStop);
#endif #endif
#endif #endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT
#if defined(ELECROW_ThinkNode_M2) userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
this->userButtonAlt = OneButton(BUTTON_PIN_ALT, false, false);
#else
this->userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
#endif
#ifdef INPUT_PULLUP_SENSE #ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did // Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE); pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
#endif #endif
userButtonAlt.attachClick(userButtonPressedScreen); userButtonAlt.attachClick(userButtonPressed);
userButtonAlt.setClickMs(BUTTON_CLICK_MS); userButtonAlt.setClickMs(BUTTON_CLICK_MS);
userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS); userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS);
userButtonAlt.setDebounceMs(1); userButtonAlt.setDebounceMs(1);
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
userButtonAlt.attachLongPressStart(userButtonPressedLongStart); userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
userButtonAlt.attachLongPressStop(userButtonPressedLongStop); userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
#endif #endif
@@ -118,60 +111,6 @@ ButtonThread::ButtonThread() : OSThread("Button")
#endif #endif
} }
void ButtonThread::switchPage()
{
// Prevent screen switch if CannedMessageModule is focused and intercepting input
#if HAS_SCREEN
extern CannedMessageModule *cannedMessageModule;
if (cannedMessageModule && cannedMessageModule->isInterceptingAndFocused()) {
LOG_DEBUG("User button ignored during canned message input");
return; // Skip screen change
}
#endif
// Default behavior if not blocked
#ifdef BUTTON_PIN
#if !defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
moduleConfig.canned_message.inputbroker_pin_press) ||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
#if defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
moduleConfig.canned_message.inputbroker_pin_press) ||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
#endif
#if defined(ARCH_PORTDUINO)
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
}
void ButtonThread::sendAdHocPosition()
{
service->refreshLocalMeshNode();
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
if (screen) {
if (sentPosition)
screen->print("Sent ad-hoc position\n");
else
screen->print("Sent ad-hoc nodeinfo\n");
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
}
}
int32_t ButtonThread::runOnce() int32_t ButtonThread::runOnce()
{ {
// If the button is pressed we suppress CPU sleep until release // If the button is pressed we suppress CPU sleep until release
@@ -202,86 +141,65 @@ int32_t ButtonThread::runOnce()
// If a nag notification is running, stop it and prevent other actions // If a nag notification is running, stop it and prevent other actions
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) { if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
externalNotificationModule->stopNow(); externalNotificationModule->stopNow();
break; return 50;
} }
#ifdef ELECROW_ThinkNode_M1 #ifdef BUTTON_PIN
sendAdHocPosition(); #if !defined(USERPREFS_BUTTON_PIN)
break; if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
#endif #endif
switchPage(); #if defined(USERPREFS_BUTTON_PIN)
break; if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
} #endif
moduleConfig.canned_message.inputbroker_pin_press) ||
case BUTTON_EVENT_PRESSED_SCREEN: { !(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
LOG_BUTTON("AltPress!"); !moduleConfig.canned_message.enabled) {
#ifdef ELECROW_ThinkNode_M1 powerFSM.trigger(EVENT_PRESS);
// If a nag notification is running, stop it and prevent other actions }
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) { #endif
externalNotificationModule->stopNow(); #if defined(ARCH_PORTDUINO)
break; if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
} }
switchPage();
break;
#endif #endif
// turn screen on or off
screen_flag = !screen_flag;
if (screen)
screen->setOn(screen_flag);
break; break;
} }
case BUTTON_EVENT_DOUBLE_PRESSED: { case BUTTON_EVENT_DOUBLE_PRESSED: {
LOG_BUTTON("Double press!"); LOG_BUTTON("Double press!");
service->refreshLocalMeshNode();
#ifdef ELECROW_ThinkNode_M1 auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW); if (screen) {
break; if (sentPosition)
#endif screen->print("Sent ad-hoc position\n");
else
// Send GPS position immediately screen->print("Sent ad-hoc nodeinfo\n");
sendAdHocPosition(); screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
}
// Show temporary on-screen confirmation banner for 3 seconds
screen->showOverlayBanner("Ad-hoc Ping Sent", 3000);
break; break;
} }
case BUTTON_EVENT_MULTI_PRESSED: { case BUTTON_EVENT_MULTI_PRESSED: {
LOG_BUTTON("Mulitipress! %hux", multipressClickCount); LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
switch (multipressClickCount) { switch (multipressClickCount) {
#if HAS_GPS && !defined(ELECROW_ThinkNode_M1) #if HAS_GPS
// 3 clicks: toggle GPS // 3 clicks: toggle GPS
case 3: case 3:
if (!config.device.disable_triple_click && (gps != nullptr)) { if (!config.device.disable_triple_click && (gps != nullptr)) {
gps->toggleGpsMode(); gps->toggleGpsMode();
if (screen)
const char *statusMsg = (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED)
? "GPS Enabled"
: "GPS Disabled";
if (screen) {
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
screen->showOverlayBanner(statusMsg, 3000);
}
} }
break; break;
#elif defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
case 3:
LOG_INFO("3 clicks: toggle buzzer");
buzzer_flag = !buzzer_flag;
if (!buzzer_flag)
noTone(PIN_BUZZER);
break;
#endif #endif
#if defined(USE_EINK) && defined(PIN_EINK_EN) // i.e. T-Echo
#if defined(USE_EINK) && defined(PIN_EINK_EN) && !defined(ELECROW_ThinkNode_M1) // i.e. T-Echo
// 4 clicks: toggle backlight // 4 clicks: toggle backlight
case 4: case 4:
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW); digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
break; break;
#endif #endif
#if !MESHTASTIC_EXCLUDE_SCREEN && HAS_SCREEN #if defined(RAK_4631)
// 5 clicks: start accelerometer/magenetometer calibration for 30 seconds // 5 clicks: start accelerometer/magenetometer calibration for 30 seconds
case 5: case 5:
if (accelerometerThread) { if (accelerometerThread) {
@@ -306,12 +224,9 @@ int32_t ButtonThread::runOnce()
case BUTTON_EVENT_LONG_PRESSED: { case BUTTON_EVENT_LONG_PRESSED: {
LOG_BUTTON("Long press!"); LOG_BUTTON("Long press!");
powerFSM.trigger(EVENT_PRESS); powerFSM.trigger(EVENT_PRESS);
if (screen) { if (screen) {
// Show shutdown message as a temporary overlay banner screen->startAlert("Shutting down...");
screen->showOverlayBanner("Shutting Down..."); // Display for 3 seconds
} }
playBeep(); playBeep();
break; break;
} }
@@ -323,30 +238,20 @@ int32_t ButtonThread::runOnce()
playShutdownMelody(); playShutdownMelody();
delay(3000); delay(3000);
power->shutdown(); power->shutdown();
nodeDB->saveToDisk();
break; break;
} }
#ifdef BUTTON_PIN_TOUCH #ifdef BUTTON_PIN_TOUCH
case BUTTON_EVENT_TOUCH_LONG_PRESSED: { case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
LOG_BUTTON("Touch press!"); LOG_BUTTON("Touch press!");
// Ignore if: no screen if (screen) {
if (!screen) // Wake if asleep
break; if (powerFSM.getState() == &stateDARK)
powerFSM.trigger(EVENT_PRESS);
#ifdef TTGO_T_ECHO // Update display (legacy behaviour)
// Ignore if: TX in progress screen->forceDisplay();
// Uncommon T-Echo hardware bug, LoRa TX triggers touch button }
if (!RadioLibInterface::instance || RadioLibInterface::instance->isSending())
break;
#endif
// Wake if asleep
if (powerFSM.getState() == &stateDARK)
powerFSM.trigger(EVENT_PRESS);
// Update display (legacy behaviour)
screen->forceDisplay();
break; break;
} }
#endif // BUTTON_PIN_TOUCH #endif // BUTTON_PIN_TOUCH
@@ -388,12 +293,8 @@ void ButtonThread::attachButtonInterrupts()
#endif #endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT
#ifdef ELECROW_ThinkNode_M2
wakeOnIrq(BUTTON_PIN_ALT, RISING);
#else
wakeOnIrq(BUTTON_PIN_ALT, FALLING); wakeOnIrq(BUTTON_PIN_ALT, FALLING);
#endif #endif
#endif
#ifdef BUTTON_PIN_TOUCH #ifdef BUTTON_PIN_TOUCH
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING); wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);

View File

@@ -24,7 +24,6 @@ class ButtonThread : public concurrency::OSThread
enum ButtonEventType { enum ButtonEventType {
BUTTON_EVENT_NONE, BUTTON_EVENT_NONE,
BUTTON_EVENT_PRESSED, BUTTON_EVENT_PRESSED,
BUTTON_EVENT_PRESSED_SCREEN,
BUTTON_EVENT_DOUBLE_PRESSED, BUTTON_EVENT_DOUBLE_PRESSED,
BUTTON_EVENT_MULTI_PRESSED, BUTTON_EVENT_MULTI_PRESSED,
BUTTON_EVENT_LONG_PRESSED, BUTTON_EVENT_LONG_PRESSED,
@@ -37,16 +36,13 @@ class ButtonThread : public concurrency::OSThread
void attachButtonInterrupts(); void attachButtonInterrupts();
void detachButtonInterrupts(); void detachButtonInterrupts();
void storeClickCount(); void storeClickCount();
bool isBuzzing() { return buzzer_flag; }
void setScreenFlag(bool flag) { screen_flag = flag; }
bool getScreenFlag() { return screen_flag; }
bool isInterceptingAndFocused();
// Disconnect and reconnect interrupts for light sleep // Disconnect and reconnect interrupts for light sleep
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
int beforeLightSleep(void *unused); int beforeLightSleep(void *unused);
int afterLightSleep(esp_sleep_wakeup_cause_t cause); int afterLightSleep(esp_sleep_wakeup_cause_t cause);
#endif #endif
private: private:
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
static OneButton userButton; // Static - accessed from an interrupt static OneButton userButton; // Static - accessed from an interrupt
@@ -68,20 +64,14 @@ class ButtonThread : public concurrency::OSThread
// set during IRQ // set during IRQ
static volatile ButtonEventType btnEvent; static volatile ButtonEventType btnEvent;
bool buzzer_flag = false;
bool screen_flag = true;
// Store click count during callback, for later use // Store click count during callback, for later use
volatile int multipressClickCount = 0; volatile int multipressClickCount = 0;
static void wakeOnIrq(int irq, int mode); static void wakeOnIrq(int irq, int mode);
static void sendAdHocPosition();
static void switchPage();
// IRQ callbacks // IRQ callbacks
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; } static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
static void userButtonPressedScreen() { btnEvent = BUTTON_EVENT_PRESSED_SCREEN; }
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; } static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
static void userButtonPressedLongStart(); static void userButtonPressedLongStart();

View File

@@ -27,6 +27,9 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
return useShortName ? "LongM" : "LongMod"; return useShortName ? "LongM" : "LongMod";
break; break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
return useShortName ? "VeryL" : "VLongSlow";
break;
default: default:
return useShortName ? "Custom" : "Invalid"; return useShortName ? "Custom" : "Invalid";
break; break;

View File

@@ -12,14 +12,13 @@
#include "SPILock.h" #include "SPILock.h"
#include "configuration.h" #include "configuration.h"
// Software SPI is used by MUI so disable SD card here until it's also implemented #ifdef HAS_SDCARD
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI)
#include <SD.h> #include <SD.h>
#include <SPI.h> #include <SPI.h>
#ifdef SDCARD_USE_SPI1 #ifdef SDCARD_USE_SPI1
SPIClass SPI_HSPI(HSPI); SPIClass SPI1(HSPI);
#define SDHandler SPI_HSPI #define SDHandler SPI1
#else #else
#define SDHandler SPI #define SDHandler SPI
#endif #endif
@@ -30,6 +29,30 @@ SPIClass SPI_HSPI(HSPI);
#endif // HAS_SDCARD #endif // HAS_SDCARD
#if defined(ARCH_STM32WL)
uint16_t OSFS::startOfEEPROM = 1;
uint16_t OSFS::endOfEEPROM = 2048;
// 3) How do I read from the medium?
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output)
{
for (uint16_t i = address; i < address + num; i++) {
*output = EEPROM.read(i);
output++;
}
}
// 4) How to I write to the medium?
void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
{
for (uint16_t i = address; i < address + num; i++) {
EEPROM.update(i, *input);
input++;
}
}
#endif
/** /**
* @brief Copies a file from one location to another. * @brief Copies a file from one location to another.
* *
@@ -39,7 +62,33 @@ SPIClass SPI_HSPI(HSPI);
*/ */
bool copyFile(const char *from, const char *to) bool copyFile(const char *from, const char *to)
{ {
#ifdef FSCom #ifdef ARCH_STM32WL
unsigned char cbuffer[2048];
// Var to hold the result of actions
OSFS::result r;
r = OSFS::getFile(from, cbuffer);
if (r == notfound) {
LOG_ERROR("Failed to open source file %s", from);
return false;
} else if (r == noerr) {
r = OSFS::newFile(to, cbuffer, true);
if (r == noerr) {
return true;
} else {
LOG_ERROR("OSFS Error %d", r);
return false;
}
} else {
LOG_ERROR("OSFS Error %d", r);
return false;
}
return true;
#elif defined(FSCom)
// take SPI Lock // take SPI Lock
concurrency::LockGuard g(spiLock); concurrency::LockGuard g(spiLock);
unsigned char cbuffer[16]; unsigned char cbuffer[16];
@@ -78,7 +127,13 @@ bool copyFile(const char *from, const char *to)
*/ */
bool renameFile(const char *pathFrom, const char *pathTo) bool renameFile(const char *pathFrom, const char *pathTo)
{ {
#ifdef FSCom #ifdef ARCH_STM32WL
if (copyFile(pathFrom, pathTo) && (OSFS::deleteFile(pathFrom) == OSFS::result::NO_ERROR)) {
return true;
} else {
return false;
}
#elif defined(FSCom)
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// take SPI Lock // take SPI Lock
@@ -307,7 +362,7 @@ void fsInit()
*/ */
void setupSDCard() void setupSDCard()
{ {
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI) #ifdef HAS_SDCARD
concurrency::LockGuard g(spiLock); concurrency::LockGuard g(spiLock);
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI); SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) { if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {

View File

@@ -15,11 +15,13 @@
#endif #endif
#if defined(ARCH_STM32WL) #if defined(ARCH_STM32WL)
// STM32WL // STM32WL series 2 Kbytes (8 rows of 256 bytes)
#include "LittleFS.h" #include <EEPROM.h>
#define FSCom InternalFS #include <OSFS.h>
#define FSBegin() FSCom.begin()
using namespace STM32_LittleFS_Namespace; // Useful consts
const OSFS::result noerr = OSFS::result::NO_ERROR;
const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND;
#endif #endif
#if defined(ARCH_RP2040) #if defined(ARCH_RP2040)

View File

@@ -76,47 +76,23 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
#endif #endif
#endif #endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
#if __has_include(<Adafruit_INA219.h>)
INA219Sensor ina219Sensor; INA219Sensor ina219Sensor;
#else
NullSensor ina219Sensor;
#endif
#if __has_include(<INA226.h>)
INA226Sensor ina226Sensor; INA226Sensor ina226Sensor;
#else
NullSensor ina226Sensor;
#endif
#if __has_include(<Adafruit_INA260.h>)
INA260Sensor ina260Sensor; INA260Sensor ina260Sensor;
#else
NullSensor ina260Sensor;
#endif
#if __has_include(<INA3221.h>)
INA3221Sensor ina3221Sensor; INA3221Sensor ina3221Sensor;
#else
NullSensor ina3221Sensor;
#endif #endif
#endif #if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_STM32WL)
#include "modules/Telemetry/Sensor/MAX17048Sensor.h" #include "modules/Telemetry/Sensor/MAX17048Sensor.h"
#include <utility> #include <utility>
extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
#if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY) #if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY)
#if __has_include(<Adafruit_MAX1704X.h>)
MAX17048Sensor max17048Sensor; MAX17048Sensor max17048Sensor;
#else
NullSensor max17048Sensor;
#endif
#endif #endif
#endif #endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT && !defined(ARCH_PORTDUINO)
RAK9154Sensor rak9154Sensor; RAK9154Sensor rak9154Sensor;
#endif #endif
@@ -227,7 +203,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
*/ */
virtual int getBatteryPercent() override virtual int getBatteryPercent() override
{ {
#if defined(HAS_RAKPROT) && !defined(HAS_PMU) #if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) { if (hasRAK()) {
return rak9154Sensor.getBusBatteryPercent(); return rak9154Sensor.getBusBatteryPercent();
} }
@@ -272,13 +248,15 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override virtual uint16_t getBattVoltage() override
{ {
#if HAS_TELEMETRY && defined(HAS_RAKPROT) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasRAK()) { if (hasRAK()) {
return getRAKVoltage(); return getRAKVoltage();
} }
#endif #endif
#if HAS_TELEMETRY && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) { if (hasINA()) {
return getINAVoltage(); return getINAVoltage();
} }
@@ -402,20 +380,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
// if we have a integrated device with a battery, we can assume that the battery is always connected // if we have a integrated device with a battery, we can assume that the battery is always connected
#ifdef BATTERY_IMMUTABLE #ifdef BATTERY_IMMUTABLE
virtual bool isBatteryConnect() override { return true; } virtual bool isBatteryConnect() override { return true; }
#elif defined(ADC_V)
virtual bool isBatteryConnect() override
{
int lastReading = digitalRead(ADC_V);
// 判断值是否变化
for (int i = 2; i < 500; i++) {
int reading = digitalRead(ADC_V);
if (reading != lastReading) {
return false; // 有变化USB供电, 没接电池
}
}
return true;
}
#else #else
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; } virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
#endif #endif
@@ -427,7 +391,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual bool isVbusIn() override virtual bool isVbusIn() override
{ {
#ifdef EXT_PWR_DETECT #ifdef EXT_PWR_DETECT
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB) #ifdef HELTEC_CAPSULE_SENSOR_V3
// if external powered that pin will be pulled down // if external powered that pin will be pulled down
if (digitalRead(EXT_PWR_DETECT) == LOW) { if (digitalRead(EXT_PWR_DETECT) == LOW) {
return true; return true;
@@ -448,7 +412,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// we can't be smart enough to say 'full'? /// we can't be smart enough to say 'full'?
virtual bool isCharging() override virtual bool isCharging() override
{ {
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT) && !defined(HAS_PMU) #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && \
!defined(HAS_PMU)
if (hasRAK()) { if (hasRAK()) {
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse; return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
} }
@@ -456,7 +421,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifdef EXT_CHRG_DETECT #ifdef EXT_CHRG_DETECT
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value; return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
#else #else
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) && \ #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && \
!defined(DISABLE_INA_CHARGING_DETECTION) !defined(DISABLE_INA_CHARGING_DETECTION)
if (hasINA()) { if (hasINA()) {
// get current flow from INA sensor - negative value means power flowing into the battery // get current flow from INA sensor - negative value means power flowing into the battery
@@ -471,8 +436,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
return isBatteryConnect() && isVbusIn(); return isBatteryConnect() && isVbusIn();
#endif #endif
#endif #endif
// by default, we check the battery voltage only
return isVbusIn();
} }
private: private:
@@ -503,7 +466,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
} }
#endif #endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
uint16_t getINAVoltage() uint16_t getINAVoltage()
{ {
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
@@ -578,7 +541,7 @@ Power::Power() : OSThread("Power")
bool Power::analogInit() bool Power::analogInit()
{ {
#ifdef EXT_PWR_DETECT #ifdef EXT_PWR_DETECT
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB) #ifdef HELTEC_CAPSULE_SENSOR_V3
pinMode(EXT_PWR_DETECT, INPUT_PULLUP); pinMode(EXT_PWR_DETECT, INPUT_PULLUP);
#else #else
pinMode(EXT_PWR_DETECT, INPUT); pinMode(EXT_PWR_DETECT, INPUT);
@@ -705,12 +668,12 @@ void Power::readPowerStatus()
int8_t batteryChargePercent = -1; int8_t batteryChargePercent = -1;
OptionalBool usbPowered = OptUnknown; OptionalBool usbPowered = OptUnknown;
OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time
OptionalBool isChargingNow = OptUnknown; OptionalBool isCharging = OptUnknown;
if (batteryLevel) { if (batteryLevel) {
hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse; hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse;
usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse; usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse;
isChargingNow = batteryLevel->isCharging() ? OptTrue : OptFalse; isCharging = batteryLevel->isCharging() ? OptTrue : OptFalse;
if (hasBattery) { if (hasBattery) {
batteryVoltageMv = batteryLevel->getBattVoltage(); batteryVoltageMv = batteryLevel->getBattVoltage();
// If the AXP192 returns a valid battery percentage, use it // If the AXP192 returns a valid battery percentage, use it
@@ -739,15 +702,15 @@ void Power::readPowerStatus()
// If changed to DISCONNECTED // If changed to DISCONNECTED
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
isChargingNow = usbPowered = OptFalse; isCharging = usbPowered = OptFalse;
// If changed to CONNECTED / READY // If changed to CONNECTED / READY
else else
isChargingNow = usbPowered = OptTrue; isCharging = usbPowered = OptTrue;
#endif #endif
// Notify any status instances that are observing us // Notify any status instances that are observing us
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent); const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent);
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(), LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent()); powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2); newStatus.notifyObservers(&powerStatus2);
@@ -793,7 +756,6 @@ void Power::readPowerStatus()
// If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in // If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in
// a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough. // a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough.
// //
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) { if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
low_voltage_counter++; low_voltage_counter++;
@@ -853,8 +815,7 @@ int32_t Power::runOnce()
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3? #ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
if (PMU->isPekeyLongPressIrq()) { if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press"); LOG_DEBUG("PEK long button press");
if (screen) screen->setOn(false);
screen->setOn(false);
} }
#endif #endif

View File

@@ -19,7 +19,7 @@
#include "sleep.h" #include "sleep.h"
#include "target_specific.h" #include "target_specific.h"
#if HAS_WIFI && !defined(ARCH_PORTDUINO) || defined(MESHTASTIC_EXCLUDE_WIFI) #if HAS_WIFI && !defined(ARCH_PORTDUINO)
#include "mesh/wifi/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#endif #endif
@@ -82,8 +82,7 @@ static uint32_t secsSlept;
static void lsEnter() static void lsEnter()
{ {
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs); LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs);
if (screen) screen->setOn(false);
screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time secsSlept = 0; // How long have we been sleeping this time
// LOG_INFO("lsEnter end"); // LOG_INFO("lsEnter end");
@@ -161,8 +160,7 @@ static void lsExit()
static void nbEnter() static void nbEnter()
{ {
LOG_DEBUG("State: NB"); LOG_DEBUG("State: NB");
if (screen) screen->setOn(false);
screen->setOn(false);
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only ESP32 should turn off bluetooth // Only ESP32 should turn off bluetooth
setBluetoothEnable(false); setBluetoothEnable(false);
@@ -174,26 +172,22 @@ static void nbEnter()
static void darkEnter() static void darkEnter()
{ {
setBluetoothEnable(true); setBluetoothEnable(true);
if (screen) screen->setOn(false);
screen->setOn(false);
} }
static void serialEnter() static void serialEnter()
{ {
LOG_DEBUG("State: SERIAL"); LOG_DEBUG("State: SERIAL");
setBluetoothEnable(false); setBluetoothEnable(false);
if (screen) { screen->setOn(true);
screen->setOn(true); screen->print("Serial connected\n");
screen->print("Serial connected\n");
}
} }
static void serialExit() static void serialExit()
{ {
// Turn bluetooth back on when we leave serial stream API // Turn bluetooth back on when we leave serial stream API
setBluetoothEnable(true); setBluetoothEnable(true);
if (screen) screen->print("Serial disconnected\n");
screen->print("Serial disconnected\n");
} }
static void powerEnter() static void powerEnter()
@@ -204,8 +198,7 @@ static void powerEnter()
LOG_INFO("Loss of power in Powered"); LOG_INFO("Loss of power in Powered");
powerFSM.trigger(EVENT_POWER_DISCONNECTED); powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} else { } else {
if (screen) screen->setOn(true);
screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
// within enter() the function getState() returns the state we came from // within enter() the function getState() returns the state we came from
@@ -228,8 +221,7 @@ static void powerIdle()
static void powerExit() static void powerExit()
{ {
if (screen) screen->setOn(true);
screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
// Mothballed: print change of power-state to device screen // Mothballed: print change of power-state to device screen
@@ -240,8 +232,7 @@ static void powerExit()
static void onEnter() static void onEnter()
{ {
LOG_DEBUG("State: ON"); LOG_DEBUG("State: ON");
if (screen) screen->setOn(true);
screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
} }
@@ -255,8 +246,7 @@ static void onIdle()
static void screenPress() static void screenPress()
{ {
if (screen) screen->onPress();
screen->onPress();
} }
static void bootEnter() static void bootEnter()
@@ -279,6 +269,9 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup() void PowerFSM_setup()
{ {
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0); bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
bool hasPower = isPowered(); bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0); LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0);
@@ -390,12 +383,6 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/firmware/issues/1071 // See: https://github.com/meshtastic/firmware/issues/1071
// Don't add power saving transitions if we are a power saving tracker or sensor or have Wifi enabled. Sleep will be initiated // Don't add power saving transitions if we are a power saving tracker or sensor or have Wifi enabled. Sleep will be initiated
// through the modules // through the modules
#if HAS_WIFI || !defined(MESHTASTIC_EXCLUDE_WIFI)
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
if ((isRouter || config.power.is_power_saving) && !isWifiAvailable() && !isTrackerOrSensor) { if ((isRouter || config.power.is_power_saving) && !isWifiAvailable() && !isTrackerOrSensor) {
powerFSM.add_timed_transition(&stateNB, &stateLS, powerFSM.add_timed_transition(&stateNB, &stateLS,
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
@@ -413,9 +400,7 @@ void PowerFSM_setup()
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
NULL, "Screen-on timeout"); NULL, "Screen-on timeout");
} }
#endif // HAS_WIFI || !defined(MESHTASTIC_EXCLUDE_WIFI) #else
#else // (not) ARCH_ESP32
// If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark // If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark
powerFSM.add_timed_transition(&stateDARK, &stateDARK, powerFSM.add_timed_transition(&stateDARK, &stateDARK,
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
@@ -424,4 +409,4 @@ void PowerFSM_setup()
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
} }
#endif #endif

View File

@@ -30,11 +30,8 @@ struct ToneDuration {
#define NOTE_B3 247 #define NOTE_B3 247
#define NOTE_CS4 277 #define NOTE_CS4 277
const int DURATION_1_8 = 125; // 1/8 note const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note const int DURATION_1_4 = 250; // 1/4 note
const int DURATION_1_2 = 500; // 1/2 note
const int DURATION_3_4 = 750; // 1/4 note
const int DURATION_1_1 = 1000; // 1/1 note
void playTones(const ToneDuration *tone_durations, int size) void playTones(const ToneDuration *tone_durations, int size)
{ {
@@ -58,12 +55,6 @@ void playBeep()
playTones(melody, sizeof(melody) / sizeof(ToneDuration)); playTones(melody, sizeof(melody) / sizeof(ToneDuration));
} }
void playLongBeep()
{
ToneDuration melody[] = {{NOTE_B3, DURATION_1_1}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playGPSEnableBeep() void playGPSEnableBeep()
{ {
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}}; ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
void playBeep(); void playBeep();
void playLongBeep();
void playStartMelody(); void playStartMelody();
void playShutdownMelody(); void playShutdownMelody();
void playGPSEnableBeep(); void playGPSEnableBeep();

View File

@@ -80,10 +80,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Override user saved region, for producing region-locked builds // Override user saved region, for producing region-locked builds
// #define REGULATORY_LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923 // #define REGULATORY_LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923
// Total system gain in dBm to subtract from Tx power to remain within regulatory and Tx PA limits // Total system gain in dBm to subtract from Tx power to remain within regulatory ERP limit for non-licensed operators
// This value should be set in variant.h and is PA gain + antenna gain (if variant has a non-removable antenna) // This value should be set in variant.h and is PA gain + antenna gain (if system ships with an antenna)
#ifndef TX_GAIN_LORA #ifndef REGULATORY_GAIN_LORA
#define TX_GAIN_LORA 0 #define REGULATORY_GAIN_LORA 0
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -99,12 +99,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// OLED & Input // OLED & Input
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#if defined(SEEED_WIO_TRACKER_L1)
#define SSD1306_ADDRESS 0x3D
#define USE_SH1106
#else
#define SSD1306_ADDRESS 0x3C #define SSD1306_ADDRESS 0x3C
#endif
#define ST7567_ADDRESS 0x3F #define ST7567_ADDRESS 0x3F
// The SH1106 controller is almost, but not quite, the same as SSD1306 // The SH1106 controller is almost, but not quite, the same as SSD1306
@@ -156,8 +152,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MLX90614_ADDR_DEF 0x5A #define MLX90614_ADDR_DEF 0x5A
#define CGRADSENS_ADDR 0x66 #define CGRADSENS_ADDR 0x66
#define LTR390UV_ADDR 0x53 #define LTR390UV_ADDR 0x53
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34 // same adress as TCA8418
#define PCT2075_ADDR 0x37
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ACCELEROMETER // ACCELEROMETER
@@ -176,7 +170,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// LED // LED
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define NCP5623_ADDR 0x38 #define NCP5623_ADDR 0x38
#define LP5562_ADDR 0x30
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Security // Security
@@ -302,11 +295,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#error HW_VENDOR must be defined #error HW_VENDOR must be defined
#endif #endif
// Support multiple RGB LED configuration
#if defined(HAS_NCP5623) || defined(HAS_LP5562) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#define HAS_RGB_LED
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Global switches to turn off features for a minimized build // Global switches to turn off features for a minimized build
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -31,8 +31,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
{ {
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB, TCA8418KB}; ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB};
return firstOfOrNONE(6, types); return firstOfOrNONE(5, types);
} }
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
@@ -41,12 +41,6 @@ ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
return firstOfOrNONE(8, types); return firstOfOrNONE(8, types);
} }
ScanI2C::FoundDevice ScanI2C::firstRGBLED() const
{
ScanI2C::DeviceType types[] = {NCP5623, LP5562};
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
{ {
return DEVICE_NONE; return DEVICE_NONE;

View File

@@ -18,7 +18,7 @@ class ScanI2C
TDECKKB, TDECKKB,
BBQ10KB, BBQ10KB,
RAK14004, RAK14004,
PMU_AXP192_AXP2101, // has the same adress as the TCA8418KB PMU_AXP192_AXP2101,
BME_680, BME_680,
BME_280, BME_280,
BMP_280, BMP_280,
@@ -49,7 +49,6 @@ class ScanI2C
VEML7700, VEML7700,
RCWL9620, RCWL9620,
NCP5623, NCP5623,
LP5562,
TSL2591, TSL2591,
OPT3001, OPT3001,
MLX90632, MLX90632,
@@ -70,8 +69,6 @@ class ScanI2C
DFROBOT_RAIN, DFROBOT_RAIN,
DPS310, DPS310,
LTR390UV, LTR390UV,
TCA8418KB,
PCT2075,
} DeviceType; } DeviceType;
// typedef uint8_t DeviceAddress; // typedef uint8_t DeviceAddress;
@@ -124,8 +121,6 @@ class ScanI2C
FoundDevice firstAccelerometer() const; FoundDevice firstAccelerometer() const;
FoundDevice firstRGBLED() const;
virtual FoundDevice find(DeviceType) const; virtual FoundDevice find(DeviceType) const;
virtual bool exists(DeviceType) const; virtual bool exists(DeviceType) const;

View File

@@ -10,6 +10,11 @@
#include "meshUtils.h" // vformat #include "meshUtils.h" // vformat
#endif #endif
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#endif
bool in_array(uint8_t *array, int size, uint8_t lookfor) bool in_array(uint8_t *array, int size, uint8_t lookfor)
{ {
int i; int i;
@@ -213,20 +218,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#ifdef HAS_NCP5623 #ifdef HAS_NCP5623
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address); SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
#endif #endif
#ifdef HAS_LP5562 #ifdef HAS_PMU
SCAN_SIMPLE_CASE(LP5562_ADDR, LP5562, "LP5562", (uint8_t)addr.address); SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "AXP192/AXP2101", (uint8_t)addr.address)
#endif #endif
case XPOWERS_AXP192_AXP2101_ADDRESS:
// Do we have the axp2101/192 or the TCA8418
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x90), 1);
if (registerValue == 0x0) {
logFoundDevice("TCA8418", (uint8_t)addr.address);
type = TCA8418KB;
} else {
logFoundDevice("AXP192/AXP2101", (uint8_t)addr.address);
type = PMU_AXP192_AXP2101;
}
break;
case BME_ADDR: case BME_ADDR:
case BME_ADDR_ALTERNATE: case BME_ADDR_ALTERNATE:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
@@ -434,7 +428,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address); SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address); SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address); SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address);
#ifdef HAS_TPS65233 #ifdef HAS_TPS65233
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
#endif #endif

View File

@@ -12,7 +12,6 @@
#include "RTC.h" #include "RTC.h"
#include "Throttle.h" #include "Throttle.h"
#include "buzz.h" #include "buzz.h"
#include "concurrency/Periodic.h"
#include "meshUtils.h" #include "meshUtils.h"
#include "main.h" // pmu_found #include "main.h" // pmu_found
@@ -90,45 +89,6 @@ static const char *getGPSPowerStateString(GPSPowerState state)
} }
} }
#ifdef PIN_GPS_SWITCH
// If we have a hardware switch, define a periodic watcher outside of the GPS runOnce thread, since this can be sleeping
// idefinitely
int lastState = LOW;
bool firstrun = true;
static int32_t gpsSwitch()
{
if (gps) {
int currentState = digitalRead(PIN_GPS_SWITCH);
// if the switch is set to zero, disable the GPS Thread
if (firstrun)
if (currentState == LOW)
lastState = HIGH;
if (currentState != lastState) {
if (currentState == LOW) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
if (!firstrun)
playGPSDisableBeep();
gps->disable();
} else {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
if (!firstrun)
playGPSEnableBeep();
gps->enable();
}
lastState = currentState;
}
firstrun = false;
}
return 1000;
}
static concurrency::Periodic *gpsPeriodic;
#endif
static void UBXChecksum(uint8_t *message, size_t length) static void UBXChecksum(uint8_t *message, size_t length)
{ {
uint8_t CK_A = 0, CK_B = 0; uint8_t CK_A = 0, CK_B = 0;
@@ -570,19 +530,6 @@ bool GPS::setup()
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s) // Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
_serial_gps->write("$PMTK886,1*29\r\n"); _serial_gps->write("$PMTK886,1*29\r\n");
delay(250); delay(250);
} else if (gnssModel == GNSS_MODEL_MTK_PA1010D) {
// PA1010D is used in the Pimoroni GPS board.
// Enable all constellations.
_serial_gps->write("$PMTK353,1,1,1,1,1*2A\r\n");
// Above command will reset the GPS and takes longer before it will accept new commands
delay(1000);
// Only ask for RMC and GGA (GNRMC and GNGGA)
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
delay(250);
// Enable SBAS / WAAS
_serial_gps->write("$PMTK301,2*2E\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) { } else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
// PA1616S is used in some GPS breakout boards from Adafruit // PA1616S is used in some GPS breakout boards from Adafruit
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here. // PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
@@ -823,6 +770,13 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
powerState = newState; powerState = newState;
LOG_INFO("GPS power state move from %s to %s", getGPSPowerStateString(oldState), getGPSPowerStateString(newState)); LOG_INFO("GPS power state move from %s to %s", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
#ifdef HELTEC_MESH_NODE_T114
if ((oldState == GPS_OFF || oldState == GPS_HARDSLEEP) && (newState != GPS_OFF && newState != GPS_HARDSLEEP)) {
_serial_gps->begin(serialSpeeds[speedSelect]);
} else if ((newState == GPS_OFF || newState == GPS_HARDSLEEP) && (oldState != GPS_OFF && oldState != GPS_HARDSLEEP)) {
_serial_gps->end();
}
#endif
switch (newState) { switch (newState) {
case GPS_ACTIVE: case GPS_ACTIVE:
case GPS_IDLE: case GPS_IDLE:
@@ -1027,16 +981,15 @@ void GPS::down()
setPowerState(GPS_IDLE); setPowerState(GPS_IDLE);
else { else {
// Check whether the GPS hardware is capable of GPS_SOFTSLEEP // Check whether the GPS hardware is capable of GPS_SOFTSLEEP
// If not, fallback to GPS_HARDSLEEP instead // If not, fallback to GPS_HARDSLEEP instead
#ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin
bool softsleepSupported = true;
#else
bool softsleepSupported = false; bool softsleepSupported = false;
#endif
// U-blox is supported via PMREQ // U-blox is supported via PMREQ
if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10)) if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10))
softsleepSupported = true; softsleepSupported = true;
#ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin
softsleepSupported = true;
#endif
if (softsleepSupported) { if (softsleepSupported) {
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than // How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
@@ -1247,14 +1200,12 @@ GnssModel_t GPS::probe(int serialSpeed)
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500); PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500); PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
// Close all NMEA sentences, valid for MTK3333 and MTK3339 platforms // Close all NMEA sentences, valid for L76B MTK platform (Waveshare Pico GPS)
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n"); _serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
delay(20); delay(20);
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B}, {"PA1010D", "1010D", GNSS_MODEL_MTK_PA1010D}, std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B},
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S}, {"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B}, {"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S},
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}, {"L80-R", "_3337_", GNSS_MODEL_MTK_L76B}, {"LS20031", "MC-1513", GNSS_MODEL_LS20031}};
{"L80", "_3339_", GNSS_MODEL_MTK_L76B}};
PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500); PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500);
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00}; uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
@@ -1437,12 +1388,6 @@ GPS *GPS::createGps()
pinMode(PIN_GPS_PPS, INPUT); pinMode(PIN_GPS_PPS, INPUT);
#endif #endif
#ifdef PIN_GPS_SWITCH
// toggle GPS via external GPIO switch
pinMode(PIN_GPS_SWITCH, INPUT);
gpsPeriodic = new concurrency::Periodic("GPSSwitch", gpsSwitch);
#endif
// Currently disabled per issue #525 (TinyGPS++ crash bug) // Currently disabled per issue #525 (TinyGPS++ crash bug)
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP // when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS #ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS

View File

@@ -27,7 +27,6 @@ typedef enum {
GNSS_MODEL_UC6580, GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN, GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B, GNSS_MODEL_MTK_L76B,
GNSS_MODEL_MTK_PA1010D,
GNSS_MODEL_MTK_PA1616S, GNSS_MODEL_MTK_PA1616S,
GNSS_MODEL_AG3335, GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352, GNSS_MODEL_AG3352,

View File

@@ -224,7 +224,7 @@ static const uint8_t _message_GSA[] = {
0x00, // Rate for DDC 0x00, // Rate for DDC
0x00, // Rate for UART1 0x00, // Rate for UART1
0x00, // Rate for UART2 0x00, // Rate for UART2
0x00, // Rate for USB useful for native linux 0x00, // Rate for USB usefull for native linux
0x00, // Rate for SPI 0x00, // Rate for SPI
0x00 // Reserved 0x00 // Reserved
}; };
@@ -258,7 +258,7 @@ static const uint8_t _message_RMC[] = {
0x00, // Rate for DDC 0x00, // Rate for DDC
0x01, // Rate for UART1 0x01, // Rate for UART1
0x00, // Rate for UART2 0x00, // Rate for UART2
0x01, // Rate for USB useful for native linux 0x01, // Rate for USB usefull for native linux
0x00, // Rate for SPI 0x00, // Rate for SPI
0x00 // Reserved 0x00 // Reserved
}; };
@@ -269,7 +269,7 @@ static const uint8_t _message_GGA[] = {
0x00, // Rate for DDC 0x00, // Rate for DDC
0x01, // Rate for UART1 0x01, // Rate for UART1
0x00, // Rate for UART2 0x00, // Rate for UART2
0x01, // Rate for USB, useful for native linux 0x01, // Rate for USB, usefull for native linux
0x00, // Rate for SPI 0x00, // Rate for SPI
0x00 // Reserved 0x00 // Reserved
}; };

View File

@@ -128,25 +128,16 @@ bool EInkDisplay::connect()
#ifdef PIN_EINK_EN #ifdef PIN_EINK_EN
// backlight power, HIGH is backlight on, LOW is off // backlight power, HIGH is backlight on, LOW is off
pinMode(PIN_EINK_EN, OUTPUT); pinMode(PIN_EINK_EN, OUTPUT);
#ifdef ELECROW_ThinkNode_M1
// ThinkNode M1 has a hardware dimmable backlight. Start enabled
digitalWrite(PIN_EINK_EN, HIGH);
#else
digitalWrite(PIN_EINK_EN, LOW); digitalWrite(PIN_EINK_EN, LOW);
#endif #endif
#endif
#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1) #if defined(TTGO_T_ECHO)
{ {
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1); 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 = new GxEPD2_BW<EINK_DISPLAY_MODEL, EINK_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(); adafruitDisplay->init();
#ifdef ELECROW_ThinkNode_M1
adafruitDisplay->setRotation(4);
#else
adafruitDisplay->setRotation(3); adafruitDisplay->setRotation(3);
#endif
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight); adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} }
#elif defined(MESHLINK) #elif defined(MESHLINK)
@@ -175,12 +166,12 @@ bool EInkDisplay::connect()
} }
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213) || \ #elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213) || \
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER) || \ defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER)
defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER)
{ {
// Start HSPI // Start HSPI
hspi = new SPIClass(HSPI); hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
// VExt already enabled in setup() // VExt already enabled in setup()
// RTC GPIO hold disabled in setup() // RTC GPIO hold disabled in setup()
@@ -191,7 +182,7 @@ bool EInkDisplay::connect()
// Init GxEPD2 // Init GxEPD2
adafruitDisplay->init(); adafruitDisplay->init();
adafruitDisplay->setRotation(3); adafruitDisplay->setRotation(3);
#if defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(CROWPANEL_ESP32S3_4_EPAPER) #if defined(CROWPANEL_ESP32S3_5_EPAPER)
adafruitDisplay->setRotation(0); adafruitDisplay->setRotation(0);
#endif #endif
} }
@@ -217,21 +208,6 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(1); adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, EINK_WIDTH, EINK_HEIGHT); adafruitDisplay->setPartialWindow(0, 0, EINK_WIDTH, EINK_HEIGHT);
} }
#elif defined(HELTEC_MESH_POCKET)
{
spi1 = &SPI1;
spi1->begin();
// VExt already enabled in setup()
// RTC GPIO hold disabled in setup()
// Create GxEPD2 objects
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);
// Init GxEPD2
adafruitDisplay->init();
adafruitDisplay->setRotation(3);
}
#endif #endif
return true; return true;

View File

@@ -68,15 +68,10 @@ class EInkDisplay : public OLEDDisplay
// If display uses HSPI // If display uses HSPI
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E213) || \ #if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E213) || \
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER) || \ defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER)
defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER)
SPIClass *hspi = NULL; SPIClass *hspi = NULL;
#endif #endif
#if defined(HELTEC_MESH_POCKET)
SPIClass *spi1 = NULL;
#endif
private: private:
// FIXME quick hack to limit drawing to a very slow rate // FIXME quick hack to limit drawing to a very slow rate
uint32_t lastDrawMsec = 0; uint32_t lastDrawMsec = 0;

View File

@@ -1,5 +0,0 @@
#ifdef HAS_LP5562
#include <LP5562.h>
extern LP5562 rgbw;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,6 @@
#include "detect/ScanI2C.h" #include "detect/ScanI2C.h"
#include "mesh/generated/meshtastic/config.pb.h" #include "mesh/generated/meshtastic/config.pb.h"
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <string>
#include <vector>
#define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2)
#if !HAS_SCREEN #if !HAS_SCREEN
#include "power.h" #include "power.h"
@@ -68,7 +64,6 @@ class Screen
#include "mesh/MeshModule.h" #include "mesh/MeshModule.h"
#include "power.h" #include "power.h"
#include <string> #include <string>
#include <vector>
// 0 to 255, though particular variants might define different defaults // 0 to 255, though particular variants might define different defaults
#ifndef BRIGHTNESS_DEFAULT #ifndef BRIGHTNESS_DEFAULT
@@ -95,7 +90,7 @@ class Screen
/// Convert an integer GPS coords to a floating point /// Convert an integer GPS coords to a floating point
#define DegD(i) (i * 1e-7) #define DegD(i) (i * 1e-7)
extern bool hasUnreadMessage;
namespace namespace
{ {
/// A basic 2D point class for drawing /// A basic 2D point class for drawing
@@ -186,23 +181,9 @@ class Screen : public concurrency::OSThread
public: public:
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY); explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
size_t frameCount = 0; // Total number of active frames
~Screen(); ~Screen();
// Which frame we want to be displayed, after we regen the frameset by calling setFrames
enum FrameFocus : uint8_t {
FOCUS_DEFAULT, // No specific frame
FOCUS_PRESERVE, // Return to the previous frame
FOCUS_FAULT,
FOCUS_TEXTMESSAGE,
FOCUS_MODULE, // Note: target module should call requestFocus(), otherwise no info about which module to focus
};
// Regenerate the normal set of frames, focusing a specific frame if requested
// Call when a frame should be added / removed, or custom frames should be cleared
void setFrames(FrameFocus focus = FOCUS_DEFAULT);
std::vector<const uint8_t *> indicatorIcons; // Per-frame custom icon pointers
Screen(const Screen &) = delete; Screen(const Screen &) = delete;
Screen &operator=(const Screen &) = delete; Screen &operator=(const Screen &) = delete;
@@ -233,11 +214,21 @@ class Screen : public concurrency::OSThread
void blink(); void blink();
void drawFrameText(OLEDDisplay *, OLEDDisplayUiState *, int16_t, int16_t, const char *);
void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength); void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength);
// Draw north // Draw north
void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading);
static uint16_t getCompassDiam(uint32_t displayWidth, uint32_t displayHeight);
float estimatedHeading(double lat, double lon); float estimatedHeading(double lat, double lon);
void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian);
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields);
/// Handle button press, trackball or swipe action) /// Handle button press, trackball or swipe action)
void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); } void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); }
void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); } void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); }
@@ -269,8 +260,6 @@ class Screen : public concurrency::OSThread
enqueueCmd(cmd); enqueueCmd(cmd);
} }
void showOverlayBanner(const char *message, uint32_t durationMs = 3000);
void startFirmwareUpdateScreen() void startFirmwareUpdateScreen()
{ {
ScreenCmd cmd; ScreenCmd cmd;
@@ -317,6 +306,9 @@ class Screen : public concurrency::OSThread
} }
} }
/// generates a very brief time delta display
std::string drawTimeDelta(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds);
/// Overrides the default utf8 character conversion, to replace empty space with question marks /// Overrides the default utf8 character conversion, to replace empty space with question marks
static char customFontTableLookup(const uint8_t ch) static char customFontTableLookup(const uint8_t ch)
{ {
@@ -608,26 +600,30 @@ class Screen : public concurrency::OSThread
// - Used to dismiss the currently shown frame (txt; waypoint) by CardKB combo // - Used to dismiss the currently shown frame (txt; waypoint) by CardKB combo
struct FramesetInfo { struct FramesetInfo {
struct FramePositions { struct FramePositions {
uint8_t fault = 255; uint8_t fault = 0;
uint8_t textMessage = 255; uint8_t textMessage = 0;
uint8_t waypoint = 255; uint8_t waypoint = 0;
uint8_t focusedModule = 255; uint8_t focusedModule = 0;
uint8_t log = 255; uint8_t log = 0;
uint8_t settings = 255; uint8_t settings = 0;
uint8_t wifi = 255; uint8_t wifi = 0;
uint8_t deviceFocused = 255;
uint8_t memory = 255;
} positions; } positions;
uint8_t frameCount = 0; uint8_t frameCount = 0;
} framesetInfo; } framesetInfo;
struct DismissedFrames { // Which frame we want to be displayed, after we regen the frameset by calling setFrames
bool textMessage = false; enum FrameFocus : uint8_t {
bool waypoint = false; FOCUS_DEFAULT, // No specific frame
bool wifi = false; FOCUS_PRESERVE, // Return to the previous frame
bool memory = false; FOCUS_FAULT,
} dismissedFrames; FOCUS_TEXTMESSAGE,
FOCUS_MODULE, // Note: target module should call requestFocus(), otherwise no info about which module to focus
};
// Regenerate the normal set of frames, focusing a specific frame if requested
// Call when a frame should be added / removed, or custom frames should be cleared
void setFrames(FrameFocus focus = FOCUS_DEFAULT);
/// Try to start drawing ASAP /// Try to start drawing ASAP
void setFastFramerate(); void setFastFramerate();
@@ -635,6 +631,13 @@ class Screen : public concurrency::OSThread
// Sets frame up for immediate drawing // Sets frame up for immediate drawing
void setFrameImmediateDraw(FrameCallback *drawFrames); void setFrameImmediateDraw(FrameCallback *drawFrames);
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
static void drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
#if defined(DISPLAY_CLOCK_FRAME) #if defined(DISPLAY_CLOCK_FRAME)
static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
@@ -688,13 +691,4 @@ class Screen : public concurrency::OSThread
} // namespace graphics } // namespace graphics
extern "C" {
extern char *alertBannerMessage;
extern uint32_t alertBannerUntil;
}
// Extern declarations for function symbols used in UIRenderer
extern std::vector<std::string> functionSymbol;
extern std::string functionSymbolString;
#endif #endif

View File

@@ -16,10 +16,6 @@
#include "graphics/fonts/OLEDDisplayFontsCS.h" #include "graphics/fonts/OLEDDisplayFontsCS.h"
#endif #endif
#ifdef CROWPANEL_ESP32S3_5_EPAPER
#include "graphics/fonts/EinkDisplayFonts.h"
#endif
#ifdef OLED_PL #ifdef OLED_PL
#define FONT_SMALL_LOCAL ArialMT_Plain_10_PL #define FONT_SMALL_LOCAL ArialMT_Plain_10_PL
#else #else
@@ -65,7 +61,7 @@
#endif #endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS)) && \ defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
// The screen is bigger so use bigger fonts // The screen is bigger so use bigger fonts
#define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19 #define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19
@@ -78,12 +74,13 @@
#endif #endif
#if defined(CROWPANEL_ESP32S3_5_EPAPER) #if defined(CROWPANEL_ESP32S3_5_EPAPER)
#include "graphics/fonts/EinkDisplayFonts.h"
#undef FONT_SMALL #undef FONT_SMALL
#undef FONT_MEDIUM #undef FONT_MEDIUM
#undef FONT_LARGE #undef FONT_LARGE
#define FONT_SMALL Monospaced_plain_30 #define FONT_SMALL FONT_LARGE_LOCAL // Height: 30
#define FONT_MEDIUM Monospaced_plain_30 #define FONT_MEDIUM FONT_LARGE_LOCAL // Height: 30
#define FONT_LARGE Monospaced_plain_30 #define FONT_LARGE FONT_LARGE_LOCAL // Height: 30
#endif #endif
#define _fontHeight(font) ((font)[1] + 1) // height is position 1 #define _fontHeight(font) ((font)[1] + 1) // height is position 1

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