mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-10 22:11:00 +10:00
Compare commits
213
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b9e06b05f | ||
|
|
288d7a3e7b | ||
|
|
4990bf51e3 | ||
|
|
b2c8cbb78d | ||
|
|
8061f83704 | ||
|
|
a3b49b9028 | ||
|
|
17945884a5 | ||
|
|
7fdee353b5 | ||
|
|
1116f06139 | ||
|
|
16cf962351 | ||
|
|
12f0a74557 | ||
|
|
2dd9c5eef2 | ||
|
|
98963218ad | ||
|
|
6628c9e66e | ||
|
|
c728cfdaf4 | ||
|
|
d96770007d | ||
|
|
9322bcdb21 | ||
|
|
1370b234eb | ||
|
|
9ba44bfbfb | ||
|
|
2f19a1d7a4 | ||
|
|
71c8143f72 | ||
|
|
222d3e6b62 | ||
|
|
2e6519bb98 | ||
|
|
934c3fa8be | ||
|
|
726d539174 | ||
|
|
e7ee4bea18 | ||
|
|
7f0cd70c07 | ||
|
|
d5fe7dc9e6 | ||
|
|
98efb25a0c | ||
|
|
8dc3c0541b | ||
|
|
efd2613bd7 | ||
|
|
fc6c89abeb | ||
|
|
c7feef00c0 | ||
|
|
f88bc732cc | ||
|
|
8c905427a1 | ||
|
|
90befeeeb1 | ||
|
|
9e61c44629 | ||
|
|
3ad80b80ee | ||
|
|
8fe12e9fda | ||
|
|
0746f8cfff | ||
|
|
4e05f20c58 | ||
|
|
0ac95e370b | ||
|
|
33d526f6f9 | ||
|
|
0abd3cdde8 | ||
|
|
870ba80092 | ||
|
|
2955c12d2a | ||
|
|
283ccb83d1 | ||
|
|
5319bc7c2c | ||
|
|
198339873a | ||
|
|
db694f2f24 | ||
|
|
29d70853e6 | ||
|
|
976d201fc1 | ||
|
|
80763ca235 | ||
|
|
844f5b46d0 | ||
|
|
814f1289f6 | ||
|
|
aec98b61b9 | ||
|
|
0b7556b590 | ||
|
|
99abfebc4a | ||
|
|
068f5af4d8 | ||
|
|
f7e4ac3e43 | ||
|
|
c36ae159ed | ||
|
|
993c242202 | ||
|
|
33e7f16c05 | ||
|
|
3d4f0b895b | ||
|
|
3b29eea577 | ||
|
|
e7e34e86d5 | ||
|
|
5a009889cc | ||
|
|
c4bac04be3 | ||
|
|
b9bdc87367 | ||
|
|
d3a86841b9 | ||
|
|
3b079c91bf | ||
|
|
d693fd4232 | ||
|
|
163c54877c | ||
|
|
2e2993f180 | ||
|
|
450f2adab0 | ||
|
|
e14b8d385a | ||
|
|
8ce1a872eb | ||
|
|
0ad1b66387 | ||
|
|
5716aeba3b | ||
|
|
abfa346630 | ||
|
|
723209b198 | ||
|
|
2ffe2d829c | ||
|
|
bfaf6c6b20 | ||
|
|
5a8ce60d68 | ||
|
|
d293d654a0 | ||
|
|
8384659608 | ||
|
|
c77b10a317 | ||
|
|
8fa5b4f7ce | ||
|
|
e30294b6da | ||
|
|
948c28afff | ||
|
|
a632d0133f | ||
|
|
f982b58d61 | ||
|
|
efb0b299b2 | ||
|
|
d09433e453 | ||
|
|
139b970409 | ||
|
|
eb80d3141d | ||
|
|
3604c1255d | ||
|
|
22d63fa69c | ||
|
|
fc030d2d19 | ||
|
|
4a534f02a4 | ||
|
|
0ea408e12b | ||
|
|
1fe9a41fb9 | ||
|
|
644d0d4a15 | ||
|
|
2aefd386b6 | ||
|
|
f04746a928 | ||
|
|
532a63e541 | ||
|
|
e4c5bfd161 | ||
|
|
1be2529fb9 | ||
|
|
ea3386f34a | ||
|
|
959756abf1 | ||
|
|
e1d238b75f | ||
|
|
c88b802e32 | ||
|
|
286bc852b3 | ||
|
|
e282491cd8 | ||
|
|
58fee80b30 | ||
|
|
3673af46cf | ||
|
|
7404228555 | ||
|
|
76b6eaa48a | ||
|
|
344fe2f70b | ||
|
|
9f74fc11de | ||
|
|
458e46b1ea | ||
|
|
6f5448fa61 | ||
|
|
d369825c38 | ||
|
|
4fbd5c9f80 | ||
|
|
aebcb34c80 | ||
|
|
2ef09d17b9 | ||
|
|
39aefde18d | ||
|
|
19d070c284 | ||
|
|
e24db2994b | ||
|
|
b7379f1516 | ||
|
|
fe8bfa0069 | ||
|
|
52750927e3 | ||
|
|
3ef7a15a17 | ||
|
|
ac7a58cd45 | ||
|
|
53c21eb30d | ||
|
|
e51e6cad84 | ||
|
|
4890f7084f | ||
|
|
3fcbfe4370 | ||
|
|
b155a63d3b | ||
|
|
60730a73c2 | ||
|
|
421f9afead | ||
|
|
da808cb43b | ||
|
|
82580c6798 | ||
|
|
429cf51539 | ||
|
|
d9e2b12097 | ||
|
|
016e68ec53 | ||
|
|
d7d08a4725 | ||
|
|
79f469ce71 | ||
|
|
0668b82858 | ||
|
|
0797378a4d | ||
|
|
0501e177e9 | ||
|
|
a79b75a0d5 | ||
|
|
391928ed08 | ||
|
|
6cbb9ab09a | ||
|
|
f185abbcdd | ||
|
|
5d12edbe07 | ||
|
|
398d1adea1 | ||
|
|
393cd96ba2 | ||
|
|
6658ec2603 | ||
|
|
b941dab900 | ||
|
|
ffe6f706f9 | ||
|
|
0ed537a336 | ||
|
|
86dad90573 | ||
|
|
20db5fdbb7 | ||
|
|
5b1ea922f3 | ||
|
|
5b94f580dc | ||
|
|
3d524be965 | ||
|
|
4ec59ce75d | ||
|
|
cb28c38828 | ||
|
|
969aefa551 | ||
|
|
3f5828c0e9 | ||
|
|
5cf365245e | ||
|
|
fdd17ac75c | ||
|
|
9e40c8893f | ||
|
|
afd5e29bce | ||
|
|
20f838a61e | ||
|
|
58736f5184 | ||
|
|
22031c5886 | ||
|
|
fe4e75eb66 | ||
|
|
42075da09e | ||
|
|
6ba82ed5b6 | ||
|
|
935b0504d4 | ||
|
|
a8fed3256e | ||
|
|
1626836a71 | ||
|
|
66161da2a7 | ||
|
|
6bbdfe1797 | ||
|
|
7ea28d34b2 | ||
|
|
65bf1630b3 | ||
|
|
3972fe1fd0 | ||
|
|
5ced739a57 | ||
|
|
b7bf251798 | ||
|
|
90742fc87e | ||
|
|
f7f356e2e2 | ||
|
|
1fad7facd6 | ||
|
|
153ab81a9f | ||
|
|
8d73d67246 | ||
|
|
0d46943bb8 | ||
|
|
deb45e471c | ||
|
|
3601eabbf8 | ||
|
|
eb2f3cef89 | ||
|
|
85be5965b0 | ||
|
|
1e34c1ef1b | ||
|
|
5f852a1c05 | ||
|
|
1d90ea6f1d | ||
|
|
65eee22396 | ||
|
|
cb938266c7 | ||
|
|
8093e2ed5a | ||
|
|
3f5dc78744 | ||
|
|
b0060b61fe | ||
|
|
a7435b85a1 | ||
|
|
729d6c576f | ||
|
|
15b84fca01 | ||
|
|
285b30dff0 |
@@ -100,7 +100,7 @@ runs:
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
@@ -8,8 +8,6 @@ runs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
|
||||
- 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
|
||||
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 accidentally duplicating work etc...
|
||||
- Please do not check in files that don't have real changes
|
||||
- Please do not reformat lines that you didn't have to change the code on
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
|
||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the Linux version),
|
||||
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
|
||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||
- If your other co-developers have comments on your PR please tweak as needed.
|
||||
- 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 you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and community members can help test your changes.
|
||||
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
||||
|
||||
## 🤝 Attestations
|
||||
|
||||
@@ -16,8 +16,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-debian-src:
|
||||
@@ -28,8 +27,6 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
path: meshtasticd
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install deps
|
||||
shell: bash
|
||||
@@ -42,7 +39,8 @@ jobs:
|
||||
sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
if: github.event_name != 'pull_request' && github.event_name != 'pull_request_target'
|
||||
uses: crazy-max/ghaction-import-gpg@v7
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||
id: gpg
|
||||
@@ -60,11 +58,11 @@ jobs:
|
||||
run: debian/ci_pack_sdeb.sh
|
||||
env:
|
||||
SERIES: ${{ inputs.series }}
|
||||
GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }}
|
||||
GPG_KEY_ID: ${{ steps.gpg.outputs.keyid || '' }}
|
||||
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
overwrite: true
|
||||
|
||||
@@ -26,8 +26,6 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Build ${{ inputs.platform }}
|
||||
id: build
|
||||
@@ -111,7 +109,7 @@ jobs:
|
||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
id: upload-firmware
|
||||
with:
|
||||
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
||||
@@ -127,7 +125,7 @@ jobs:
|
||||
release/device-*.bat
|
||||
|
||||
- name: Store manifests as an artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
id: upload-manifest
|
||||
with:
|
||||
name: manifest-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
||||
|
||||
@@ -4,9 +4,14 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
# trunk-ignore(checkov/CKV_GHA_7)
|
||||
target:
|
||||
type: string
|
||||
required: false
|
||||
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
|
||||
arch:
|
||||
type: choice
|
||||
options:
|
||||
- all
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
@@ -15,32 +20,18 @@ on:
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
target:
|
||||
type: string
|
||||
required: false
|
||||
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
|
||||
# find-target:
|
||||
# type: boolean
|
||||
# default: true
|
||||
# description: 'Find the available targets'
|
||||
description: Choose an arch to limit the search, or 'all' to search all architectures.
|
||||
default: all
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
find-targets:
|
||||
if: ${{ inputs.target == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
- all
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
@@ -51,14 +42,37 @@ jobs:
|
||||
- run: pip install -U platformio
|
||||
- name: Generate matrix
|
||||
id: jsonStep
|
||||
env:
|
||||
BUILDTARGET: ${{ inputs.target }}
|
||||
MATRIXARCH: ${{ inputs.arch }}
|
||||
run: |
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level extra)
|
||||
echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Arch: ${{matrix.arch}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Targets:" >> $GITHUB_STEP_SUMMARY
|
||||
echo $TARGETS | jq -r 'sort_by(.board) |.[] | "- " + .board' >> $GITHUB_STEP_SUMMARY
|
||||
if [ "$BUILDTARGET" = "" ]; then
|
||||
echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Arch: $MATRIXARCH" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🎯 The following target boards are available to build:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Platform | Board |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY
|
||||
echo $TARGETS | jq -r 'sort_by(.board) | sort_by(.platform) |.[] | "| " + .platform + " | " + .board + " |" ' >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "We build this one:" >> $GITHUB_STEP_SUMMARY
|
||||
ARCH=$(echo "$TARGETS" | jq --arg BUILDTARGET "$BUILDTARGET" -r '.[] | select(.board==$BUILDTARGET) | .platform')
|
||||
echo "| Platform | Board |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| $ARCH | "$BUILDTARGET" |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
if [[ "$ARCH" == "" ]]; then
|
||||
echo "## ❌ Error: Target "$BUILDTARGET" not found!" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "## ✅ Target "$BUILDTARGET" found, proceeding to build." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "You may need to refresh this page to make the built firmware appear below." >> $GITHUB_STEP_SUMMARY
|
||||
echo "arch=$ARCH" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
outputs:
|
||||
arch: ${{ steps.jsonStep.outputs.arch }}
|
||||
|
||||
version:
|
||||
if: ${{ inputs.target != '' }}
|
||||
@@ -78,16 +92,16 @@ jobs:
|
||||
|
||||
build:
|
||||
if: ${{ inputs.target != '' && inputs.arch != 'native' }}
|
||||
needs: [version]
|
||||
needs: [version, find-targets]
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ inputs.target }}
|
||||
platform: ${{ inputs.arch }}
|
||||
platform: ${{ needs.find-targets.outputs.arch }}
|
||||
|
||||
gather-artifacts:
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
needs: [version, build]
|
||||
@@ -98,7 +112,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-*-*
|
||||
@@ -111,7 +125,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -127,7 +141,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: firmware-*-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -146,7 +160,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop # Default branch, same as 'cron' above
|
||||
paths:
|
||||
- debian/**
|
||||
- "*.rpkg"
|
||||
@@ -16,7 +16,7 @@ on:
|
||||
- .github/workflows/hook_copr.yml
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
@@ -35,8 +35,8 @@ jobs:
|
||||
series:
|
||||
- jammy # 22.04 LTS
|
||||
- noble # 24.04 LTS
|
||||
- plucky # 25.04
|
||||
- questing # 25.10
|
||||
- resolute # 26.04 LTS
|
||||
uses: ./.github/workflows/package_ppa.yml
|
||||
with:
|
||||
ppa_repo: ppa:meshtastic/daily
|
||||
|
||||
@@ -37,7 +37,7 @@ on:
|
||||
value: ${{ jobs.docker-build.outputs.digest }}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
@@ -50,8 +50,6 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Get release version string
|
||||
run: |
|
||||
@@ -60,16 +58,16 @@ jobs:
|
||||
|
||||
- name: Docker login
|
||||
if: ${{ inputs.push }}
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: meshtastic
|
||||
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Docker setup
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Sanitize platform string
|
||||
id: sanitize_platform
|
||||
@@ -78,7 +76,7 @@ jobs:
|
||||
|
||||
- name: Docker tag
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: meshtastic/meshtasticd
|
||||
tags: |
|
||||
@@ -86,7 +84,7 @@ jobs:
|
||||
flavor: latest=false
|
||||
|
||||
- name: Docker build and push
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
id: docker_variant
|
||||
with:
|
||||
context: .
|
||||
|
||||
@@ -12,7 +12,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
@@ -86,8 +86,6 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Get release version string
|
||||
run: |
|
||||
@@ -139,14 +137,14 @@ jobs:
|
||||
id: tags
|
||||
|
||||
- name: Docker login
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: meshtastic
|
||||
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
|
||||
|
||||
- name: Docker meta (Debian)
|
||||
id: meta_debian
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: meshtastic/meshtasticd
|
||||
tags: |
|
||||
@@ -167,7 +165,7 @@ jobs:
|
||||
|
||||
- name: Docker meta (Alpine)
|
||||
id: meta_alpine
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: meshtastic/meshtasticd
|
||||
tags: |
|
||||
|
||||
@@ -11,8 +11,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-copr-hook:
|
||||
@@ -22,8 +21,6 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{ github.ref }}
|
||||
repository: ${{ github.repository }}
|
||||
|
||||
- name: Trigger COPR build
|
||||
uses: vidplace7/copr-build@main
|
||||
|
||||
@@ -15,8 +15,7 @@ on:
|
||||
- "**.md"
|
||||
- version.properties
|
||||
|
||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||
pull_request_target:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
@@ -29,6 +28,8 @@ on:
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
strategy:
|
||||
@@ -88,8 +89,6 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
- name: Check ${{ matrix.check.board }}
|
||||
uses: meshtastic/gh-action-firmware@main
|
||||
with:
|
||||
@@ -126,9 +125,16 @@ jobs:
|
||||
|
||||
test-native:
|
||||
if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }}
|
||||
permissions: # Needed for dorny/test-reporter.
|
||||
contents: read
|
||||
actions: read
|
||||
checks: write
|
||||
uses: ./.github/workflows/test_native.yml
|
||||
|
||||
docker:
|
||||
permissions: # Needed for pushing to GHCR.
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -153,9 +159,6 @@ jobs:
|
||||
gather-artifacts:
|
||||
# trunk-ignore(checkov/CKV2_GHA_1)
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -173,11 +176,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
run: ls -R
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -205,7 +205,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -224,20 +224,13 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
path: ./*.elf
|
||||
retention-days: 30
|
||||
|
||||
- uses: scruplelesswizard/comment-artifact@main
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
shame:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
continue-on-error: true
|
||||
@@ -245,42 +238,44 @@ jobs:
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
if: github.event_name == 'pull_request_target'
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
filter: blob:none # means we download all the git history but none of the commit (except ones with checkout like the head)
|
||||
fetch-depth: 0
|
||||
- name: Download the current manifests
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ./manifests-new/
|
||||
pattern: manifest-*
|
||||
merge-multiple: true
|
||||
- name: Upload combined manifests for later commit and global stats crunching.
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
id: upload-manifest
|
||||
with:
|
||||
name: manifests-${{ github.sha }}
|
||||
overwrite: true
|
||||
path: manifests-new/*.mt.json
|
||||
- name: Find the merge base
|
||||
if: github.event_name == 'pull_request_target'
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "MERGE_BASE=$(git merge-base "origin/$base" "$head")" >> $GITHUB_ENV
|
||||
env:
|
||||
base: ${{ github.base_ref }}
|
||||
head: ${{ github.sha }}
|
||||
# Currently broken (for-loop through EVERY artifact -- rate limiting)
|
||||
# - name: Download the old manifests
|
||||
# if: github.event_name == 'pull_request_target'
|
||||
# if: github.event_name == 'pull_request'
|
||||
# run: gh run download -R "$repo" --name "manifests-$merge_base" --dir manifest-old/
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# merge_base: ${{ env.MERGE_BASE }}
|
||||
# repo: ${{ github.repository }}
|
||||
# - name: Do scan and post comment
|
||||
# if: github.event_name == 'pull_request_target'
|
||||
# if: github.event_name == 'pull_request'
|
||||
# run: python3 bin/shame.py ${{ github.event.pull_request.number }} manifests-old/ manifests-new/
|
||||
|
||||
release-artifacts:
|
||||
permissions: # Needed for 'gh release upload'.
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
|
||||
outputs:
|
||||
@@ -324,14 +319,14 @@ jobs:
|
||||
body: ${{ steps.release_notes.outputs.notes }}
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -355,7 +350,7 @@ jobs:
|
||||
}' > firmware-${{ needs.version.outputs.long }}.json
|
||||
|
||||
- name: Save Release manifest artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: manifest-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -372,6 +367,8 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
release-firmware:
|
||||
permissions: # Needed for 'gh release upload'.
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -396,7 +393,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -413,7 +410,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -454,14 +451,14 @@ jobs:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Get firmware artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./publish
|
||||
|
||||
- name: Get manifest artifact
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: manifest-${{ needs.version.outputs.long }}
|
||||
path: ./publish
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
name: Merge Queue
|
||||
# Not sure how concurrency works in merge_queue, removing for now.
|
||||
# concurrency:
|
||||
# group: merge-queue-${{ github.head_ref || github.run_id }}
|
||||
# cancel-in-progress: true
|
||||
on:
|
||||
# Merge group is a special trigger that is used to trigger the workflow when a merge group is created.
|
||||
merge_group:
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
arch:
|
||||
- all
|
||||
- check
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
cache: pip
|
||||
- run: pip install -U platformio
|
||||
- name: Generate matrix
|
||||
id: jsonStep
|
||||
run: |
|
||||
if [[ "$GITHUB_HEAD_REF" == "" ]]; then
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
||||
else
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr)
|
||||
fi
|
||||
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF"
|
||||
echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
all: ${{ steps.jsonStep.outputs.all }}
|
||||
check: ${{ steps.jsonStep.outputs.check }}
|
||||
|
||||
version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Get release version string
|
||||
run: |
|
||||
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
env:
|
||||
BUILD_LOCATION: local
|
||||
outputs:
|
||||
long: ${{ steps.version.outputs.long }}
|
||||
deb: ${{ steps.version.outputs.deb }}
|
||||
|
||||
check:
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
check: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
- name: Check ${{ matrix.check.board }}
|
||||
run: bin/check-all.sh ${{ matrix.check.board }}
|
||||
|
||||
build:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
matrix:
|
||||
build: ${{ fromJson(needs.setup.outputs.all) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.build.board }}
|
||||
platform: ${{ matrix.build.platform }}
|
||||
|
||||
build-debian-src:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
uses: ./.github/workflows/build_debian_src.yml
|
||||
with:
|
||||
series: UNRELEASED
|
||||
build_location: local
|
||||
secrets: inherit
|
||||
|
||||
package-pio-deps-native-tft:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/package_pio_deps.yml
|
||||
with:
|
||||
pio_env: native-tft
|
||||
secrets: inherit
|
||||
|
||||
test-native:
|
||||
if: ${{ !contains(github.ref_name, 'event/') }}
|
||||
uses: ./.github/workflows/test_native.yml
|
||||
|
||||
docker:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro: [debian, alpine]
|
||||
platform: [linux/amd64, linux/arm64, linux/arm/v7]
|
||||
pio_env: [native, native-tft]
|
||||
exclude:
|
||||
- distro: alpine
|
||||
platform: linux/arm/v7
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm64
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm/v7
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: ${{ matrix.distro }}
|
||||
platform: ${{ matrix.platform }}
|
||||
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
|
||||
pio_env: ${{ matrix.pio_env }}
|
||||
push: false
|
||||
|
||||
gather-artifacts:
|
||||
# trunk-ignore(checkov/CKV2_GHA_1)
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-latest
|
||||
needs: [version, build]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
path: |
|
||||
./firmware-*.bin
|
||||
./firmware-*.uf2
|
||||
./firmware-*.hex
|
||||
./firmware-*.zip
|
||||
./device-*.sh
|
||||
./device-*.bat
|
||||
./littlefs-*.bin
|
||||
./bleota*bin
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
# For diagnostics
|
||||
- name: Show artifacts
|
||||
run: ls -lR
|
||||
|
||||
- name: Device scripts permissions
|
||||
run: |
|
||||
chmod +x ./output/device-install.sh || true
|
||||
chmod +x ./output/device-update.sh || true
|
||||
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
path: ./*.elf
|
||||
retention-days: 30
|
||||
|
||||
- uses: scruplelesswizard/comment-artifact@main
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
release-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
needs:
|
||||
- version
|
||||
- gather-artifacts
|
||||
- build-debian-src
|
||||
- package-pio-deps-native-tft
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v2
|
||||
id: create_release
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
name: Meshtastic Firmware ${{ needs.version.outputs.long }} Alpha
|
||||
tag_name: v${{ needs.version.outputs.long }}
|
||||
body: |
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./output/pio-deps-native-tft
|
||||
|
||||
- name: Zip Linux sources
|
||||
working-directory: output
|
||||
run: |
|
||||
zip -j -9 -r ./meshtasticd-${{ needs.version.outputs.deb }}-src.zip ./debian-src
|
||||
zip -9 -r ./platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip ./pio-deps-native-tft
|
||||
|
||||
# For diagnostics
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -lR
|
||||
|
||||
- name: Add Linux sources to GtiHub Release
|
||||
# Only run when targeting master branch with workflow_dispatch
|
||||
if: ${{ github.ref_name == 'master' }}
|
||||
run: |
|
||||
gh release upload v${{ needs.version.outputs.long }} ./output/meshtasticd-${{ needs.version.outputs.deb }}-src.zip
|
||||
gh release upload v${{ needs.version.outputs.long }} ./output/platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
release-firmware:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
needs: [release-artifacts, version]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -lR
|
||||
|
||||
- name: Device scripts permissions
|
||||
run: |
|
||||
chmod +x ./output/device-install.sh || true
|
||||
chmod +x ./output/device-update.sh || true
|
||||
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./elfs
|
||||
|
||||
- name: Zip debug elfs
|
||||
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./elfs
|
||||
|
||||
# For diagnostics
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -lR
|
||||
|
||||
- name: Add bins and debug elfs to GitHub Release
|
||||
# Only run when targeting master branch with workflow_dispatch
|
||||
if: ${{ github.ref_name == 'master' }}
|
||||
run: |
|
||||
gh release upload v${{ needs.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
gh release upload v${{ needs.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
publish-firmware:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
needs: [release-firmware, version]
|
||||
env:
|
||||
targets: |-
|
||||
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.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-${{ needs.version.outputs.long }}
|
||||
keep_files: true
|
||||
user_name: github-actions[bot]
|
||||
user_email: github-actions[bot]@users.noreply.github.com
|
||||
commit_message: ${{ needs.version.outputs.long }}
|
||||
enable_jekyll: true
|
||||
@@ -18,8 +18,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-debian-src:
|
||||
@@ -58,7 +57,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
@@ -16,8 +16,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
pkg-pio-libdeps:
|
||||
@@ -27,8 +26,6 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
@@ -54,9 +51,19 @@ jobs:
|
||||
PLATFORMIO_LIBDEPS_DIR: pio/libdeps
|
||||
PLATFORMIO_PACKAGES_DIR: pio/packages
|
||||
PLATFORMIO_CORE_DIR: pio/core
|
||||
PLATFORMIO_SETTING_ENABLE_TELEMETRY: 0
|
||||
PLATFORMIO_SETTING_CHECK_PLATFORMIO_INTERVAL: 3650
|
||||
PLATFORMIO_SETTING_CHECK_PRUNE_SYSTEM_THRESHOLD: 10240
|
||||
|
||||
- name: Mangle platformio cache
|
||||
# Add "1" to epoch-timestamps of all downloads in the cache.
|
||||
# This is a hack to prevent internet access at build-time.
|
||||
run: |
|
||||
cp pio/core/.cache/downloads/usage.db pio/core/.cache/downloads/usage.db.bak
|
||||
jq -c 'with_entries(.value |= (. | tostring + "1" | tonumber))' pio/core/.cache/downloads/usage.db.bak > pio/core/.cache/downloads/usage.db
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
@@ -16,8 +16,7 @@ on:
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-debian-src:
|
||||
@@ -36,8 +35,6 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
path: meshtasticd
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install deps
|
||||
shell: bash
|
||||
@@ -46,7 +43,7 @@ jobs:
|
||||
sudo apt-get install -y dput
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
uses: crazy-max/ghaction-import-gpg@v7
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||
id: gpg
|
||||
@@ -60,7 +57,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
@@ -70,5 +67,6 @@ jobs:
|
||||
|
||||
- name: Publish with dput
|
||||
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 15 # dput is terrible, sometimes runs 'forever'
|
||||
run: |
|
||||
dput ${{ inputs.ppa_repo }} meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Download test artifacts
|
||||
if: needs.native-tests.result != 'skipped'
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
@@ -23,8 +23,8 @@ jobs:
|
||||
series:
|
||||
- jammy # 22.04 LTS
|
||||
- noble # 24.04 LTS
|
||||
- plucky # 25.04
|
||||
- questing # 25.10
|
||||
- resolute # 26.04 LTS
|
||||
uses: ./.github/workflows/package_ppa.yml
|
||||
with:
|
||||
ppa_repo: |-
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: report.sarif
|
||||
overwrite: true
|
||||
|
||||
@@ -16,8 +16,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup native build
|
||||
@@ -59,7 +57,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
|
||||
@@ -72,8 +70,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup native build
|
||||
@@ -94,7 +90,7 @@ jobs:
|
||||
|
||||
- name: Save test results
|
||||
if: always() # run this step even if previous step failed
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -108,7 +104,7 @@ jobs:
|
||||
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
|
||||
@@ -128,29 +124,26 @@ jobs:
|
||||
if: always()
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Download test artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
- name: Test Report
|
||||
uses: dorny/test-reporter@v2.5.0
|
||||
uses: dorny/test-reporter@v3.0.0
|
||||
with:
|
||||
name: PlatformIO Tests
|
||||
path: testreport.xml
|
||||
reporter: java-junit
|
||||
|
||||
- name: Download coverage artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
@@ -163,7 +156,7 @@ jobs:
|
||||
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
||||
|
||||
- name: Save Code Coverage Report
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: code-coverage-report-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
node-version: 24
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v5
|
||||
with:
|
||||
version: latest
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ permissions: read-all
|
||||
jobs:
|
||||
update-protobufs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
permissions: # Needed for peter-evans/create-pull-request.
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
|
||||
+12
-12
@@ -4,31 +4,31 @@ cli:
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.7.4
|
||||
ref: v1.7.6
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.506
|
||||
- renovate@43.43.2
|
||||
- checkov@3.2.513
|
||||
- renovate@43.104.6
|
||||
- prettier@3.8.1
|
||||
- trufflehog@3.93.5
|
||||
- trufflehog@3.94.2
|
||||
- yamllint@1.38.0
|
||||
- bandit@1.9.4
|
||||
- trivy@0.69.1
|
||||
- trivy@0.69.3
|
||||
- taplo@0.10.0
|
||||
- ruff@0.15.4
|
||||
- isort@8.0.0
|
||||
- markdownlint@0.47.0
|
||||
- ruff@0.15.9
|
||||
- isort@8.0.1
|
||||
- markdownlint@0.48.0
|
||||
- oxipng@10.1.0
|
||||
- svgo@4.0.0
|
||||
- actionlint@1.7.11
|
||||
- svgo@4.0.1
|
||||
- actionlint@1.7.12
|
||||
- flake8@7.3.0
|
||||
- hadolint@2.14.0
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.11.0
|
||||
- black@26.1.0
|
||||
- black@26.3.1
|
||||
- git-diff-check
|
||||
- gitleaks@8.30.0
|
||||
- gitleaks@8.30.1
|
||||
- clang-format@16.0.3
|
||||
ignore:
|
||||
- linters: [ALL]
|
||||
|
||||
@@ -187,6 +187,7 @@ Logging:
|
||||
LogLevel: info # debug, info, warn, error
|
||||
# TraceFile: /var/log/meshtasticd.json
|
||||
# JSONFile: /packets.json # File location for JSON output of decoded packets
|
||||
# JSONFileRotate: 60 # Rotate JSON file every N minutes, or 0 for no rotation
|
||||
# JSONFilter: position # filter for packets to save to JSON file
|
||||
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
||||
|
||||
@@ -214,3 +215,4 @@ General:
|
||||
AvailableDirectory: /etc/meshtasticd/available.d/
|
||||
# MACAddress: AA:BB:CC:DD:EE:FF
|
||||
# MACAddressSource: eth0
|
||||
# APIPort: 4403
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: BananaPi-BPI-R4-sx1262
|
||||
support: community
|
||||
compatible:
|
||||
- bananapi_bpi-r4 # OpenWrt target
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # BananaPi-BPI-R4 SPI via 26p GPIO Header
|
||||
## CS: 28
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
## https://www.mikroe.com/lr-iot-click
|
||||
Meta:
|
||||
name: OpenWRT One mikroBUS LR-IOT-CLICK
|
||||
support: community
|
||||
compatible:
|
||||
- openwrt_one # OpenWrt target
|
||||
|
||||
Lora:
|
||||
Module: lr1110 # OpenWRT ONE mikroBUS with LR-IOT-CLICK
|
||||
# CS: 25
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: OpenWRT One mikroBUS sx1262
|
||||
support: community
|
||||
compatible:
|
||||
- openwrt_one # OpenWrt target
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
IRQ: 10
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# meshtasticd configuration files
|
||||
|
||||
This directory contains YAML configuration files for meshtasticd. Each file describes a specific hardware configuration, including the LoRa module and pin assignments. These configurations are used by meshtasticd to correctly interface with the hardware.
|
||||
|
||||
## Metadata structure
|
||||
|
||||
Each configuration file includes a `Meta` section that provides information about the configuration.
|
||||
This configuration is consumed by configuration-selection tools.
|
||||
|
||||
```yaml
|
||||
Meta:
|
||||
name: MeshAdv-Pi E22-900M30S # A unique identifier for this configuration.
|
||||
support: community # community, official, or deprecated; determined by Meshtastic Leads.
|
||||
compatible: # A list of compatible products or platforms.
|
||||
- raspberry-pi
|
||||
```
|
||||
`name`: A unique identifier for the configuration, typically reflecting the hardware it supports.
|
||||
|
||||
`support`: Indicates the level of support for this configuration. It can be one of the following:
|
||||
|
||||
- `community`: Supported by the Meshtastic community. Meshtastic Members may not possess, or have not tested this configuration.
|
||||
- `official`: Fully supported by Meshtastic. Meshtastic Members have tested and verified this configuration.
|
||||
- `deprecated`: No longer recommended for deployment by Meshtastic.
|
||||
|
||||
`compatible`: A list of compatible products or platforms that can use this configuration.
|
||||
This will vary depending on the intended use case / platform.
|
||||
Multiple compatible entries can be included. E.g. Armbian `BOARD` value or OpenWrt `TARGET` value.
|
||||
These tags can be consumed by different configuration-selection tools, filtering based upon their platform/etc.
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Waveshare 1.44inch LCD HAT
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
### Waveshare 1.44inch LCD HAT
|
||||
Display:
|
||||
Panel: ST7735S
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Waveshare 2.8inch LCD HAT
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Display:
|
||||
|
||||
### Waveshare 2.8inch RPi LCD
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E80-900M22S
|
||||
## This is a bit experimental
|
||||
##
|
||||
##
|
||||
Module: lr1121
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO3_TCXO_VOLTAGE: 1.8
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
rfswitch_table:
|
||||
pins: [DIO5, DIO6, DIO7]
|
||||
MODE_STBY: [LOW, LOW, LOW]
|
||||
MODE_RX: [LOW, HIGH, LOW]
|
||||
MODE_TX: [HIGH, HIGH, LOW]
|
||||
MODE_TX_HP: [HIGH, LOW, LOW]
|
||||
MODE_TX_HF: [LOW, LOW, LOW]
|
||||
MODE_GNSS: [LOW, LOW, HIGH]
|
||||
MODE_WIFI: [LOW, LOW, LOW]
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E80-900M22S
|
||||
## This is a bit experimental
|
||||
##
|
||||
##
|
||||
Module: lr1121
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO3_TCXO_VOLTAGE: 1.8
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
rfswitch_table:
|
||||
pins:
|
||||
- DIO5
|
||||
- DIO6
|
||||
MODE_STBY:
|
||||
- LOW
|
||||
- LOW
|
||||
MODE_RX:
|
||||
- HIGH
|
||||
- LOW
|
||||
MODE_TX:
|
||||
- HIGH
|
||||
- HIGH
|
||||
MODE_TX_HP:
|
||||
- LOW
|
||||
- HIGH
|
||||
MODE_TX_HF:
|
||||
- LOW
|
||||
- LOW
|
||||
MODE_GNSS:
|
||||
- LOW
|
||||
- LOW
|
||||
MODE_WIFI:
|
||||
- LOW
|
||||
- LOW
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E80-900M22S
|
||||
## This is a bit experimental
|
||||
##
|
||||
##
|
||||
Module: lr1121
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO3_TCXO_VOLTAGE: 1.8
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
rfswitch_table:
|
||||
pins: [DIO5, DIO6, DIO7]
|
||||
MODE_STBY: [LOW, LOW, LOW]
|
||||
MODE_RX: [LOW, LOW, LOW]
|
||||
MODE_TX: [LOW, HIGH, LOW]
|
||||
MODE_TX_HP: [HIGH, LOW, LOW]
|
||||
# MODE_TX_HF: []
|
||||
# MODE_GNSS: []
|
||||
MODE_WIFI: [LOW, LOW, LOW]
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Adafruit RFM9x
|
||||
support: deprecated
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: RF95 # Adafruit RFM9x
|
||||
Reset: 25
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# MeshAdv-Pi E22-900M30S
|
||||
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
|
||||
Meta:
|
||||
name: MeshAdv-Pi E22-900M30S
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 21
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# MeshAdv Mini E22-900M22S
|
||||
# https://github.com/chrismyers2000/MeshAdv-Mini
|
||||
Meta:
|
||||
name: MeshAdv Mini E22-900M22S
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Ebyte E22-900M22S
|
||||
CS: 8
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 1
|
||||
support: official
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
|
||||
### RAK13300in Slot 1
|
||||
### RAK13300 in Slot 1
|
||||
Module: sx1262
|
||||
IRQ: 22 #IO6
|
||||
Reset: 16 # IO4
|
||||
Busy: 24 # IO5
|
||||
# Ant_sw: 13 # IO3
|
||||
Enable_Pins:
|
||||
- 12
|
||||
- 13
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
spidev: spidev0.0
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 2
|
||||
support: official
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
### RAK13300in Slot 2 pins
|
||||
### RAK13300 in Slot 2 pins
|
||||
IRQ: 18 #IO6
|
||||
Reset: 24 # IO4
|
||||
Busy: 19 # IO5
|
||||
# Ant_sw: 23 # IO3
|
||||
Enable_Pins:
|
||||
- 26
|
||||
- 23
|
||||
spidev: spidev0.1
|
||||
# CS: 7
|
||||
@@ -0,0 +1,22 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13302 Slot 1
|
||||
support: official
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
|
||||
### RAK13302 in Slot 1
|
||||
Module: sx1262
|
||||
IRQ: 22 #IO6
|
||||
Reset: 16 # IO4
|
||||
Busy: 24 # IO5
|
||||
# Ant_sw: 13 # IO3
|
||||
Enable_Pins:
|
||||
- 12
|
||||
- 13
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
spidev: spidev0.0
|
||||
# CS: 8
|
||||
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
|
||||
@@ -0,0 +1,18 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13302 Slot 2
|
||||
support: official
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
### RAK13302 in Slot 2 pins
|
||||
IRQ: 18 #IO6
|
||||
Reset: 24 # IO4
|
||||
Busy: 19 # IO5
|
||||
# Ant_sw: 23 # IO3
|
||||
Enable_Pins:
|
||||
- 26
|
||||
- 23
|
||||
spidev: spidev0.1
|
||||
# CS: 7
|
||||
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
|
||||
+22
-20
@@ -1,20 +1,22 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E80-900M22S
|
||||
## This is a bit experimental
|
||||
##
|
||||
##
|
||||
Module: lr1121
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO3_TCXO_VOLTAGE: 1.8
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
---
|
||||
Meta:
|
||||
name: Femtofox Ebyte E80-900M22S with TCXO
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-pico-mini # Armbian
|
||||
|
||||
Lora:
|
||||
## Ebyte E80-900M22S
|
||||
## This is a bit experimental
|
||||
##
|
||||
##
|
||||
Module: lr1121
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO3_TCXO_VOLTAGE: 1.8
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
+24
-21
@@ -1,21 +1,24 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup
|
||||
## HT-RA62 (Has internal switching, but whatever)
|
||||
## Seeed WIO SX1262 (already has TXEN-DIO2 link, but needs RXEN)
|
||||
## Will work with any module with or without RF switching, and with TCXO
|
||||
Module: sx1262
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||
# TXen: bridge to DIO2 on E22 module
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
---
|
||||
Meta:
|
||||
name: Femtofox SX1262 TCXO
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-pico-mini # Armbian
|
||||
|
||||
Lora:
|
||||
## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup
|
||||
## HT-RA62 (Has internal switching, but whatever)
|
||||
## Seeed WIO SX1262 (already has TXEN-DIO2 link, but needs RXEN)
|
||||
## Will work with any module with or without RF switching, and with TCXO
|
||||
Module: sx1262
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||
# TXen: bridge to DIO2 on E22 module
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
+24
-21
@@ -1,21 +1,24 @@
|
||||
---
|
||||
Lora:
|
||||
## Ebyte E22-900MM22S with no external RF switching setup
|
||||
## Waveshare SX126X XXXM, AI Thinker RA-01SH
|
||||
## Will work with any module with or without RF switching and no TCXO
|
||||
|
||||
Module: sx1262
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: false
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||
# TXen: bridge to DIO2 on E22 module
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
|
||||
General:
|
||||
MACAddressSource: eth0
|
||||
---
|
||||
Meta:
|
||||
name: Femtofox SX1262 XTAL
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-pico-mini # Armbian
|
||||
|
||||
Lora:
|
||||
## Ebyte E22-900MM22S with no external RF switching setup
|
||||
## Waveshare SX126X XXXM, AI Thinker RA-01SH
|
||||
## Will work with any module with or without RF switching and no TCXO
|
||||
|
||||
Module: sx1262
|
||||
gpiochip: 1 # subtract 32 from the gpio numbers
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: false
|
||||
CS: 16 #pin6 / GPIO48 1C0
|
||||
IRQ: 23 #pin17 / GPIO55 1C7
|
||||
Busy: 22 #pin16 / GPIO54 1C6
|
||||
Reset: 25 #pin13 / GPIO57 1D1
|
||||
RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things?
|
||||
# TXen: bridge to DIO2 on E22 module
|
||||
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
|
||||
spiSpeed: 2000000
|
||||
@@ -1,13 +1,21 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 1 (Autoconf default)
|
||||
support: official
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
|
||||
### RAK13300in Slot 1
|
||||
### RAK13300 in Slot 1
|
||||
Module: sx1262
|
||||
IRQ: 22 #IO6
|
||||
Reset: 16 # IO4
|
||||
Busy: 24 # IO5
|
||||
# Ant_sw: 13 # IO3
|
||||
Enable_Pins:
|
||||
- 12
|
||||
- 13
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
spidev: spidev0.0
|
||||
GPIO_DETECT_PA: 13
|
||||
TX_GAIN_LORA: [8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7]
|
||||
# GPIO_DETECT_PA: 13
|
||||
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Luckfox Lyra PicoCalc Wio LoRa SX1262
|
||||
support: official
|
||||
compatible:
|
||||
- luckfox-lyra-plus # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
|
||||
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
|
||||
# 1 Watt Lyra Ultra hat
|
||||
Meta:
|
||||
name: wehooper4 Luckfox Ultra 1W
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-pico-ultra # Armbian
|
||||
- luckfox-lyra-ultra # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
|
||||
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
|
||||
# 2 Watt Lyra Ultra hat
|
||||
Meta:
|
||||
name: wehooper4 Luckfox Ultra 2W
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-pico-ultra # Armbian
|
||||
- luckfox-lyra-ultra # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
# Enable overlay 'luckfox-lyra-plus-spi0-cs0_rmio13-spidev' with armbian-config
|
||||
# Waveshare LoRa HAT for Raspberry Pi Pico
|
||||
# https://www.waveshare.com/wiki/Pico-LoRa-SX1262
|
||||
Meta:
|
||||
name: Waveshare LoRa HAT for Raspberry Pi Pico
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-lyra-plus # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# MeshAdv-Pi E22-900M30S
|
||||
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
|
||||
Meta:
|
||||
name: MeshAdv-Pi E22-900M30S
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: # GPIO0_C2 (physical 40)
|
||||
pin: 18
|
||||
gpiochip: 0
|
||||
line: 18
|
||||
IRQ: # GPIO1_D1 (physical 36)
|
||||
pin: 57
|
||||
gpiochip: 1
|
||||
line: 25
|
||||
Busy: # GPIO0_C1 (physical 38)
|
||||
pin: 17
|
||||
gpiochip: 0
|
||||
line: 17
|
||||
Reset: # GPIO0_B6 (physical 12)
|
||||
pin: 14
|
||||
gpiochip: 0
|
||||
line: 14
|
||||
TXen: # GPIO1_C2 (physical 33)
|
||||
pin: 50
|
||||
gpiochip: 1
|
||||
line: 18
|
||||
RXen: # GPIO1_D2 (physical 32)
|
||||
pin: 58
|
||||
gpiochip: 1
|
||||
line: 26
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
# Only for E22-900M33S:
|
||||
# Limit the output power to 8 dBm
|
||||
# SX126X_MAX_POWER: 8
|
||||
spidev: spidev0.0
|
||||
@@ -0,0 +1,33 @@
|
||||
# MeshAdv Mini E22-900M22S
|
||||
# https://github.com/chrismyers2000/MeshAdv-Mini
|
||||
Meta:
|
||||
name: MeshAdv Mini E22-900M22S
|
||||
support: community
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Ebyte E22-900M22S
|
||||
CS: # GPIO0_B2_d (phys 24, RPi CE0)
|
||||
pin: 10
|
||||
gpiochip: 0
|
||||
line: 10
|
||||
IRQ: # GPIO1_D1_d (phys 36, RPi GPIO16)
|
||||
pin: 57
|
||||
gpiochip: 1
|
||||
line: 25
|
||||
Busy: # GPIO0_C1_d (phys 38, RPi GPIO20)
|
||||
pin: 17
|
||||
gpiochip: 0
|
||||
line: 17
|
||||
Reset: # GPIO0_B4_d (phys 18, RPi GPIO24)
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
RXen: # GPIO1_D2_d (phys 32, RPi GPIO12)
|
||||
pin: 58
|
||||
gpiochip: 1
|
||||
line: 26
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
spidev: spidev0.0
|
||||
@@ -0,0 +1,38 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 1
|
||||
support: community # Promote when tested
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
IRQ: # GPIO0_A5 (IO6)
|
||||
pin: 5
|
||||
gpiochip: 0
|
||||
line: 5
|
||||
Reset: # GPIO1_D1 (IO4)
|
||||
pin: 57
|
||||
gpiochip: 1
|
||||
line: 25
|
||||
Busy: # GPIO0_B4 (IO5)
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
# Ant_sw: # GPIO1_C2 (IO3)
|
||||
# pin: 50
|
||||
# gpiochip: 1
|
||||
# line: 18
|
||||
Enable_Pins:
|
||||
- pin: 58 # GPIO1_D2
|
||||
gpiochip: 1
|
||||
line: 26
|
||||
- pin: 50 # GPIO1_C2
|
||||
gpiochip: 1
|
||||
line: 18
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
spidev: spidev0.0
|
||||
# CS: # GPIO0_B2
|
||||
# pin: 10
|
||||
# gpiochip: 0
|
||||
# line: 10
|
||||
@@ -0,0 +1,36 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 2
|
||||
support: community # Promote when tested
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
IRQ: # GPIO0_B6 (IO6)
|
||||
pin: 14
|
||||
gpiochip: 0
|
||||
line: 14
|
||||
Reset: # GPIO0_B4 (IO4)
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
Busy: # GPIO1_C0 (IO5)
|
||||
pin: 48
|
||||
gpiochip: 1
|
||||
line: 16
|
||||
# Ant_sw: # GPIO0_B5 (IO3)
|
||||
# pin: 13
|
||||
# gpiochip: 0
|
||||
# line: 13
|
||||
Enable_Pins:
|
||||
- pin: 51 # GPIO1_C3
|
||||
gpiochip: 1
|
||||
line: 19
|
||||
- pin: 13 # GPIO0_B5
|
||||
gpiochip: 0
|
||||
line: 13
|
||||
spidev: spidev0.1
|
||||
# CS: # GPIO0_B1
|
||||
# pin: 9
|
||||
# gpiochip: 0
|
||||
# line: 9
|
||||
@@ -0,0 +1,39 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 1
|
||||
support: community # Promote when tested
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
IRQ: # GPIO0_A5 (IO6)
|
||||
pin: 5
|
||||
gpiochip: 0
|
||||
line: 5
|
||||
Reset: # GPIO1_D1 (IO4)
|
||||
pin: 57
|
||||
gpiochip: 1
|
||||
line: 25
|
||||
Busy: # GPIO0_B4 (IO5)
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
# Ant_sw: # GPIO1_C2 (IO3)
|
||||
# pin: 50
|
||||
# gpiochip: 1
|
||||
# line: 18
|
||||
Enable_Pins:
|
||||
- pin: 58 # GPIO1_D2
|
||||
gpiochip: 1
|
||||
line: 26
|
||||
- pin: 50 # GPIO1_C2
|
||||
gpiochip: 1
|
||||
line: 18
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
spidev: spidev0.0
|
||||
# CS: # GPIO0_B2
|
||||
# pin: 10
|
||||
# gpiochip: 0
|
||||
# line: 10
|
||||
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
|
||||
@@ -0,0 +1,37 @@
|
||||
Meta:
|
||||
name: RAK6421 + RAK13300 Slot 2
|
||||
support: community # Promote when tested
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
IRQ: # GPIO0_B6 (IO6)
|
||||
pin: 14
|
||||
gpiochip: 0
|
||||
line: 14
|
||||
Reset: # GPIO0_B4 (IO4)
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
Busy: # GPIO1_C0 (IO5)
|
||||
pin: 48
|
||||
gpiochip: 1
|
||||
line: 16
|
||||
# Ant_sw: # GPIO0_B5 (IO3)
|
||||
# pin: 13
|
||||
# gpiochip: 0
|
||||
# line: 13
|
||||
Enable_Pins:
|
||||
- pin: 51 # GPIO1_C3
|
||||
gpiochip: 1
|
||||
line: 19
|
||||
- pin: 13 # GPIO0_B5
|
||||
gpiochip: 0
|
||||
line: 13
|
||||
spidev: spidev0.1
|
||||
# CS: # GPIO0_B1
|
||||
# pin: 9
|
||||
# gpiochip: 0
|
||||
# line: 9
|
||||
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
|
||||
@@ -0,0 +1,30 @@
|
||||
Meta:
|
||||
name: Waveshare SX1262
|
||||
support: deprecated
|
||||
compatible:
|
||||
- luckfox-lyra-zero-w # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Waveshare SX126X XXXM
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
CS: # GPIO0_C2 (physical 40)
|
||||
pin: 18
|
||||
gpiochip: 0
|
||||
line: 18
|
||||
IRQ: # GPIO1_D1 (physical 36)
|
||||
pin: 57
|
||||
gpiochip: 1
|
||||
line: 25
|
||||
Busy: # GPIO0_C1 (physical 38)
|
||||
pin: 17
|
||||
gpiochip: 0
|
||||
line: 17
|
||||
Reset: # GPIO0_B6 (physical 12)
|
||||
pin: 14
|
||||
gpiochip: 0
|
||||
line: 14
|
||||
SX126X_ANT_SW: # GPIO1_B3 (physical 31)
|
||||
pin: 43
|
||||
gpiochip: 1
|
||||
line: 11
|
||||
spidev: spidev0.0
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Lora Meshstick SX1262
|
||||
support: official
|
||||
compatible:
|
||||
- usb
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Lora Meshstick SX1262
|
||||
support: community
|
||||
compatible:
|
||||
- usb
|
||||
|
||||
Lora:
|
||||
Module: lr1121
|
||||
CS: 0
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
Meta:
|
||||
name: Pinedio USB SX1262
|
||||
support: deprecated
|
||||
compatible:
|
||||
- usb
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 0
|
||||
IRQ: 10
|
||||
spidev: ch341
|
||||
spidev: ch341
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: raxda-rock2f-starter-edition-hat
|
||||
support: community
|
||||
compatible:
|
||||
- rock-2f # Armbian
|
||||
|
||||
Lora:
|
||||
|
||||
### Raxda Rock 2F running Armbian Linux 6.1.99-vendor-rk35xx
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# https://www.waveshare.com/core1262-868m.htm
|
||||
# https://github.com/markbirss/lora-starter-edition-sx1262-i2c
|
||||
Meta:
|
||||
name: lora-starter-edition-sx1262-i2c
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: meshstick-1262
|
||||
support: official
|
||||
compatible:
|
||||
- usb
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: meshtoad-e22
|
||||
support: official
|
||||
compatible:
|
||||
- usb
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: umesh-1262-30dbm
|
||||
support: community
|
||||
compatible:
|
||||
- clockwork-uconsole
|
||||
|
||||
Lora:
|
||||
Module: sx1262
|
||||
CS: 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: umesh-1268-30dbm
|
||||
support: community
|
||||
compatible:
|
||||
- clockwork-uconsole
|
||||
|
||||
Lora:
|
||||
Module: sx1268
|
||||
CS: 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
Meta:
|
||||
name: Waveshare SX1262
|
||||
support: deprecated
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Waveshare SX126X XXXM
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# https://www.waveshare.com/pico-lora-sx1262-868m.htm
|
||||
# https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter
|
||||
|
||||
Meta:
|
||||
name: ws-raspberry-pico-to-rpi-adapter
|
||||
support: community
|
||||
compatible:
|
||||
- raspberry-pi
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
# 5 CS 24
|
||||
# 26 DIO1/IRQ 26
|
||||
|
||||
Meta:
|
||||
name: ws-raspberry-pico-to-orangepi-03
|
||||
support: community
|
||||
compatible:
|
||||
- orange-pi-zero-3 # Armbian
|
||||
|
||||
Lora:
|
||||
Module: sx1262 # Waveshare Raspberry Pico Lora module
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
|
||||
@@ -43,7 +43,7 @@ for pio_env in pio_envs:
|
||||
env = {
|
||||
"ci": {"board": pio_env, "platform": env_platform},
|
||||
"board_level": cfg.get(f"env:{pio_env}", "board_level", default=None),
|
||||
"board_check": bool(cfg.get(f"env:{pio_env}", "board_check", default=False)),
|
||||
"board_check": cfg.get(f"env:{pio_env}", "board_check", default="false").strip().lower() == "true",
|
||||
}
|
||||
all_envs.append(env)
|
||||
|
||||
|
||||
@@ -87,6 +87,12 @@
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<release version="2.7.22" date="2026-04-06">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.22</url>
|
||||
</release>
|
||||
<release version="2.7.21" date="2026-03-11">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.21</url>
|
||||
</release>
|
||||
<release version="2.7.20" date="2026-02-11">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.20</url>
|
||||
</release>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"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"],
|
||||
["0x2886", "0x1667"]
|
||||
],
|
||||
"usb_product": "HT-n5262G",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "heltec_mesh_node_t096",
|
||||
"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/",
|
||||
"vendor": "Heltec"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"memory_type": "qio_opi",
|
||||
"partitions": "default_16MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=0",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "LilyGo T5-ePaper-S3",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://lilygo.cc/products/t5-e-paper-s3-pro",
|
||||
"vendor": "LILYGO"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DARDUINO_T_Beam",
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "tbeam"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "can", "ethernet"],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "TTGO T-Beam (PSRAM Disabled)",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 1310720,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://github.com/LilyGO/TTGO-T-Beam",
|
||||
"vendor": "TTGO"
|
||||
}
|
||||
+1
-1
@@ -12,6 +12,6 @@ Ex:
|
||||
- `logo_320x480.png`
|
||||
- `logo_320x240.png`
|
||||
|
||||
This file is copied to `data/boot/logo.png` before filesytem image compilation.
|
||||
This file is copied to `data/boot/logo.png` before filesystem image compilation.
|
||||
|
||||
For additional examples see the [`event/defcon33` branch](https://github.com/meshtastic/firmware/tree/event/defcon33).
|
||||
|
||||
Vendored
+12
@@ -1,3 +1,15 @@
|
||||
meshtasticd (2.7.22.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.22
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Mon, 06 Apr 2026 11:34:12 +0000
|
||||
|
||||
meshtasticd (2.7.21.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.21
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 11 Mar 2026 11:45:36 +0000
|
||||
|
||||
meshtasticd (2.7.20.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.20
|
||||
|
||||
Vendored
+14
-2
@@ -3,10 +3,17 @@ export DEBEMAIL="jbennett@incomsystems.biz"
|
||||
export PLATFORMIO_LIBDEPS_DIR=pio/libdeps
|
||||
export PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||
export PLATFORMIO_CORE_DIR=pio/core
|
||||
export PLATFORMIO_SETTING_ENABLE_TELEMETRY=0
|
||||
export PLATFORMIO_SETTING_CHECK_PLATFORMIO_INTERVAL=3650
|
||||
export PLATFORMIO_SETTING_CHECK_PRUNE_SYSTEM_THRESHOLD=10240
|
||||
|
||||
# Download libraries to `pio`
|
||||
platformio pkg install -e native-tft
|
||||
platformio pkg install -e native-tft -t platformio/tool-scons@4.40502.0
|
||||
# Mangle PlatformIO cache to prevent internet access at build-time
|
||||
# Simply adds 1 to all expiry (epoch) timestamps, adding ~500 years to expiry date
|
||||
cp pio/core/.cache/downloads/usage.db pio/core/.cache/downloads/usage.db.bak
|
||||
jq -c 'with_entries(.value |= (. | tostring + "1" | tonumber))' pio/core/.cache/downloads/usage.db.bak >pio/core/.cache/downloads/usage.db
|
||||
# Compress `pio` directory to prevent dh_clean from sanitizing it
|
||||
tar -cf pio.tar pio/
|
||||
rm -rf pio
|
||||
@@ -20,5 +27,10 @@ rm -rf debian/changelog
|
||||
dch --create --distribution "$SERIES" --package "$package" --newversion "$PKG_VERSION~$SERIES" \
|
||||
"GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES"
|
||||
|
||||
# Build the source deb
|
||||
debuild -S -nc -k"$GPG_KEY_ID"
|
||||
if [[ -n $GPG_KEY_ID ]]; then
|
||||
# Build and sign the source deb
|
||||
debuild -S -nc -k"$GPG_KEY_ID"
|
||||
else
|
||||
# Build the source deb without signing (forks)
|
||||
debuild -S -nc
|
||||
fi
|
||||
|
||||
Vendored
+4
-1
@@ -9,7 +9,10 @@
|
||||
PIO_ENV:=\
|
||||
PLATFORMIO_CORE_DIR=pio/core \
|
||||
PLATFORMIO_LIBDEPS_DIR=pio/libdeps \
|
||||
PLATFORMIO_PACKAGES_DIR=pio/packages
|
||||
PLATFORMIO_PACKAGES_DIR=pio/packages \
|
||||
PLATFORMIO_SETTING_ENABLE_TELEMETRY=0 \
|
||||
PLATFORMIO_SETTING_CHECK_PLATFORMIO_INTERVAL=3650 \
|
||||
PLATFORMIO_SETTING_CHECK_PRUNE_SYSTEM_THRESHOLD=10240
|
||||
|
||||
# Raspbian armhf builds should be compatible with armv6-hardfloat
|
||||
# https://www.valvers.com/open-software/raspberry-pi/bare-metal-programming-in-c-part-1/#rpi1-compiler-flags
|
||||
|
||||
+24
-23
@@ -50,6 +50,7 @@ build_flags = -Wno-missing-field-initializers
|
||||
-DRADIOLIB_EXCLUDE_APRS=1
|
||||
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
||||
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
||||
-DMESHTASTIC_EXCLUDE_ZPS=1
|
||||
-DMESHTASTIC_EXCLUDE_REPLYBOT=1
|
||||
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
|
||||
-DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1
|
||||
@@ -77,10 +78,10 @@ lib_deps =
|
||||
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/b841b0415721f1341ea41cccfb4adccfaf951567.zip
|
||||
# renovate: datasource=custom.pio depName=Nanopb packageName=nanopb/library/Nanopb
|
||||
nanopb/Nanopb@0.4.91
|
||||
# renovate: datasource=custom.pio depName=ErriezCRC32 packageName=erriez/library/ErriezCRC32
|
||||
erriez/ErriezCRC32@1.0.1
|
||||
# renovate: datasource=github-tags depName=Nanopb packageName=nanopb/nanopb
|
||||
https://github.com/nanopb/nanopb/archive/refs/tags/nanopb-0.4.9.1.zip
|
||||
# renovate: datasource=github-tags depName=ErriezCRC32 packageName=Erriez/ErriezCRC32
|
||||
https://github.com/Erriez/ErriezCRC32/archive/refs/tags/1.0.1.zip
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
@@ -95,34 +96,38 @@ check_flags =
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL
|
||||
end2endzone/NonBlockingRTTTL@1.4.0
|
||||
# renovate: datasource=github-tags depName=NonBlockingRTTTL packageName=end2endzone/NonBlockingRTTTL
|
||||
https://github.com/end2endzone/NonBlockingRTTTL/archive/refs/tags/1.4.0.zip
|
||||
build_unflags =
|
||||
-std=c++11
|
||||
-std=gnu++11
|
||||
build_flags = ${env.build_flags} -Os
|
||||
-std=gnu++17
|
||||
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
|
||||
|
||||
; Common libs for communicating over TCP/IP networks such as MQTT
|
||||
[networking_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=custom.pio depName=TBPubSubClient packageName=thingsboard/library/TBPubSubClient
|
||||
thingsboard/TBPubSubClient@2.12.1
|
||||
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
|
||||
arduino-libraries/NTPClient@3.2.1
|
||||
# renovate: datasource=github-tags depName=TBPubSubClient packageName=thingsboard/pubsubclient
|
||||
https://github.com/thingsboard/pubsubclient/archive/refs/tags/v2.12.1.zip
|
||||
# renovate: datasource=github-tags depName=NTPClient packageName=arduino-libraries/NTPClient
|
||||
https://github.com/arduino-libraries/NTPClient/archive/refs/tags/3.2.1.zip
|
||||
|
||||
; Extra TCP/IP networking libs for supported devices
|
||||
[networking_extra]
|
||||
lib_deps =
|
||||
# renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog
|
||||
arcao/Syslog@2.0.0
|
||||
# renovate: datasource=github-tags depName=Syslog packageName=arcao/Syslog
|
||||
https://github.com/arcao/Syslog/archive/refs/tags/v2.0.zip
|
||||
|
||||
[radiolib_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
||||
jgromes/RadioLib@7.6.0
|
||||
# renovate: datasource=github-tags depName=RadioLib packageName=jgromes/RadioLib
|
||||
https://github.com/jgromes/RadioLib/archive/refs/tags/7.6.0.zip
|
||||
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/6c75195e9987b7a49563232234f2f868dd343cae.zip
|
||||
https://github.com/meshtastic/device-ui/archive/1897dd17fceb1f101bb1a3245680aa3439edcfdd.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
@@ -191,16 +196,10 @@ lib_deps =
|
||||
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
|
||||
# renovate: datasource=custom.pio depName=Adafruit SHTC3 packageName=adafruit/library/Adafruit SHTC3 Library
|
||||
adafruit/Adafruit SHTC3 Library@1.0.2
|
||||
# renovate: datasource=custom.pio depName=Adafruit LPS2X packageName=adafruit/library/Adafruit LPS2X
|
||||
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
|
||||
# renovate: datasource=custom.pio depName=Adafruit VEML7700 packageName=adafruit/library/Adafruit VEML7700 Library
|
||||
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
|
||||
# renovate: datasource=custom.pio depName=SparkFun Qwiic Scale NAU7802 packageName=sparkfun/library/SparkFun Qwiic Scale NAU7802 Arduino Library
|
||||
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6
|
||||
# renovate: datasource=custom.pio depName=ClosedCube OPT3001 packageName=closedcube/library/ClosedCube OPT3001
|
||||
@@ -215,6 +214,8 @@ lib_deps =
|
||||
sensirion/Sensirion I2C SFA3x@1.0.0
|
||||
# renovate: datasource=custom.pio depName=Sensirion I2C SCD30 packageName=sensirion/library/Sensirion I2C SCD30
|
||||
sensirion/Sensirion I2C SCD30@1.0.0
|
||||
# renovate: datasource=custom.pio depName=arduino-sht packageName=sensirion/library/arduino-sht
|
||||
sensirion/arduino-sht@1.2.6
|
||||
|
||||
; Environmental sensors with BSEC2 (Bosch proprietary IAQ)
|
||||
[environmental_extra]
|
||||
@@ -229,5 +230,5 @@ lib_deps =
|
||||
[environmental_extra_no_bsec]
|
||||
lib_deps =
|
||||
${environmental_extra_common.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=adafruit/Adafruit BME680 Library packageName=adafruit/library/Adafruit BME680
|
||||
adafruit/Adafruit BME680 Library@^2.0.5
|
||||
# renovate: datasource=custom.pio depName=Adafruit_BME680 packageName=adafruit/library/Adafruit BME680 Library
|
||||
adafruit/Adafruit BME680 Library@2.0.6
|
||||
|
||||
+1
-1
Submodule protobufs updated: f7f7c8d2e4...e30092e616
@@ -4,6 +4,8 @@
|
||||
":dependencyDashboard",
|
||||
":semanticCommitTypeAll(chore)",
|
||||
":ignoreModulesAndTests",
|
||||
":noUnscheduledUpdates",
|
||||
"schedule:daily",
|
||||
"group:recommended",
|
||||
"replacements:all",
|
||||
"workarounds:all"
|
||||
|
||||
@@ -98,7 +98,6 @@ Syslog &Syslog::logMask(uint8_t priMask)
|
||||
|
||||
void Syslog::enable()
|
||||
{
|
||||
this->_client->begin(this->_port);
|
||||
this->_enabled = true;
|
||||
}
|
||||
|
||||
@@ -166,14 +165,21 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
|
||||
if ((pri & LOG_FACMASK) == 0)
|
||||
pri = LOG_MAKEPRI(LOG_FAC(this->_priDefault), pri);
|
||||
|
||||
// W5100S: acquire UDP socket on-demand to avoid permanent socket consumption
|
||||
if (!this->_client->begin(this->_port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->_server != NULL) {
|
||||
result = this->_client->beginPacket(this->_server, this->_port);
|
||||
} else {
|
||||
result = this->_client->beginPacket(this->_ip, this->_port);
|
||||
}
|
||||
|
||||
if (result != 1)
|
||||
if (result != 1) {
|
||||
this->_client->stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
this->_client->print('<');
|
||||
this->_client->print(pri);
|
||||
@@ -193,6 +199,8 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
|
||||
this->_client->print(message);
|
||||
this->_client->endPacket();
|
||||
|
||||
this->_client->stop(); // W5100S: release UDP socket for other services
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
||||
bool usePreset)
|
||||
{
|
||||
|
||||
// If use_preset is false, always return "Custom"
|
||||
// If use_preset is false, always return "Custom" — callers such as RadioInterface and Channels
|
||||
// rely on this being a stable literal for channel-name hashing and default-channel detection.
|
||||
if (!usePreset) {
|
||||
return "Custom";
|
||||
}
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include "nrfx_power.h"
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_NRF52)
|
||||
#include "Nrf52SaadcLock.h"
|
||||
#include "concurrency/LockGuard.h"
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_HEAP_MQTT) && !MESHTASTIC_EXCLUDE_MQTT
|
||||
#include "mqtt/MQTT.h"
|
||||
#include "target_specific.h"
|
||||
@@ -328,6 +333,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
|
||||
scaled *= operativeAdcMultiplier;
|
||||
#else // block for all other platforms
|
||||
#ifdef ARCH_NRF52
|
||||
concurrency::LockGuard saadcGuard(concurrency::nrf52SaadcLock);
|
||||
#endif
|
||||
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
raw += analogRead(BATTERY_PIN);
|
||||
}
|
||||
|
||||
+8
-2
@@ -38,7 +38,10 @@ static bool isPowered()
|
||||
return true;
|
||||
#endif
|
||||
|
||||
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||
bool isRouter = ((config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)
|
||||
? 1
|
||||
: 0);
|
||||
|
||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||
// We assume routers might be powered all the time, but from a low current (solar) source
|
||||
@@ -262,7 +265,10 @@ Fsm powerFSM(&stateBOOT);
|
||||
|
||||
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 ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)
|
||||
? 1
|
||||
: 0);
|
||||
bool hasPower = isPowered();
|
||||
|
||||
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0);
|
||||
|
||||
@@ -137,7 +137,7 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
if (color) {
|
||||
::printf("\u001b[0m");
|
||||
}
|
||||
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||
::printf("| %02d:%02d:%02d %u.%03u ", hour, min, sec, millis() / 1000, millis() % 1000);
|
||||
#else
|
||||
printf("%s ", logLevel);
|
||||
if (color) {
|
||||
@@ -151,7 +151,7 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
if (color) {
|
||||
::printf("\u001b[0m");
|
||||
}
|
||||
::printf("| ??:??:?? %u ", millis() / 1000);
|
||||
::printf("| ??:??:?? %u.%03u ", millis() / 1000, millis() % 1000);
|
||||
#else
|
||||
printf("%s ", logLevel);
|
||||
if (color) {
|
||||
@@ -345,7 +345,7 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
return;
|
||||
}
|
||||
|
||||
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
|
||||
void RedirectablePrint::hexDump(const char *logLevel, const unsigned char *buf, uint16_t len)
|
||||
{
|
||||
const char alphabet[17] = "0123456789abcdef";
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+");
|
||||
|
||||
@@ -44,7 +44,7 @@ class RedirectablePrint : public Print
|
||||
/** like printf but va_list based */
|
||||
size_t vprintf(const char *logLevel, const char *format, va_list arg);
|
||||
|
||||
void hexDump(const char *logLevel, unsigned char *buf, uint16_t len);
|
||||
void hexDump(const char *logLevel, const unsigned char *buf, uint16_t len);
|
||||
|
||||
std::string mt_sprintf(const std::string fmt_str, ...);
|
||||
|
||||
|
||||
+56
-1
@@ -6,6 +6,11 @@
|
||||
#include "Tone.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAS_I2S)
|
||||
#include "main.h"
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
extern "C" void delay(uint32_t dwMs);
|
||||
#endif
|
||||
@@ -50,6 +55,50 @@ const int DURATION_1_2 = 500; // 1/2 note
|
||||
const int DURATION_3_4 = 750; // 3/4 note
|
||||
const int DURATION_1_1 = 1000; // 1/1 note
|
||||
|
||||
#ifdef HAS_I2S
|
||||
void playTonesRTTTL(const ToneDuration *tone_durations, int size)
|
||||
{
|
||||
// translate ToneDuration[] to RTTTL string and play using audioThread
|
||||
static std::unordered_map<int, std::string> freqToNote = {
|
||||
{NOTE_C3, "c4"}, {NOTE_CS3, "c#4"}, {NOTE_D3, "d4"}, {NOTE_DS3, "d#4"}, {NOTE_E3, "e4"}, {NOTE_F3, "f4"},
|
||||
{NOTE_FS3, "f#4"}, {NOTE_G3, "g4"}, {NOTE_GS3, "g#4"}, {NOTE_A3, "a4"}, {NOTE_AS3, "a#4"}, {NOTE_B3, "b4"},
|
||||
{NOTE_C4, "c5"}, {NOTE_E4, "e5"}, {NOTE_G4, "g5"}, {NOTE_A4, "a5"}, {NOTE_C5, "c6"}, {NOTE_E5, "e6"},
|
||||
{NOTE_G5, "g6"}, {NOTE_F5, "f6"}, {NOTE_G6, "g7"}, {NOTE_E7, "e8"}};
|
||||
|
||||
char rtttl[128] = "tone:d=32,o=4,b=200:"; // default duration and octave
|
||||
for (int i = 0; i < size; i++) {
|
||||
const auto &td = tone_durations[i];
|
||||
std::string note = "b4";
|
||||
if (freqToNote.find(td.frequency_khz) != freqToNote.end()) {
|
||||
note = freqToNote[td.frequency_khz];
|
||||
}
|
||||
int dur = 32; // default duration
|
||||
if (td.duration_ms >= 1000)
|
||||
dur = 1;
|
||||
else if (td.duration_ms >= 500)
|
||||
dur = 2;
|
||||
else if (td.duration_ms >= 250)
|
||||
dur = 4;
|
||||
else if (td.duration_ms >= 125)
|
||||
dur = 8;
|
||||
else if (td.duration_ms >= 62)
|
||||
dur = 16;
|
||||
else
|
||||
dur = 32;
|
||||
|
||||
char noteStr[64];
|
||||
snprintf(noteStr, sizeof(noteStr), "%s,%d", note.c_str(), dur);
|
||||
strncat(rtttl, noteStr, sizeof(rtttl) - strlen(rtttl) - 1);
|
||||
|
||||
audioThread->beginRttl(rtttl, strlen(rtttl));
|
||||
while (audioThread->isPlaying()) {
|
||||
delay(10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void playTones(const ToneDuration *tone_durations, int size)
|
||||
{
|
||||
if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED ||
|
||||
@@ -57,7 +106,13 @@ void playTones(const ToneDuration *tone_durations, int size)
|
||||
// Buzzer is disabled or not set to system tones
|
||||
return;
|
||||
}
|
||||
#ifdef PIN_BUZZER
|
||||
#ifdef HAS_I2S
|
||||
if (moduleConfig.external_notification.use_i2s_as_buzzer && audioThread) {
|
||||
playTonesRTTTL(tone_durations, size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(PIN_BUZZER)
|
||||
if (!config.device.buzzer_gpio)
|
||||
config.device.buzzer_gpio = PIN_BUZZER;
|
||||
#endif
|
||||
|
||||
+32
-3
@@ -78,6 +78,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// Configuration
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Pre-hop drop handling (compile-time flag).
|
||||
#ifndef MESHTASTIC_PREHOP_DROP
|
||||
#define MESHTASTIC_PREHOP_DROP 0
|
||||
#endif
|
||||
|
||||
/// Convert a preprocessor name into a quoted string
|
||||
#define xstr(s) ystr(s)
|
||||
#define ystr(s) #s
|
||||
@@ -149,6 +154,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7
|
||||
#endif
|
||||
|
||||
#ifdef USE_KCT8103L_PA
|
||||
// Power Amps are often non-linear, so we can use an array of values for the power curve
|
||||
#if defined(HELTEC_WIRELESS_TRACKER_V2)
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 7
|
||||
#elif defined(HELTEC_MESH_NODE_T096)
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 11, 10, 9, 8, 7
|
||||
#else
|
||||
// If a board enables USE_KCT8103L_PA but does not match a known variant and has
|
||||
// not already provided a PA curve, fail at compile time to avoid unsafe defaults.
|
||||
#if !defined(NUM_PA_POINTS) || !defined(TX_GAIN_LORA)
|
||||
#error "USE_KCT8103L_PA is defined, but no PA gain curve (NUM_PA_POINTS / TX_GAIN_LORA) is configured for this board."
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RAK13302
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
|
||||
@@ -163,6 +185,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define TX_GAIN_LORA 0
|
||||
#endif
|
||||
|
||||
#ifndef HAS_LORA_FEM
|
||||
#define HAS_LORA_FEM 0
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Feature toggles
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -205,7 +231,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define BME_ADDR 0x76
|
||||
#define BME_ADDR_ALTERNATE 0x77
|
||||
#define MCP9808_ADDR 0x18
|
||||
#define INA_ADDR 0x40
|
||||
#define INA_ADDR 0x40 // same as SHT2X
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
#define INA_ADDR_WAVESHARE_UPS 0x43
|
||||
#define INA3221_ADDR 0x42
|
||||
@@ -218,8 +244,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define LPS22HB_ADDR 0x5C
|
||||
#define LPS22HB_ADDR_ALT 0x5D
|
||||
#define SFA30_ADDR 0x5D
|
||||
#define SHT31_4x_ADDR 0x44
|
||||
#define SHT31_4x_ADDR_ALT 0x45
|
||||
#define SHTXX_ADDR 0x44
|
||||
#define SHTXX_ADDR_ALT 0x45
|
||||
#define PMSA003I_ADDR 0x12
|
||||
#define QMA6100P_ADDR 0x12
|
||||
#define AHT10_ADDR 0x38
|
||||
@@ -261,6 +287,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define BHI260AP_ADDR 0x28
|
||||
#define BMM150_ADDR 0x13
|
||||
#define DA217_ADDR 0x26
|
||||
#define BMI270_ADDR 0x68
|
||||
#define BMI270_ADDR_ALT 0x69
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LED
|
||||
@@ -487,6 +515,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MESHTASTIC_EXCLUDE_REMOTEHARDWARE 1
|
||||
#define MESHTASTIC_EXCLUDE_STOREFORWARD 1
|
||||
#define MESHTASTIC_EXCLUDE_TEXTMESSAGE 1
|
||||
#define MESHTASTIC_EXCLUDE_TRAFFIC_MANAGEMENT 1
|
||||
#define MESHTASTIC_EXCLUDE_ATAK 1
|
||||
#define MESHTASTIC_EXCLUDE_CANNEDMESSAGES 1
|
||||
#define MESHTASTIC_EXCLUDE_NEIGHBORINFO 1
|
||||
|
||||
@@ -37,8 +37,8 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||
{
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948, QMA6100P, BMM150};
|
||||
return firstOfOrNONE(9, types);
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948, QMA6100P, BMM150, BMI270};
|
||||
return firstOfOrNONE(10, types);
|
||||
}
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstAQI() const
|
||||
|
||||
@@ -31,9 +31,6 @@ class ScanI2C
|
||||
INA3221,
|
||||
MAX17048,
|
||||
MCP9808,
|
||||
SHT31,
|
||||
SHT4X,
|
||||
SHTC3,
|
||||
LPS22HB,
|
||||
QMC6310U,
|
||||
QMC6310N,
|
||||
@@ -89,10 +86,13 @@ class ScanI2C
|
||||
DA217,
|
||||
CHSC6X,
|
||||
CST226SE,
|
||||
BMI270,
|
||||
SEN5X,
|
||||
SFA30,
|
||||
CW2015,
|
||||
SCD30
|
||||
SCD30,
|
||||
ADS1115,
|
||||
SHTXX
|
||||
} DeviceType;
|
||||
|
||||
// typedef uint8_t DeviceAddress;
|
||||
|
||||
@@ -136,7 +136,9 @@ bool ScanI2CTwoWire::i2cCommandResponseLength(ScanI2C::DeviceAddress addr, uint1
|
||||
return match;
|
||||
}
|
||||
|
||||
/// for SEN5X detection
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||
// FIXME Move to a separate file for detection of sensors that require more complex interactions?
|
||||
// For SEN5X detection
|
||||
// Note, this code needs to be called before setting the I2C bus speed
|
||||
// for the screen at high speed. The speed needs to be at 100kHz, otherwise
|
||||
// detection will not work
|
||||
@@ -174,6 +176,46 @@ String readSEN5xProductName(TwoWire *i2cBus, uint8_t address)
|
||||
|
||||
return String(productName);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
bool detectSHT21SerialNumber(TwoWire *i2cBus, uint8_t address)
|
||||
{
|
||||
|
||||
i2cBus->beginTransmission(address);
|
||||
i2cBus->write(0xFA);
|
||||
i2cBus->write(0x0F);
|
||||
|
||||
if (i2cBus->endTransmission() != 0)
|
||||
return false;
|
||||
|
||||
if (i2cBus->requestFrom(address, (uint8_t)8) != 8)
|
||||
return false;
|
||||
|
||||
// Just flush the data
|
||||
while (i2cBus->available() < 8) {
|
||||
i2cBus->read();
|
||||
}
|
||||
|
||||
i2cBus->beginTransmission(address);
|
||||
i2cBus->write(0xFC);
|
||||
i2cBus->write(0xC9);
|
||||
|
||||
if (i2cBus->endTransmission() != 0)
|
||||
return false;
|
||||
|
||||
if (i2cBus->requestFrom(address, (uint8_t)6) != 6)
|
||||
return false;
|
||||
|
||||
// Just flush the data
|
||||
while (i2cBus->available() < 6) {
|
||||
i2cBus->read();
|
||||
}
|
||||
|
||||
// Assume we detect the SHT21 if something came back from the request
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
||||
case ADDR: \
|
||||
@@ -341,7 +383,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
type = DPS310;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (type == DPS310) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
||||
switch (registerValue) {
|
||||
@@ -369,7 +413,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
break;
|
||||
#endif
|
||||
#if !defined(M5STACK_UNITC6L)
|
||||
case INA_ADDR:
|
||||
case INA_ADDR: // Same as SHT2X
|
||||
case INA_ADDR_ALTERNATE:
|
||||
case INA_ADDR_WAVESHARE_UPS:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||
@@ -385,7 +429,12 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
logFoundDevice("INA260", (uint8_t)addr.address);
|
||||
type = INA260;
|
||||
}
|
||||
} else { // Assume INA219 if INA260 ID is not found
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
} else if (detectSHT21SerialNumber(i2cBus, (uint8_t)addr.address)) {
|
||||
logFoundDevice("SHTXX (SHT2X)", (uint8_t)addr.address);
|
||||
type = SHTXX;
|
||||
#endif
|
||||
} else { // Assume INA219 if none of the above ones are found
|
||||
logFoundDevice("INA219", (uint8_t)addr.address);
|
||||
type = INA219;
|
||||
}
|
||||
@@ -446,22 +495,19 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHT31_4x_ADDR: // same as OPT3001_ADDR_ALT
|
||||
case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR
|
||||
case SHTXX_ADDR: // same as OPT3001_ADDR_ALT
|
||||
case SHTXX_ADDR_ALT: // same as OPT3001_ADDR
|
||||
if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
||||
type = OPT3001;
|
||||
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
||||
} else if (i2cCommandResponseLength(addr, 0x89, 6)) { // SHT4x serial number (6 bytes inc. CRC)
|
||||
type = SHT4X;
|
||||
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
||||
} else {
|
||||
type = SHT31;
|
||||
logFoundDevice("SHT31", (uint8_t)addr.address);
|
||||
} else { // SHTXX
|
||||
type = SHTXX;
|
||||
logFoundDevice("SHTXX", (uint8_t)addr.address);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3", (uint8_t)addr.address)
|
||||
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTXX, "SHTXX", (uint8_t)addr.address)
|
||||
case RCWL9620_ADDR:
|
||||
// get MAX30102 PARTID
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
|
||||
@@ -652,9 +698,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
}
|
||||
break;
|
||||
|
||||
case ICM20948_ADDR: // same as BMX160_ADDR and SEN5X_ADDR
|
||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
||||
// ICM20948 Register check
|
||||
case ICM20948_ADDR: // same as BMX160_ADDR, BMI270_ADDR_ALT, and SEN5X_ADDR
|
||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR, BMI270_ADDR
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||
#ifdef HAS_ICM20948
|
||||
type = ICM20948;
|
||||
@@ -665,7 +710,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
type = ICM20948;
|
||||
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
||||
break;
|
||||
} else if (registerValue == 0x24) {
|
||||
type = BMI270;
|
||||
logFoundDevice("BMI270", (uint8_t)addr.address);
|
||||
break;
|
||||
} else if (registerValue == 0xD8) { // BMX160 chip ID at register 0x00
|
||||
type = BMX160;
|
||||
logFoundDevice("BMX160", (uint8_t)addr.address);
|
||||
break;
|
||||
} else {
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||
String prod = "";
|
||||
prod = readSEN5xProductName(i2cBus, addr.address);
|
||||
if (prod.startsWith("SEN55")) {
|
||||
@@ -681,6 +735,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
logFoundDevice("Sensirion SEN50", addr.address);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (addr.address == BMX160_ADDR) {
|
||||
type = BMX160;
|
||||
logFoundDevice("BMX160", (uint8_t)addr.address);
|
||||
@@ -718,11 +773,18 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
if (len == 5 && memcmp(expectedInfo, info, len) == 0) {
|
||||
LOG_INFO("NXP SE050 crypto chip found");
|
||||
type = NXP_SE050;
|
||||
|
||||
} else {
|
||||
LOG_INFO("FT6336U touchscreen found");
|
||||
type = FT6336U;
|
||||
break;
|
||||
}
|
||||
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 2);
|
||||
if (registerValue == 0x8583 || registerValue == 0x8580) {
|
||||
type = ADS1115;
|
||||
logFoundDevice("ADS1115 ADC", (uint8_t)addr.address);
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_INFO("FT6336U touchscreen found");
|
||||
type = FT6336U;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+14
-6
@@ -93,7 +93,7 @@ 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
|
||||
// indefinitely
|
||||
|
||||
int lastState = LOW;
|
||||
bool firstrun = true;
|
||||
@@ -103,6 +103,14 @@ static int32_t gpsSwitch()
|
||||
if (gps) {
|
||||
int currentState = digitalRead(PIN_GPS_SWITCH);
|
||||
|
||||
// Respect explicit NOT_PRESENT mode and do not let the hardware switch re-enable GPS.
|
||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
|
||||
gps->disable();
|
||||
lastState = currentState;
|
||||
firstrun = false;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
// if the switch is set to zero, disable the GPS Thread
|
||||
if (firstrun)
|
||||
if (currentState == LOW)
|
||||
@@ -586,14 +594,14 @@ bool GPS::setup()
|
||||
_serial_gps->write("$PMTK301,2*2E\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
|
||||
// Set the initial configuration of the device - these _should_ work for most AT6558 devices
|
||||
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACKCas(0x06, 0x07, 250) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("ATGM336H: Could not set Config");
|
||||
}
|
||||
|
||||
// Set the update frequence to 1Hz
|
||||
// Set the update frequency to 1Hz
|
||||
msglen = makeCASPacket(0x06, 0x04, sizeof(_message_CAS_CFG_RATE_1HZ), _message_CAS_CFG_RATE_1HZ);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACKCas(0x06, 0x04, 250) != GNSS_RESPONSE_OK) {
|
||||
@@ -700,7 +708,7 @@ bool GPS::setup()
|
||||
} else { // 8,9
|
||||
LOG_INFO("GPS+SBAS+GLONASS+Galileo configured");
|
||||
}
|
||||
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next
|
||||
// Documentation say, we need wait at least 0.5s after reconfiguration of GNSS module, before sending next
|
||||
// commands for the M8 it tends to be more... 1 sec should be enough ;>)
|
||||
delay(1000);
|
||||
}
|
||||
@@ -733,7 +741,7 @@ bool GPS::setup()
|
||||
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "enable powersave for GPS", 500);
|
||||
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersave details for GPS", 500);
|
||||
|
||||
// For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats.
|
||||
// For M8 we want to enable NMEA version 4.10 so we can see the additional sats.
|
||||
if (gnssModel == GNSS_MODEL_UBLOX8) {
|
||||
clearBuffer();
|
||||
SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "enable NMEA 4.10", 500);
|
||||
@@ -1211,7 +1219,7 @@ int32_t GPS::runOnce()
|
||||
return disable(); // This should trigger when we have a fixed position, and get that first position
|
||||
|
||||
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
||||
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
||||
// if not awake we can run super infrequently (once every 5 secs?) to see if we need to wake.
|
||||
return (powerState == GPS_ACTIVE) ? GPS_THREAD_INTERVAL : 5000;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _lon
|
||||
|
||||
GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
|
||||
{
|
||||
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
|
||||
// Change decimal representation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
GeoCoord::setCoords();
|
||||
@@ -20,7 +20,7 @@ GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
|
||||
|
||||
GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
|
||||
{
|
||||
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
|
||||
// Change decimal representation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
GeoCoord::setCoords();
|
||||
@@ -467,10 +467,10 @@ int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new point bassed on the passed in poin
|
||||
* Create a new point based on the passed-in point
|
||||
* Ported from http://www.edwilliams.org/avform147.htm#LL
|
||||
* @param bearing
|
||||
* The bearing in raidans
|
||||
* The bearing in radians
|
||||
* @param range_meters
|
||||
* range in meters
|
||||
* @return GeoCoord object of point at bearing and range from initial point
|
||||
@@ -593,4 +593,4 @@ double GeoCoord::toRadians(double deg)
|
||||
double GeoCoord::toDegrees(double r)
|
||||
{
|
||||
return r * 180 / PI;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-2
@@ -2,6 +2,7 @@
|
||||
#include "configuration.h"
|
||||
#include "detect/ScanI2C.h"
|
||||
#include "main.h"
|
||||
#include "modules/NodeInfoModule.h"
|
||||
#include <Throttle.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
@@ -12,6 +13,14 @@ uint32_t lastSetFromPhoneNtpOrGps = 0;
|
||||
static uint32_t lastTimeValidationWarning = 0;
|
||||
static const uint32_t TIME_VALIDATION_WARNING_INTERVAL_MS = 15000; // 15 seconds
|
||||
|
||||
static void triggerNodeInfoCheckOnTimeSource(RTCQuality oldQuality, RTCQuality newQuality)
|
||||
{
|
||||
if (oldQuality == RTCQualityNone && newQuality > RTCQualityNone && nodeInfoModule) {
|
||||
LOG_DEBUG("Time source acquired (%s -> %s), triggering NodeInfo recheck", RtcName(oldQuality), RtcName(newQuality));
|
||||
nodeInfoModule->triggerImmediateNodeInfoCheck();
|
||||
}
|
||||
}
|
||||
|
||||
RTCQuality getRTCQuality()
|
||||
{
|
||||
return currentQuality;
|
||||
@@ -61,9 +70,11 @@ RTCSetResult readFromRTC()
|
||||
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
|
||||
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
RTCQuality oldQuality = currentQuality;
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
currentQuality = RTCQualityDevice;
|
||||
triggerNodeInfoCheckOnTimeSource(oldQuality, currentQuality);
|
||||
}
|
||||
return RTCSetResultSuccess;
|
||||
} else {
|
||||
@@ -105,9 +116,11 @@ RTCSetResult readFromRTC()
|
||||
LOG_DEBUG("Read RTC time from %s getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", rtc.getChipName(), t.tm_year + 1900,
|
||||
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
RTCQuality oldQuality = currentQuality;
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
currentQuality = RTCQualityDevice;
|
||||
triggerNodeInfoCheckOnTimeSource(oldQuality, currentQuality);
|
||||
}
|
||||
return RTCSetResultSuccess;
|
||||
} else {
|
||||
@@ -139,9 +152,11 @@ RTCSetResult readFromRTC()
|
||||
}
|
||||
#endif
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
RTCQuality oldQuality = currentQuality;
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
currentQuality = RTCQualityDevice;
|
||||
triggerNodeInfoCheckOnTimeSource(oldQuality, currentQuality);
|
||||
}
|
||||
return RTCSetResultSuccess;
|
||||
}
|
||||
@@ -214,6 +229,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpd
|
||||
}
|
||||
|
||||
if (shouldSet) {
|
||||
RTCQuality oldQuality = currentQuality;
|
||||
currentQuality = q;
|
||||
lastSetMsec = now;
|
||||
if (currentQuality >= RTCQualityNTP) {
|
||||
@@ -223,7 +239,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpd
|
||||
// This delta value works on all platforms
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv->tv_sec;
|
||||
// If this platform has a setable RTC, set it
|
||||
// If this platform has a settable RTC, set it
|
||||
#ifdef RV3028_RTC
|
||||
if (rtc_found.address == RV3028_RTC) {
|
||||
Melopero_RV3028 rtc;
|
||||
@@ -281,6 +297,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpd
|
||||
#endif
|
||||
|
||||
readFromRTC();
|
||||
triggerNodeInfoCheckOnTimeSource(oldQuality, currentQuality);
|
||||
return RTCSetResultSuccess;
|
||||
} else {
|
||||
return RTCSetResultNotSet; // RTC was already set with a higher quality time
|
||||
@@ -397,12 +414,23 @@ uint32_t getValidTime(RTCQuality minQuality, bool local)
|
||||
return (currentQuality >= minQuality) ? getTime(local) : 0;
|
||||
}
|
||||
|
||||
#ifdef PIO_UNIT_TESTING
|
||||
void setBootRelativeTimeForUnitTest(uint32_t secondsSinceBoot)
|
||||
{
|
||||
currentQuality = RTCQualityNone;
|
||||
zeroOffsetSecs = 0;
|
||||
timeStartMsec = millis() - (secondsSinceBoot * 1000);
|
||||
lastSetFromPhoneNtpOrGps = 0;
|
||||
lastTimeValidationWarning = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
time_t gm_mktime(const struct tm *tm)
|
||||
{
|
||||
#if !MESHTASTIC_EXCLUDE_TZ
|
||||
time_t result = 0;
|
||||
|
||||
// First, get us to the start of tm->year, by calcuating the number of days since the Unix epoch.
|
||||
// First, get us to the start of tm->year, by calculating the number of days since the Unix epoch.
|
||||
int year = 1900 + tm->tm_year; // tm_year is years since 1900
|
||||
int year_minus_one = year - 1;
|
||||
int days_before_this_year = 0;
|
||||
|
||||
@@ -54,6 +54,10 @@ uint32_t getValidTime(RTCQuality minQuality, bool local = false);
|
||||
|
||||
RTCSetResult readFromRTC();
|
||||
|
||||
#ifdef PIO_UNIT_TESTING
|
||||
void setBootRelativeTimeForUnitTest(uint32_t secondsSinceBoot);
|
||||
#endif
|
||||
|
||||
time_t gm_mktime(const struct tm *tm);
|
||||
|
||||
#define SEC_PER_DAY 86400
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ static const uint8_t _message_CAS_CFG_RATE_1HZ[] = {
|
||||
|
||||
// CFG-NAVX (0x06, 0x07)
|
||||
// Initial ATGM33H-5N configuration, Updates for Dynamic Mode, Fix Mode, and SV system
|
||||
// Qwirk: The ATGM33H-5N-31 should only support GPS+BDS, however it will happily enable
|
||||
// Quirk: The ATGM33H-5N-31 should only support GPS+BDS, however it will happily enable
|
||||
// and use GPS+BDS+GLONASS iff the correct CFG_NAVX command is used.
|
||||
static const uint8_t _message_CAS_CFG_NAVX_CONF[] = {
|
||||
0x03, 0x01, 0x00, 0x00, // Update Mask: Dynamic Mode, Fix Mode, Nav Settings
|
||||
|
||||
+6
-6
@@ -57,7 +57,7 @@ static const uint8_t _message_CFG_PM2[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00 // 0x64, 0x40, 0x01, 0x00 // reserved 11
|
||||
};
|
||||
|
||||
// Constallation setup, none required for Neo-6
|
||||
// Constellation setup, none required for Neo-6
|
||||
|
||||
// For Neo-7 GPS & SBAS
|
||||
static const uint8_t _message_GNSS_7[] = {
|
||||
@@ -157,7 +157,7 @@ static const uint8_t _message_NAVX5[] = {
|
||||
0x00, 0x00, 0x00, 0x00, // Reserved 9
|
||||
0x00, // Reserved 10
|
||||
0x00, // Reserved 11
|
||||
0x00, // usePPP (Precice Point Positioning) (0 = false, 1 = true)
|
||||
0x00, // usePPP (Precise Point Positioning) (0 = false, 1 = true)
|
||||
0x01, // useAOP (AssistNow Autonomous configuration) = 1 (enabled)
|
||||
0x00, // Reserved 12
|
||||
0x00, // Reserved 13
|
||||
@@ -185,7 +185,7 @@ static const uint8_t _message_NAVX5_8[] = {
|
||||
0x00, // Reserved 4
|
||||
0x00, 0x00, // Reserved 5
|
||||
0x00, 0x00, // Reserved 6
|
||||
0x00, // usePPP (Precice Point Positioning) (0 = false, 1 = true)
|
||||
0x00, // usePPP (Precise Point Positioning) (0 = false, 1 = true)
|
||||
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
|
||||
0x00, 0x00, // Reserved 7
|
||||
0x00, 0x00, // aopOrbMaxErr = 0 to reset to firmware default
|
||||
@@ -314,7 +314,7 @@ static const uint8_t _message_DISABLE_TXT_INFO[] = {
|
||||
// This command applies to M8 products
|
||||
static const uint8_t _message_PMS[] = {
|
||||
0x00, // Version (0)
|
||||
0x03, // Power setup value 3 = Agresssive 1Hz
|
||||
0x03, // Power setup value 3 = Agressive 1Hz
|
||||
0x00, 0x00, // period: not applicable, set to 0
|
||||
0x00, 0x00, // onTime: not applicable, set to 0
|
||||
0x00, 0x00 // reserved, generated by u-center
|
||||
@@ -337,7 +337,7 @@ static const uint8_t _message_SAVE_10[] = {
|
||||
// As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR.
|
||||
// BBR will survive a restart, and power off for a while, but modules with small backup
|
||||
// batteries or super caps will not retain the config for a long power off time.
|
||||
// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast aquisition after
|
||||
// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast acquisition after
|
||||
// sleep
|
||||
|
||||
// VALSET Commands for M10
|
||||
@@ -462,7 +462,7 @@ Default GNSS configuration is: GPS, Galileo, BDS B1l, with QZSS and SBAS enabled
|
||||
The PMREQ puts the receiver to sleep and wakeup re-acquires really fast and seems to not need
|
||||
the PM config. Lets try without it.
|
||||
PMREQ sort of works with SBAS, but the awake time is too short to re-acquire any SBAS sats.
|
||||
The defination of "Got Fix" doesn't seem to include SBAS. Much more too this...
|
||||
The definition of "Got Fix" doesn't seem to include SBAS. Much more too this...
|
||||
Even if it was, it can take minutes (up to 12.5),
|
||||
even under good sat visibility conditions to re-acquire the SBAS data.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef USE_EINK
|
||||
#if defined(USE_EINK) && !defined(USE_EINK_PARALLELDISPLAY)
|
||||
#include "EInkDisplay2.h"
|
||||
#include "SPILock.h"
|
||||
#include "main.h"
|
||||
@@ -101,7 +101,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
|
||||
return true;
|
||||
}
|
||||
|
||||
// End the update process - virtual method, overriden in derived class
|
||||
// End the update process - virtual method, overridden in derived class
|
||||
void EInkDisplay::endUpdate()
|
||||
{
|
||||
// Power off display hardware, then deep-sleep (Except Wireless Paper V1.1, no deep-sleep)
|
||||
@@ -143,6 +143,10 @@ bool EInkDisplay::connect()
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
// ThinkNode M1 has a hardware dimmable backlight. Start enabled
|
||||
digitalWrite(PIN_EINK_EN, HIGH);
|
||||
#elif defined(MINI_EPAPER_S3)
|
||||
// T-Mini Epaper S3 requires panel power rail enabled before SPI transfer.
|
||||
digitalWrite(PIN_EINK_EN, HIGH);
|
||||
delay(10);
|
||||
#else
|
||||
digitalWrite(PIN_EINK_EN, LOW);
|
||||
#endif
|
||||
@@ -202,7 +206,8 @@ bool EInkDisplay::connect()
|
||||
}
|
||||
|
||||
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || \
|
||||
defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER)
|
||||
defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER) || \
|
||||
defined(MINI_EPAPER_S3)
|
||||
{
|
||||
// Start HSPI
|
||||
hspi = new SPIClass(HSPI);
|
||||
@@ -216,9 +221,13 @@ bool EInkDisplay::connect()
|
||||
|
||||
// Init GxEPD2
|
||||
adafruitDisplay->init();
|
||||
#if defined(MINI_EPAPER_S3)
|
||||
adafruitDisplay->setRotation(3);
|
||||
#else
|
||||
adafruitDisplay->setRotation(3);
|
||||
#if defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(CROWPANEL_ESP32S3_4_EPAPER)
|
||||
adafruitDisplay->setRotation(0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#elif defined(PCA10059) || defined(ME25LS01)
|
||||
@@ -259,17 +268,6 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, EINK_WIDTH, EINK_HEIGHT);
|
||||
}
|
||||
#elif defined(MINI_EPAPER_S3)
|
||||
spi1 = new SPIClass(HSPI);
|
||||
spi1->begin(PIN_SPI1_SCK, PIN_SPI1_MISO, PIN_SPI1_MOSI, PIN_EINK_CS);
|
||||
|
||||
// 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(1);
|
||||
#elif defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213)
|
||||
|
||||
// Detect display model, before starting SPI
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_EINK
|
||||
#if defined(USE_EINK) && !defined(USE_EINK_PARALLELDISPLAY)
|
||||
|
||||
#include "GxEPD2_BW.h"
|
||||
#include <OLEDDisplay.h>
|
||||
@@ -89,12 +89,12 @@ class EInkDisplay : public OLEDDisplay
|
||||
// If display uses HSPI
|
||||
#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(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER) || defined(ELECROW_ThinkNode_M5)
|
||||
defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER) || defined(ELECROW_ThinkNode_M5) || \
|
||||
defined(MINI_EPAPER_S3)
|
||||
SPIClass *hspi = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(HELTEC_MESH_POCKET) || defined(SEEED_WIO_TRACKER_L1_EINK) || defined(HELTEC_MESH_SOLAR_EINK) || \
|
||||
defined(MINI_EPAPER_S3)
|
||||
#if defined(HELTEC_MESH_POCKET) || defined(SEEED_WIO_TRACKER_L1_EINK) || defined(HELTEC_MESH_SOLAR_EINK)
|
||||
SPIClass *spi1 = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ void EInkDynamicDisplay::adjustRefreshCounters()
|
||||
// Trigger the display update by calling base class
|
||||
bool EInkDynamicDisplay::update()
|
||||
{
|
||||
// Detemine the refresh mode to use, and start the update
|
||||
// Determine the refresh mode to use, and start the update
|
||||
bool refreshApproved = determineMode();
|
||||
if (refreshApproved) {
|
||||
EInkDisplay::forceDisplay(0); // Bypass base class' own rate-limiting system
|
||||
@@ -317,7 +317,7 @@ void EInkDynamicDisplay::checkFrameMatchesPrevious()
|
||||
LOG_DEBUG("refresh=SKIPPED, reason=FRAME_MATCHED_PREVIOUS, frameFlags=0x%x", frameFlags);
|
||||
}
|
||||
|
||||
// Have too many fast-refreshes occured consecutively, since last full refresh?
|
||||
// Have too many fast-refreshes occurred consecutively, since last full refresh?
|
||||
void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
|
||||
{
|
||||
// If a decision was already reached, don't run the check
|
||||
@@ -561,4 +561,4 @@ void EInkDynamicDisplay::awaitRefresh()
|
||||
}
|
||||
#endif // HAS_EINK_ASYNCFULL
|
||||
|
||||
#endif // USE_EINK_DYNAMICDISPLAY
|
||||
#endif // USE_EINK_DYNAMICDISPLAY
|
||||
|
||||
@@ -0,0 +1,427 @@
|
||||
#include "EInkParallelDisplay.h"
|
||||
|
||||
#ifdef USE_EINK_PARALLELDISPLAY
|
||||
|
||||
#include "Wire.h"
|
||||
#include "variant.h"
|
||||
#include <Arduino.h>
|
||||
#include <atomic>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "FastEPD.h"
|
||||
|
||||
// Thresholds for choosing partial vs full update
|
||||
#ifndef EPD_PARTIAL_THRESHOLD_ROWS
|
||||
#define EPD_PARTIAL_THRESHOLD_ROWS 128 // if changed region <= this many rows, prefer partial
|
||||
#endif
|
||||
#ifndef EPD_FULLSLOW_PERIOD
|
||||
#define EPD_FULLSLOW_PERIOD 100 // every N full updates do a slow (CLEAR_SLOW) full refresh
|
||||
#endif
|
||||
#ifndef EPD_RESPONSIVE_MIN_MS
|
||||
#define EPD_RESPONSIVE_MIN_MS 1000 // simple rate-limit (ms) for responsive updates
|
||||
#endif
|
||||
|
||||
EInkParallelDisplay::EInkParallelDisplay(uint16_t width, uint16_t height, EpdRotation rot) : epaper(nullptr), rotation(rot)
|
||||
{
|
||||
LOG_INFO("init EInkParallelDisplay");
|
||||
// Set dimensions in OLEDDisplay base class
|
||||
this->geometry = GEOMETRY_RAWMODE;
|
||||
this->displayWidth = width;
|
||||
this->displayHeight = height;
|
||||
|
||||
// Round shortest side up to nearest byte, to prevent truncation causing an undersized buffer
|
||||
uint16_t shortSide = min(width, height);
|
||||
uint16_t longSide = max(width, height);
|
||||
if (shortSide % 8 != 0)
|
||||
shortSide = (shortSide | 7) + 1;
|
||||
|
||||
this->displayBufferSize = longSide * (shortSide / 8);
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// allocate dirty pixel buffer same size as epaper buffers (rowBytes * height)
|
||||
size_t rowBytes = (this->displayWidth + 7) / 8;
|
||||
dirtyPixelsSize = rowBytes * this->displayHeight;
|
||||
dirtyPixels = (uint8_t *)calloc(dirtyPixelsSize, 1);
|
||||
ghostPixelCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
EInkParallelDisplay::~EInkParallelDisplay()
|
||||
{
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
if (dirtyPixels) {
|
||||
free(dirtyPixels);
|
||||
dirtyPixels = nullptr;
|
||||
}
|
||||
#endif
|
||||
// If an async full update is running, wait for it to finish
|
||||
if (asyncFullRunning.load()) {
|
||||
// wait a short while for task to finish
|
||||
for (int i = 0; i < 50 && asyncFullRunning.load(); ++i) {
|
||||
delay(50);
|
||||
}
|
||||
if (asyncTaskHandle) {
|
||||
// Let it finish or delete it
|
||||
vTaskDelete(asyncTaskHandle);
|
||||
asyncTaskHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
delete epaper;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the OLEDDisplay::init() path.
|
||||
*/
|
||||
bool EInkParallelDisplay::connect()
|
||||
{
|
||||
LOG_INFO("Do EPD init");
|
||||
if (!epaper) {
|
||||
epaper = new FASTEPD;
|
||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO, 28000000);
|
||||
#elif defined(T5_S3_EPAPER_PRO_V2)
|
||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO_V2, 28000000);
|
||||
// initialize all port 0 pins (0-7) as outputs / HIGH
|
||||
for (int i = 0; i < 8; i++) {
|
||||
epaper->ioPinMode(i, OUTPUT);
|
||||
epaper->ioWrite(i, HIGH);
|
||||
}
|
||||
#else
|
||||
#error "unsupported EPD device!"
|
||||
#endif
|
||||
}
|
||||
|
||||
// epaper->setRotation(rotation); // does not work, messes up width/height
|
||||
epaper->setMode(BB_MODE_1BPP);
|
||||
epaper->clearWhite();
|
||||
epaper->fullUpdate(true);
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// After a full/clear the dirty tracking should be reset
|
||||
resetGhostPixelTracking();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendCommand - simple passthrough (not required for epd_driver-based path)
|
||||
*/
|
||||
void EInkParallelDisplay::sendCommand(uint8_t com)
|
||||
{
|
||||
LOG_DEBUG("EInkParallelDisplay::sendCommand %d", (int)com);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start a background task that will perform a blocking fullUpdate(). This lets
|
||||
* display() return quickly while the heavy refresh runs in the background.
|
||||
*/
|
||||
void EInkParallelDisplay::startAsyncFullUpdate(int clearMode)
|
||||
{
|
||||
if (asyncFullRunning.load())
|
||||
return; // already running
|
||||
|
||||
asyncFullRunning.store(true);
|
||||
// pass 'this' as parameter
|
||||
BaseType_t rc = xTaskCreatePinnedToCore(EInkParallelDisplay::asyncFullUpdateTask, "epd_full", 4096 / sizeof(StackType_t),
|
||||
this, 2, &asyncTaskHandle,
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
0
|
||||
#else
|
||||
1
|
||||
#endif
|
||||
);
|
||||
if (rc != pdPASS) {
|
||||
LOG_WARN("Failed to create async full-update task, falling back to blocking update");
|
||||
epaper->fullUpdate(clearMode, false);
|
||||
epaper->backupPlane();
|
||||
asyncFullRunning.store(false);
|
||||
asyncTaskHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeRTOS task entry: runs the full update and then backs up plane.
|
||||
*/
|
||||
void EInkParallelDisplay::asyncFullUpdateTask(void *pvParameters)
|
||||
{
|
||||
EInkParallelDisplay *self = static_cast<EInkParallelDisplay *>(pvParameters);
|
||||
if (!self) {
|
||||
vTaskDelete(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// choose CLEAR_SLOW occasionally
|
||||
int clearMode = CLEAR_FAST;
|
||||
if (self->fastRefreshCount >= EPD_FULLSLOW_PERIOD) {
|
||||
clearMode = CLEAR_SLOW;
|
||||
self->fastRefreshCount = 0;
|
||||
} else {
|
||||
// when running async full, treat it as a full so reset fast count
|
||||
self->fastRefreshCount = 0;
|
||||
}
|
||||
|
||||
self->epaper->fullUpdate(clearMode, false);
|
||||
self->epaper->backupPlane();
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// A full refresh clears ghosting state
|
||||
self->resetGhostPixelTracking();
|
||||
#endif
|
||||
|
||||
self->asyncFullRunning.store(false);
|
||||
self->asyncTaskHandle = nullptr;
|
||||
|
||||
// delete this task
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the OLEDDisplay buffer (vertical byte layout) into the 1bpp horizontal-bytes
|
||||
* buffer used by the FASTEPD library. For performance we write directly into FASTEPD's
|
||||
* currentBuffer() while comparing against previousBuffer() to detect changed rows.
|
||||
* After conversion we call FASTEPD::partialUpdate() or FASTEPD::fullUpdate() according
|
||||
* to a heuristic so only the minimal region is refreshed.
|
||||
*/
|
||||
void EInkParallelDisplay::display(void)
|
||||
{
|
||||
const uint16_t w = this->displayWidth;
|
||||
const uint16_t h = this->displayHeight;
|
||||
|
||||
// Simple rate limiting: avoid very-frequent responsive updates
|
||||
uint32_t nowMs = millis();
|
||||
if (lastUpdateMs != 0 && (nowMs - lastUpdateMs) < EPD_RESPONSIVE_MIN_MS) {
|
||||
LOG_DEBUG("rate-limited, skipping update");
|
||||
return;
|
||||
}
|
||||
|
||||
// bytes per row in epd format (one byte = 8 horizontal pixels)
|
||||
const uint32_t rowBytes = (w + 7) / 8;
|
||||
|
||||
// Get pointers to internal buffers
|
||||
uint8_t *cur = epaper->currentBuffer();
|
||||
uint8_t *prev = epaper->previousBuffer(); // may be NULL on first init
|
||||
|
||||
// Track changed row range while converting
|
||||
int newTop = h; // min changed row (initialized to out-of-range)
|
||||
int newBottom = -1; // max changed row
|
||||
|
||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
||||
// Track changed byte column range (for clipped fullUpdate fallback)
|
||||
int newLeftByte = (int)rowBytes;
|
||||
int newRightByte = -1;
|
||||
#endif
|
||||
|
||||
// Compute a quick hash of the incoming OLED buffer (so we can skip identical frames)
|
||||
uint32_t imageHash = 0;
|
||||
uint32_t bufBytes = (w / 8) * h; // vertical-byte layout size
|
||||
for (uint32_t bi = 0; bi < bufBytes; ++bi) {
|
||||
imageHash ^= ((uint32_t)buffer[bi]) << (bi & 31);
|
||||
}
|
||||
if (imageHash == previousImageHash) {
|
||||
// LOG_DEBUG("image identical to previous, skipping update");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// reset ghost count for this conversion pass; we'll mark bits that change
|
||||
ghostPixelCount = 0;
|
||||
#endif
|
||||
|
||||
// Convert: OLED buffer layout -> FASTEPD 1bpp horizontal-bytes layout into cur,
|
||||
// comparing against prev when available to detect changes.
|
||||
for (uint32_t y = 0; y < h; ++y) {
|
||||
const uint32_t base = (y >> 3) * w; // (y/8) * width
|
||||
const uint8_t bitMask = (uint8_t)(1u << (y & 7)); // mask for this row in vertical-byte layout
|
||||
const uint32_t rowBase = y * rowBytes;
|
||||
|
||||
// process full 8-pixel bytes
|
||||
for (uint32_t xb = 0; xb < rowBytes; ++xb) {
|
||||
uint32_t x0 = xb * 8;
|
||||
// read up to 8 source bytes (vertical-byte per column)
|
||||
uint8_t b0 = (x0 + 0 < w) ? buffer[base + x0 + 0] : 0;
|
||||
uint8_t b1 = (x0 + 1 < w) ? buffer[base + x0 + 1] : 0;
|
||||
uint8_t b2 = (x0 + 2 < w) ? buffer[base + x0 + 2] : 0;
|
||||
uint8_t b3 = (x0 + 3 < w) ? buffer[base + x0 + 3] : 0;
|
||||
uint8_t b4 = (x0 + 4 < w) ? buffer[base + x0 + 4] : 0;
|
||||
uint8_t b5 = (x0 + 5 < w) ? buffer[base + x0 + 5] : 0;
|
||||
uint8_t b6 = (x0 + 6 < w) ? buffer[base + x0 + 6] : 0;
|
||||
uint8_t b7 = (x0 + 7 < w) ? buffer[base + x0 + 7] : 0;
|
||||
|
||||
// build output byte: MSB = leftmost pixel
|
||||
uint8_t out = 0;
|
||||
out |= (uint8_t)((b0 & bitMask) ? 0x80 : 0x00);
|
||||
out |= (uint8_t)((b1 & bitMask) ? 0x40 : 0x00);
|
||||
out |= (uint8_t)((b2 & bitMask) ? 0x20 : 0x00);
|
||||
out |= (uint8_t)((b3 & bitMask) ? 0x10 : 0x00);
|
||||
out |= (uint8_t)((b4 & bitMask) ? 0x08 : 0x00);
|
||||
out |= (uint8_t)((b5 & bitMask) ? 0x04 : 0x00);
|
||||
out |= (uint8_t)((b6 & bitMask) ? 0x02 : 0x00);
|
||||
out |= (uint8_t)((b7 & bitMask) ? 0x01 : 0x00);
|
||||
|
||||
// handle partial byte at end of row by masking off invalid bits
|
||||
uint8_t mask = 0xFF;
|
||||
uint32_t bitsRemain = (w > x0) ? (w - x0) : 0;
|
||||
if (bitsRemain > 0 && bitsRemain < 8) {
|
||||
mask = (uint8_t)(0xFF << (8 - bitsRemain));
|
||||
out &= mask;
|
||||
}
|
||||
|
||||
// invert to FASTEPD polarity
|
||||
out = (~out) & mask;
|
||||
|
||||
uint32_t pos = rowBase + xb;
|
||||
uint8_t prevVal = prev ? (prev[pos] & mask) : 0x00;
|
||||
// Consider this byte changed if previous buffer differs (or prev is null)
|
||||
bool changed = (prev == nullptr) || (prevVal != out);
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
if (changed && prev)
|
||||
markDirtyBits(prev, pos, mask, out);
|
||||
#endif
|
||||
|
||||
// mark row changed only if the previous buffer differs
|
||||
if (changed) {
|
||||
if (y < (uint32_t)newTop)
|
||||
newTop = y;
|
||||
if ((int)y > newBottom)
|
||||
newBottom = y;
|
||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
||||
// record changed column bytes
|
||||
if ((int)xb < newLeftByte)
|
||||
newLeftByte = (int)xb;
|
||||
if ((int)xb > newRightByte)
|
||||
newRightByte = (int)xb;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Always write the computed value into the current buffer (avoid leaving stale bytes)
|
||||
cur[pos] = (cur[pos] & ~mask) | out;
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing changed, avoid any panel update
|
||||
if (newBottom < 0) {
|
||||
LOG_DEBUG("no pixel changes detected, skipping update (conv)");
|
||||
previousImageHash = imageHash; // still remember that frame
|
||||
return;
|
||||
}
|
||||
|
||||
// Choose partial vs full update using heuristic
|
||||
// Decide if we should force a full update after many fast updates
|
||||
bool forceFull = (fastRefreshCount >= EPD_FULLSLOW_PERIOD);
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// If ghost pixels exceed limit, force a full update to clear ghosting
|
||||
if (ghostPixelCount > ghostPixelLimit) {
|
||||
LOG_WARN("ghost pixels %u > limit %u, forcing full refresh", ghostPixelCount, ghostPixelLimit);
|
||||
forceFull = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compute pixel bounds from newTop/newBottom
|
||||
int startRow = (newTop / 8) * 8;
|
||||
int endRow = (newBottom / 8) * 8 + 7;
|
||||
|
||||
LOG_DEBUG("EPD update rows=%d..%d alignedRows=%d..%d rowBytes=%u", newTop, newBottom, startRow, endRow, rowBytes);
|
||||
|
||||
if (epaper->getMode() == BB_MODE_1BPP && !forceFull && (newBottom - newTop) <= EPD_PARTIAL_THRESHOLD_ROWS) {
|
||||
// Prefer partial update path if driver is reliable; otherwise use clipped fullUpdate fallback.
|
||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
||||
// Workaround for FastEPD partial update bug: use clipped fullUpdate instead
|
||||
// Build a pixel rectangle for a clipped fullUpdate using the changed columns
|
||||
int startCol = (newLeftByte <= newRightByte) ? (newLeftByte * 8) : 0;
|
||||
int endCol = (newLeftByte <= newRightByte) ? ((newRightByte + 1) * 8 - 1) : (w - 1);
|
||||
|
||||
BB_RECT rect{startCol, startRow, endCol - startCol + 1, endRow - startRow + 1};
|
||||
// LOG_DEBUG("Using clipped fullUpdate rect x=%d y=%d w=%d h=%d", rect.x, rect.y, rect.w, rect.h);
|
||||
epaper->fullUpdate(CLEAR_FAST, false, &rect);
|
||||
#else
|
||||
// Use rows for partial update
|
||||
LOG_DEBUG("calling partialUpdate startRow=%d endRow=%d", startRow, endRow);
|
||||
epaper->partialUpdate(true, startRow, endRow);
|
||||
#endif
|
||||
epaper->backupPlane();
|
||||
fastRefreshCount++;
|
||||
} else {
|
||||
// Full update: run async if possible (startAsyncFullUpdate will fall back to blocking)
|
||||
startAsyncFullUpdate(forceFull ? CLEAR_SLOW : CLEAR_FAST);
|
||||
}
|
||||
|
||||
lastUpdateMs = millis();
|
||||
previousImageHash = imageHash;
|
||||
|
||||
// Keep same behavior as before
|
||||
lastDrawMsec = millis();
|
||||
}
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// markDirtyBits: mark per-bit dirty flags and update ghostPixelCount
|
||||
void EInkParallelDisplay::markDirtyBits(const uint8_t *prevBuf, uint32_t pos, uint8_t mask, uint8_t out)
|
||||
{
|
||||
// defensive: need dirtyPixels allocated and prevBuf valid
|
||||
if (!dirtyPixels || !prevBuf)
|
||||
return;
|
||||
|
||||
// 'out' is in FASTEPD polarity (1 = black, 0 = white)
|
||||
uint8_t newBlack = out & mask; // bits that will be black now
|
||||
uint8_t newWhite = (~out) & mask; // bits that will be white now
|
||||
|
||||
// previously recorded dirty bits for this byte
|
||||
uint8_t before = dirtyPixels[pos];
|
||||
|
||||
// Ghost bits: bits that were previously marked dirty and are now being driven white
|
||||
uint8_t ghostBits = before & newWhite;
|
||||
if (ghostBits) {
|
||||
ghostPixelCount += __builtin_popcount((unsigned)ghostBits);
|
||||
}
|
||||
|
||||
// Only mark bits dirty when they turn black now (accumulate until a full refresh)
|
||||
uint8_t newlyDirty = newBlack & (~before);
|
||||
if (newlyDirty) {
|
||||
dirtyPixels[pos] |= newlyDirty;
|
||||
}
|
||||
}
|
||||
|
||||
// reset ghost tracking (call after a full refresh)
|
||||
void EInkParallelDisplay::resetGhostPixelTracking()
|
||||
{
|
||||
if (!dirtyPixels)
|
||||
return;
|
||||
memset(dirtyPixels, 0, dirtyPixelsSize);
|
||||
ghostPixelCount = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* forceDisplay: use lastDrawMsec
|
||||
*/
|
||||
bool EInkParallelDisplay::forceDisplay(uint32_t msecLimit)
|
||||
{
|
||||
uint32_t now = millis();
|
||||
if (lastDrawMsec == 0 || (now - lastDrawMsec) > msecLimit) {
|
||||
display();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EInkParallelDisplay::endUpdate()
|
||||
{
|
||||
{
|
||||
// ensure any async full update is started/completed
|
||||
if (asyncFullRunning.load()) {
|
||||
// nothing to do; background task will run and call backupPlane when done
|
||||
} else {
|
||||
epaper->fullUpdate(CLEAR_FAST, false);
|
||||
epaper->backupPlane();
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
resetGhostPixelTracking();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef USE_EINK_PARALLELDISPLAY
|
||||
#include <OLEDDisplay.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
class FASTEPD;
|
||||
|
||||
/**
|
||||
* Adapter for E-Ink 8-bit parallel displays (EPD), specifically devices supported by FastEPD library
|
||||
*/
|
||||
class EInkParallelDisplay : public OLEDDisplay
|
||||
{
|
||||
public:
|
||||
enum EpdRotation {
|
||||
EPD_ROT_LANDSCAPE = 0,
|
||||
EPD_ROT_PORTRAIT = 90,
|
||||
EPD_ROT_INVERTED_LANDSCAPE = 180,
|
||||
EPD_ROT_INVERTED_PORTRAIT = 270,
|
||||
};
|
||||
|
||||
EInkParallelDisplay(uint16_t width, uint16_t height, EpdRotation rotation);
|
||||
virtual ~EInkParallelDisplay();
|
||||
|
||||
// OLEDDisplay virtuals
|
||||
bool connect() override;
|
||||
void sendCommand(uint8_t com) override;
|
||||
int getBufferOffset(void) override { return 0; }
|
||||
|
||||
void display(void) override;
|
||||
bool forceDisplay(uint32_t msecLimit = 1000);
|
||||
void endUpdate();
|
||||
|
||||
protected:
|
||||
uint32_t lastDrawMsec = 0;
|
||||
FASTEPD *epaper;
|
||||
|
||||
private:
|
||||
// Async full-refresh support
|
||||
std::atomic<bool> asyncFullRunning{false};
|
||||
TaskHandle_t asyncTaskHandle = nullptr;
|
||||
void startAsyncFullUpdate(int clearMode);
|
||||
static void asyncFullUpdateTask(void *pvParameters);
|
||||
|
||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
||||
// helpers
|
||||
void resetGhostPixelTracking();
|
||||
void markDirtyBits(const uint8_t *prevBuf, uint32_t pos, uint8_t mask, uint8_t out);
|
||||
void countGhostPixelsAndMaybePromote(int &newTop, int &newBottom, bool &forceFull);
|
||||
|
||||
// per-bit dirty buffer (same format as epaper buffers): one bit == one pixel
|
||||
uint8_t *dirtyPixels = nullptr;
|
||||
size_t dirtyPixelsSize = 0;
|
||||
uint32_t ghostPixelCount = 0;
|
||||
uint32_t ghostPixelLimit = EINK_LIMIT_GHOSTING_PX;
|
||||
#endif
|
||||
|
||||
EpdRotation rotation;
|
||||
uint32_t previousImageHash = 0;
|
||||
uint32_t lastUpdateMs = 0;
|
||||
int fastRefreshCount = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user