mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-30 06:31:01 +00:00
Compare commits
185 Commits
meshtastic
...
v2.6.5.fc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc3d9f2a15 | ||
|
|
69f938ea98 | ||
|
|
ec298199ee | ||
|
|
0d800b7a22 | ||
|
|
1b1d4625aa | ||
|
|
fb2010552f | ||
|
|
c94dd1e331 | ||
|
|
cfc2a96a45 | ||
|
|
c0dab4a672 | ||
|
|
12d1305618 | ||
|
|
a084073cc1 | ||
|
|
e2933bcb5b | ||
|
|
606abfc116 | ||
|
|
860e8eca5a | ||
|
|
5a9d70b445 | ||
|
|
2125c03974 | ||
|
|
56eb0c08b2 | ||
|
|
1b33189fe6 | ||
|
|
25237a15ff | ||
|
|
0110275494 | ||
|
|
4dfba50304 | ||
|
|
7494106170 | ||
|
|
0665802823 | ||
|
|
1017f6af35 | ||
|
|
11bafae287 | ||
|
|
31130fd49e | ||
|
|
594cb0cc1e | ||
|
|
ef18a9b5b5 | ||
|
|
67fddcc214 | ||
|
|
f6ed10f329 | ||
|
|
644849126c | ||
|
|
ea4ce8d827 | ||
|
|
128c347c64 | ||
|
|
ae88759059 | ||
|
|
2c01fad798 | ||
|
|
a5efbfccd7 | ||
|
|
886bffe8f3 | ||
|
|
39408fd3b1 | ||
|
|
3314b00fcc | ||
|
|
72db671e00 | ||
|
|
bd2d2981c9 | ||
|
|
da26ff5b95 | ||
|
|
f626f02005 | ||
|
|
f18f60cd0b | ||
|
|
850d21dcb9 | ||
|
|
e08177ba98 | ||
|
|
b52c355f2f | ||
|
|
e79d4492e8 | ||
|
|
95523a9659 | ||
|
|
32d91ed859 | ||
|
|
a93d779ec0 | ||
|
|
38c8c20a2b | ||
|
|
b89355ffa6 | ||
|
|
8a4a0cc932 | ||
|
|
cbcdc3ed00 | ||
|
|
d663d44647 | ||
|
|
3148e7277d | ||
|
|
7df327664e | ||
|
|
a902776e57 | ||
|
|
ea9485657e | ||
|
|
0491c890d7 | ||
|
|
4a3991a8c6 | ||
|
|
c602bfecbd | ||
|
|
6c7c0770f9 | ||
|
|
89cde1a8e6 | ||
|
|
02237f5ac6 | ||
|
|
4a12b4eb32 | ||
|
|
a2387c79ee | ||
|
|
d7504921fb | ||
|
|
4e1030ef9c | ||
|
|
1e41c994b3 | ||
|
|
4590ef2e7b | ||
|
|
769f0623be | ||
|
|
52527b24a7 | ||
|
|
6c17694b64 | ||
|
|
640e731ad2 | ||
|
|
ba81a8ad87 | ||
|
|
83d8e3cb09 | ||
|
|
6429eca5e4 | ||
|
|
13101c1bab | ||
|
|
d28af68b5a | ||
|
|
53a7afff41 | ||
|
|
eb375d8e62 | ||
|
|
33f2b7144f | ||
|
|
e5f8218d34 | ||
|
|
0ddb507055 | ||
|
|
3afe84c4f4 | ||
|
|
e9d8a3d7f9 | ||
|
|
e722a97987 | ||
|
|
daa4186d65 | ||
|
|
1ee800e901 | ||
|
|
cf7f0f9d08 | ||
|
|
1e4a0134e6 | ||
|
|
0951fdd49b | ||
|
|
848a3ed6a1 | ||
|
|
fd7a1f2ccb | ||
|
|
5acaf8f897 | ||
|
|
cff93adb5e | ||
|
|
e4d3ec1f59 | ||
|
|
ae27aaaf43 | ||
|
|
31c0e8fa2c | ||
|
|
0d95b1afcc | ||
|
|
46235f6f8b | ||
|
|
d1068fd1e4 | ||
|
|
f41afb14b1 | ||
|
|
f8ad02aab3 | ||
|
|
077759e15d | ||
|
|
22aa2d7582 | ||
|
|
6673cb9292 | ||
|
|
8efc9702d3 | ||
|
|
2876eec7ed | ||
|
|
9cc13e628a | ||
|
|
af8b64e84e | ||
|
|
96ba94843b | ||
|
|
2d565c2921 | ||
|
|
2525111c39 | ||
|
|
64b9cfe199 | ||
|
|
dc100e4d3e | ||
|
|
1640fb105d | ||
|
|
99e42b4d22 | ||
|
|
79233fe99d | ||
|
|
f66784ed2a | ||
|
|
f198d5d49f | ||
|
|
4d34b3d73c | ||
|
|
8efe8a2ea3 | ||
|
|
499ea56e3b | ||
|
|
2473af6995 | ||
|
|
508ab171d6 | ||
|
|
ec59f7d7dd | ||
|
|
f4c79530ec | ||
|
|
e9effb9fff | ||
|
|
cb6dfb66d2 | ||
|
|
8795a63427 | ||
|
|
186e509607 | ||
|
|
7c3eddebc2 | ||
|
|
78b4eff568 | ||
|
|
3c1f92ce84 | ||
|
|
5de6bc1851 | ||
|
|
c54fc5b7c5 | ||
|
|
94de2315c1 | ||
|
|
7f17747d8c | ||
|
|
16a0dce83c | ||
|
|
3fd47d9713 | ||
|
|
284598ed56 | ||
|
|
2a3e1f904d | ||
|
|
60e46cd765 | ||
|
|
563747c5cd | ||
|
|
5c77d42345 | ||
|
|
f0a2ae9ff3 | ||
|
|
f7afa9a81e | ||
|
|
c8bd6c32cc | ||
|
|
f6a9e7d741 | ||
|
|
e6a98b1d6b | ||
|
|
b2ef92a328 | ||
|
|
b25db1f42c | ||
|
|
a924b9d94a | ||
|
|
f5e0e282b6 | ||
|
|
a3a9b2fe84 | ||
|
|
6c8058e1d8 | ||
|
|
445efe9e21 | ||
|
|
b96b027926 | ||
|
|
239e5412b3 | ||
|
|
ede3f7b702 | ||
|
|
f0f2cd0e0e | ||
|
|
fdbadc992c | ||
|
|
2391982c1d | ||
|
|
41875d245e | ||
|
|
95bcd7ab0b | ||
|
|
050f0016c4 | ||
|
|
6715662281 | ||
|
|
b6562e175f | ||
|
|
f89f916f96 | ||
|
|
43a6e711da | ||
|
|
63b20e358f | ||
|
|
12fde696c1 | ||
|
|
5c8f1fb46b | ||
|
|
ce38ac10d1 | ||
|
|
d5ec205572 | ||
|
|
9893d24c62 | ||
|
|
ab61cd65d1 | ||
|
|
baef8dce79 | ||
|
|
99d3e5eb70 | ||
|
|
088fce7d11 | ||
|
|
b46bf16385 | ||
|
|
1c827f5512 |
@@ -1,9 +1,10 @@
|
|||||||
|
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||||
|
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
|
||||||
# trunk-ignore(hadolint/DL3008): Use latest version of packages
|
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& apt-get -y install --no-install-recommends \
|
&& apt-get -y install --no-install-recommends \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
@@ -27,9 +28,15 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
|||||||
hwdata \
|
hwdata \
|
||||||
gpg \
|
gpg \
|
||||||
gnupg2 \
|
gnupg2 \
|
||||||
|
libusb-1.0-0-dev \
|
||||||
|
libuv1-dev \
|
||||||
|
libi2c-dev \
|
||||||
|
libxcb-xkb-dev \
|
||||||
|
libxkbcommon-dev \
|
||||||
|
libinput-dev \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN pipx install platformio==6.1.15
|
RUN pipx install platformio
|
||||||
|
|
||||||
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
|
|
||||||
|
pip install --no-cache-dir setuptools
|
||||||
|
pipx install esptool
|
||||||
|
|||||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,4 +1,5 @@
|
|||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
*.cmd text eol=crlf
|
||||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
*.bat text eol=crlf
|
||||||
|
*.ps1 text eol=crlf
|
||||||
*.{sh,[sS][hH]} text eol=lf
|
*.{sh,[sS][hH]} text eol=lf
|
||||||
|
|||||||
9
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
9
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
@@ -72,6 +72,15 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: mui
|
||||||
|
attributes:
|
||||||
|
label: Is this bug report about any UI component firmware like InkHUD or Meshtatic UI (MUI)?
|
||||||
|
options:
|
||||||
|
- label: Meshtastic UI aka MUI colorTFT
|
||||||
|
- label: InkHUD ePaper
|
||||||
|
- label: OLED slide UI on any display
|
||||||
|
|
||||||
- type: input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
9
.github/actions/build-variant/action.yml
vendored
9
.github/actions/build-variant/action.yml
vendored
@@ -43,6 +43,13 @@ runs:
|
|||||||
id: base
|
id: base
|
||||||
uses: ./.github/actions/setup-base
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Get web ui version
|
||||||
|
if: inputs.include-web-ui == 'true'
|
||||||
|
id: webver
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "ver=$(cat bin/web.version)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Pull web ui
|
- name: Pull web ui
|
||||||
if: inputs.include-web-ui == 'true'
|
if: inputs.include-web-ui == 'true'
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@master
|
||||||
@@ -51,7 +58,7 @@ runs:
|
|||||||
file: build.tar
|
file: build.tar
|
||||||
target: build.tar
|
target: build.tar
|
||||||
token: ${{ inputs.github_token }}
|
token: ${{ inputs.github_token }}
|
||||||
version: tags/v2.5.3
|
version: tags/v${{ steps.webver.outputs.ver }}
|
||||||
|
|
||||||
- name: Unpack web ui
|
- name: Unpack web ui
|
||||||
if: inputs.include-web-ui == 'true'
|
if: inputs.include-web-ui == 'true'
|
||||||
|
|||||||
2
.github/actions/setup-native/action.yml
vendored
2
.github/actions/setup-native/action.yml
vendored
@@ -11,4 +11,4 @@ runs:
|
|||||||
- name: Install libs needed for native build
|
- name: Install libs needed for native build
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
|
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev libuv1-dev
|
||||||
|
|||||||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@@ -19,6 +19,8 @@ updates:
|
|||||||
interval: daily
|
interval: daily
|
||||||
time: "05:00"
|
time: "05:00"
|
||||||
timezone: US/Pacific
|
timezone: US/Pacific
|
||||||
|
ignore:
|
||||||
|
- dependency-name: protobufs
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: /.github/workflows
|
directory: /.github/workflows
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
18
.github/pull_request_template.md
vendored
18
.github/pull_request_template.md
vendored
@@ -1,7 +1,6 @@
|
|||||||
|
## 🙏 Thank you for sending in a pull request, here's some tips to get started!
|
||||||
|
|
||||||
### ❌ (Please delete all these tips and replace them with your text) ❌
|
### ❌ (Please delete all these tips and replace them with your text) ❌
|
||||||
|
|
||||||
## Thank you for sending in a pull request, here's some tips to get started!
|
|
||||||
|
|
||||||
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
|
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
|
||||||
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
||||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||||
@@ -12,4 +11,17 @@
|
|||||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||||
- If your other co-developers have comments on your PR please tweak as needed.
|
- If your other co-developers have comments on your PR please tweak as needed.
|
||||||
- Please also enable "Allow edits by maintainers".
|
- Please also enable "Allow edits by maintainers".
|
||||||
|
- Please do not submit untested code.
|
||||||
|
- If you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and commnunity members can help test your changes.
|
||||||
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
||||||
|
|
||||||
|
|
||||||
|
## 🤝 Attestations
|
||||||
|
- [ ] I have tested that my proposed changes behave as described.
|
||||||
|
- [ ] I have tested that my proposed changes do not cause any obvious regressions on the following devices:
|
||||||
|
- [ ] Heltec (Lora32) V3
|
||||||
|
- [ ] LilyGo T-Deck
|
||||||
|
- [ ] LilyGo T-Beam
|
||||||
|
- [ ] RAK WisBlock 4631
|
||||||
|
- [ ] Seeed Studio T-1000E tracker card
|
||||||
|
- [ ] Other (please specify below)
|
||||||
|
|||||||
2
.github/workflows/build_debian_src.yml
vendored
2
.github/workflows/build_debian_src.yml
vendored
@@ -4,7 +4,7 @@ on:
|
|||||||
workflow_call:
|
workflow_call:
|
||||||
secrets:
|
secrets:
|
||||||
PPA_GPG_PRIVATE_KEY:
|
PPA_GPG_PRIVATE_KEY:
|
||||||
required: true
|
required: false
|
||||||
inputs:
|
inputs:
|
||||||
series:
|
series:
|
||||||
description: Ubuntu/Debian series to target
|
description: Ubuntu/Debian series to target
|
||||||
|
|||||||
39
.github/workflows/main_matrix.yml
vendored
39
.github/workflows/main_matrix.yml
vendored
@@ -135,10 +135,11 @@ jobs:
|
|||||||
build_location: local
|
build_location: local
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
package-pio-deps-native:
|
package-pio-deps-native-tft:
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
uses: ./.github/workflows/package_pio_deps.yml
|
uses: ./.github/workflows/package_pio_deps.yml
|
||||||
with:
|
with:
|
||||||
pio_env: native
|
pio_env: native-tft
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
test-native:
|
test-native:
|
||||||
@@ -288,7 +289,7 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- gather-artifacts
|
- gather-artifacts
|
||||||
- build-debian-src
|
- build-debian-src
|
||||||
- package-pio-deps-native
|
- package-pio-deps-native-tft
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -324,18 +325,18 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output/debian-src
|
path: ./output/debian-src
|
||||||
|
|
||||||
- name: Download native pio deps
|
- name: Download `native-tft` pio deps
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
pattern: platformio-deps-native-${{ steps.version.outputs.long }}
|
pattern: platformio-deps-native-tft-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output/pio-deps-native
|
path: ./output/pio-deps-native-tft
|
||||||
|
|
||||||
- name: Zip linux sources
|
- name: Zip linux sources
|
||||||
working-directory: output
|
working-directory: output
|
||||||
run: |
|
run: |
|
||||||
zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
|
zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
|
||||||
zip -9 -r ./platformio-deps-native-${{ steps.version.outputs.long }}.zip ./pio-deps-native
|
zip -9 -r ./platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip ./pio-deps-native-tft
|
||||||
|
|
||||||
# For diagnostics
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -344,32 +345,10 @@ jobs:
|
|||||||
- name: Add linux sources to release
|
- name: Add linux sources to release
|
||||||
run: |
|
run: |
|
||||||
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
|
gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
|
||||||
gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-${{ steps.version.outputs.long }}.zip
|
gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Bump version.properties
|
|
||||||
run: >-
|
|
||||||
bin/bump_version.py
|
|
||||||
|
|
||||||
- name: Ensure debian deps are installed
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y --fix-missing
|
|
||||||
sudo apt-get install -y devscripts
|
|
||||||
|
|
||||||
- name: Update debian changelog
|
|
||||||
run: >-
|
|
||||||
debian/ci_changelog.sh
|
|
||||||
|
|
||||||
- name: Create version.properties pull request
|
|
||||||
uses: peter-evans/create-pull-request@v7
|
|
||||||
with:
|
|
||||||
title: Bump version.properties
|
|
||||||
add-paths: |
|
|
||||||
version.properties
|
|
||||||
debian/changelog
|
|
||||||
|
|
||||||
release-firmware:
|
release-firmware:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
46
.github/workflows/release_channels.yml
vendored
46
.github/workflows/release_channels.yml
vendored
@@ -43,3 +43,49 @@ jobs:
|
|||||||
copr_project: |-
|
copr_project: |-
|
||||||
${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
# Create a PR to bump version when a release is Published
|
||||||
|
bump-version:
|
||||||
|
if: ${{ github.event.release.published }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
run: |
|
||||||
|
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
env:
|
||||||
|
BUILD_LOCATION: local
|
||||||
|
|
||||||
|
- name: Bump version.properties
|
||||||
|
run: >-
|
||||||
|
bin/bump_version.py
|
||||||
|
|
||||||
|
- name: Ensure debian deps are installed
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y --fix-missing
|
||||||
|
sudo apt-get install -y devscripts
|
||||||
|
|
||||||
|
- name: Update debian changelog
|
||||||
|
run: >-
|
||||||
|
debian/ci_changelog.sh
|
||||||
|
|
||||||
|
- name: Create version.properties pull request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
title: Bump version.properties
|
||||||
|
add-paths: |
|
||||||
|
version.properties
|
||||||
|
debian/changelog
|
||||||
|
|||||||
7
.github/workflows/sec_sast_semgrep_cron.yml
vendored
7
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -6,11 +6,14 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: 0 1 * * 6
|
- cron: 0 1 * * 6
|
||||||
|
|
||||||
permissions: read-all
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
semgrep-full:
|
semgrep-full:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
container:
|
container:
|
||||||
image: semgrep/semgrep
|
image: semgrep/semgrep
|
||||||
|
|
||||||
|
|||||||
1
.github/workflows/stale_bot.yml
vendored
1
.github/workflows/stale_bot.yml
vendored
@@ -18,5 +18,6 @@ jobs:
|
|||||||
- name: Stale PR+Issues
|
- name: Stale PR+Issues
|
||||||
uses: actions/stale@v9.1.0
|
uses: actions/stale@v9.1.0
|
||||||
with:
|
with:
|
||||||
|
days-before-stale: 45
|
||||||
exempt-issue-labels: pinned,3.0
|
exempt-issue-labels: pinned,3.0
|
||||||
exempt-pr-labels: pinned,3.0
|
exempt-pr-labels: pinned,3.0
|
||||||
|
|||||||
2
.github/workflows/test_native.yml
vendored
2
.github/workflows/test_native.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Test Report
|
- name: Test Report
|
||||||
uses: dorny/test-reporter@v1.9.1
|
uses: dorny/test-reporter@v2.0.0
|
||||||
with:
|
with:
|
||||||
name: PlatformIO Tests
|
name: PlatformIO Tests
|
||||||
path: testreport.xml
|
path: testreport.xml
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.22.10
|
version: 1.22.12
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
@@ -8,27 +8,26 @@ plugins:
|
|||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- prettier@3.5.2
|
- prettier@3.5.3
|
||||||
- trufflehog@3.88.12
|
- trufflehog@3.88.23
|
||||||
- yamllint@1.35.1
|
- yamllint@1.37.0
|
||||||
- bandit@1.8.3
|
- bandit@1.8.3
|
||||||
- checkov@3.2.373
|
|
||||||
- terrascan@1.19.9
|
- terrascan@1.19.9
|
||||||
- trivy@0.59.1
|
- trivy@0.61.0
|
||||||
- taplo@0.9.3
|
- taplo@0.9.3
|
||||||
- ruff@0.9.7
|
- ruff@0.11.4
|
||||||
- isort@6.0.0
|
- isort@6.0.1
|
||||||
- markdownlint@0.44.0
|
- markdownlint@0.44.0
|
||||||
- oxipng@9.1.4
|
- oxipng@9.1.4
|
||||||
- svgo@3.3.2
|
- svgo@3.3.2
|
||||||
- actionlint@1.7.7
|
- actionlint@1.7.7
|
||||||
- flake8@7.1.2
|
- flake8@7.2.0
|
||||||
- hadolint@2.12.1-beta
|
- hadolint@2.12.1-beta
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.10.0
|
- shellcheck@0.10.0
|
||||||
- black@25.1.0
|
- black@25.1.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.24.0
|
- gitleaks@8.24.2
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
ignore:
|
ignore:
|
||||||
- linters: [ALL]
|
- linters: [ALL]
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -7,5 +7,8 @@
|
|||||||
"cmake.configureOnOpen": false,
|
"cmake.configureOnOpen": false,
|
||||||
"[cpp]": {
|
"[cpp]": {
|
||||||
"editor.defaultFormatter": "trunk.io"
|
"editor.defaultFormatter": "trunk.io"
|
||||||
|
},
|
||||||
|
"[powershell]": {
|
||||||
|
"editor.defaultFormatter": "ms-vscode.powershell"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
Dockerfile
17
Dockerfile
@@ -12,8 +12,8 @@ ENV TZ=Etc/UTC
|
|||||||
# Install Dependencies
|
# Install Dependencies
|
||||||
ENV PIP_ROOT_USER_ACTION=ignore
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
wget g++ zip git ca-certificates \
|
curl wget g++ zip git ca-certificates \
|
||||||
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
|
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
|
||||||
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
|
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||||
&& pip install --no-cache-dir -U platformio \
|
&& pip install --no-cache-dir -U platformio \
|
||||||
@@ -27,6 +27,12 @@ COPY . /tmp/firmware
|
|||||||
RUN bash ./bin/build-native.sh && \
|
RUN bash ./bin/build-native.sh && \
|
||||||
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
|
|
||||||
|
# Fetch web assets
|
||||||
|
RUN curl -L "https://github.com/meshtastic/web/releases/download/v$(cat /tmp/firmware/bin/web.version)/build.tar" -o /tmp/web.tar \
|
||||||
|
&& mkdir -p /tmp/web \
|
||||||
|
&& tar -xf /tmp/web.tar -C /tmp/web/ \
|
||||||
|
&& gzip -dr /tmp/web \
|
||||||
|
&& rm /tmp/web.tar
|
||||||
|
|
||||||
##### PRODUCTION BUILD #############
|
##### PRODUCTION BUILD #############
|
||||||
|
|
||||||
@@ -38,7 +44,7 @@ ENV TZ=Etc/UTC
|
|||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apt-get update && apt-get --no-install-recommends -y install \
|
RUN apt-get update && apt-get --no-install-recommends -y install \
|
||||||
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 \
|
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev liborcania2.3 libulfius2.7 libssl3 \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
|
||||||
&& mkdir -p /var/lib/meshtasticd \
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
&& mkdir -p /etc/meshtasticd/config.d \
|
&& mkdir -p /etc/meshtasticd/config.d \
|
||||||
@@ -46,6 +52,7 @@ RUN apt-get update && apt-get --no-install-recommends -y install \
|
|||||||
|
|
||||||
# Fetch compiled binary from the builder
|
# Fetch compiled binary from the builder
|
||||||
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/
|
||||||
|
COPY --from=builder /tmp/web /usr/share/meshtasticd/
|
||||||
# Copy config templates
|
# Copy config templates
|
||||||
COPY ./bin/config.d /etc/meshtasticd/available.d
|
COPY ./bin/config.d /etc/meshtasticd/available.d
|
||||||
|
|
||||||
@@ -54,7 +61,9 @@ VOLUME /var/lib/meshtasticd
|
|||||||
|
|
||||||
# Expose Meshtastic TCP API port from the host
|
# Expose Meshtastic TCP API port from the host
|
||||||
EXPOSE 4403
|
EXPOSE 4403
|
||||||
|
# Expose Meshtastic Web UI port from the host
|
||||||
|
EXPOSE 443
|
||||||
|
|
||||||
CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ]
|
CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ]
|
||||||
|
|
||||||
HEALTHCHECK NONE
|
HEALTHCHECK NONE
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ FROM python:3.13-alpine3.21 AS builder
|
|||||||
ENV PIP_ROOT_USER_ACTION=ignore
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
RUN apk --no-cache add \
|
RUN apk --no-cache add \
|
||||||
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||||
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone \
|
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
|
||||||
&& rm -rf /var/cache/apk/* \
|
&& rm -rf /var/cache/apk/* \
|
||||||
&& pip install --no-cache-dir -U platformio \
|
&& pip install --no-cache-dir -U platformio \
|
||||||
&& mkdir /tmp/firmware
|
&& mkdir /tmp/firmware
|
||||||
@@ -32,7 +32,7 @@ FROM alpine:3.21
|
|||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apk --no-cache add \
|
RUN apk --no-cache add \
|
||||||
libstdc++ libgpiod yaml-cpp libusb i2c-tools \
|
libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
|
||||||
&& rm -rf /var/cache/apk/* \
|
&& rm -rf /var/cache/apk/* \
|
||||||
&& mkdir -p /var/lib/meshtasticd \
|
&& mkdir -p /var/lib/meshtasticd \
|
||||||
&& mkdir -p /etc/meshtasticd/config.d \
|
&& mkdir -p /etc/meshtasticd/config.d \
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ build_flags =
|
|||||||
-DLIBPAX_ARDUINO
|
-DLIBPAX_ARDUINO
|
||||||
-DLIBPAX_WIFI
|
-DLIBPAX_WIFI
|
||||||
-DLIBPAX_BLE
|
-DLIBPAX_BLE
|
||||||
|
-DHAS_UDP_MULTICAST=1
|
||||||
;-DDEBUG_HEAP
|
;-DDEBUG_HEAP
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@@ -44,11 +45,11 @@ lib_deps =
|
|||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
https://github.com/meshtastic/esp32_https_server/archive/23665b3adc080a311dcbb586ed5941b5f94d6ea2.zip
|
||||||
h2zero/NimBLE-Arduino@^1.4.3
|
h2zero/NimBLE-Arduino@^1.4.3
|
||||||
https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
|
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||||
lewisxhe/XPowersLib@^0.2.7
|
lewisxhe/XPowersLib@^0.2.7
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[esp32c6_base]
|
[esp32c6_base]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
platform = https://github.com/Jason2866/platform-espressif32.git#22faa566df8c789000f8136cd8d0aca49617af55
|
platform = https://github.com/Jason2866/platform-espressif32/archive/22faa566df8c789000f8136cd8d0aca49617af55.zip
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-Wall
|
-Wall
|
||||||
@@ -25,7 +25,7 @@ lib_deps =
|
|||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
lewisxhe/XPowersLib@^0.2.7
|
lewisxhe/XPowersLib@^0.2.7
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
[nrf52_base]
|
[nrf52_base]
|
||||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||||
platform = platformio/nordicnrf52@^10.7.0
|
platform = platformio/nordicnrf52@^10.8.0
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages =
|
platform_packages =
|
||||||
; our custom Git version until they merge our PR
|
; our custom Git version until they merge our PR
|
||||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||||
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
||||||
|
|
||||||
build_type = debug
|
build_type = debug
|
||||||
@@ -17,7 +17,6 @@ build_flags =
|
|||||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||||
-DMESHTASTIC_EXCLUDE_AUDIO=1
|
-DMESHTASTIC_EXCLUDE_AUDIO=1
|
||||||
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
|
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
|
||||||
-DMAX_NUM_NODES=80
|
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ build_flags = ${nrf52_base.build_flags}
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52_base.lib_deps}
|
${nrf52_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
|
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/e31a8825ea3300b163a0a3c1ddd5de34e10e1371.zip
|
||||||
|
|
||||||
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
|
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
|
||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform = https://github.com/meshtastic/platform-native.git#562d189828f09fbf4c4093b3c0104bae9d8e9ff9
|
platform = https://github.com/meshtastic/platform-native/archive/c5bd469ab9b5a6966321e09557b27d906961da63.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -26,7 +26,7 @@ lib_deps =
|
|||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@^1.2.0
|
||||||
https://github.com/pine64/libch341-spi-userspace#a9b17e3452f7fb747000d9b4ad4409155b39f6ef
|
https://github.com/pine64/libch341-spi-userspace/archive/a9b17e3452f7fb747000d9b4ad4409155b39f6ef.zip
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
@@ -34,10 +34,12 @@ build_flags =
|
|||||||
-Isrc/platform/portduino
|
-Isrc/platform/portduino
|
||||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
|
-DHAS_UDP_MULTICAST
|
||||||
-lpthread
|
-lpthread
|
||||||
-lstdc++fs
|
-lstdc++fs
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
-lgpiod
|
-lgpiod
|
||||||
-lyaml-cpp
|
-lyaml-cpp
|
||||||
-li2c
|
-li2c
|
||||||
|
-luv
|
||||||
-std=c++17
|
-std=c++17
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2040_base]
|
[rp2040_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
|
platform = https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
@@ -18,6 +18,7 @@ build_src_filter =
|
|||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
lvgl
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2350_base]
|
[rp2350_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
|
platform = https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.4.3
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
[stm32_base]
|
[stm32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/ststm32
|
platform = ststm32
|
||||||
platform_packages = platformio/framework-arduinoststm32@^4.20900.0
|
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip
|
||||||
|
extra_scripts =
|
||||||
|
${env.extra_scripts}
|
||||||
|
post:extra_scripts/extra_stm32.py
|
||||||
|
|
||||||
build_type = release
|
build_type = release
|
||||||
|
|
||||||
;board_build.flash_offset = 0x08000000
|
build_flags =
|
||||||
|
|
||||||
build_flags =
|
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-flto
|
-flto
|
||||||
-Isrc/platform/stm32wl -g
|
-Isrc/platform/stm32wl -g
|
||||||
@@ -18,27 +19,24 @@ build_flags =
|
|||||||
-DMESHTASTIC_EXCLUDE_SCREEN
|
-DMESHTASTIC_EXCLUDE_SCREEN
|
||||||
-DMESHTASTIC_EXCLUDE_MQTT
|
-DMESHTASTIC_EXCLUDE_MQTT
|
||||||
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
||||||
-DMESHTASTIC_EXCLUDE_PKI
|
|
||||||
-DMESHTASTIC_EXCLUDE_GPS
|
-DMESHTASTIC_EXCLUDE_GPS
|
||||||
; -DVECT_TAB_OFFSET=0x08000000
|
;-DDEBUG_MUTE
|
||||||
-DconfigUSE_CMSIS_RTOS_V2=1
|
|
||||||
; -DSPI_MODE_0=SPI_MODE0
|
|
||||||
-fmerge-all-constants
|
-fmerge-all-constants
|
||||||
-ffunction-sections
|
-ffunction-sections
|
||||||
-fdata-sections
|
-fdata-sections
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
||||||
|
|
||||||
board_upload.offset_address = 0x08000000
|
board_upload.offset_address = 0x08000000
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
|
debug_tool = stlink
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
charlesbaynham/OSFS@^1.2.3
|
${radiolib_base.lib_deps}
|
||||||
jgromes/RadioLib@7.0.2
|
https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip
|
||||||
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
|
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
mathertel/OneButton@2.6.1
|
mathertel/OneButton@2.6.1
|
||||||
Wire
|
Wire
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ cp $SRCBIN $OUTDIR/$basename-update.bin
|
|||||||
|
|
||||||
echo "Building Filesystem for ESP32 targets"
|
echo "Building Filesystem for ESP32 targets"
|
||||||
pio run --environment $1 -t buildfs
|
pio run --environment $1 -t buildfs
|
||||||
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$VERSION.bin
|
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$1-$VERSION.bin
|
||||||
# Remove webserver files from the filesystem and rebuild
|
# Remove webserver files from the filesystem and rebuild
|
||||||
ls -l data/static # Diagnostic list of files
|
ls -l data/static # Diagnostic list of files
|
||||||
rm -rf data/static
|
rm -rf data/static
|
||||||
pio run --environment $1 -t buildfs
|
pio run --environment $1 -t buildfs
|
||||||
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
|
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$1-$VERSION.bin
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/device-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
@@ -24,7 +24,7 @@ mkdir -p $OUTDIR/
|
|||||||
rm -r $OUTDIR/* || true
|
rm -r $OUTDIR/* || true
|
||||||
|
|
||||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||||
platformio pkg update --environment native || platformioFailed
|
pio pkg update --environment native || platformioFailed
|
||||||
pio run --environment native || platformioFailed
|
pio run --environment native || platformioFailed
|
||||||
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||||
cp bin/native-install.* $OUTDIR
|
cp bin/native-install.* $OUTDIR
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
### Including the "Module:" line!
|
### Including the "Module:" line!
|
||||||
---
|
---
|
||||||
Lora:
|
Lora:
|
||||||
|
# Default to auto-detecting the module type
|
||||||
|
# This will be overridden by configs from config.d
|
||||||
|
Module: auto
|
||||||
|
|
||||||
|
# # Uncomment to enable Simulation mode, or use --sim
|
||||||
|
# Module: sim
|
||||||
|
|
||||||
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
||||||
# CS: 7
|
# CS: 7
|
||||||
@@ -191,5 +197,6 @@ General:
|
|||||||
MaxNodes: 200
|
MaxNodes: 200
|
||||||
MaxMessageQueue: 100
|
MaxMessageQueue: 100
|
||||||
ConfigDirectory: /etc/meshtasticd/config.d/
|
ConfigDirectory: /etc/meshtasticd/config.d/
|
||||||
|
AvailableDirectory: /etc/meshtasticd/available.d/
|
||||||
# MACAddress: AA:BB:CC:DD:EE:FF
|
# MACAddress: AA:BB:CC:DD:EE:FF
|
||||||
# MACAddressSource: eth0
|
# MACAddressSource: eth0
|
||||||
|
|||||||
4
bin/config.d/MUI/X11_480x480.yaml
Normal file
4
bin/config.d/MUI/X11_480x480.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Display:
|
||||||
|
Panel: X11
|
||||||
|
Width: 480
|
||||||
|
Height: 480
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Module: RF95 # Adafruit RFM9x
|
|
||||||
# Reset: 25
|
|
||||||
# CS: 7
|
|
||||||
# IRQ: 22
|
|
||||||
# Busy: 23
|
|
||||||
6
bin/config.d/lora-Adafruit-RFM9x.yaml
Normal file
6
bin/config.d/lora-Adafruit-RFM9x.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Lora:
|
||||||
|
Module: RF95 # Adafruit RFM9x
|
||||||
|
Reset: 25
|
||||||
|
CS: 7
|
||||||
|
IRQ: 22
|
||||||
|
# Busy: 23
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# MeshAdv-Pi E22-900M30S
|
||||||
|
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
|
||||||
Lora:
|
Lora:
|
||||||
Module: sx1262
|
Module: sx1262
|
||||||
CS: 21
|
CS: 21
|
||||||
@@ -9,4 +11,4 @@ Lora:
|
|||||||
DIO3_TCXO_VOLTAGE: true
|
DIO3_TCXO_VOLTAGE: true
|
||||||
# Only for E22-900M33S:
|
# Only for E22-900M33S:
|
||||||
# Limit the output power to 8 dBm
|
# Limit the output power to 8 dBm
|
||||||
# SX126X_MAX_POWER: 8
|
# SX126X_MAX_POWER: 8
|
||||||
|
|||||||
11
bin/config.d/lora-MeshAdv-Mini-900M22S.yaml
Normal file
11
bin/config.d/lora-MeshAdv-Mini-900M22S.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# MeshAdv Mini E22-900M22S
|
||||||
|
# https://github.com/chrismyers2000/MeshAdv-Mini
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Ebyte E22-900M22S
|
||||||
|
CS: 8
|
||||||
|
IRQ: 16
|
||||||
|
Busy: 20
|
||||||
|
Reset: 24
|
||||||
|
TXen: 13
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
49
bin/config.d/lora-raxda-rock2f-starter-edition-hat.yaml
Normal file
49
bin/config.d/lora-raxda-rock2f-starter-edition-hat.yaml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
Lora:
|
||||||
|
|
||||||
|
### Raxda Rock 2F running Armbian Linux 6.1.99-vendor-rk35xx
|
||||||
|
### https://github.com/markbirss/rock-2f
|
||||||
|
### https://github.com/markbirss/lora-starter-edition-sx1262-i2c
|
||||||
|
### https://github.com/radxa-pkg/radxa-overlays/blob/main/arch/arm64/boot/dts/rockchip/overlays/rk3528-spi0-cs1-spidev.dts
|
||||||
|
### Require install of https://github.com/radxa-pkg/radxa-overlays and rk3528-spi0-cs1-spidev.dtbo copied to /boot/dtb/rockchip/overlay and enabled
|
||||||
|
### in /boot/armbianEnv.txt - overlays=rk3528-spi0-cs1-spidev
|
||||||
|
### The Radxa Rock 2F employs multiple gpio chips.
|
||||||
|
### Each gpio pin must be unique, but can be assigned to a specific gpio chip and line.
|
||||||
|
### In case solely a no. is given, the default gpio chip and pin == line will be employed.
|
||||||
|
###
|
||||||
|
Module: sx1262 # Radxa Rock 2F + Starter Edition SX1262 HAT by Mark Birss
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: 1.8
|
||||||
|
spidev: spidev0.1
|
||||||
|
CS: # NSS PIN_24 -> chip 4, line 14
|
||||||
|
pin: 24
|
||||||
|
gpiochip: 4
|
||||||
|
line: 14
|
||||||
|
SCK: # SCK PIN_23 -> chip 4, line 12
|
||||||
|
pin: 23
|
||||||
|
gpiochip: 4
|
||||||
|
line: 12
|
||||||
|
Busy: # BUSY PIN_7 -> chip 4, line 6
|
||||||
|
pin: 7
|
||||||
|
gpiochip: 4
|
||||||
|
line: 6
|
||||||
|
MOSI: # MOSI PIN_19 -> chip 4, line 10
|
||||||
|
pin: 19
|
||||||
|
gpiochip: 4
|
||||||
|
line: 10
|
||||||
|
MISO: # MISO PIN_21 -> chip 4, line 11
|
||||||
|
pin: 21
|
||||||
|
gpiochip: 4
|
||||||
|
line: 11
|
||||||
|
Reset: # NRST PIN_12 -> chip 1, line 13
|
||||||
|
pin: 12
|
||||||
|
gpiochip: 1
|
||||||
|
line: 13
|
||||||
|
IRQ: # DIO1 PIN_15 -> chip 4, line 22
|
||||||
|
pin: 15
|
||||||
|
gpiochip: 4
|
||||||
|
line: 22
|
||||||
|
# RXen: # RXEN PIN_22 -> chip 3!, line 17
|
||||||
|
# pin: 22
|
||||||
|
# gpiochip: 3
|
||||||
|
# line: 17
|
||||||
|
# TXen: RADIOLIB_NC # TXEN no PIN, no line, fallback to default gpio chip
|
||||||
10
bin/config.d/lora-starter-edition-sx1262-i2c.yaml
Normal file
10
bin/config.d/lora-starter-edition-sx1262-i2c.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# https://www.waveshare.com/core1262-868m.htm
|
||||||
|
# https://github.com/markbirss/lora-starter-edition-sx1262-i2c
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
CS: 8
|
||||||
|
IRQ: 22
|
||||||
|
Busy: 4
|
||||||
|
Reset: 18
|
||||||
17
bin/config.d/lora-usb-meshtoad-e22.yaml
Normal file
17
bin/config.d/lora-usb-meshtoad-e22.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Lora:
|
||||||
|
Module: sx1262
|
||||||
|
CS: 0
|
||||||
|
IRQ: 6
|
||||||
|
Reset: 2
|
||||||
|
Busy: 4
|
||||||
|
RXen: 1
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
spidev: ch341
|
||||||
|
USB_PID: 0x5512
|
||||||
|
USB_VID: 0x1A86
|
||||||
|
# Optional: Reduce power to 10 dBm to
|
||||||
|
# avoid over-drawing the USB port
|
||||||
|
# SX126X_MAX_POWER: 10
|
||||||
|
# Optional: Set the serial number for multi-radio support
|
||||||
|
# USB_Serialnum: 13374201
|
||||||
10
bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
Normal file
10
bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# https://www.waveshare.com/pico-lora-sx1262-868m.htm
|
||||||
|
# https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter
|
||||||
|
Lora:
|
||||||
|
Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter
|
||||||
|
DIO2_AS_RF_SWITCH: true
|
||||||
|
DIO3_TCXO_VOLTAGE: true
|
||||||
|
CS: 21
|
||||||
|
IRQ: 16
|
||||||
|
Busy: 20
|
||||||
|
Reset: 18
|
||||||
@@ -1,72 +1,295 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
SETLOCAL EnableDelayedExpansion
|
||||||
|
TITLE Meshtastic device-install
|
||||||
|
|
||||||
set PYTHON=python
|
SET "SCRIPT_NAME=%~nx0"
|
||||||
set WEB_APP=0
|
SET "DEBUG=0"
|
||||||
|
SET "PYTHON="
|
||||||
|
SET "WEB_APP=0"
|
||||||
|
SET "TFT_BUILD=0"
|
||||||
|
SET "BIGDB8=0"
|
||||||
|
SET "BIGDB16=0"
|
||||||
|
SET "ESPTOOL_BAUD=115200"
|
||||||
|
SET "ESPTOOL_CMD="
|
||||||
|
SET "LOGCOUNTER=0"
|
||||||
|
|
||||||
:: Determine the correct esptool command to use
|
@REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
|
||||||
where esptool >nul 2>&1
|
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
|
||||||
if %ERRORLEVEL% EQU 0 (
|
SET "C3=esp32c3"
|
||||||
set "ESPTOOL_CMD=esptool"
|
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
|
||||||
) else (
|
SET "BIGDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core t-watch-s3 tracksenger"
|
||||||
set "ESPTOOL_CMD=%PYTHON% -m esptool"
|
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite"
|
||||||
)
|
|
||||||
|
|
||||||
goto GETOPTS
|
GOTO getopts
|
||||||
:HELP
|
:help
|
||||||
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] [--web]
|
ECHO Flash image file to device, but first erasing and writing system information.
|
||||||
echo Flash image file to device, but first erasing and writing system information
|
ECHO.
|
||||||
echo.
|
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] (--web)
|
||||||
echo -h Display this help and exit
|
ECHO.
|
||||||
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
|
ECHO Options:
|
||||||
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
|
ECHO -f filename The firmware .bin file to flash. Custom to your device type and region. (required)
|
||||||
echo -f FILENAME The .bin file to flash. Custom to your device type and region.
|
ECHO The file must be located in this current directory.
|
||||||
echo --web Flash WEB APP.
|
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
|
||||||
goto EOF
|
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
|
ECHO -P python Specify alternate python interpreter to use to invoke esptool. (default: python)
|
||||||
|
ECHO If supplied the script will use python.
|
||||||
|
ECHO If not supplied the script will try to find esptool in Path.
|
||||||
|
ECHO --web Enable WebUI. (default: false)
|
||||||
|
ECHO.
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.bin -p COM11
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.bin -p COM11 --web
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
:GETOPTS
|
:version
|
||||||
if /I "%1"=="-h" goto HELP
|
ECHO %SCRIPT_NAME% [Version 2.6.1]
|
||||||
if /I "%1"=="--help" goto HELP
|
ECHO Meshtastic
|
||||||
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
GOTO eof
|
||||||
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
|
||||||
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
:getopts
|
||||||
if /I "%1"=="--web" set WEB_APP=1 & SHIFT
|
IF "%~1"=="" GOTO endopts
|
||||||
|
IF /I "%~1"=="-?" GOTO help
|
||||||
|
IF /I "%~1"=="-h" GOTO help
|
||||||
|
IF /I "%~1"=="--help" GOTO help
|
||||||
|
IF /I "%~1"=="-v" GOTO version
|
||||||
|
IF /I "%~1"=="--version" GOTO version
|
||||||
|
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
|
||||||
|
IF /I "%~1"=="-f" SET "FILENAME=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-p" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--port" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-P" SET "PYTHON=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--web" SET "WEB_APP=1"
|
||||||
SHIFT
|
SHIFT
|
||||||
IF NOT "__%1__"=="____" goto GETOPTS
|
GOTO getopts
|
||||||
|
:endopts
|
||||||
|
|
||||||
IF "__%FILENAME%__" == "____" (
|
CALL :LOG_MESSAGE DEBUG "Checking FILENAME parameter..."
|
||||||
echo "Missing FILENAME"
|
IF "__!FILENAME!__"=="____" (
|
||||||
goto HELP
|
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
|
||||||
)
|
GOTO help
|
||||||
IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
) ELSE (
|
||||||
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
|
||||||
%ESPTOOL_CMD% --baud 115200 erase_flash
|
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x00 %FILENAME%
|
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
|
||||||
|
GOTO help
|
||||||
@REM Account for S3 and C3 board's different OTA partition
|
|
||||||
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% IF x%FILENAME:station-g2=%==x%FILENAME% IF x%FILENAME:unphone=%==x%FILENAME% (
|
|
||||||
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota.bin
|
|
||||||
) else (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-c3.bin
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
|
|
||||||
)
|
)
|
||||||
IF %WEB_APP%==1 (
|
IF "__!FILENAME:firmware-=!__"=="__!FILENAME!__" (
|
||||||
for %%f in (littlefswebui-*.bin) do (
|
CALL :LOG_MESSAGE ERROR "Filename must be a firmware-* file."
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
|
GOTO help
|
||||||
)
|
|
||||||
) else (
|
|
||||||
for %%f in (littlefs-*.bin) do (
|
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
) else (
|
@REM Remove ".\" or "./" file prefix if present.
|
||||||
echo "Invalid file: %FILENAME%"
|
SET "FILENAME=!FILENAME:.\=!"
|
||||||
goto HELP
|
SET "FILENAME=!FILENAME:./=!"
|
||||||
) else (
|
|
||||||
echo "Invalid file: %FILENAME%"
|
|
||||||
goto HELP
|
|
||||||
)
|
)
|
||||||
|
|
||||||
:EOF
|
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
|
||||||
|
IF NOT EXIST !FILENAME! (
|
||||||
|
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
|
||||||
|
IF NOT "!FILENAME:update=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Use script device-update.bat to flash update !FILENAME!."
|
||||||
|
GOTO eof
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
||||||
|
IF NOT "__%PYTHON%__"=="____" (
|
||||||
|
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
|
||||||
|
WHERE esptool >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% EQU 0 (
|
||||||
|
@REM WHERE exits with code 0 if esptool is found.
|
||||||
|
SET "ESPTOOL_CMD=esptool"
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=python -m esptool"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% GEQ 2 (
|
||||||
|
@REM esptool exits with code 1 if help is displayed.
|
||||||
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
|
EXIT /B 1
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
IF %DEBUG% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
|
SET "ESPTOOL_CMD=REM !ESPTOOL_CMD!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
|
||||||
|
IF "__!ESPTOOL_PORT!__" == "____" (
|
||||||
|
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
|
||||||
|
|
||||||
|
@REM Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
|
||||||
|
@REM https://github.com/meshtastic/web-flasher/blob/main/types/resources.ts#L3
|
||||||
|
IF NOT "!FILENAME:-tft-=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *-tft-* file. !FILENAME!"
|
||||||
|
IF %WEB_APP% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Cannot enable WebUI (--web) and MUI." & GOTO eof
|
||||||
|
)
|
||||||
|
SET "TFT_BUILD=1"
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
FOR %%a IN (%BIGDB_8MB%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %BIGDB_8MB%.
|
||||||
|
SET "BIGDB8=1"
|
||||||
|
GOTO end_loop_bigdb_8mb
|
||||||
|
)
|
||||||
|
)
|
||||||
|
:end_loop_bigdb_8mb
|
||||||
|
|
||||||
|
FOR %%a IN (%BIGDB_16MB%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %BIGDB_16MB%.
|
||||||
|
SET "BIGDB16=1"
|
||||||
|
GOTO end_loop_bigdb_16mb
|
||||||
|
)
|
||||||
|
)
|
||||||
|
:end_loop_bigdb_16mb
|
||||||
|
|
||||||
|
IF %BIGDB8% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 8mb partition selected."
|
||||||
|
IF %BIGDB16% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 16mb partition selected."
|
||||||
|
|
||||||
|
@REM Extract BASENAME from %FILENAME% for later use.
|
||||||
|
SET "BASENAME=!FILENAME:firmware-=!"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!"
|
||||||
|
|
||||||
|
@REM Account for S3 and C3 board's different OTA partition.
|
||||||
|
FOR %%a IN (%S3%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %S3%.
|
||||||
|
SET "OTA_FILENAME=bleota-s3.bin"
|
||||||
|
GOTO :end_loop_s3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
FOR %%a IN (%C3%) DO (
|
||||||
|
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
|
||||||
|
@REM We are working with any of %C3%.
|
||||||
|
SET "OTA_FILENAME=bleota-c3.bin"
|
||||||
|
GOTO :end_loop_c3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Everything else
|
||||||
|
SET "OTA_FILENAME=bleota.bin"
|
||||||
|
:end_loop_s3
|
||||||
|
:end_loop_c3
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!"
|
||||||
|
|
||||||
|
@REM Check if (--web) is enabled and prefix BASENAME with "littlefswebui-" else "littlefs-".
|
||||||
|
IF %WEB_APP% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE INFO "WebUI selected."
|
||||||
|
SET "SPIFFS_FILENAME=littlefswebui-%BASENAME%"
|
||||||
|
) ELSE (
|
||||||
|
SET "SPIFFS_FILENAME=littlefs-%BASENAME%"
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
|
||||||
|
|
||||||
|
@REM Default offsets.
|
||||||
|
@REM https://github.com/meshtastic/web-flasher/blob/main/stores/firmwareStore.ts#L202
|
||||||
|
SET "OTA_OFFSET=0x260000"
|
||||||
|
SET "SPIFFS_OFFSET=0x300000"
|
||||||
|
|
||||||
|
@REM Offsets for BigDB 8mb.
|
||||||
|
IF %BIGDB8% EQU 1 (
|
||||||
|
SET "OTA_OFFSET=0x340000"
|
||||||
|
SET "SPIFFS_OFFSET=0x670000"
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Offsets for BigDB 16mb.
|
||||||
|
IF %BIGDB16% EQU 1 (
|
||||||
|
SET "OTA_OFFSET=0x650000"
|
||||||
|
SET "SPIFFS_OFFSET=0xc90000"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!"
|
||||||
|
|
||||||
|
@REM Ensure target files exist before flashing operations.
|
||||||
|
IF NOT EXIST !FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
IF NOT EXIST !OTA_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!OTA_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
IF NOT EXIST !SPIFFS_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!SPIFFS_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
|
||||||
|
|
||||||
|
@REM Flashing operations.
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash "!FILENAME!", but first erasing and writing system information..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! erase_flash || GOTO eof
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x00 "!FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash BLEOTA "!OTA_FILENAME!" at OTA_OFFSET !OTA_OFFSET!..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !OTA_OFFSET! "!OTA_FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash SPIFFS "!SPIFFS_FILENAME!" at SPIFFS_OFFSET !SPIFFS_OFFSET!..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !SPIFFS_OFFSET! "!SPIFFS_FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|
||||||
|
:RUN_ESPTOOL
|
||||||
|
@REM Subroutine used to run ESPTOOL_CMD with arguments.
|
||||||
|
@REM Also handles %ERRORLEVEL%.
|
||||||
|
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
|
||||||
|
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:LOG_MESSAGE
|
||||||
|
@REM Subroutine used to print log messages in four different levels.
|
||||||
|
@REM DEBUG messages only get printed if [-d] flag is passed to script.
|
||||||
|
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
|
||||||
|
SET /A LOGCOUNTER=LOGCOUNTER+1
|
||||||
|
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO [91m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[91m%~2[0m
|
||||||
|
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO [32m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[32m%~2[0m
|
||||||
|
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO [33m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[33m%~2[0m
|
||||||
|
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO [34m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[34m%~2[0m
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:GET_TIMESTAMP
|
||||||
|
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
|
||||||
|
@REM CALL :GET_TIMESTAMP
|
||||||
|
@REM.
|
||||||
|
@REM Updates: !TIMESTAMP!
|
||||||
|
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
|
||||||
|
SET "HH=%%a"
|
||||||
|
SET "MM=%%b"
|
||||||
|
SET "ss=%%c"
|
||||||
|
)
|
||||||
|
SET "TIMESTAMP=!HH!:!MM!:!ss!"
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:RESET_ERROR
|
||||||
|
@REM Subroutine to reset %ERRORLEVEL% to 0.
|
||||||
|
@REM CALL :RESET_ERROR
|
||||||
|
@REM.
|
||||||
|
@REM Updates: %ERRORLEVEL%
|
||||||
|
EXIT /B 0
|
||||||
|
GOTO :eof
|
||||||
|
|||||||
@@ -1,18 +1,60 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
||||||
WEB_APP=false
|
WEB_APP=false
|
||||||
|
TFT_BUILD=false
|
||||||
|
MCU=""
|
||||||
|
|
||||||
|
# Variant groups
|
||||||
|
BIGDB_8MB=(
|
||||||
|
"picomputer-s3"
|
||||||
|
"unphone"
|
||||||
|
"seeed-sensecap-indicator"
|
||||||
|
"crowpanel-esp32s3"
|
||||||
|
"heltec_capsule_sensor_v3"
|
||||||
|
"heltec-v3"
|
||||||
|
"heltec-vision-master-e213"
|
||||||
|
"heltec-vision-master-e290"
|
||||||
|
"heltec-vision-master-t190"
|
||||||
|
"heltec-wireless-paper"
|
||||||
|
"heltec-wireless-tracker"
|
||||||
|
"heltec-wsl-v3"
|
||||||
|
"icarus"
|
||||||
|
"seeed-xiao-s3"
|
||||||
|
"tbeam-s3-core"
|
||||||
|
"t-watch-s3"
|
||||||
|
"tracksenger"
|
||||||
|
)
|
||||||
|
BIGDB_16MB=(
|
||||||
|
"t-deck"
|
||||||
|
"mesh-tab"
|
||||||
|
"t-energy-s3"
|
||||||
|
"dreamcatcher"
|
||||||
|
"ESP32-S3-Pico"
|
||||||
|
"m5stack-cores3"
|
||||||
|
"station-g2"
|
||||||
|
"t-eth-elite"
|
||||||
|
)
|
||||||
|
S3_VARIANTS=(
|
||||||
|
"s3"
|
||||||
|
"-v3"
|
||||||
|
"t-deck"
|
||||||
|
"wireless-paper"
|
||||||
|
"wireless-tracker"
|
||||||
|
"station-g2"
|
||||||
|
"unphone"
|
||||||
|
)
|
||||||
|
|
||||||
# Determine the correct esptool command to use
|
# Determine the correct esptool command to use
|
||||||
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="$PYTHON -m esptool"
|
ESPTOOL_CMD="$PYTHON -m esptool"
|
||||||
elif command -v esptool >/dev/null 2>&1; then
|
elif command -v esptool >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="esptool"
|
ESPTOOL_CMD="esptool"
|
||||||
elif command -v esptool.py >/dev/null 2>&1; then
|
elif command -v esptool.py >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="esptool.py"
|
ESPTOOL_CMD="esptool.py"
|
||||||
else
|
else
|
||||||
echo "Error: esptool not found"
|
echo "Error: esptool not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
@@ -20,75 +62,141 @@ set -e
|
|||||||
# Usage info
|
# Usage info
|
||||||
show_help() {
|
show_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--web]
|
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME] [--web]
|
||||||
Flash image file to device, but first erasing and writing system information"
|
Flash image file to device, but first erasing and writing system information.
|
||||||
|
|
||||||
-h Display this help and exit
|
-h Display this help and exit.
|
||||||
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
||||||
-f FILENAME The .bin file to flash. Custom to your device type and region.
|
-f FILENAME The firmware .bin file to flash. Custom to your device type and region.
|
||||||
--web Flash WEB APP.
|
--web Enable WebUI. (Default: false)
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
# Preprocess long options like --web
|
# Parse arguments using a single while loop
|
||||||
for arg in "$@"; do
|
while [ $# -gt 0 ]; do
|
||||||
case "$arg" in
|
case "$1" in
|
||||||
--web)
|
-h | --help)
|
||||||
WEB_APP=true
|
|
||||||
shift # Remove this argument from the list
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
while getopts ":hp:P:f:" opt; do
|
|
||||||
case "${opt}" in
|
|
||||||
h)
|
|
||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
p)
|
-p)
|
||||||
export ESPTOOL_PORT=${OPTARG}
|
ESPTOOL_CMD="$ESPTOOL_CMD --port $2"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
P)
|
-P)
|
||||||
PYTHON=${OPTARG}
|
PYTHON="$2"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
f)
|
-f)
|
||||||
FILENAME=${OPTARG}
|
FILENAME="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--web)
|
||||||
|
WEB_APP=true
|
||||||
|
;;
|
||||||
|
--) # Stop parsing options
|
||||||
|
shift
|
||||||
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid flag."
|
echo "Unknown argument: $1" >&2
|
||||||
show_help >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
shift # Move to the next argument
|
||||||
done
|
done
|
||||||
shift "$((OPTIND - 1))"
|
|
||||||
|
|
||||||
[ -z "$FILENAME" -a -n "$1" ] && {
|
[ -z "$FILENAME" -a -n "$1" ] && {
|
||||||
FILENAME=$1
|
FILENAME=$1
|
||||||
shift
|
shift
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [[ $FILENAME != firmware-* ]]; then
|
||||||
|
echo "Filename must be a firmware-* file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if FILENAME contains "-tft-" and prevent web/mui comingling.
|
||||||
|
if [[ ${FILENAME//-tft-/} != "$FILENAME" ]]; then
|
||||||
|
TFT_BUILD=true
|
||||||
|
if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then
|
||||||
|
echo "Cannot enable WebUI (--web) and MUI."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract BASENAME from %FILENAME% for later use.
|
||||||
|
BASENAME="${FILENAME/firmware-/}"
|
||||||
|
|
||||||
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
||||||
|
# Default littlefs* offset (--web).
|
||||||
|
OFFSET=0x300000
|
||||||
|
|
||||||
|
# Default OTA Offset
|
||||||
|
OTA_OFFSET=0x260000
|
||||||
|
|
||||||
|
# littlefs* offset for BigDB 8mb and OTA OFFSET.
|
||||||
|
for variant in "${BIGDB_8MB[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
OFFSET=0x670000
|
||||||
|
OTA_OFFSET=0x340000
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# littlefs* offset for BigDB 16mb and OTA OFFSET.
|
||||||
|
for variant in "${BIGDB_16MB[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
OFFSET=0xc90000
|
||||||
|
OTA_OFFSET=0x650000
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Account for S3 board's different OTA partition
|
||||||
|
# FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
|
||||||
|
for variant in "${S3_VARIANTS[@]}"; do
|
||||||
|
if [ -z "${FILENAME##*"$variant"*}" ]; then
|
||||||
|
MCU="esp32s3"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$MCU" != "esp32s3" ]; then
|
||||||
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
|
OTAFILE=bleota.bin
|
||||||
|
else
|
||||||
|
OTAFILE=bleota-c3.bin
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
OTAFILE=bleota-s3.bin
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if WEB_APP (--web) is enabled and add "littlefswebui-" to BASENAME else "littlefs-".
|
||||||
|
if [ "$WEB_APP" = true ]; then
|
||||||
|
SPIFFSFILE=littlefswebui-${BASENAME}
|
||||||
|
else
|
||||||
|
SPIFFSFILE=littlefs-${BASENAME}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f $FILENAME ]]; then
|
||||||
|
echo "Error: file ${FILENAME} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f $OTAFILE ]]; then
|
||||||
|
echo "Error: file ${OTAFILE} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f $SPIFFSFILE ]]; then
|
||||||
|
echo "Error: file ${SPIFFSFILE} wasn't found. Terminating."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
$ESPTOOL_CMD erase_flash
|
$ESPTOOL_CMD erase_flash
|
||||||
$ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
|
$ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
|
||||||
# Account for S3 board's different OTA partition
|
echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
|
||||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
$ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}"
|
||||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota.bin
|
$ESPTOOL_CMD write_flash $OFFSET "${SPIFFSFILE}"
|
||||||
else
|
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota-c3.bin
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
|
|
||||||
fi
|
|
||||||
if [ "$WEB_APP" = true ]; then
|
|
||||||
$ESPTOOL_CMD write_flash 0x300000 littlefswebui-*.bin
|
|
||||||
else
|
|
||||||
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
else
|
||||||
show_help
|
show_help
|
||||||
|
|||||||
112
bin/device-install_test.ps1
Normal file
112
bin/device-install_test.ps1
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Unit-test for .\device-install.bat.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This script performs a positive unit-test on .\device-install.bat by creating the expected .bin
|
||||||
|
files for a device followed by running the .bat script without flashing the firmware (--debug).
|
||||||
|
If any errors are hit they are presented in the standard output. Investigate accordingly.
|
||||||
|
|
||||||
|
This script needs to be placed in the same directory as .\device-install.bat.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\device-install_test.ps1
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\device-install_test.ps1 -Verbose
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
.\device-install.bat --help
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
function New-EmptyFile() {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $true)]
|
||||||
|
# Specifies the file name.
|
||||||
|
[string]$FileName,
|
||||||
|
[Parameter(Position = 1)]
|
||||||
|
# Specifies the target path. (Get-Location).Path is the default.
|
||||||
|
[string]$Directory = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$filePath = Join-Path -Path $Directory -ChildPath $FileName
|
||||||
|
|
||||||
|
Write-Verbose -Message "Create empty test file if it doesn't exist: $($FileName)"
|
||||||
|
New-Item -Path "$filePath" -ItemType File -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Remove-EmptyFile() {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $true)]
|
||||||
|
# Specifies the file name.
|
||||||
|
[string]$FileName,
|
||||||
|
[Parameter(Position = 1)]
|
||||||
|
# Specifies the target path. (Get-Location).Path is the default.
|
||||||
|
[string]$Directory = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$filePath = Join-Path -Path $Directory -ChildPath $FileName
|
||||||
|
|
||||||
|
Write-Verbose -Message "Deleted empty test file: $($FileName)"
|
||||||
|
Remove-Item -Path "$filePath" | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$TestCases = New-Object -TypeName PSObject -Property @{
|
||||||
|
# Use this PSObject to define testcases according to this syntax:
|
||||||
|
# "testname" = @("firmware-testname","bleota","littlefs-testname","args")
|
||||||
|
"t-deck" = @("firmware-t-deck-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-t-deck-2.6.0.0b106d4.bin", "")
|
||||||
|
"t-deck_web" = @("firmware-t-deck-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefswebui-t-deck-2.6.0.0b106d4.bin", "--web")
|
||||||
|
"t-deck-tft" = @("firmware-t-deck-tft-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-t-deck-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
"heltec-ht62-esp32c3" = @("firmware-heltec-ht62-esp32c3-sx1262-2.6.0.0b106d4.bin", "bleota-c3.bin", "littlefs-heltec-ht62-esp32c3-sx1262-2.6.0.0b106d4.bin", "")
|
||||||
|
"tlora-c6" = @("firmware-tlora-c6-2.6.0.0b106d4.bin", "bleota.bin", "littlefs-tlora-c6-2.6.0.0b106d4.bin", "")
|
||||||
|
"heltec-v3_web" = @("firmware-heltec-v3-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefswebui-heltec-v3-2.6.0.0b106d4.bin", "--web")
|
||||||
|
"seeed-sensecap-indicator-tft" = @("firmware-seeed-sensecap-indicator-tft-2.6.0.0b106d4.bin", "bleota.bin", "littlefs-seeed-sensecap-indicator-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
"picomputer-s3-tft" = @("firmware-picomputer-s3-tft-2.6.0.0b106d4.bin", "bleota-s3.bin", "littlefs-picomputer-s3-tft-2.6.0.0b106d4.bin", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($TestCase in $TestCases.PSObject.Properties) {
|
||||||
|
$Name = $TestCase.Name
|
||||||
|
$Files = $TestCase.Value
|
||||||
|
$Errors = $null
|
||||||
|
$Counter = 0
|
||||||
|
|
||||||
|
Write-Host -Object "Testcase: $Name`:" -ForegroundColor Green
|
||||||
|
foreach ($File in $Files) {
|
||||||
|
if ($File.EndsWith(".bin")) {
|
||||||
|
New-EmptyFile -FileName $File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host -Object "Performing test on $Name..." -ForegroundColor Blue
|
||||||
|
$Test = Invoke-Expression -Command "cmd /c .\device-install.bat --debug -f $($TestCases."$Name"[0]) $($TestCases."$Name"[3])"
|
||||||
|
|
||||||
|
foreach ($Line in $Test) {
|
||||||
|
if ($Line -match "Set OTA_OFFSET to" -or `
|
||||||
|
$Line -match "Set SPIFFS_OFFSET to") {
|
||||||
|
Write-Host -Object "$($Line -replace "^.*?Set","Set")" -ForegroundColor Blue
|
||||||
|
}
|
||||||
|
elseif ($VerbosePreference -eq "Continue") {
|
||||||
|
Write-Host -Object $Line
|
||||||
|
}
|
||||||
|
if ($Line -match "ERROR") {
|
||||||
|
$Errors += $Line
|
||||||
|
$Counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($null -ne $Errors) {
|
||||||
|
Write-Host -Object "$Counter ERROR(s) detected!" -ForegroundColor Red
|
||||||
|
if (-not ($VerbosePreference -eq "Continue")) { Write-Host -Object $Errors }
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($File in $Files) {
|
||||||
|
if ($File.EndsWith(".bin")) {
|
||||||
|
Remove-EmptyFile -FileName $File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,48 +1,176 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
SETLOCAL EnableDelayedExpansion
|
||||||
|
TITLE Meshtastic device-update
|
||||||
|
|
||||||
set PYTHON=python
|
SET "SCRIPT_NAME=%~nx0"
|
||||||
|
SET "DEBUG=0"
|
||||||
|
SET "PYTHON="
|
||||||
|
SET "ESPTOOL_BAUD=115200"
|
||||||
|
SET "ESPTOOL_CMD="
|
||||||
|
SET "LOGCOUNTER=0"
|
||||||
|
|
||||||
:: Determine the correct esptool command to use
|
GOTO getopts
|
||||||
where esptool >nul 2>&1
|
:help
|
||||||
if %ERRORLEVEL% EQU 0 (
|
ECHO Flash image file to device, but leave existing system intact.
|
||||||
set "ESPTOOL_CMD=esptool"
|
ECHO.
|
||||||
) else (
|
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python]
|
||||||
set "ESPTOOL_CMD=%PYTHON% -m esptool"
|
ECHO.
|
||||||
)
|
ECHO Options:
|
||||||
|
ECHO -f filename The update .bin file to flash. Custom to your device type and region. (required)
|
||||||
|
ECHO The file must be located in this current directory.
|
||||||
|
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
|
||||||
|
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
|
ECHO -P python Specify alternate python interpreter to use to invoke esptool. (default: python)
|
||||||
|
ECHO If supplied the script will use python.
|
||||||
|
ECHO If not supplied the script will try to find esptool in Path.
|
||||||
|
ECHO.
|
||||||
|
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4-update.bin -p COM11
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
goto GETOPTS
|
:version
|
||||||
:HELP
|
ECHO %SCRIPT_NAME% [Version 2.6.1]
|
||||||
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME]
|
ECHO Meshtastic
|
||||||
echo Flash image file to device, leave existing system intact.
|
GOTO eof
|
||||||
echo.
|
|
||||||
echo -h Display this help and exit
|
|
||||||
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
|
|
||||||
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
|
|
||||||
echo -f FILENAME The *update.bin file to flash. Custom to your device type.
|
|
||||||
goto EOF
|
|
||||||
|
|
||||||
:GETOPTS
|
:getopts
|
||||||
if /I "%1"=="-h" goto HELP
|
IF "%~1"=="" GOTO endopts
|
||||||
if /I "%1"=="--help" goto HELP
|
IF /I "%~1"=="-?" GOTO help
|
||||||
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
IF /I "%~1"=="-h" GOTO help
|
||||||
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
IF /I "%~1"=="--help" GOTO help
|
||||||
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
IF /I "%~1"=="-v" GOTO version
|
||||||
|
IF /I "%~1"=="--version" GOTO version
|
||||||
|
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
|
||||||
|
IF /I "%~1"=="-f" SET "FILENAME=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-p" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--port" SET "ESPTOOL_PORT=%~2" & SHIFT
|
||||||
|
IF "%~1"=="-P" SET "PYTHON=%~2" & SHIFT
|
||||||
SHIFT
|
SHIFT
|
||||||
IF NOT "__%1__"=="____" goto GETOPTS
|
GOTO getopts
|
||||||
|
:endopts
|
||||||
|
|
||||||
IF "__%FILENAME%__" == "____" (
|
CALL :LOG_MESSAGE DEBUG "Checking FILENAME parameter..."
|
||||||
echo "Missing FILENAME"
|
IF "__!FILENAME!__"=="____" (
|
||||||
goto HELP
|
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
|
||||||
)
|
GOTO help
|
||||||
IF EXIST %FILENAME% IF NOT x%FILENAME:update=%==x%FILENAME% (
|
) ELSE (
|
||||||
echo Trying to flash update %FILENAME%
|
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x10000 %FILENAME%
|
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
|
||||||
) else (
|
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
|
||||||
echo "Invalid file: %FILENAME%"
|
GOTO help
|
||||||
goto HELP
|
)
|
||||||
) else (
|
@REM Remove ".\" or "./" file prefix if present.
|
||||||
echo "Invalid file: %FILENAME%"
|
SET "FILENAME=!FILENAME:.\=!"
|
||||||
goto HELP
|
SET "FILENAME=!FILENAME:./=!"
|
||||||
)
|
)
|
||||||
|
|
||||||
:EOF
|
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
|
||||||
|
IF NOT EXIST !FILENAME! (
|
||||||
|
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
|
||||||
|
IF "!FILENAME:update=!"=="!FILENAME!" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!."
|
||||||
|
GOTO eof
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
||||||
|
IF NOT "__%PYTHON%__"=="____" (
|
||||||
|
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
|
||||||
|
WHERE esptool >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% EQU 0 (
|
||||||
|
@REM WHERE exits with code 0 if esptool is found.
|
||||||
|
SET "ESPTOOL_CMD=esptool"
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=python -m esptool"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
|
IF %ERRORLEVEL% GEQ 2 (
|
||||||
|
@REM esptool exits with code 1 if help is displayed.
|
||||||
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
|
EXIT /B 1
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
IF %DEBUG% EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
|
SET "ESPTOOL_CMD=REM !ESPTOOL_CMD!"
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
|
||||||
|
IF "__!ESPTOOL_PORT!__" == "____" (
|
||||||
|
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
|
||||||
|
) ELSE (
|
||||||
|
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
|
||||||
|
)
|
||||||
|
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
|
||||||
|
|
||||||
|
@REM Flashing operations.
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET 0x10000..."
|
||||||
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x10000 "!FILENAME!" || GOTO eof
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|
||||||
|
:RUN_ESPTOOL
|
||||||
|
@REM Subroutine used to run ESPTOOL_CMD with arguments.
|
||||||
|
@REM Also handles %ERRORLEVEL%.
|
||||||
|
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
|
||||||
|
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:LOG_MESSAGE
|
||||||
|
@REM Subroutine used to print log messages in four different levels.
|
||||||
|
@REM DEBUG messages only get printed if [-d] flag is passed to script.
|
||||||
|
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
|
||||||
|
SET /A LOGCOUNTER=LOGCOUNTER+1
|
||||||
|
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO [91m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[91m%~2[0m
|
||||||
|
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO [32m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[32m%~2[0m
|
||||||
|
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO [33m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[33m%~2[0m
|
||||||
|
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO [34m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[34m%~2[0m
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:GET_TIMESTAMP
|
||||||
|
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
|
||||||
|
@REM CALL :GET_TIMESTAMP
|
||||||
|
@REM.
|
||||||
|
@REM Updates: !TIMESTAMP!
|
||||||
|
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
|
||||||
|
SET "HH=%%a"
|
||||||
|
SET "MM=%%b"
|
||||||
|
SET "ss=%%c"
|
||||||
|
)
|
||||||
|
SET "TIMESTAMP=!HH!:!MM!:!ss!"
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:RESET_ERROR
|
||||||
|
@REM Subroutine to reset %ERRORLEVEL% to 0.
|
||||||
|
@REM CALL :RESET_ERROR
|
||||||
|
@REM.
|
||||||
|
@REM Updates: %ERRORLEVEL%
|
||||||
|
EXIT /B 0
|
||||||
|
GOTO :eof
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ while getopts ":hp:P:f:" opt; do
|
|||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
p) export ESPTOOL_PORT=${OPTARG}
|
p) ESPTOOL_CMD="$ESPTOOL_CMD --port ${OPTARG}"
|
||||||
;;
|
;;
|
||||||
P) PYTHON=${OPTARG}
|
P) PYTHON=${OPTARG}
|
||||||
;;
|
;;
|
||||||
f) FILENAME=${OPTARG}
|
f) FILENAME=${OPTARG}
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ for subdir, dirs, files in os.walk(rootdir):
|
|||||||
outlist.append(section)
|
outlist.append(section)
|
||||||
else:
|
else:
|
||||||
outlist.append(section)
|
outlist.append(section)
|
||||||
|
# Add the TFT variants if the base variant is selected
|
||||||
|
elif section.replace("-tft", "") in outlist and config[config[c].name].get("board_level") != "extra":
|
||||||
|
outlist.append(section)
|
||||||
|
elif section.replace("-inkhud", "") in outlist and config[config[c].name].get("board_level") != "extra":
|
||||||
|
outlist.append(section)
|
||||||
if "board_check" in config[config[c].name]:
|
if "board_check" in config[config[c].name]:
|
||||||
if (config[config[c].name]["board_check"] == "true") & (
|
if (config[config[c].name]["board_check"] == "true") & (
|
||||||
"check" in options
|
"check" in options
|
||||||
@@ -43,4 +48,4 @@ for subdir, dirs, files in os.walk(rootdir):
|
|||||||
if ("quick" in options) & (len(outlist) > 3):
|
if ("quick" in options) & (len(outlist) > 3):
|
||||||
print(json.dumps(random.sample(outlist, 3)))
|
print(json.dumps(random.sample(outlist, 3)))
|
||||||
else:
|
else:
|
||||||
print(json.dumps(outlist))
|
print(json.dumps(outlist))
|
||||||
@@ -83,7 +83,7 @@ if platform.name == "espressif32":
|
|||||||
|
|
||||||
if platform.name == "nordicnrf52":
|
if platform.name == "nordicnrf52":
|
||||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
|
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
|
||||||
env.VerboseAction(f"{sys.executable} ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
|
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
|
||||||
"Generating UF2 file"))
|
"Generating UF2 file"))
|
||||||
|
|
||||||
Import("projenv")
|
Import("projenv")
|
||||||
@@ -125,4 +125,9 @@ for flag in flags:
|
|||||||
|
|
||||||
projenv.Append(
|
projenv.Append(
|
||||||
CCFLAGS=flags,
|
CCFLAGS=flags,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for lb in env.GetLibBuilders():
|
||||||
|
if lb.name == "meshtastic-device-ui":
|
||||||
|
lb.env.Append(CPPDEFINES=[("APP_VERSION", verObj["long"])])
|
||||||
|
break
|
||||||
|
|||||||
@@ -1 +1,10 @@
|
|||||||
cd protobufs && ..\nanopb-0.4.9\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto
|
@ECHO OFF
|
||||||
|
SETLOCAL
|
||||||
|
|
||||||
|
cd protobufs
|
||||||
|
..\nanopb-0.4.9\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ function meshtastic_version {
|
|||||||
meshtastic_version=$(python3 bin/buildinfo.py short)
|
meshtastic_version=$(python3 bin/buildinfo.py short)
|
||||||
echo -n "$meshtastic_version"
|
echo -n "$meshtastic_version"
|
||||||
}
|
}
|
||||||
|
function web_version {
|
||||||
|
web_version=$(cat bin/web.version)
|
||||||
|
echo -n "$web_version"
|
||||||
|
}
|
||||||
function git_commits_num {
|
function git_commits_num {
|
||||||
total_commits=$(git rev-list --all --count)
|
total_commits=$(git rev-list --all --count)
|
||||||
echo -n "$total_commits"
|
echo -n "$total_commits"
|
||||||
|
|||||||
@@ -1,2 +1,124 @@
|
|||||||
@echo off
|
@ECHO OFF
|
||||||
if [%1]==[] (echo "Please specify a platformio NRF target (i.e. rak4631) as the first argument.") else (python3 .\bin\uf2conv.py .\.pio\build\%1\firmware.hex -c -o .\.pio\build\%1\firmware.uf2 -f 0xADA52840)
|
SETLOCAL EnableDelayedExpansion
|
||||||
|
TITLE Meshtastic uf2-convert
|
||||||
|
|
||||||
|
SET "SCRIPT_NAME=%~nx0"
|
||||||
|
SET "DEBUG=0"
|
||||||
|
SET "NRF=0"
|
||||||
|
SET "UF2CONV_CMD=python3 .\bin\uf2conv.py"
|
||||||
|
|
||||||
|
GOTO getopts
|
||||||
|
:help
|
||||||
|
ECHO.
|
||||||
|
ECHO Usage: %SCRIPT_NAME% -t [t-echo^|rak4631^|nano-g2-ultra^|wio-tracker-wm1110^|canaryone^|
|
||||||
|
ECHO heltec-mesh-node-t114^|tracker-t1000-e^|rak_wismeshtap^|rak2560^|
|
||||||
|
ECHO nrf52_promicro_diy_tcxo]
|
||||||
|
ECHO.
|
||||||
|
ECHO Options:
|
||||||
|
ECHO -t target Specify a platformio NRF target to build for. (required)
|
||||||
|
ECHO.
|
||||||
|
ECHO Example: %SCRIPT_NAME% -t rak4631
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
|
:version
|
||||||
|
ECHO %SCRIPT_NAME% [Version 2.6.0]
|
||||||
|
ECHO Meshtastic
|
||||||
|
GOTO eof
|
||||||
|
|
||||||
|
:getopts
|
||||||
|
IF "%~1"=="" GOTO endopts
|
||||||
|
IF /I "%~1"=="-?" GOTO help
|
||||||
|
IF /I "%~1"=="-h" GOTO help
|
||||||
|
IF /I "%~1"=="--help" GOTO help
|
||||||
|
IF /I "%~1"=="-v" GOTO version
|
||||||
|
IF /I "%~1"=="--version" GOTO version
|
||||||
|
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
|
||||||
|
IF /I "%~1"=="-t" SET "TARGETNAME=%~2" & SHIFT
|
||||||
|
IF /I "%~1"=="--target" SET "TARGETNAME=%~2" & SHIFT
|
||||||
|
SHIFT
|
||||||
|
GOTO getopts
|
||||||
|
:endopts
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Checking TARGETNAME parameter..."
|
||||||
|
IF "__!TARGETNAME!__"=="____" (
|
||||||
|
CALL :LOG_MESSAGE DEBUG "Missing -t target input."
|
||||||
|
GOTO help
|
||||||
|
)
|
||||||
|
|
||||||
|
IF %DEBUG% EQU 1 SET "UF2CONV_CMD=REM python3 .\bin\uf2conv.py"
|
||||||
|
|
||||||
|
SET "NRFTARGETS=t-echo rak4631 nano-g2-ultra wio-tracker-wm1110 canaryone heltec-mesh-node-t114 tracker-t1000-e rak_wismeshtap rak2560 nrf52_promicro_diy_tcxo"
|
||||||
|
FOR %%a IN (%NRFTARGETS%) DO (
|
||||||
|
IF /I "%%a"=="!TARGETNAME!" (
|
||||||
|
@REM We are working with any of %NRFTARGETS%.
|
||||||
|
SET "NRF=1"
|
||||||
|
GOTO end_loop_nrf
|
||||||
|
)
|
||||||
|
)
|
||||||
|
:end_loop_nrf
|
||||||
|
|
||||||
|
@REM Building operations.
|
||||||
|
IF !NRF! EQU 1 (
|
||||||
|
CALL :LOG_MESSAGE INFO "Trying to build for !TARGETNAME!..."
|
||||||
|
CALL :RUN_UF2CONV !TARGETNAME! || GOTO eof
|
||||||
|
) ELSE (
|
||||||
|
CALL :LOG_MESSAGE WARN "!TARGETNAME! is not supported..."
|
||||||
|
GOTO eof
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
|
||||||
|
:eof
|
||||||
|
ENDLOCAL
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|
||||||
|
:RUN_UF2CONV
|
||||||
|
@REM Subroutine used to run .\bin\uf2conv.py with arguments.
|
||||||
|
@REM Also handles %ERRORLEVEL%.
|
||||||
|
@REM CALL :RUN_UF2CONV [target]
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :RUN_UF2CONV rak4631
|
||||||
|
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !UF2CONV_CMD! .\.pio\build\%~1\firmware.hex -c -o .\.pio\build\%~1\firmware.uf2 -f 0xADA52840"
|
||||||
|
CALL :RESET_ERROR
|
||||||
|
!UF2CONV_CMD! .\.pio\build\%~1\firmware.hex -c -o .\.pio\build\%~1\firmware.uf2 -f 0xADA52840
|
||||||
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
|
CALL :LOG_MESSAGE ERROR "Error running command: !UF2CONV_CMD! .\.pio\build\%~1\firmware.hex -c -o .\.pio\build\%~1\firmware.uf2 -f 0xADA52840"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
)
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:LOG_MESSAGE
|
||||||
|
@REM Subroutine used to print log messages in four different levels.
|
||||||
|
@REM DEBUG messages only get printed if [-d] flag is passed to script.
|
||||||
|
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
|
||||||
|
@REM.
|
||||||
|
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
|
||||||
|
SET /A LOGCOUNTER=LOGCOUNTER+1
|
||||||
|
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO [91m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[91m%~2[0m
|
||||||
|
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO [32m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[32m%~2[0m
|
||||||
|
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO [33m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[33m%~2[0m
|
||||||
|
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO [34m%1 [0m[37m^| !TIMESTAMP! !LOGCOUNTER! [0m[34m%~2[0m
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:GET_TIMESTAMP
|
||||||
|
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
|
||||||
|
@REM CALL :GET_TIMESTAMP
|
||||||
|
@REM.
|
||||||
|
@REM Updates: !TIMESTAMP!
|
||||||
|
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
|
||||||
|
SET "HH=%%a"
|
||||||
|
SET "MM=%%b"
|
||||||
|
SET "ss=%%c"
|
||||||
|
)
|
||||||
|
SET "TIMESTAMP=!HH!:!MM!:!ss!"
|
||||||
|
GOTO :eof
|
||||||
|
|
||||||
|
:RESET_ERROR
|
||||||
|
@REM Subroutine to reset %ERRORLEVEL% to 0.
|
||||||
|
@REM CALL :RESET_ERROR
|
||||||
|
@REM.
|
||||||
|
@REM Updates: %ERRORLEVEL%
|
||||||
|
EXIT /B 0
|
||||||
|
GOTO :eof
|
||||||
|
|||||||
1
bin/web.version
Normal file
1
bin/web.version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2.6.0
|
||||||
53
boards/ThinkNode-M1.json
Normal file
53
boards/ThinkNode-M1.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v6.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
["0x239A", "0x4405"],
|
||||||
|
["0x239A", "0x0029"],
|
||||||
|
["0x239A", "0x002A"]
|
||||||
|
],
|
||||||
|
"usb_product": "elecrow_eink",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "ELECROW-ThinkNode-M1",
|
||||||
|
"variants_dir": "variants",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "6.1.1",
|
||||||
|
"sd_fwid": "0x00B6"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": ["bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"onboard_tools": ["jlink"],
|
||||||
|
"svd_path": "nrf52840.svd",
|
||||||
|
"openocd_target": "nrf52840-mdk-rs"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "elecrow eink",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "nrfutil",
|
||||||
|
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"wait_for_upload_port": true
|
||||||
|
},
|
||||||
|
"url": "FIXME",
|
||||||
|
"vendor": "ELECROW"
|
||||||
|
}
|
||||||
@@ -7,13 +7,15 @@
|
|||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
"-DARDUINO_ESP32S3_DEV",
|
"-DARDUINO_ESP32S3_DEV",
|
||||||
"-DARDUINO_USB_MODE=1",
|
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DBOARD_HAS_PSRAM"
|
||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "qio",
|
||||||
"hwids": [["0x303A", "0x1001"]],
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3"
|
"variant": "esp32s3"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"ldscript": "esp32s3_out.ld",
|
"ldscript": "esp32s3_out.ld",
|
||||||
"partitions": "default_8MB.csv"
|
"partitions": "default_8MB.csv",
|
||||||
|
"memory_type": "qio_opi"
|
||||||
},
|
},
|
||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [
|
"hwids": [
|
||||||
["0x303A", "0x1001"],
|
["0x303A", "0x1001"],
|
||||||
["0x303A", "0x0002"]
|
["0x303A", "0x0002"]
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"ldscript": "esp32s3_out.ld",
|
"ldscript": "esp32s3_out.ld",
|
||||||
"partitions": "default_8MB.csv"
|
"partitions": "default_8MB.csv",
|
||||||
|
"memory_type": "qio_opi"
|
||||||
},
|
},
|
||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [
|
"hwids": [
|
||||||
["0x303A", "0x1001"],
|
["0x303A", "0x1001"],
|
||||||
["0x303A", "0x0002"]
|
["0x303A", "0x0002"]
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"ldscript": "esp32s3_out.ld",
|
"ldscript": "esp32s3_out.ld",
|
||||||
"partitions": "default_8MB.csv"
|
"partitions": "default_8MB.csv",
|
||||||
|
"memory_type": "qio_opi"
|
||||||
},
|
},
|
||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [
|
"hwids": [
|
||||||
["0x303A", "0x1001"],
|
["0x303A", "0x1001"],
|
||||||
["0x303A", "0x0002"]
|
["0x303A", "0x0002"]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"f_boot": "120000000L",
|
"f_boot": "120000000L",
|
||||||
"boot": "qio",
|
"boot": "qio",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [["0x1A86", "0x7523"]],
|
"hwids": [["0x1A86", "0x7523"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3"
|
"variant": "esp32s3"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [["0x2886", "0x0059"]],
|
"hwids": [["0x2886", "0x0059"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "seeed-xiao-s3"
|
"variant": "seeed-xiao-s3"
|
||||||
|
|||||||
56
boards/seeed_xiao_nrf52840_kit.json
Normal file
56
boards/seeed_xiao_nrf52840_kit.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v7.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
["0x2886", "0x0166"]
|
||||||
|
],
|
||||||
|
"usb_product": "XIAO-BOOT",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "seeed_xiao_nrf52840_kit",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "7.3.0",
|
||||||
|
"sd_fwid": "0x0123"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": ["bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"svd_path": "nrf52840.svd",
|
||||||
|
"openocd_target": "nrf52840-mdk-rs"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "seeed_xiao_nrf52840_kit",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "nrfutil",
|
||||||
|
"protocols": [
|
||||||
|
"jlink",
|
||||||
|
"nrfjprog",
|
||||||
|
"nrfutil",
|
||||||
|
"stlink",
|
||||||
|
"cmsis-dap",
|
||||||
|
"blackmagic"
|
||||||
|
],
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"wait_for_upload_port": true
|
||||||
|
},
|
||||||
|
"url": "https://www.seeedstudio.com/XIAO-nRF52840-Wio-SX1262-Kit-for-Meshtastic-p-6400.html",
|
||||||
|
"vendor": "seeed"
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "opi",
|
||||||
"hwids": [
|
"hwids": [
|
||||||
["0x303A", "0x1001"],
|
["0x303A", "0x1001"],
|
||||||
["0x303A", "0x0002"]
|
["0x303A", "0x0002"]
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "t-watch-s3"
|
"variant": "t-watch-s3"
|
||||||
},
|
},
|
||||||
"connectivity": ["wifi"],
|
"connectivity": ["wifi", "bluetooth"],
|
||||||
"debug": {
|
"debug": {
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"earlephilhower": {
|
|
||||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
|
||||||
"usb_vid": "0x2E8A",
|
|
||||||
"usb_pid": "0x000A"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"core": "earlephilhower",
|
|
||||||
"cpu": "cortex-m0plus",
|
|
||||||
"extra_flags": "-DARDUINO_GENERIC_RP2040 -DRASPBERRY_PI_PICO -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
|
||||||
"f_cpu": "133000000L",
|
|
||||||
"hwids": [
|
|
||||||
["0x2E8A", "0x00C0"],
|
|
||||||
["0x2E8A", "0x000A"]
|
|
||||||
],
|
|
||||||
"mcu": "rp2040",
|
|
||||||
"variant": "WisBlock_RAK11300_Board"
|
|
||||||
},
|
|
||||||
"debug": {
|
|
||||||
"jlink_device": "RP2040_M0_0",
|
|
||||||
"openocd_target": "rp2040.cfg",
|
|
||||||
"svd_path": "rp2040.svd"
|
|
||||||
},
|
|
||||||
"frameworks": ["arduino"],
|
|
||||||
"name": "WisBlock RAK11300",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 270336,
|
|
||||||
"maximum_size": 2097152,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"native_usb": true,
|
|
||||||
"use_1200bps_touch": true,
|
|
||||||
"wait_for_upload_port": false,
|
|
||||||
"protocol": "picotool",
|
|
||||||
"protocols": ["cmsis-dap", "raspberrypi-swd", "picotool", "picoprobe"]
|
|
||||||
},
|
|
||||||
"url": "https://docs.rakwireless.com/",
|
|
||||||
"vendor": "RAKwireless"
|
|
||||||
}
|
|
||||||
5
debian/ci_pack_sdeb.sh
vendored
5
debian/ci_pack_sdeb.sh
vendored
@@ -10,8 +10,9 @@ platformio pkg install -e native -t platformio/tool-scons@4.40502.0
|
|||||||
# Compress `pio` directory to prevent dh_clean from sanitizing it
|
# Compress `pio` directory to prevent dh_clean from sanitizing it
|
||||||
tar -cf pio.tar pio/
|
tar -cf pio.tar pio/
|
||||||
rm -rf pio
|
rm -rf pio
|
||||||
# Download the latest meshtastic/web release build.tar to `web.tar`
|
# Download the meshtastic/web release build.tar to `web.tar`
|
||||||
curl -L https://github.com/meshtastic/web/releases/latest/download/build.tar -o web.tar
|
web_ver=$(cat bin/web.version)
|
||||||
|
curl -L "https://github.com/meshtastic/web/releases/download/v$web_ver/build.tar" -o web.tar
|
||||||
|
|
||||||
package=$(dpkg-parsechangelog --show-field Source)
|
package=$(dpkg-parsechangelog --show-field Source)
|
||||||
|
|
||||||
|
|||||||
1
debian/control
vendored
1
debian/control
vendored
@@ -17,6 +17,7 @@ Build-Depends: debhelper-compat (= 13),
|
|||||||
libbluetooth-dev,
|
libbluetooth-dev,
|
||||||
libusb-1.0-0-dev,
|
libusb-1.0-0-dev,
|
||||||
libi2c-dev,
|
libi2c-dev,
|
||||||
|
libuv1-dev,
|
||||||
openssl,
|
openssl,
|
||||||
libssl-dev,
|
libssl-dev,
|
||||||
libulfius-dev,
|
libulfius-dev,
|
||||||
|
|||||||
22
extra_scripts/extra_stm32.py
Executable file
22
extra_scripts/extra_stm32.py
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
# trunk-ignore-all(ruff/F821)
|
||||||
|
# trunk-ignore-all(flake8/F821): For SConstruct imports
|
||||||
|
|
||||||
|
Import("env")
|
||||||
|
# Custom HEX from ELF
|
||||||
|
env.AddPostAction(
|
||||||
|
"$BUILD_DIR/${PROGNAME}.elf",
|
||||||
|
env.VerboseAction(
|
||||||
|
" ".join(
|
||||||
|
[
|
||||||
|
"$OBJCOPY",
|
||||||
|
"-O",
|
||||||
|
"ihex",
|
||||||
|
"-R",
|
||||||
|
".eeprom",
|
||||||
|
"$BUILD_DIR/${PROGNAME}.elf",
|
||||||
|
"$BUILD_DIR/${PROGNAME}.hex",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
"Building $BUILD_DIR/${PROGNAME}.hex",
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -21,7 +21,7 @@ Summary: Meshtastic daemon for communicating with Meshtastic devices
|
|||||||
License: GPL-3.0
|
License: GPL-3.0
|
||||||
URL: https://github.com/meshtastic/firmware
|
URL: https://github.com/meshtastic/firmware
|
||||||
Source0: {{{ git_dir_pack }}}
|
Source0: {{{ git_dir_pack }}}
|
||||||
Source1: https://github.com/meshtastic/web/releases/latest/download/build.tar
|
Source1: https://github.com/meshtastic/web/releases/download/v{{{ web_version }}}/build.tar
|
||||||
|
|
||||||
BuildRequires: systemd-rpm-macros
|
BuildRequires: systemd-rpm-macros
|
||||||
BuildRequires: python3-devel
|
BuildRequires: python3-devel
|
||||||
@@ -36,6 +36,7 @@ BuildRequires: pkgconfig(libgpiod)
|
|||||||
BuildRequires: pkgconfig(bluez)
|
BuildRequires: pkgconfig(bluez)
|
||||||
BuildRequires: pkgconfig(libusb-1.0)
|
BuildRequires: pkgconfig(libusb-1.0)
|
||||||
BuildRequires: libi2c-devel
|
BuildRequires: libi2c-devel
|
||||||
|
BuildRequires: pkgconfig(libuv)
|
||||||
# Web components:
|
# Web components:
|
||||||
BuildRequires: pkgconfig(openssl)
|
BuildRequires: pkgconfig(openssl)
|
||||||
BuildRequires: pkgconfig(liborcania)
|
BuildRequires: pkgconfig(liborcania)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ default_envs = tbeam
|
|||||||
extra_configs =
|
extra_configs =
|
||||||
arch/*/*.ini
|
arch/*/*.ini
|
||||||
variants/*/platformio.ini
|
variants/*/platformio.ini
|
||||||
|
src/graphics/niche/InkHUD/PlatformioConfig.ini
|
||||||
|
|
||||||
description = Meshtastic
|
description = Meshtastic
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
@@ -54,11 +56,11 @@ build_flags = -Wno-missing-field-initializers
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95
|
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/0119501e9983bd894830b02f545c377ee08d66fe.zip
|
||||||
mathertel/OneButton@2.6.1
|
mathertel/OneButton@2.6.1
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm/archive/7db3702bf0cfe97b783d6c72595e3f38e0b19159.zip
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
https://github.com/meshtastic/TinyGPSPlus/archive/71a82db35f3b973440044c476d4bcdc673b104f4.zip
|
||||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
https://github.com/meshtastic/ArduinoThread/archive/7c3ee9e1951551b949763b1f5280f8db1fa4068d.zip
|
||||||
nanopb/Nanopb@0.4.91
|
nanopb/Nanopb@0.4.91
|
||||||
erriez/ErriezCRC32@1.0.1
|
erriez/ErriezCRC32@1.0.1
|
||||||
|
|
||||||
@@ -77,7 +79,7 @@ lib_deps =
|
|||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
end2endzone/NonBlockingRTTTL@1.3.0
|
end2endzone/NonBlockingRTTTL@1.3.0
|
||||||
build_flags = ${env.build_flags} -Os
|
build_flags = ${env.build_flags} -Os
|
||||||
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
|
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
|
||||||
|
|
||||||
; Common libs for communicating over TCP/IP networks such as MQTT
|
; Common libs for communicating over TCP/IP networks such as MQTT
|
||||||
[networking_base]
|
[networking_base]
|
||||||
@@ -90,16 +92,21 @@ lib_deps =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
jgromes/RadioLib@7.1.2
|
jgromes/RadioLib@7.1.2
|
||||||
|
|
||||||
|
[device-ui_base]
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/meshtastic/device-ui/archive/56ef8db7eb4dda44dc0c1ec5828044debbbc6d33.zip
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
; (not included in native / portduino)
|
; (not included in native / portduino)
|
||||||
[environmental_base]
|
[environmental_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
adafruit/Adafruit BusIO@1.16.2
|
adafruit/Adafruit BusIO@1.17.0
|
||||||
adafruit/Adafruit Unified Sensor@1.1.14
|
adafruit/Adafruit Unified Sensor@1.1.15
|
||||||
adafruit/Adafruit BMP280 Library@2.6.8
|
adafruit/Adafruit BMP280 Library@2.6.8
|
||||||
adafruit/Adafruit BMP085 Library@1.2.4
|
adafruit/Adafruit BMP085 Library@1.2.4
|
||||||
adafruit/Adafruit BME280 Library@2.2.4
|
adafruit/Adafruit BME280 Library@2.2.4
|
||||||
adafruit/Adafruit BMP3XX Library@2.1.5
|
adafruit/Adafruit BMP3XX Library@2.1.6
|
||||||
|
adafruit/Adafruit DPS310@1.1.5
|
||||||
adafruit/Adafruit MCP9808 Library@2.0.2
|
adafruit/Adafruit MCP9808 Library@2.0.2
|
||||||
adafruit/Adafruit INA260 Library@1.5.2
|
adafruit/Adafruit INA260 Library@1.5.2
|
||||||
adafruit/Adafruit INA219@1.2.3
|
adafruit/Adafruit INA219@1.2.3
|
||||||
@@ -107,27 +114,27 @@ lib_deps =
|
|||||||
adafruit/Adafruit SHTC3 Library@1.0.1
|
adafruit/Adafruit SHTC3 Library@1.0.1
|
||||||
adafruit/Adafruit LPS2X@2.0.6
|
adafruit/Adafruit LPS2X@2.0.6
|
||||||
adafruit/Adafruit SHT31 Library@2.2.2
|
adafruit/Adafruit SHT31 Library@2.2.2
|
||||||
adafruit/Adafruit PM25 AQI Sensor@1.1.1
|
adafruit/Adafruit PM25 AQI Sensor@1.2.0
|
||||||
adafruit/Adafruit MPU6050@2.2.6
|
adafruit/Adafruit MPU6050@2.2.6
|
||||||
adafruit/Adafruit LIS3DH@1.3.0
|
adafruit/Adafruit LIS3DH@1.3.0
|
||||||
adafruit/Adafruit AHTX0@2.0.5
|
adafruit/Adafruit AHTX0@2.0.5
|
||||||
adafruit/Adafruit LSM6DS@4.7.3
|
adafruit/Adafruit LSM6DS@4.7.4
|
||||||
adafruit/Adafruit VEML7700 Library@2.1.6
|
adafruit/Adafruit VEML7700 Library@2.1.6
|
||||||
adafruit/Adafruit SHT4x Library@1.0.5
|
adafruit/Adafruit SHT4x Library@1.0.5
|
||||||
adafruit/Adafruit TSL2591 Library@1.4.5
|
adafruit/Adafruit TSL2591 Library@1.4.5
|
||||||
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6
|
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6
|
||||||
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
|
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.3.0
|
||||||
ClosedCube OPT3001@1.1.2
|
ClosedCube OPT3001@1.1.2
|
||||||
emotibit/EmotiBit MLX90632@1.0.8
|
emotibit/EmotiBit MLX90632@1.0.8
|
||||||
adafruit/Adafruit MLX90614 Library@2.1.5
|
adafruit/Adafruit MLX90614 Library@2.1.5
|
||||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
https://github.com/boschsensortec/Bosch-BSEC2-Library/archive/v1.7.2502.zip
|
||||||
boschsensortec/BME68x Sensor Library@1.1.40407
|
boschsensortec/BME68x Sensor Library@1.1.40407
|
||||||
https://github.com/KodinLanewave/INA3221@1.0.1
|
https://github.com/KodinLanewave/INA3221/archive/1.0.1.zip
|
||||||
mprograms/QMC5883LCompass@1.2.3
|
mprograms/QMC5883LCompass@1.2.3
|
||||||
dfrobot/DFRobot_RTU@1.0.3
|
dfrobot/DFRobot_RTU@1.0.3
|
||||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
https://github.com/meshtastic/DFRobot_LarkWeatherStation/archive/4de3a9cadef0f6a5220a8a906cf9775b02b0040d.zip
|
||||||
https://github.com/DFRobot/DFRobot_RainfallSensor#38fea5e02b40a5430be6dab39a99a6f6347d667e
|
https://github.com/DFRobot/DFRobot_RainfallSensor/archive/38fea5e02b40a5430be6dab39a99a6f6347d667e.zip
|
||||||
robtillaart/INA226@0.6.0
|
robtillaart/INA226@0.6.4
|
||||||
|
|
||||||
; Health Sensor Libraries
|
; Health Sensor Libraries
|
||||||
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
||||||
|
|||||||
Submodule protobufs updated: e2790151f0...5a5ab103d2
@@ -6,6 +6,11 @@
|
|||||||
NCP5623 rgb;
|
NCP5623 rgb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_LP5562
|
||||||
|
#include <graphics/NomadStarLED.h>
|
||||||
|
LP5562 rgbw;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_NEOPIXEL
|
#ifdef HAS_NEOPIXEL
|
||||||
#include <graphics/NeoPixel.h>
|
#include <graphics/NeoPixel.h>
|
||||||
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
|
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
|
||||||
@@ -26,7 +31,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep); // Let us know when shutdown() is issued.
|
notifyDeepSleepObserver.observe(¬ifyDeepSleep); // Let us know when shutdown() is issued.
|
||||||
|
|
||||||
// Enables Ambient Lighting by default if conditions are meet.
|
// Enables Ambient Lighting by default if conditions are meet.
|
||||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
#ifdef HAS_RGB_LED
|
||||||
#ifdef ENABLE_AMBIENTLIGHTING
|
#ifdef ENABLE_AMBIENTLIGHTING
|
||||||
moduleConfig.ambient_lighting.led_state = true;
|
moduleConfig.ambient_lighting.led_state = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -39,7 +44,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
|
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
|
||||||
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
|
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
|
||||||
|
|
||||||
#ifdef HAS_NCP5623
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562)
|
||||||
_type = type;
|
_type = type;
|
||||||
if (_type == ScanI2C::DeviceType::NONE) {
|
if (_type == ScanI2C::DeviceType::NONE) {
|
||||||
LOG_DEBUG("AmbientLighting Disable due to no RGB leds found on I2C bus");
|
LOG_DEBUG("AmbientLighting Disable due to no RGB leds found on I2C bus");
|
||||||
@@ -47,17 +52,21 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
#ifdef HAS_RGB_LED
|
||||||
if (!moduleConfig.ambient_lighting.led_state) {
|
if (!moduleConfig.ambient_lighting.led_state) {
|
||||||
LOG_DEBUG("AmbientLighting Disable due to moduleConfig.ambient_lighting.led_state OFF");
|
LOG_DEBUG("AmbientLighting Disable due to moduleConfig.ambient_lighting.led_state OFF");
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("AmbientLighting init");
|
LOG_DEBUG("AmbientLighting init");
|
||||||
#ifdef HAS_NCP5623
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562)
|
||||||
if (_type == ScanI2C::NCP5623) {
|
if (_type == ScanI2C::NCP5623) {
|
||||||
rgb.begin();
|
rgb.begin();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_LP5562
|
||||||
|
} else if (_type == ScanI2C::LP5562) {
|
||||||
|
rgbw.begin();
|
||||||
|
#endif
|
||||||
#ifdef RGBLED_RED
|
#ifdef RGBLED_RED
|
||||||
pinMode(RGBLED_RED, OUTPUT);
|
pinMode(RGBLED_RED, OUTPUT);
|
||||||
pinMode(RGBLED_GREEN, OUTPUT);
|
pinMode(RGBLED_GREEN, OUTPUT);
|
||||||
@@ -70,7 +79,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
#endif
|
#endif
|
||||||
setLighting();
|
setLighting();
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_NCP5623
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -78,13 +87,13 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
protected:
|
protected:
|
||||||
int32_t runOnce() override
|
int32_t runOnce() override
|
||||||
{
|
{
|
||||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
#ifdef HAS_RGB_LED
|
||||||
#ifdef HAS_NCP5623
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562)
|
||||||
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
|
if ((_type == ScanI2C::NCP5623 || _type == ScanI2C::LP5562) && moduleConfig.ambient_lighting.led_state) {
|
||||||
#endif
|
#endif
|
||||||
setLighting();
|
setLighting();
|
||||||
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
|
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
|
||||||
#ifdef HAS_NCP5623
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -108,6 +117,14 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
rgb.setBlue(0);
|
rgb.setBlue(0);
|
||||||
LOG_INFO("OFF: NCP5623 Ambient lighting");
|
LOG_INFO("OFF: NCP5623 Ambient lighting");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_LP5562
|
||||||
|
rgbw.setCurrent(0);
|
||||||
|
rgbw.setRed(0);
|
||||||
|
rgbw.setGreen(0);
|
||||||
|
rgbw.setBlue(0);
|
||||||
|
rgbw.setWhite(0);
|
||||||
|
LOG_INFO("OFF: LP5562 Ambient lighting");
|
||||||
|
#endif
|
||||||
#ifdef HAS_NEOPIXEL
|
#ifdef HAS_NEOPIXEL
|
||||||
pixels.clear();
|
pixels.clear();
|
||||||
pixels.show();
|
pixels.show();
|
||||||
@@ -141,6 +158,14 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
LOG_DEBUG("Init NCP5623 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current,
|
LOG_DEBUG("Init NCP5623 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current,
|
||||||
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_LP5562
|
||||||
|
rgbw.setCurrent(moduleConfig.ambient_lighting.current);
|
||||||
|
rgbw.setRed(moduleConfig.ambient_lighting.red);
|
||||||
|
rgbw.setGreen(moduleConfig.ambient_lighting.green);
|
||||||
|
rgbw.setBlue(moduleConfig.ambient_lighting.blue);
|
||||||
|
LOG_DEBUG("Init LP5562 Ambient light w/ current=%d, red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.current,
|
||||||
|
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||||
|
#endif
|
||||||
#ifdef HAS_NEOPIXEL
|
#ifdef HAS_NEOPIXEL
|
||||||
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||||
moduleConfig.ambient_lighting.blue),
|
moduleConfig.ambient_lighting.blue),
|
||||||
|
|||||||
@@ -41,10 +41,8 @@ class AudioThread : public concurrency::OSThread
|
|||||||
delete i2sRtttl;
|
delete i2sRtttl;
|
||||||
i2sRtttl = nullptr;
|
i2sRtttl = nullptr;
|
||||||
}
|
}
|
||||||
if (rtttlFile != nullptr) {
|
delete rtttlFile;
|
||||||
delete rtttlFile;
|
rtttlFile = nullptr;
|
||||||
rtttlFile = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCPUFast(false);
|
setCPUFast(false);
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/BluetoothStatus.h
Normal file
105
src/BluetoothStatus.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Status.h"
|
||||||
|
#include "assert.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
namespace meshtastic
|
||||||
|
{
|
||||||
|
|
||||||
|
// Describes the state of the Bluetooth connection
|
||||||
|
// Allows display to handle pairing events without each UI needing to explicitly hook the Bluefruit / NimBLE code
|
||||||
|
class BluetoothStatus : public Status
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class ConnectionState {
|
||||||
|
DISCONNECTED,
|
||||||
|
PAIRING,
|
||||||
|
CONNECTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
CallbackObserver<BluetoothStatus, const BluetoothStatus *> statusObserver =
|
||||||
|
CallbackObserver<BluetoothStatus, const BluetoothStatus *>(this, &BluetoothStatus::updateStatus);
|
||||||
|
|
||||||
|
ConnectionState state = ConnectionState::DISCONNECTED;
|
||||||
|
std::string passkey; // Stored as string, because Bluefruit allows passkeys with a leading zero
|
||||||
|
|
||||||
|
public:
|
||||||
|
BluetoothStatus() { statusType = STATUS_TYPE_BLUETOOTH; }
|
||||||
|
|
||||||
|
// New BluetoothStatus: connected or disconnected
|
||||||
|
explicit BluetoothStatus(ConnectionState state)
|
||||||
|
{
|
||||||
|
assert(state != ConnectionState::PAIRING); // If pairing, use constructor which specifies passkey
|
||||||
|
statusType = STATUS_TYPE_BLUETOOTH;
|
||||||
|
this->state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New BluetoothStatus: pairing, with passkey
|
||||||
|
explicit BluetoothStatus(const std::string &passkey) : Status()
|
||||||
|
{
|
||||||
|
statusType = STATUS_TYPE_BLUETOOTH;
|
||||||
|
this->state = ConnectionState::PAIRING;
|
||||||
|
this->passkey = passkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionState getConnectionState() const { return this->state; }
|
||||||
|
|
||||||
|
std::string getPasskey() const
|
||||||
|
{
|
||||||
|
assert(state == ConnectionState::PAIRING);
|
||||||
|
return this->passkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void observe(Observable<const BluetoothStatus *> *source) { statusObserver.observe(source); }
|
||||||
|
|
||||||
|
bool matches(const BluetoothStatus *newStatus) const
|
||||||
|
{
|
||||||
|
if (this->state == newStatus->getConnectionState()) {
|
||||||
|
// Same state: CONNECTED / DISCONNECTED
|
||||||
|
if (this->state != ConnectionState::PAIRING)
|
||||||
|
return true;
|
||||||
|
// Same state: PAIRING, and passkey matches
|
||||||
|
else if (this->getPasskey() == newStatus->getPasskey())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int updateStatus(const BluetoothStatus *newStatus)
|
||||||
|
{
|
||||||
|
// Has the status changed?
|
||||||
|
if (!matches(newStatus)) {
|
||||||
|
// Copy the members
|
||||||
|
state = newStatus->getConnectionState();
|
||||||
|
if (state == ConnectionState::PAIRING)
|
||||||
|
passkey = newStatus->getPasskey();
|
||||||
|
|
||||||
|
// Tell anyone interested that we have an update
|
||||||
|
onNewStatus.notifyObservers(this);
|
||||||
|
|
||||||
|
// Debug only:
|
||||||
|
switch (state) {
|
||||||
|
case ConnectionState::PAIRING:
|
||||||
|
LOG_DEBUG("BluetoothStatus PAIRING, key=%s", passkey.c_str());
|
||||||
|
break;
|
||||||
|
case ConnectionState::CONNECTED:
|
||||||
|
LOG_DEBUG("BluetoothStatus CONNECTED");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConnectionState::DISCONNECTED:
|
||||||
|
LOG_DEBUG("BluetoothStatus DISCONNECTED");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace meshtastic
|
||||||
|
|
||||||
|
extern meshtastic::BluetoothStatus *bluetoothStatus;
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "sleep.h"
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
#include "platform/portduino/PortduinoGlue.h"
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -46,7 +47,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
#ifdef USERPREFS_BUTTON_PIN
|
#ifdef USERPREFS_BUTTON_PIN
|
||||||
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
|
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
|
||||||
#endif
|
#endif
|
||||||
#if defined(HELTEC_CAPSULE_SENSOR_V3)
|
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB)
|
||||||
this->userButton = OneButton(pin, false, false);
|
this->userButton = OneButton(pin, false, false);
|
||||||
#elif defined(BUTTON_ACTIVE_LOW)
|
#elif defined(BUTTON_ACTIVE_LOW)
|
||||||
this->userButton = OneButton(pin, BUTTON_ACTIVE_LOW, BUTTON_ACTIVE_PULLUP);
|
this->userButton = OneButton(pin, BUTTON_ACTIVE_LOW, BUTTON_ACTIVE_PULLUP);
|
||||||
@@ -72,23 +73,28 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
userButton.setDebounceMs(1);
|
userButton.setDebounceMs(1);
|
||||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||||
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
|
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
|
||||||
#ifndef T_DECK // T-Deck immediately wakes up after shutdown, so disable this function
|
#if !defined(T_DECK) && \
|
||||||
|
!defined( \
|
||||||
|
ELECROW_ThinkNode_M2) // T-Deck immediately wakes up after shutdown, Thinknode M2 has this on the smaller ALT button
|
||||||
userButton.attachLongPressStart(userButtonPressedLongStart);
|
userButton.attachLongPressStart(userButtonPressedLongStart);
|
||||||
userButton.attachLongPressStop(userButtonPressedLongStop);
|
userButton.attachLongPressStop(userButtonPressedLongStop);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUTTON_PIN_ALT
|
#ifdef BUTTON_PIN_ALT
|
||||||
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
|
#if defined(ELECROW_ThinkNode_M2)
|
||||||
|
this->userButtonAlt = OneButton(BUTTON_PIN_ALT, false, false);
|
||||||
|
#else
|
||||||
|
this->userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
|
||||||
|
#endif
|
||||||
#ifdef INPUT_PULLUP_SENSE
|
#ifdef INPUT_PULLUP_SENSE
|
||||||
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
||||||
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
|
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
|
||||||
#endif
|
#endif
|
||||||
userButtonAlt.attachClick(userButtonPressed);
|
userButtonAlt.attachClick(userButtonPressedScreen);
|
||||||
userButtonAlt.setClickMs(BUTTON_CLICK_MS);
|
userButtonAlt.setClickMs(BUTTON_CLICK_MS);
|
||||||
userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS);
|
userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS);
|
||||||
userButtonAlt.setDebounceMs(1);
|
userButtonAlt.setDebounceMs(1);
|
||||||
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
|
|
||||||
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
|
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
|
||||||
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
|
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
|
||||||
#endif
|
#endif
|
||||||
@@ -99,10 +105,60 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
|
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Register callbacks for before and after lightsleep
|
||||||
|
// Used to detach and reattach interrupts
|
||||||
|
lsObserver.observe(¬ifyLightSleep);
|
||||||
|
lsEndObserver.observe(¬ifyLightSleepEnd);
|
||||||
|
#endif
|
||||||
|
|
||||||
attachButtonInterrupts();
|
attachButtonInterrupts();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ButtonThread::switchPage()
|
||||||
|
{
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
#if !defined(USERPREFS_BUTTON_PIN)
|
||||||
|
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
|
||||||
|
moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||||
|
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
||||||
|
!moduleConfig.canned_message.enabled) {
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(USERPREFS_BUTTON_PIN)
|
||||||
|
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
|
||||||
|
moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||||
|
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
||||||
|
!moduleConfig.canned_message.enabled) {
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if defined(ARCH_PORTDUINO)
|
||||||
|
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
|
||||||
|
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||||
|
!moduleConfig.canned_message.enabled) {
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonThread::sendAdHocPosition()
|
||||||
|
{
|
||||||
|
service->refreshLocalMeshNode();
|
||||||
|
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
||||||
|
if (screen) {
|
||||||
|
if (sentPosition)
|
||||||
|
screen->print("Sent ad-hoc position\n");
|
||||||
|
else
|
||||||
|
screen->print("Sent ad-hoc nodeinfo\n");
|
||||||
|
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t ButtonThread::runOnce()
|
int32_t ButtonThread::runOnce()
|
||||||
{
|
{
|
||||||
// If the button is pressed we suppress CPU sleep until release
|
// If the button is pressed we suppress CPU sleep until release
|
||||||
@@ -133,49 +189,48 @@ int32_t ButtonThread::runOnce()
|
|||||||
// If a nag notification is running, stop it and prevent other actions
|
// If a nag notification is running, stop it and prevent other actions
|
||||||
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
||||||
externalNotificationModule->stopNow();
|
externalNotificationModule->stopNow();
|
||||||
return 50;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef BUTTON_PIN
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
#if !defined(USERPREFS_BUTTON_PIN)
|
sendAdHocPosition();
|
||||||
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(USERPREFS_BUTTON_PIN)
|
switchPage();
|
||||||
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
|
break;
|
||||||
#endif
|
}
|
||||||
moduleConfig.canned_message.inputbroker_pin_press) ||
|
|
||||||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
case BUTTON_EVENT_PRESSED_SCREEN: {
|
||||||
!moduleConfig.canned_message.enabled) {
|
LOG_BUTTON("AltPress!");
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
}
|
// If a nag notification is running, stop it and prevent other actions
|
||||||
#endif
|
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
||||||
#if defined(ARCH_PORTDUINO)
|
externalNotificationModule->stopNow();
|
||||||
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
|
break;
|
||||||
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
|
|
||||||
!moduleConfig.canned_message.enabled) {
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
}
|
}
|
||||||
|
switchPage();
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
// turn screen on or off
|
||||||
|
screen_flag = !screen_flag;
|
||||||
|
if (screen)
|
||||||
|
screen->setOn(screen_flag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||||
LOG_BUTTON("Double press!");
|
LOG_BUTTON("Double press!");
|
||||||
service->refreshLocalMeshNode();
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||||
if (screen) {
|
break;
|
||||||
if (sentPosition)
|
#endif
|
||||||
screen->print("Sent ad-hoc position\n");
|
sendAdHocPosition();
|
||||||
else
|
|
||||||
screen->print("Sent ad-hoc nodeinfo\n");
|
|
||||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_MULTI_PRESSED: {
|
case BUTTON_EVENT_MULTI_PRESSED: {
|
||||||
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
||||||
switch (multipressClickCount) {
|
switch (multipressClickCount) {
|
||||||
#if HAS_GPS
|
#if HAS_GPS && !defined(ELECROW_ThinkNode_M1)
|
||||||
// 3 clicks: toggle GPS
|
// 3 clicks: toggle GPS
|
||||||
case 3:
|
case 3:
|
||||||
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
||||||
@@ -184,8 +239,17 @@ int32_t ButtonThread::runOnce()
|
|||||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#elif defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
|
||||||
|
case 3:
|
||||||
|
LOG_INFO("3 clicks: toggle buzzer");
|
||||||
|
buzzer_flag = !buzzer_flag;
|
||||||
|
if (!buzzer_flag)
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_EINK) && defined(PIN_EINK_EN) // i.e. T-Echo
|
|
||||||
|
#if defined(USE_EINK) && defined(PIN_EINK_EN) && !defined(ELECROW_ThinkNode_M1) // i.e. T-Echo
|
||||||
// 4 clicks: toggle backlight
|
// 4 clicks: toggle backlight
|
||||||
case 4:
|
case 4:
|
||||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||||
@@ -285,8 +349,12 @@ void ButtonThread::attachButtonInterrupts()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUTTON_PIN_ALT
|
#ifdef BUTTON_PIN_ALT
|
||||||
|
#ifdef ELECROW_ThinkNode_M2
|
||||||
|
wakeOnIrq(BUTTON_PIN_ALT, RISING);
|
||||||
|
#else
|
||||||
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BUTTON_PIN_TOUCH
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||||
@@ -320,6 +388,26 @@ void ButtonThread::detachButtonInterrupts()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
|
||||||
|
// Detach our class' interrupts before lightsleep
|
||||||
|
// Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
|
||||||
|
int ButtonThread::beforeLightSleep(void *unused)
|
||||||
|
{
|
||||||
|
detachButtonInterrupts();
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconfigure our interrupts
|
||||||
|
// Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
|
||||||
|
int ButtonThread::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||||
|
{
|
||||||
|
attachButtonInterrupts();
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch a GPIO and if we get an IRQ, wake the main thread.
|
* Watch a GPIO and if we get an IRQ, wake the main thread.
|
||||||
* Use to add wake on button press
|
* Use to add wake on button press
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
enum ButtonEventType {
|
enum ButtonEventType {
|
||||||
BUTTON_EVENT_NONE,
|
BUTTON_EVENT_NONE,
|
||||||
BUTTON_EVENT_PRESSED,
|
BUTTON_EVENT_PRESSED,
|
||||||
|
BUTTON_EVENT_PRESSED_SCREEN,
|
||||||
BUTTON_EVENT_DOUBLE_PRESSED,
|
BUTTON_EVENT_DOUBLE_PRESSED,
|
||||||
BUTTON_EVENT_MULTI_PRESSED,
|
BUTTON_EVENT_MULTI_PRESSED,
|
||||||
BUTTON_EVENT_LONG_PRESSED,
|
BUTTON_EVENT_LONG_PRESSED,
|
||||||
@@ -36,7 +37,15 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
void attachButtonInterrupts();
|
void attachButtonInterrupts();
|
||||||
void detachButtonInterrupts();
|
void detachButtonInterrupts();
|
||||||
void storeClickCount();
|
void storeClickCount();
|
||||||
|
bool isBuzzing() { return buzzer_flag; }
|
||||||
|
void setScreenFlag(bool flag) { screen_flag = flag; }
|
||||||
|
bool getScreenFlag() { return screen_flag; }
|
||||||
|
|
||||||
|
// Disconnect and reconnect interrupts for light sleep
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
int beforeLightSleep(void *unused);
|
||||||
|
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
|
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
|
||||||
static OneButton userButton; // Static - accessed from an interrupt
|
static OneButton userButton; // Static - accessed from an interrupt
|
||||||
@@ -48,16 +57,30 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
OneButton userButtonTouch;
|
OneButton userButtonTouch;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Get notified when lightsleep begins and ends
|
||||||
|
CallbackObserver<ButtonThread, void *> lsObserver =
|
||||||
|
CallbackObserver<ButtonThread, void *>(this, &ButtonThread::beforeLightSleep);
|
||||||
|
CallbackObserver<ButtonThread, esp_sleep_wakeup_cause_t> lsEndObserver =
|
||||||
|
CallbackObserver<ButtonThread, esp_sleep_wakeup_cause_t>(this, &ButtonThread::afterLightSleep);
|
||||||
|
#endif
|
||||||
|
|
||||||
// set during IRQ
|
// set during IRQ
|
||||||
static volatile ButtonEventType btnEvent;
|
static volatile ButtonEventType btnEvent;
|
||||||
|
bool buzzer_flag = false;
|
||||||
|
bool screen_flag = true;
|
||||||
|
|
||||||
// Store click count during callback, for later use
|
// Store click count during callback, for later use
|
||||||
volatile int multipressClickCount = 0;
|
volatile int multipressClickCount = 0;
|
||||||
|
|
||||||
static void wakeOnIrq(int irq, int mode);
|
static void wakeOnIrq(int irq, int mode);
|
||||||
|
|
||||||
|
static void sendAdHocPosition();
|
||||||
|
static void switchPage();
|
||||||
|
|
||||||
// IRQ callbacks
|
// IRQ callbacks
|
||||||
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
||||||
|
static void userButtonPressedScreen() { btnEvent = BUTTON_EVENT_PRESSED_SCREEN; }
|
||||||
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
||||||
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
||||||
static void userButtonPressedLongStart();
|
static void userButtonPressedLongStart();
|
||||||
|
|||||||
@@ -121,10 +121,15 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...);
|
|||||||
// Default Bluetooth PIN
|
// Default Bluetooth PIN
|
||||||
#define defaultBLEPin 123456
|
#define defaultBLEPin 123456
|
||||||
|
|
||||||
#if HAS_ETHERNET
|
#if HAS_ETHERNET && !defined(USE_WS5500)
|
||||||
#include <RAK13800_W5100S.h>
|
#include <RAK13800_W5100S.h>
|
||||||
#endif // HAS_ETHERNET
|
#endif // HAS_ETHERNET
|
||||||
|
|
||||||
|
#if HAS_ETHERNET && defined(USE_WS5500)
|
||||||
|
#include <ETHClass2.h>
|
||||||
|
#define ETH ETH2
|
||||||
|
#endif // HAS_ETHERNET
|
||||||
|
|
||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif // HAS_WIFI
|
#endif // HAS_WIFI
|
||||||
@@ -164,4 +169,4 @@ class Syslog
|
|||||||
bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0)));
|
bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0)));
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HAS_ETHERNET || HAS_WIFI
|
#endif // HAS_NETWORKING
|
||||||
@@ -27,9 +27,6 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
|||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||||
return useShortName ? "LongM" : "LongMod";
|
return useShortName ? "LongM" : "LongMod";
|
||||||
break;
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
|
||||||
return useShortName ? "VeryL" : "VLongSlow";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return useShortName ? "Custom" : "Invalid";
|
return useShortName ? "Custom" : "Invalid";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -23,32 +23,12 @@ SPIClass SPI1(HSPI);
|
|||||||
#define SDHandler SPI
|
#define SDHandler SPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // HAS_SDCARD
|
#ifndef SD_SPI_FREQUENCY
|
||||||
|
#define SD_SPI_FREQUENCY 4000000U
|
||||||
#if defined(ARCH_STM32WL)
|
|
||||||
|
|
||||||
uint16_t OSFS::startOfEEPROM = 1;
|
|
||||||
uint16_t OSFS::endOfEEPROM = 2048;
|
|
||||||
|
|
||||||
// 3) How do I read from the medium?
|
|
||||||
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output)
|
|
||||||
{
|
|
||||||
for (uint16_t i = address; i < address + num; i++) {
|
|
||||||
*output = EEPROM.read(i);
|
|
||||||
output++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) How to I write to the medium?
|
|
||||||
void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
|
|
||||||
{
|
|
||||||
for (uint16_t i = address; i < address + num; i++) {
|
|
||||||
EEPROM.update(i, *input);
|
|
||||||
input++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // HAS_SDCARD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies a file from one location to another.
|
* @brief Copies a file from one location to another.
|
||||||
*
|
*
|
||||||
@@ -58,33 +38,7 @@ void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
|
|||||||
*/
|
*/
|
||||||
bool copyFile(const char *from, const char *to)
|
bool copyFile(const char *from, const char *to)
|
||||||
{
|
{
|
||||||
#ifdef ARCH_STM32WL
|
#ifdef FSCom
|
||||||
unsigned char cbuffer[2048];
|
|
||||||
|
|
||||||
// Var to hold the result of actions
|
|
||||||
OSFS::result r;
|
|
||||||
|
|
||||||
r = OSFS::getFile(from, cbuffer);
|
|
||||||
|
|
||||||
if (r == notfound) {
|
|
||||||
LOG_ERROR("Failed to open source file %s", from);
|
|
||||||
return false;
|
|
||||||
} else if (r == noerr) {
|
|
||||||
r = OSFS::newFile(to, cbuffer, true);
|
|
||||||
if (r == noerr) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
LOG_ERROR("OSFS Error %d", r);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
LOG_ERROR("OSFS Error %d", r);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
#elif defined(FSCom)
|
|
||||||
// take SPI Lock
|
// take SPI Lock
|
||||||
concurrency::LockGuard g(spiLock);
|
concurrency::LockGuard g(spiLock);
|
||||||
unsigned char cbuffer[16];
|
unsigned char cbuffer[16];
|
||||||
@@ -123,13 +77,7 @@ bool copyFile(const char *from, const char *to)
|
|||||||
*/
|
*/
|
||||||
bool renameFile(const char *pathFrom, const char *pathTo)
|
bool renameFile(const char *pathFrom, const char *pathTo)
|
||||||
{
|
{
|
||||||
#ifdef ARCH_STM32WL
|
#ifdef FSCom
|
||||||
if (copyFile(pathFrom, pathTo) && (OSFS::deleteFile(pathFrom) == OSFS::result::NO_ERROR)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#elif defined(FSCom)
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// take SPI Lock
|
// take SPI Lock
|
||||||
@@ -361,8 +309,7 @@ void setupSDCard()
|
|||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
concurrency::LockGuard g(spiLock);
|
concurrency::LockGuard g(spiLock);
|
||||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||||
|
if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {
|
||||||
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
|
||||||
LOG_DEBUG("No SD_MMC card detected");
|
LOG_DEBUG("No SD_MMC card detected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ARCH_STM32WL)
|
#if defined(ARCH_STM32WL)
|
||||||
// STM32WL series 2 Kbytes (8 rows of 256 bytes)
|
// STM32WL
|
||||||
#include <EEPROM.h>
|
#include "LittleFS.h"
|
||||||
#include <OSFS.h>
|
#define FSCom InternalFS
|
||||||
|
#define FSBegin() FSCom.begin()
|
||||||
// Useful consts
|
using namespace STM32_LittleFS_Namespace;
|
||||||
const OSFS::result noerr = OSFS::result::NO_ERROR;
|
|
||||||
const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ARCH_RP2040)
|
#if defined(ARCH_RP2040)
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_ETHERNET && defined(USE_WS5500)
|
||||||
|
#include <ETHClass2.h>
|
||||||
|
#define ETH ETH2
|
||||||
|
#endif // HAS_ETHERNET
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DELAY_FOREVER
|
#ifndef DELAY_FOREVER
|
||||||
@@ -375,6 +380,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
// if we have a integrated device with a battery, we can assume that the battery is always connected
|
// if we have a integrated device with a battery, we can assume that the battery is always connected
|
||||||
#ifdef BATTERY_IMMUTABLE
|
#ifdef BATTERY_IMMUTABLE
|
||||||
virtual bool isBatteryConnect() override { return true; }
|
virtual bool isBatteryConnect() override { return true; }
|
||||||
|
#elif defined(ADC_V)
|
||||||
|
virtual bool isBatteryConnect() override
|
||||||
|
{
|
||||||
|
int lastReading = digitalRead(ADC_V);
|
||||||
|
// 判断值是否变化
|
||||||
|
for (int i = 2; i < 500; i++) {
|
||||||
|
int reading = digitalRead(ADC_V);
|
||||||
|
if (reading != lastReading) {
|
||||||
|
return false; // 有变化,USB供电, 没接电池
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||||
#endif
|
#endif
|
||||||
@@ -386,7 +405,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
virtual bool isVbusIn() override
|
virtual bool isVbusIn() override
|
||||||
{
|
{
|
||||||
#ifdef EXT_PWR_DETECT
|
#ifdef EXT_PWR_DETECT
|
||||||
#ifdef HELTEC_CAPSULE_SENSOR_V3
|
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB)
|
||||||
// if external powered that pin will be pulled down
|
// if external powered that pin will be pulled down
|
||||||
if (digitalRead(EXT_PWR_DETECT) == LOW) {
|
if (digitalRead(EXT_PWR_DETECT) == LOW) {
|
||||||
return true;
|
return true;
|
||||||
@@ -536,7 +555,7 @@ Power::Power() : OSThread("Power")
|
|||||||
bool Power::analogInit()
|
bool Power::analogInit()
|
||||||
{
|
{
|
||||||
#ifdef EXT_PWR_DETECT
|
#ifdef EXT_PWR_DETECT
|
||||||
#ifdef HELTEC_CAPSULE_SENSOR_V3
|
#if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB)
|
||||||
pinMode(EXT_PWR_DETECT, INPUT_PULLUP);
|
pinMode(EXT_PWR_DETECT, INPUT_PULLUP);
|
||||||
#else
|
#else
|
||||||
pinMode(EXT_PWR_DETECT, INPUT);
|
pinMode(EXT_PWR_DETECT, INPUT);
|
||||||
@@ -663,12 +682,12 @@ void Power::readPowerStatus()
|
|||||||
int8_t batteryChargePercent = -1;
|
int8_t batteryChargePercent = -1;
|
||||||
OptionalBool usbPowered = OptUnknown;
|
OptionalBool usbPowered = OptUnknown;
|
||||||
OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time
|
OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time
|
||||||
OptionalBool isCharging = OptUnknown;
|
OptionalBool isChargingNow = OptUnknown;
|
||||||
|
|
||||||
if (batteryLevel) {
|
if (batteryLevel) {
|
||||||
hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse;
|
hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse;
|
||||||
usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse;
|
usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse;
|
||||||
isCharging = batteryLevel->isCharging() ? OptTrue : OptFalse;
|
isChargingNow = batteryLevel->isCharging() ? OptTrue : OptFalse;
|
||||||
if (hasBattery) {
|
if (hasBattery) {
|
||||||
batteryVoltageMv = batteryLevel->getBattVoltage();
|
batteryVoltageMv = batteryLevel->getBattVoltage();
|
||||||
// If the AXP192 returns a valid battery percentage, use it
|
// If the AXP192 returns a valid battery percentage, use it
|
||||||
@@ -697,15 +716,15 @@ void Power::readPowerStatus()
|
|||||||
|
|
||||||
// If changed to DISCONNECTED
|
// If changed to DISCONNECTED
|
||||||
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
|
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
|
||||||
isCharging = usbPowered = OptFalse;
|
isChargingNow = usbPowered = OptFalse;
|
||||||
// If changed to CONNECTED / READY
|
// If changed to CONNECTED / READY
|
||||||
else
|
else
|
||||||
isCharging = usbPowered = OptTrue;
|
isChargingNow = usbPowered = OptTrue;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Notify any status instances that are observing us
|
// Notify any status instances that are observing us
|
||||||
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent);
|
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent);
|
||||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
||||||
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||||
newStatus.notifyObservers(&powerStatus2);
|
newStatus.notifyObservers(&powerStatus2);
|
||||||
@@ -751,6 +770,7 @@ void Power::readPowerStatus()
|
|||||||
// If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in
|
// If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in
|
||||||
// a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough.
|
// a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough.
|
||||||
//
|
//
|
||||||
|
|
||||||
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
||||||
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
|
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
|
||||||
low_voltage_counter++;
|
low_voltage_counter++;
|
||||||
|
|||||||
@@ -11,12 +11,18 @@ static File openFile(const char *filename, bool fullAtomic)
|
|||||||
FSCom.remove(filename);
|
FSCom.remove(filename);
|
||||||
return FSCom.open(filename, FILE_O_WRITE);
|
return FSCom.open(filename, FILE_O_WRITE);
|
||||||
#endif
|
#endif
|
||||||
if (!fullAtomic)
|
if (!fullAtomic) {
|
||||||
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
||||||
|
}
|
||||||
|
|
||||||
String filenameTmp = filename;
|
String filenameTmp = filename;
|
||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
|
|
||||||
|
// FIXME: If we are doing a full atomic write, we may need to remove the old tmp file now
|
||||||
|
// if (fullAtomic) {
|
||||||
|
// FSCom.remove(filename);
|
||||||
|
// }
|
||||||
|
|
||||||
// clear any previous LFS errors
|
// clear any previous LFS errors
|
||||||
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#define STATUS_TYPE_POWER 1
|
#define STATUS_TYPE_POWER 1
|
||||||
#define STATUS_TYPE_GPS 2
|
#define STATUS_TYPE_GPS 2
|
||||||
#define STATUS_TYPE_NODE 3
|
#define STATUS_TYPE_NODE 3
|
||||||
|
#define STATUS_TYPE_BLUETOOTH 4
|
||||||
|
|
||||||
namespace meshtastic
|
namespace meshtastic
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,8 +30,11 @@ struct ToneDuration {
|
|||||||
#define NOTE_B3 247
|
#define NOTE_B3 247
|
||||||
#define NOTE_CS4 277
|
#define NOTE_CS4 277
|
||||||
|
|
||||||
const int DURATION_1_8 = 125; // 1/8 note
|
const int DURATION_1_8 = 125; // 1/8 note
|
||||||
const int DURATION_1_4 = 250; // 1/4 note
|
const int DURATION_1_4 = 250; // 1/4 note
|
||||||
|
const int DURATION_1_2 = 500; // 1/2 note
|
||||||
|
const int DURATION_3_4 = 750; // 1/4 note
|
||||||
|
const int DURATION_1_1 = 1000; // 1/1 note
|
||||||
|
|
||||||
void playTones(const ToneDuration *tone_durations, int size)
|
void playTones(const ToneDuration *tone_durations, int size)
|
||||||
{
|
{
|
||||||
@@ -55,6 +58,12 @@ void playBeep()
|
|||||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void playLongBeep()
|
||||||
|
{
|
||||||
|
ToneDuration melody[] = {{NOTE_B3, DURATION_1_1}};
|
||||||
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||||
|
}
|
||||||
|
|
||||||
void playGPSEnableBeep()
|
void playGPSEnableBeep()
|
||||||
{
|
{
|
||||||
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};
|
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void playBeep();
|
void playBeep();
|
||||||
|
void playLongBeep();
|
||||||
void playStartMelody();
|
void playStartMelody();
|
||||||
void playShutdownMelody();
|
void playShutdownMelody();
|
||||||
void playGPSEnableBeep();
|
void playGPSEnableBeep();
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define LPS22HB_ADDR 0x5C
|
#define LPS22HB_ADDR 0x5C
|
||||||
#define LPS22HB_ADDR_ALT 0x5D
|
#define LPS22HB_ADDR_ALT 0x5D
|
||||||
#define SHT31_4x_ADDR 0x44
|
#define SHT31_4x_ADDR 0x44
|
||||||
|
#define SHT31_4x_ADDR_ALT 0x45
|
||||||
#define PMSA0031_ADDR 0x12
|
#define PMSA0031_ADDR 0x12
|
||||||
#define QMA6100P_ADDR 0x12
|
#define QMA6100P_ADDR 0x12
|
||||||
#define AHT10_ADDR 0x38
|
#define AHT10_ADDR 0x38
|
||||||
@@ -150,6 +151,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define MAX30102_ADDR 0x57
|
#define MAX30102_ADDR 0x57
|
||||||
#define MLX90614_ADDR_DEF 0x5A
|
#define MLX90614_ADDR_DEF 0x5A
|
||||||
#define CGRADSENS_ADDR 0x66
|
#define CGRADSENS_ADDR 0x66
|
||||||
|
#define LTR390UV_ADDR 0x53
|
||||||
|
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34 // same adress as TCA8418
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// ACCELEROMETER
|
// ACCELEROMETER
|
||||||
@@ -168,6 +171,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// LED
|
// LED
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#define NCP5623_ADDR 0x38
|
#define NCP5623_ADDR 0x38
|
||||||
|
#define LP5562_ADDR 0x30
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Security
|
// Security
|
||||||
@@ -293,6 +297,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#error HW_VENDOR must be defined
|
#error HW_VENDOR must be defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Support multiple RGB LED configuration
|
||||||
|
#if defined(HAS_NCP5623) || defined(HAS_LP5562) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||||
|
#define HAS_RGB_LED
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Global switches to turn off features for a minimized build
|
// Global switches to turn off features for a minimized build
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
|||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB};
|
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB, TCA8418KB};
|
||||||
return firstOfOrNONE(5, types);
|
return firstOfOrNONE(6, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||||
@@ -41,6 +41,12 @@ ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
|||||||
return firstOfOrNONE(8, types);
|
return firstOfOrNONE(8, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstRGBLED() const
|
||||||
|
{
|
||||||
|
ScanI2C::DeviceType types[] = {NCP5623, LP5562};
|
||||||
|
return firstOfOrNONE(2, types);
|
||||||
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
||||||
{
|
{
|
||||||
return DEVICE_NONE;
|
return DEVICE_NONE;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ScanI2C
|
|||||||
TDECKKB,
|
TDECKKB,
|
||||||
BBQ10KB,
|
BBQ10KB,
|
||||||
RAK14004,
|
RAK14004,
|
||||||
PMU_AXP192_AXP2101,
|
PMU_AXP192_AXP2101, // has the same adress as the TCA8418KB
|
||||||
BME_680,
|
BME_680,
|
||||||
BME_280,
|
BME_280,
|
||||||
BMP_280,
|
BMP_280,
|
||||||
@@ -49,6 +49,7 @@ class ScanI2C
|
|||||||
VEML7700,
|
VEML7700,
|
||||||
RCWL9620,
|
RCWL9620,
|
||||||
NCP5623,
|
NCP5623,
|
||||||
|
LP5562,
|
||||||
TSL2591,
|
TSL2591,
|
||||||
OPT3001,
|
OPT3001,
|
||||||
MLX90632,
|
MLX90632,
|
||||||
@@ -67,6 +68,9 @@ class ScanI2C
|
|||||||
INA226,
|
INA226,
|
||||||
NXP_SE050,
|
NXP_SE050,
|
||||||
DFROBOT_RAIN,
|
DFROBOT_RAIN,
|
||||||
|
DPS310,
|
||||||
|
LTR390UV,
|
||||||
|
TCA8418KB,
|
||||||
} DeviceType;
|
} DeviceType;
|
||||||
|
|
||||||
// typedef uint8_t DeviceAddress;
|
// typedef uint8_t DeviceAddress;
|
||||||
@@ -119,6 +123,8 @@ class ScanI2C
|
|||||||
|
|
||||||
FoundDevice firstAccelerometer() const;
|
FoundDevice firstAccelerometer() const;
|
||||||
|
|
||||||
|
FoundDevice firstRGBLED() const;
|
||||||
|
|
||||||
virtual FoundDevice find(DeviceType) const;
|
virtual FoundDevice find(DeviceType) const;
|
||||||
|
|
||||||
virtual bool exists(DeviceType) const;
|
virtual bool exists(DeviceType) const;
|
||||||
|
|||||||
@@ -10,11 +10,6 @@
|
|||||||
#include "meshUtils.h" // vformat
|
#include "meshUtils.h" // vformat
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
|
|
||||||
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
|
|
||||||
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool in_array(uint8_t *array, int size, uint8_t lookfor)
|
bool in_array(uint8_t *array, int size, uint8_t lookfor)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -218,9 +213,20 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_LP5562
|
||||||
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "AXP192/AXP2101", (uint8_t)addr.address)
|
SCAN_SIMPLE_CASE(LP5562_ADDR, LP5562, "LP5562", (uint8_t)addr.address);
|
||||||
#endif
|
#endif
|
||||||
|
case XPOWERS_AXP192_AXP2101_ADDRESS:
|
||||||
|
// Do we have the axp2101/192 or the TCA8418
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x90), 1);
|
||||||
|
if (registerValue == 0x0) {
|
||||||
|
logFoundDevice("TCA8418", (uint8_t)addr.address);
|
||||||
|
type = TCA8418KB;
|
||||||
|
} else {
|
||||||
|
logFoundDevice("AXP192/AXP2101", (uint8_t)addr.address);
|
||||||
|
type = PMU_AXP192_AXP2101;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BME_ADDR:
|
case BME_ADDR:
|
||||||
case BME_ADDR_ALTERNATE:
|
case BME_ADDR_ALTERNATE:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
||||||
@@ -237,6 +243,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
logFoundDevice("BMP085/BMP180", (uint8_t)addr.address);
|
logFoundDevice("BMP085/BMP180", (uint8_t)addr.address);
|
||||||
type = BMP_085;
|
type = BMP_085;
|
||||||
break;
|
break;
|
||||||
|
case 0x00:
|
||||||
|
// do we have a DPS310 instead?
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0D), 1);
|
||||||
|
switch (registerValue) {
|
||||||
|
case 0x10:
|
||||||
|
logFoundDevice("DPS310", (uint8_t)addr.address);
|
||||||
|
type = DPS310;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
||||||
switch (registerValue) {
|
switch (registerValue) {
|
||||||
@@ -339,7 +355,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHT31_4x_ADDR:
|
case SHT31_4x_ADDR: // same as OPT3001_ADDR_ALT
|
||||||
|
case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
||||||
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
|
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
|
||||||
type = SHT4X;
|
type = SHT4X;
|
||||||
@@ -412,11 +429,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001", (uint8_t)addr.address);
|
|
||||||
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
||||||
|
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
|
||||||
#ifdef HAS_TPS65233
|
#ifdef HAS_TPS65233
|
||||||
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
148
src/gps/GPS.cpp
148
src/gps/GPS.cpp
@@ -1,3 +1,7 @@
|
|||||||
|
#include <cstring> // Include for strstr
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
#include "Default.h"
|
#include "Default.h"
|
||||||
@@ -8,6 +12,7 @@
|
|||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Throttle.h"
|
#include "Throttle.h"
|
||||||
#include "buzz.h"
|
#include "buzz.h"
|
||||||
|
#include "concurrency/Periodic.h"
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
|
|
||||||
#include "main.h" // pmu_found
|
#include "main.h" // pmu_found
|
||||||
@@ -85,6 +90,45 @@ static const char *getGPSPowerStateString(GPSPowerState state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PIN_GPS_SWITCH
|
||||||
|
// If we have a hardware switch, define a periodic watcher outside of the GPS runOnce thread, since this can be sleeping
|
||||||
|
// idefinitely
|
||||||
|
|
||||||
|
int lastState = LOW;
|
||||||
|
bool firstrun = true;
|
||||||
|
|
||||||
|
static int32_t gpsSwitch()
|
||||||
|
{
|
||||||
|
if (gps) {
|
||||||
|
int currentState = digitalRead(PIN_GPS_SWITCH);
|
||||||
|
|
||||||
|
// if the switch is set to zero, disable the GPS Thread
|
||||||
|
if (firstrun)
|
||||||
|
if (currentState == LOW)
|
||||||
|
lastState = HIGH;
|
||||||
|
|
||||||
|
if (currentState != lastState) {
|
||||||
|
if (currentState == LOW) {
|
||||||
|
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
||||||
|
if (!firstrun)
|
||||||
|
playGPSDisableBeep();
|
||||||
|
gps->disable();
|
||||||
|
} else {
|
||||||
|
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||||
|
if (!firstrun)
|
||||||
|
playGPSEnableBeep();
|
||||||
|
gps->enable();
|
||||||
|
}
|
||||||
|
lastState = currentState;
|
||||||
|
}
|
||||||
|
firstrun = false;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static concurrency::Periodic *gpsPeriodic;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void UBXChecksum(uint8_t *message, size_t length)
|
static void UBXChecksum(uint8_t *message, size_t length)
|
||||||
{
|
{
|
||||||
uint8_t CK_A = 0, CK_B = 0;
|
uint8_t CK_A = 0, CK_B = 0;
|
||||||
@@ -977,15 +1021,16 @@ void GPS::down()
|
|||||||
setPowerState(GPS_IDLE);
|
setPowerState(GPS_IDLE);
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// Check whether the GPS hardware is capable of GPS_SOFTSLEEP
|
// Check whether the GPS hardware is capable of GPS_SOFTSLEEP
|
||||||
// If not, fallback to GPS_HARDSLEEP instead
|
// If not, fallback to GPS_HARDSLEEP instead
|
||||||
|
#ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin
|
||||||
|
bool softsleepSupported = true;
|
||||||
|
#else
|
||||||
bool softsleepSupported = false;
|
bool softsleepSupported = false;
|
||||||
|
#endif
|
||||||
// U-blox is supported via PMREQ
|
// U-blox is supported via PMREQ
|
||||||
if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10))
|
if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9, GNSS_MODEL_UBLOX10))
|
||||||
softsleepSupported = true;
|
softsleepSupported = true;
|
||||||
#ifdef PIN_GPS_STANDBY // L76B, L76K and clones have a standby pin
|
|
||||||
softsleepSupported = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (softsleepSupported) {
|
if (softsleepSupported) {
|
||||||
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
|
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
|
||||||
@@ -1100,12 +1145,16 @@ int32_t GPS::runOnce()
|
|||||||
return (powerState == GPS_ACTIVE) ? GPS_THREAD_INTERVAL : 5000;
|
return (powerState == GPS_ACTIVE) ? GPS_THREAD_INTERVAL : 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the GPS rx buffer as quickly as possible
|
// clear the GPS rx/tx buffer as quickly as possible
|
||||||
void GPS::clearBuffer()
|
void GPS::clearBuffer()
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
_serial_gps->flush(false);
|
||||||
|
#else
|
||||||
int x = _serial_gps->available();
|
int x = _serial_gps->available();
|
||||||
while (x--)
|
while (x--)
|
||||||
_serial_gps->read();
|
_serial_gps->read();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
|
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
|
||||||
@@ -1117,7 +1166,7 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *PROBE_MESSAGE = "Trying %s (%s)...";
|
static const char *PROBE_MESSAGE = "Trying %s (%s)...";
|
||||||
static const char *DETECTED_MESSAGE = "%s detected, using %s Module";
|
static const char *DETECTED_MESSAGE = "%s detected";
|
||||||
|
|
||||||
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
||||||
do { \
|
do { \
|
||||||
@@ -1125,11 +1174,22 @@ static const char *DETECTED_MESSAGE = "%s detected, using %s Module";
|
|||||||
clearBuffer(); \
|
clearBuffer(); \
|
||||||
_serial_gps->write(TOWRITE "\r\n"); \
|
_serial_gps->write(TOWRITE "\r\n"); \
|
||||||
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
|
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
|
||||||
LOG_INFO(DETECTED_MESSAGE, CHIP, #DRIVER); \
|
LOG_INFO(DETECTED_MESSAGE, CHIP); \
|
||||||
return DRIVER; \
|
return DRIVER; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define PROBE_FAMILY(FAMILY_NAME, COMMAND, RESPONSE_MAP, TIMEOUT) \
|
||||||
|
do { \
|
||||||
|
LOG_DEBUG(PROBE_MESSAGE, COMMAND, FAMILY_NAME); \
|
||||||
|
clearBuffer(); \
|
||||||
|
_serial_gps->write(COMMAND "\r\n"); \
|
||||||
|
GnssModel_t detectedDriver = getProbeResponse(TIMEOUT, RESPONSE_MAP); \
|
||||||
|
if (detectedDriver != GNSS_MODEL_UNKNOWN) { \
|
||||||
|
return detectedDriver; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
GnssModel_t GPS::probe(int serialSpeed)
|
GnssModel_t GPS::probe(int serialSpeed)
|
||||||
{
|
{
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
||||||
@@ -1160,31 +1220,35 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
delay(20);
|
delay(20);
|
||||||
|
|
||||||
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
|
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
|
||||||
PROBE_SIMPLE("UC6580", "$PDTINFO", "UC6580", GNSS_MODEL_UC6580, 500);
|
std::vector<ChipInfo> unicore = {{"UC6580", "UC6580", GNSS_MODEL_UC6580}, {"UM600", "UM600", GNSS_MODEL_UC6580}};
|
||||||
PROBE_SIMPLE("UM600", "$PDTINFO", "UM600", GNSS_MODEL_UC6580, 500);
|
PROBE_FAMILY("Unicore Family", "$PDTINFO", unicore, 500);
|
||||||
PROBE_SIMPLE("ATGM336H", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H, 500);
|
|
||||||
/* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS))
|
std::vector<ChipInfo> atgm = {
|
||||||
based on AT6558 */
|
{"ATGM336H", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H},
|
||||||
PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500);
|
/* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS)) based on AT6558 */
|
||||||
|
{"ATGM332D", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H}};
|
||||||
|
PROBE_FAMILY("ATGM33xx Family", "$PCAS06,1*1A", atgm, 500);
|
||||||
|
|
||||||
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
|
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
|
||||||
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
|
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
|
||||||
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
|
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
|
||||||
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
||||||
PROBE_SIMPLE("AG3335", "$PAIR021*39", "$PAIR021,AG3335", GNSS_MODEL_AG3335, 500);
|
std::vector<ChipInfo> airoha = {{"AG3335", "$PAIR021,AG3335", GNSS_MODEL_AG3335},
|
||||||
PROBE_SIMPLE("AG3352", "$PAIR021*39", "$PAIR021,AG3352", GNSS_MODEL_AG3352, 500);
|
{"AG3352", "$PAIR021,AG3352", GNSS_MODEL_AG3352},
|
||||||
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
|
{"RYS3520", "$PAIR021,REYAX_RYS3520_V2", GNSS_MODEL_AG3352}};
|
||||||
|
PROBE_FAMILY("Airoha Family", "$PAIR021*39", airoha, 1000);
|
||||||
|
|
||||||
|
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
|
||||||
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
|
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
|
||||||
|
|
||||||
// Close all NMEA sentences, valid for L76B MTK platform (Waveshare Pico GPS)
|
// Close all NMEA sentences, valid for MTK3333 and MTK3339 platforms
|
||||||
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
||||||
delay(20);
|
delay(20);
|
||||||
|
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B},
|
||||||
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S},
|
||||||
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
{"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B},
|
||||||
|
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}};
|
||||||
PROBE_SIMPLE("LS20031", "$PMTK605*31", "MC-1513", GNSS_MODEL_LS20031, 500);
|
PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500);
|
||||||
|
|
||||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||||
@@ -1281,6 +1345,38 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
return GNSS_MODEL_UNKNOWN;
|
return GNSS_MODEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GnssModel_t GPS::getProbeResponse(unsigned long timeout, const std::vector<ChipInfo> &responseMap)
|
||||||
|
{
|
||||||
|
String response = "";
|
||||||
|
unsigned long start = millis();
|
||||||
|
while (millis() - start < timeout) {
|
||||||
|
if (_serial_gps->available()) {
|
||||||
|
response += (char)_serial_gps->read();
|
||||||
|
|
||||||
|
if (response.endsWith(",") || response.endsWith("\r\n")) {
|
||||||
|
#ifdef GPS_DEBUG
|
||||||
|
LOG_DEBUG(response.c_str());
|
||||||
|
#endif
|
||||||
|
// check if we can see our chips
|
||||||
|
for (const auto &chipInfo : responseMap) {
|
||||||
|
if (strstr(response.c_str(), chipInfo.detectionString.c_str()) != nullptr) {
|
||||||
|
LOG_INFO("%s detected", chipInfo.chipName.c_str());
|
||||||
|
return chipInfo.driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (response.endsWith("\r\n")) {
|
||||||
|
response.trim();
|
||||||
|
response = ""; // Reset the response string for the next potential message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef GPS_DEBUG
|
||||||
|
LOG_DEBUG(response.c_str());
|
||||||
|
#endif
|
||||||
|
return GNSS_MODEL_UNKNOWN; // Return empty string on timeout
|
||||||
|
}
|
||||||
|
|
||||||
GPS *GPS::createGps()
|
GPS *GPS::createGps()
|
||||||
{
|
{
|
||||||
int8_t _rx_gpio = config.position.rx_gpio;
|
int8_t _rx_gpio = config.position.rx_gpio;
|
||||||
@@ -1334,6 +1430,12 @@ GPS *GPS::createGps()
|
|||||||
pinMode(PIN_GPS_PPS, INPUT);
|
pinMode(PIN_GPS_PPS, INPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_GPS_SWITCH
|
||||||
|
// toggle GPS via external GPIO switch
|
||||||
|
pinMode(PIN_GPS_SWITCH, INPUT);
|
||||||
|
gpsPeriodic = new concurrency::Periodic("GPSSwitch", gpsSwitch);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Currently disabled per issue #525 (TinyGPS++ crash bug)
|
// Currently disabled per issue #525 (TinyGPS++ crash bug)
|
||||||
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
|
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ enum GPSPowerState : uint8_t {
|
|||||||
GPS_OFF // Powered off indefinitely
|
GPS_OFF // Powered off indefinitely
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChipInfo {
|
||||||
|
String chipName; // The name of the chip (for logging)
|
||||||
|
String detectionString; // The string to match in the response
|
||||||
|
GnssModel_t driver; // The driver to use
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* A gps class that only reads from the GPS periodically and keeps the gps powered down except when reading
|
* A gps class that only reads from the GPS periodically and keeps the gps powered down except when reading
|
||||||
*
|
*
|
||||||
@@ -230,6 +235,8 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
GnssModel_t getProbeResponse(unsigned long timeout, const std::vector<ChipInfo> &responseMap);
|
||||||
|
|
||||||
// Get GNSS model
|
// Get GNSS model
|
||||||
GnssModel_t probe(int serialSpeed);
|
GnssModel_t probe(int serialSpeed);
|
||||||
|
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ static const uint8_t _message_GSA[] = {
|
|||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x00, // Rate for UART1
|
0x00, // Rate for UART1
|
||||||
0x00, // Rate for UART2
|
0x00, // Rate for UART2
|
||||||
0x00, // Rate for USB usefull for native linux
|
0x00, // Rate for USB useful for native linux
|
||||||
0x00, // Rate for SPI
|
0x00, // Rate for SPI
|
||||||
0x00 // Reserved
|
0x00 // Reserved
|
||||||
};
|
};
|
||||||
@@ -258,7 +258,7 @@ static const uint8_t _message_RMC[] = {
|
|||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x01, // Rate for UART1
|
0x01, // Rate for UART1
|
||||||
0x00, // Rate for UART2
|
0x00, // Rate for UART2
|
||||||
0x01, // Rate for USB usefull for native linux
|
0x01, // Rate for USB useful for native linux
|
||||||
0x00, // Rate for SPI
|
0x00, // Rate for SPI
|
||||||
0x00 // Reserved
|
0x00 // Reserved
|
||||||
};
|
};
|
||||||
@@ -269,7 +269,7 @@ static const uint8_t _message_GGA[] = {
|
|||||||
0x00, // Rate for DDC
|
0x00, // Rate for DDC
|
||||||
0x01, // Rate for UART1
|
0x01, // Rate for UART1
|
||||||
0x00, // Rate for UART2
|
0x00, // Rate for UART2
|
||||||
0x01, // Rate for USB, usefull for native linux
|
0x01, // Rate for USB, useful for native linux
|
||||||
0x00, // Rate for SPI
|
0x00, // Rate for SPI
|
||||||
0x00 // Reserved
|
0x00 // Reserved
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -128,16 +128,25 @@ bool EInkDisplay::connect()
|
|||||||
#ifdef PIN_EINK_EN
|
#ifdef PIN_EINK_EN
|
||||||
// backlight power, HIGH is backlight on, LOW is off
|
// backlight power, HIGH is backlight on, LOW is off
|
||||||
pinMode(PIN_EINK_EN, OUTPUT);
|
pinMode(PIN_EINK_EN, OUTPUT);
|
||||||
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
|
// ThinkNode M1 has a hardware dimmable backlight. Start enabled
|
||||||
|
digitalWrite(PIN_EINK_EN, HIGH);
|
||||||
|
#else
|
||||||
digitalWrite(PIN_EINK_EN, LOW);
|
digitalWrite(PIN_EINK_EN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_ECHO)
|
#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1)
|
||||||
{
|
{
|
||||||
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
||||||
|
|
||||||
adafruitDisplay = new GxEPD2_BW<EINK_DISPLAY_MODEL, EINK_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
adafruitDisplay = new GxEPD2_BW<EINK_DISPLAY_MODEL, EINK_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||||
adafruitDisplay->init();
|
adafruitDisplay->init();
|
||||||
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
|
adafruitDisplay->setRotation(4);
|
||||||
|
#else
|
||||||
adafruitDisplay->setRotation(3);
|
adafruitDisplay->setRotation(3);
|
||||||
|
#endif
|
||||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
}
|
}
|
||||||
#elif defined(MESHLINK)
|
#elif defined(MESHLINK)
|
||||||
@@ -166,7 +175,8 @@ bool EInkDisplay::connect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213) || \
|
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_VISION_MASTER_E213) || \
|
||||||
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER)
|
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER) || \
|
||||||
|
defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER)
|
||||||
{
|
{
|
||||||
// Start HSPI
|
// Start HSPI
|
||||||
hspi = new SPIClass(HSPI);
|
hspi = new SPIClass(HSPI);
|
||||||
@@ -182,6 +192,9 @@ bool EInkDisplay::connect()
|
|||||||
// Init GxEPD2
|
// Init GxEPD2
|
||||||
adafruitDisplay->init();
|
adafruitDisplay->init();
|
||||||
adafruitDisplay->setRotation(3);
|
adafruitDisplay->setRotation(3);
|
||||||
|
#if defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(CROWPANEL_ESP32S3_4_EPAPER)
|
||||||
|
adafruitDisplay->setRotation(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#elif defined(PCA10059) || defined(ME25LS01)
|
#elif defined(PCA10059) || defined(ME25LS01)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ class EInkDisplay : public OLEDDisplay
|
|||||||
|
|
||||||
// If display uses HSPI
|
// If display uses HSPI
|
||||||
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E213) || \
|
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_VISION_MASTER_E213) || \
|
||||||
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER)
|
defined(HELTEC_VISION_MASTER_E290) || defined(TLORA_T3S3_EPAPER) || defined(CROWPANEL_ESP32S3_5_EPAPER) || \
|
||||||
|
defined(CROWPANEL_ESP32S3_4_EPAPER) || defined(CROWPANEL_ESP32S3_2_EPAPER)
|
||||||
SPIClass *hspi = NULL;
|
SPIClass *hspi = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -77,4 +78,4 @@ class EInkDisplay : public OLEDDisplay
|
|||||||
uint32_t lastDrawMsec = 0;
|
uint32_t lastDrawMsec = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -324,6 +324,14 @@ void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
|
|||||||
if (refresh != UNSPECIFIED)
|
if (refresh != UNSPECIFIED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Bypass limit if UNLIMITED_FAST mode is active
|
||||||
|
if (frameFlags & UNLIMITED_FAST) {
|
||||||
|
refresh = FAST;
|
||||||
|
reason = NO_OBJECTIONS;
|
||||||
|
LOG_DEBUG("refresh=FAST, reason=UNLIMITED_FAST_MODE_ACTIVE, frameFlags=0x%x", frameFlags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If too many FAST refreshes consecutively - force a FULL refresh
|
// If too many FAST refreshes consecutively - force a FULL refresh
|
||||||
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
|
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
|
|||||||
EInkDynamicDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus);
|
EInkDynamicDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus);
|
||||||
~EInkDynamicDisplay();
|
~EInkDynamicDisplay();
|
||||||
|
|
||||||
|
// Methods to enable or disable unlimited fast refresh mode
|
||||||
|
void enableUnlimitedFastMode() { addFrameFlag(UNLIMITED_FAST); }
|
||||||
|
void disableUnlimitedFastMode() { frameFlags = (frameFlagTypes)(frameFlags & ~UNLIMITED_FAST); }
|
||||||
|
|
||||||
// What kind of frame is this
|
// What kind of frame is this
|
||||||
enum frameFlagTypes : uint8_t {
|
enum frameFlagTypes : uint8_t {
|
||||||
BACKGROUND = (1 << 0), // For frames via display()
|
BACKGROUND = (1 << 0), // For frames via display()
|
||||||
@@ -30,6 +34,7 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
|
|||||||
COSMETIC = (1 << 2), // For splashes
|
COSMETIC = (1 << 2), // For splashes
|
||||||
DEMAND_FAST = (1 << 3), // Special case only
|
DEMAND_FAST = (1 << 3), // Special case only
|
||||||
BLOCKING = (1 << 4), // Modifier - block while refresh runs
|
BLOCKING = (1 << 4), // Modifier - block while refresh runs
|
||||||
|
UNLIMITED_FAST = (1 << 5)
|
||||||
};
|
};
|
||||||
void addFrameFlag(frameFlagTypes flag);
|
void addFrameFlag(frameFlagTypes flag);
|
||||||
|
|
||||||
|
|||||||
5
src/graphics/NomadStarLED.h
Normal file
5
src/graphics/NomadStarLED.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#ifdef HAS_LP5562
|
||||||
|
#include <LP5562.h>
|
||||||
|
extern LP5562 rgbw;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "ButtonThread.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -1606,6 +1607,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
|||||||
if (on != screenOn) {
|
if (on != screenOn) {
|
||||||
if (on) {
|
if (on) {
|
||||||
LOG_INFO("Turn on screen");
|
LOG_INFO("Turn on screen");
|
||||||
|
buttonThread->setScreenFlag(true);
|
||||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||||
#ifdef T_WATCH_S3
|
#ifdef T_WATCH_S3
|
||||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||||
@@ -1641,6 +1643,12 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
|||||||
setScreensaverFrames(einkScreensaver);
|
setScreensaverFrames(einkScreensaver);
|
||||||
#endif
|
#endif
|
||||||
LOG_INFO("Turn off screen");
|
LOG_INFO("Turn off screen");
|
||||||
|
buttonThread->setScreenFlag(false);
|
||||||
|
#ifdef ELECROW_ThinkNode_M1
|
||||||
|
if (digitalRead(PIN_EINK_EN) == HIGH) {
|
||||||
|
digitalWrite(PIN_EINK_EN, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
dispdev->displayOff();
|
dispdev->displayOff();
|
||||||
#ifdef USE_ST7789
|
#ifdef USE_ST7789
|
||||||
SPI1.end();
|
SPI1.end();
|
||||||
@@ -2664,14 +2672,19 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
// minutes %= 60;
|
// minutes %= 60;
|
||||||
// hours %= 24;
|
// hours %= 24;
|
||||||
|
|
||||||
|
// Show uptime as days, hours, minutes OR seconds
|
||||||
|
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
|
||||||
|
|
||||||
|
// Line 1 (Still)
|
||||||
|
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
||||||
|
if (config.display.heading_bold)
|
||||||
|
display->drawString(x - 1 + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
||||||
|
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
|
|
||||||
// Setup string to assemble analogClock string
|
// Setup string to assemble analogClock string
|
||||||
std::string analogClock = "";
|
std::string analogClock = "";
|
||||||
|
|
||||||
// Show uptime as days, hours, minutes OR seconds
|
|
||||||
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
|
|
||||||
|
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
||||||
if (rtc_sec > 0) {
|
if (rtc_sec > 0) {
|
||||||
long hms = rtc_sec % SEC_PER_DAY;
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
@@ -2704,9 +2717,6 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
analogClock += timebuf;
|
analogClock += timebuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line 1
|
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
|
||||||
|
|
||||||
// Line 2
|
// Line 2
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, analogClock.c_str());
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, analogClock.c_str());
|
||||||
|
|
||||||
@@ -2728,7 +2738,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
drawGPSpowerstat(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
drawGPSpowerstat(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||||
#ifdef SHOW_REDRAWS
|
#ifdef SHOW_REDRAWS
|
||||||
if (heartbeat)
|
if (heartbeat)
|
||||||
display->setPixel(0, 0);
|
display->setPixel(0, 0);
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsCS.h"
|
#include "graphics/fonts/OLEDDisplayFontsCS.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CROWPANEL_ESP32S3_5_EPAPER
|
||||||
|
#include "graphics/fonts/EinkDisplayFonts.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OLED_PL
|
#ifdef OLED_PL
|
||||||
#define FONT_SMALL_LOCAL ArialMT_Plain_10_PL
|
#define FONT_SMALL_LOCAL ArialMT_Plain_10_PL
|
||||||
#else
|
#else
|
||||||
@@ -73,6 +77,15 @@
|
|||||||
#define FONT_LARGE FONT_LARGE_LOCAL // Height: 28
|
#define FONT_LARGE FONT_LARGE_LOCAL // Height: 28
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CROWPANEL_ESP32S3_5_EPAPER)
|
||||||
|
#undef FONT_SMALL
|
||||||
|
#undef FONT_MEDIUM
|
||||||
|
#undef FONT_LARGE
|
||||||
|
#define FONT_SMALL Monospaced_plain_30
|
||||||
|
#define FONT_MEDIUM Monospaced_plain_30
|
||||||
|
#define FONT_LARGE Monospaced_plain_30
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _fontHeight(font) ((font)[1] + 1) // height is position 1
|
#define _fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||||
|
|
||||||
#define FONT_HEIGHT_SMALL _fontHeight(FONT_SMALL)
|
#define FONT_HEIGHT_SMALL _fontHeight(FONT_SMALL)
|
||||||
|
|||||||
1184
src/graphics/fonts/EinkDisplayFonts.cpp
Normal file
1184
src/graphics/fonts/EinkDisplayFonts.cpp
Normal file
File diff suppressed because it is too large
Load Diff
14
src/graphics/fonts/EinkDisplayFonts.h
Normal file
14
src/graphics/fonts/EinkDisplayFonts.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef EINKDISPLAYFONTS_h
|
||||||
|
#define EINKDISPLAYFONTS_h
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
#include <Arduino.h>
|
||||||
|
#elif __MBED__
|
||||||
|
#define PROGMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monospaced Plain 30
|
||||||
|
*/
|
||||||
|
extern const uint8_t Monospaced_plain_30[] PROGMEM;
|
||||||
|
#endif
|
||||||
108
src/graphics/niche/Drivers/Backlight/LatchingBacklight.cpp
Normal file
108
src/graphics/niche/Drivers/Backlight/LatchingBacklight.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
|
||||||
|
#include "./LatchingBacklight.h"
|
||||||
|
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
|
using namespace NicheGraphics::Drivers;
|
||||||
|
|
||||||
|
// Private constructor
|
||||||
|
// Called by getInstance
|
||||||
|
LatchingBacklight::LatchingBacklight()
|
||||||
|
{
|
||||||
|
// Attach the deep sleep callback
|
||||||
|
deepSleepObserver.observe(¬ifyDeepSleep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get access to (or create) the singleton instance of this class
|
||||||
|
LatchingBacklight *LatchingBacklight::getInstance()
|
||||||
|
{
|
||||||
|
// Instantiate the class the first time this method is called
|
||||||
|
static LatchingBacklight *const singletonInstance = new LatchingBacklight;
|
||||||
|
|
||||||
|
return singletonInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which pin controls the backlight?
|
||||||
|
// Is the light active HIGH (default) or active LOW?
|
||||||
|
void LatchingBacklight::setPin(uint8_t pin, bool activeWhen)
|
||||||
|
{
|
||||||
|
this->pin = pin;
|
||||||
|
this->logicActive = activeWhen;
|
||||||
|
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
off(); // Explicit off seem required by T-Echo?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when device is shutting down
|
||||||
|
// Ensures the backlight is off
|
||||||
|
int LatchingBacklight::beforeDeepSleep(void *unused)
|
||||||
|
{
|
||||||
|
// Contingency only
|
||||||
|
// - pin wasn't set
|
||||||
|
if (pin != (uint8_t)-1) {
|
||||||
|
off();
|
||||||
|
pinMode(pin, INPUT); // High impedance - unnecessary?
|
||||||
|
} else
|
||||||
|
LOG_WARN("LatchingBacklight instantiated, but pin not set");
|
||||||
|
return 0; // Continue with deep sleep
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the backlight on *temporarily*
|
||||||
|
// This should be used for momentary illumination, such as while a button is held
|
||||||
|
// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
|
||||||
|
void LatchingBacklight::peek()
|
||||||
|
{
|
||||||
|
assert(pin != (uint8_t)-1);
|
||||||
|
digitalWrite(pin, logicActive); // On
|
||||||
|
on = true;
|
||||||
|
latched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the backlight on, and keep it on
|
||||||
|
// This should be used when the backlight should remain active, even after user input ends
|
||||||
|
// e.g. when enabled via the menu
|
||||||
|
// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
|
||||||
|
void LatchingBacklight::latch()
|
||||||
|
{
|
||||||
|
assert(pin != (uint8_t)-1);
|
||||||
|
|
||||||
|
// Blink if moving from peek to latch
|
||||||
|
// Indicates to user that the transition has taken place
|
||||||
|
if (on && !latched) {
|
||||||
|
digitalWrite(pin, !logicActive); // Off
|
||||||
|
delay(25);
|
||||||
|
digitalWrite(pin, logicActive); // On
|
||||||
|
delay(25);
|
||||||
|
digitalWrite(pin, !logicActive); // Off
|
||||||
|
delay(25);
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(pin, logicActive); // On
|
||||||
|
on = true;
|
||||||
|
latched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the backlight off
|
||||||
|
// Suitable for ending both peek and latch
|
||||||
|
void LatchingBacklight::off()
|
||||||
|
{
|
||||||
|
assert(pin != (uint8_t)-1);
|
||||||
|
digitalWrite(pin, !logicActive); // Off
|
||||||
|
on = false;
|
||||||
|
latched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LatchingBacklight::isOn()
|
||||||
|
{
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LatchingBacklight::isLatched()
|
||||||
|
{
|
||||||
|
return latched;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
50
src/graphics/niche/Drivers/Backlight/LatchingBacklight.h
Normal file
50
src/graphics/niche/Drivers/Backlight/LatchingBacklight.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Singleton class
|
||||||
|
On-demand control of a display's backlight, connected to a GPIO
|
||||||
|
Initial use case is control of T-Echo's frontlight, via the capacitive touch button
|
||||||
|
|
||||||
|
- momentary on
|
||||||
|
- latched on
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "Observer.h"
|
||||||
|
|
||||||
|
namespace NicheGraphics::Drivers
|
||||||
|
{
|
||||||
|
|
||||||
|
class LatchingBacklight
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static LatchingBacklight *getInstance(); // Create or get the singleton instance
|
||||||
|
void setPin(uint8_t pin, bool activeWhen = HIGH);
|
||||||
|
|
||||||
|
int beforeDeepSleep(void *unused); // Callback for auto-shutoff
|
||||||
|
|
||||||
|
void peek(); // Backlight on temporarily, e.g. while button held
|
||||||
|
void latch(); // Backlight on permanently, e.g. toggled via menu
|
||||||
|
void off(); // Backlight off. Suitable for both peek and latch
|
||||||
|
|
||||||
|
bool isOn(); // Either peek or latch
|
||||||
|
bool isLatched();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LatchingBacklight(); // Constructor made private: force use of getInstance
|
||||||
|
|
||||||
|
// Get notified when the system is shutting down
|
||||||
|
CallbackObserver<LatchingBacklight, void *> deepSleepObserver =
|
||||||
|
CallbackObserver<LatchingBacklight, void *>(this, &LatchingBacklight::beforeDeepSleep);
|
||||||
|
|
||||||
|
uint8_t pin = (uint8_t)-1;
|
||||||
|
bool logicActive = HIGH; // Is light active HIGH or active LOW
|
||||||
|
|
||||||
|
bool on = false; // Is light on (either peek or latched)
|
||||||
|
bool latched = false; // Is light latched on
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace NicheGraphics::Drivers
|
||||||
1
src/graphics/niche/Drivers/EInk/DEPG0154BNS800.cpp
Normal file
1
src/graphics/niche/Drivers/EInk/DEPG0154BNS800.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "./DEPG0154BNS800.h"
|
||||||
34
src/graphics/niche/Drivers/EInk/DEPG0154BNS800.h
Normal file
34
src/graphics/niche/Drivers/EInk/DEPG0154BNS800.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
E-Ink display driver
|
||||||
|
- DEPG0154BNS800
|
||||||
|
- Manufacturer: DKE
|
||||||
|
- Size: 1.54 inch
|
||||||
|
- Resolution: 152px x 152px
|
||||||
|
- Flex connector marking: FPC7525
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "./SSD16XX.h"
|
||||||
|
|
||||||
|
namespace NicheGraphics::Drivers
|
||||||
|
{
|
||||||
|
class DEPG0154BNS800 : public SSD16XX
|
||||||
|
{
|
||||||
|
// Display properties
|
||||||
|
private:
|
||||||
|
static constexpr uint32_t width = 152;
|
||||||
|
static constexpr uint32_t height = 152;
|
||||||
|
static constexpr UpdateTypes supported = (UpdateTypes)(FULL);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DEPG0154BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace NicheGraphics::Drivers
|
||||||
|
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
120
src/graphics/niche/Drivers/EInk/DEPG0290BNS800.cpp
Normal file
120
src/graphics/niche/Drivers/EInk/DEPG0290BNS800.cpp
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#include "./DEPG0290BNS800.h"
|
||||||
|
|
||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
|
||||||
|
using namespace NicheGraphics::Drivers;
|
||||||
|
|
||||||
|
// Describes the operation performed when a "fast refresh" is performed
|
||||||
|
// Source: custom, with DEPG0150BNS810 as a reference
|
||||||
|
static const uint8_t LUT_FAST[] = {
|
||||||
|
// 1 2 3 4
|
||||||
|
0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels)
|
||||||
|
0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels)
|
||||||
|
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels)
|
||||||
|
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels)
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM
|
||||||
|
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1. Tap existing black pixels back into place
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. Move new pixels
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. New pixels, and also existing black pixels
|
||||||
|
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 4. All pixels, then cooldown
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||||
|
|
||||||
|
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
// How strongly the pixels are pulled and pushed
|
||||||
|
void DEPG0290BNS800::configVoltages()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
// Listed as "typical" in datasheet
|
||||||
|
sendCommand(0x04);
|
||||||
|
sendData(0x41); // VSH1 15V
|
||||||
|
sendData(0x00); // VSH2 NA
|
||||||
|
sendData(0x32); // VSL -15V
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
// From OTP memory
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load settings about how the pixels are moved from old state to new state during a refresh
|
||||||
|
// - manually specified,
|
||||||
|
// - or with stored values from displays OTP memory
|
||||||
|
void DEPG0290BNS800::configWaveform()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
sendCommand(0x3C); // Border waveform:
|
||||||
|
sendData(0x60); // Actively hold screen border during update
|
||||||
|
|
||||||
|
sendCommand(0x32); // Write LUT register from MCU:
|
||||||
|
sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
// From OTP memory
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes the sequence of events performed by the displays controller IC during a refresh
|
||||||
|
// Includes "power up", "load settings from memory", "update the pixels", etc
|
||||||
|
void DEPG0290BNS800::configUpdateSequence()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
sendCommand(0x22); // Set "update sequence"
|
||||||
|
sendData(0xCF); // Differential, use manually loaded waveform
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
sendCommand(0x22); // Set "update sequence"
|
||||||
|
sendData(0xF7); // Non-differential, load waveform from OTP
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once the refresh operation has been started,
|
||||||
|
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
|
||||||
|
// Only used when refresh is "async"
|
||||||
|
void DEPG0290BNS800::detachFromUpdate()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
return beginPolling(50, 450); // At least 450ms for fast refresh
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
return beginPolling(100, 3000); // At least 3 seconds for full refresh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For this display, we do not need to re-write the new image.
|
||||||
|
// We're overriding SSD16XX::finalizeUpdate to make this small optimization.
|
||||||
|
// The display does also work just fine with the generic SSD16XX method, though.
|
||||||
|
void DEPG0290BNS800::finalizeUpdate()
|
||||||
|
{
|
||||||
|
// Put a copy of the image into the "old memory".
|
||||||
|
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
|
||||||
|
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
|
||||||
|
if (updateType != FULL) {
|
||||||
|
// writeNewImage(); // Not required for this display
|
||||||
|
writeOldImage();
|
||||||
|
sendCommand(0x7F); // Terminate image write without update
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user